diff --git a/docs/console-parity.md b/docs/console-parity.md new file mode 100644 index 0000000..7460355 --- /dev/null +++ b/docs/console-parity.md @@ -0,0 +1,104 @@ +# Console parity: App Store Connect and Play Console in the desktop app + +The desktop app (apps/desktop, [desktop.md](desktop.md)) is meant to replace App Store Connect and Play Console for +everything storebound can read or write. This page lists every owner-editable thing in the two consoles that the CLI +covers, and what the desktop does with it. + +Columns: + +- **storebound**: the command that reads or writes it, and where the value lives (the source of truth in the app + folder: `storebound.config.ts`, `store/listing.md`, `store/appstore.md`, `.storebound/`). +- **View**: the desktop shows the current value. +- **Edit**: the desktop edits it in place (validation, unsaved-changes guard, undo) and saves it into the source file. +- **Store write**: the desktop writes it to the store (dry run in the window, native confirm dialog, then the real + run; owner-only steps through the owner-action dialog). +- **Gap**: what is missing, or why a cell stays "no" on purpose. + +Status: **audit before the editors (2026-10-14)**. Every row whose CLI can write the value but the desktop cannot edit +it is a gap. Phase 2 closes them; this table is updated with the result. + +## App Store Connect + +| Console screen | storebound | View | Edit | Store write | Gap | +| --- | --- | --- | --- | --- | --- | +| App Information > Name (per locale) | `apple listing` (`### name`, apple.name, app.name) | counter only | no | yes (`apple.listing`) | no text editor | +| App Information > Subtitle | `apple listing` (`### subtitle`) | counter only | no | yes | no text editor | +| Version > Promotional Text | `apple listing` (`### promotionalText`) | counter only | no | yes | no text editor | +| Version > Description | `apple listing` (`### description`) | counter only | no | yes | no text editor | +| Version > Keywords | `apple listing` (`### keywords`), `check --aso` | counter only | no | yes | no editor, no keyword checks while typing | +| Version > What's New | `apple listing`, `whats-new apply` (`### whatsNew`) | no | no | yes | no editor | +| Version > Support URL | `apple listing` (app.supportUrl) | no | no | yes | not shown, no editor | +| Version > Marketing URL | `apple listing` (app.marketingUrl) | no | no | yes | not shown, no editor | +| App Privacy > Privacy Policy URL | `apple listing` (app.privacyPolicyUrl) | no | no | yes | not shown, no editor | +| Version > Copyright | `apple listing` (app.copyright) | no | no | yes | not shown, no editor | +| Version > version string, build | `apple listing --version --build` | yes | version field | yes | none | +| Version > Screenshots (per device, locale) | `shots render`, `apple screenshots` | renders | no | yes (`apple.screenshots`) | no ordering or replacement of scenes | +| Version > App Previews | `shots video`, `apple previews` | renders | no | yes | no replacement | +| App Information > Category, subcategories | `apple appinfo` (apple.info.categories) | yes | no | yes (`apple.appinfo`) | no editor | +| App Information > Age Rating | `apple appinfo` (apple.info.ageRating), console plan | yes | no | yes | no editor of the answers | +| App Information > Content Rights | `apple appinfo` (apple.info.contentRights) | yes | no | yes | no editor | +| Pricing and Availability > Free, territories | `apple appinfo` (apple.info.free) | yes | no | yes | no editor | +| Pricing and Availability > Pre-orders | `apple preorder` | no | no | terminal (owner) | public step; terminal only | +| App Privacy (data types, purposes) | appPrivacy.types, `console fill apple-app-privacy` | yes | no | no API (console fill) | no editor of the answers | +| App Review Information > Contact | `apple review-details` (.storebound/credentials.json reviewContact) | masked | no | yes (`apple.review_details`) | no editor | +| App Review Information > Notes | `apple review-details` (apple.info.reviewNotes, reviewAccess.instructions) | yes | no | yes | no editor | +| App Review Information > Sign-in required, demo account | reviewAccess.signInRequired, credentials.json reviewDemoAccount | masked | no | yes | no editor of sign-in required | +| Export compliance (encryption) | `apple encryption` (apple.usesNonExemptEncryption) | yes | no | yes | no editor | +| In-App Purchases > reference name, display name, description per locale | `apple iap` (products[]) | parity only | no | yes (`apple.iap`) | no editor | +| In-App Purchases > price | products[].usd, overrides, `prices import` | yes (Prices) | no | yes, owner gate | no editor of the base price | +| In-App Purchases > review note, screenshot | products[].reviewNote / reviewScreenshot, `apple iap-review` | no | no | yes (`apple.iap_review`) | not shown, no editor | +| Subscriptions > group name per locale | `apple subscriptions` (subscriptions[].listings) | no | no | yes | no editor | +| Subscriptions > name, description per locale | `apple subscriptions` (subscriptions[].subscriptions[].listings) | parity only | no | yes | no editor | +| Subscriptions > level, period, price | `apple subscriptions` | parity only | no | yes, owner gate for live prices | no editor | +| Subscriptions > introductory and promotional offers | subscriptions[].subscriptions[].intro / offers | no | no | yes (sync) | no editor | +| Subscriptions > offer codes | `apple subscriptions` (offerCodes), `apple offer-codes` | no | no | terminal (owner) | no editor | +| Subscriptions > win-back offers | `apple win-back` (winBack) | no | no | terminal (owner) | no editor | +| In-App Purchases > promoted purchases | `apple promoted` (apple.promoted) | no | no | terminal (owner) | no editor | +| Custom product pages | `apple cpp list / create / upload` (apple.customProductPages) | no | no | CLI only | not in the window | +| In-app events | `apple events list / create / upload` (apple.events) | no | no | CLI only | not in the window | +| Product Page Optimization | `apple ppo` | yes | create / start / stop | yes (owner start / stop) | none | +| TestFlight > What to Test (per build) | `apple testflight what-to-test` | yes | yes (text) | yes | per-locale text not editable | +| TestFlight > groups | `apple testflight groups sync` (apple.testflight.groups) | yes | no | yes (create missing) | no group editor | +| TestFlight > Test Information (beta description, notes) | `apple testflight info` (apple.testflight.description / reviewNotes) | no | no | CLI only | not in the window | +| TestFlight > testers | `owner.testflight_testers` (.storebound/testers.csv) | count | no | yes (owner) | CSV not editable | +| Ratings and Reviews > reply | `reviews draft / reply / approve / send` | yes | yes | yes (owner send) | none | +| Version > phased release | `owner.ios_phased` | yes | n/a | yes (owner) | none | +| Version > Submit for review | `owner.apple_submit` / `owner.apple_resubmit` | yes | n/a | yes (owner) | none | + +## Google Play Console + +| Console screen | storebound | View | Edit | Store write | Gap | +| --- | --- | --- | --- | --- | --- | +| Main store listing > App name (per language) | `play listing` (`### title`, app.name) | counter only | no | yes (`play.listing`) | no text editor | +| Main store listing > Short description | `play listing` (`### short`) | counter only | no | yes | no text editor | +| Main store listing > Full description | `play listing` (`### full`) | counter only | no | yes | no text editor, no stuffing check while typing | +| Release > Release notes (per language) | `play release`, `whats-new apply` (`### What's new`) | counter only | no | with the release (owner) | no editor | +| Main store listing > Graphics (icon, feature graphic, screenshots) | `icons`, `shots render`, `play images` | renders | no | yes (`play.images`) | no ordering or replacement of scenes | +| Main store listing > Video (YouTube URL) | `play listing` (play.video) | no | no | yes | not shown, no editor | +| Store settings > Contact email | `play listing` app details (app.contactEmail) | no | no | yes | not shown, no editor | +| Store settings > Website | `play listing` app details (app.website) | no | no | yes | not shown, no editor | +| Store settings > App category | play.category, console plan (no API) | yes | no | no API | no editor | +| App content > Privacy policy | app.privacyPolicyUrl, console plan | no | no | no API | not shown, no editor | +| App content > Data safety | `play data-safety` (dataSafety) | yes | no | yes (`play.data_safety`) | no editor of the answers | +| App content > Content rating (IARC) | social, products[].randomRewards, `console fill play-content-rating` | yes | no | no API (console fill) | no editor of the answers | +| App content > Target audience | play.targetAges, `console fill play-target-audience` | plan | no | no API (console fill) | no editor | +| Monetize > In-app products: title, description per language | `play products` (products[].listings) | parity only | no | yes (`play.products`) | no editor | +| Monetize > In-app products: price | products[].usd / overrides, `prices import` | yes (Prices) | no | yes, owner gate | no editor of the base price | +| Monetize > Subscriptions: title, benefits, description per language | `play subscriptions` | parity only | no | yes | no editor | +| Monetize > Subscriptions: base plans, offers, price | `play subscriptions` | parity only | no | yes, owner gate | no editor | +| Pricing > regional prices (price sheet) | `prices export / import` | yes | no | yes (owner) | sheet not editable in place | +| Production > Countries / regions | play.countries, console plan | count | no | no API | no editor | +| Publishing overview > Managed publishing | play.managedPublishing | yes | no | no API | no editor | +| Testing tracks (internal, closed, open) | `play release --track` | status | n/a | terminal (owner) | sends builds to testers: not in the window by design | +| Production > staged rollout | `owner.play_rollout` | yes | n/a | yes (owner) | none | +| Production > Send to production | `owner.play_production` | yes | n/a | yes (owner) | none | +| Ratings and reviews > reply | `reviews draft / reply / approve / send` | yes | yes | yes (owner send) | none | +| Internal app sharing | `play share` | no | n/a | CLI only | not in the window | + +## Both stores + +| What | storebound | View | Edit | Store write | Gap | +| --- | --- | --- | --- | --- | --- | +| Pull the live texts into the files | `apple listing pull`, `play listing pull`, `catalog pull` | no | n/a | n/a (writes local files) | not in the window | +| Store-only app (no folder): listing text | (none) | yes (status) | no | no | store-only apps are read-only in the window | +| Uncommitted changes in the app folder | git | no | n/a | n/a | not shown | diff --git a/docs/desktop.md b/docs/desktop.md index 427a60e..db67603 100644 --- a/docs/desktop.md +++ b/docs/desktop.md @@ -17,6 +17,8 @@ development; this page is for contributors. - **Catalog parity.** Products (and subscriptions, once the config has them) are defined once; `portfolio.status` compares the config with both stores (ids missing on a store, ids on one store only). +Console parity (what the window can view, edit and write for each console screen): [console-parity.md](console-parity.md). + Types of the protocol: `cli/lib/desktop-protocol.ts`; pure portfolio logic: `cli/lib/portfolio.ts`. ## Safety model