desktop: Releases > Send for review (App Store submission state, builds by number, Submit / Resubmit / in-app purchases; Play versionCodes by number, Send to production, managed publishing, console plans for countries and Send changes for review), plan panel before every owner dialog with streamed progress; App info console steps for every console plan form with verify; Catalog price-change owner actions and the declined state; Data safety deletion answer; TestFlight create missing groups; Android SDK in Dependencies; upload progress in job toasts; boot check send-for-review cases on D1 and D3 state

This commit is contained in:
CRTkafa 2026-10-12 12:07:59 +08:00
parent 33eb24a3dc
commit 2b101f0fd8
22 changed files with 1527 additions and 57 deletions

View file

@ -25,15 +25,24 @@ Types of the protocol: `cli/lib/desktop-protocol.ts`; pure portfolio logic: `cli
the sidecar's stdin. Write methods are dry runs unless the call carries a confirm token: HMAC-SHA256 over the
method, the canonical `{ project, args }` and a 60 s expiry, single use. The host mints one only after the owner
pressed Apply in a native dialog that shows the summary and the dry run (`write_with_confirm`).
- No method submits for review, releases an approved version, publishes, cancels a submission, sends a build to
external testers or removes testers. Under `serve`, the CLI's own terminal confirmations answer no, with one
exception: the **owner actions** (`owner.play_rollout` share / halt / resume / complete, `owner.ios_phased`
on / pause / resume / complete, `owner.reply_send` one approved draft, `owner.testflight_testers` adds the testers
of `.storebound/testers.csv`). They are desktop-only (never MCP tools), dry runs from the window like every write,
and their real run needs the host token. Only then serve sets `STOREBOUND_OWNER_CONFIRMED` for that one child,
which answers the command's question. The native dialog names the action on its button ("Yes: Change the Play
staged rollout"). `tests/desktop-d3.test.ts` and `src-tauri/tests/d3_writes.rs` pin the token binding of every
write the window offers.
- No method releases an approved version, publishes, cancels a submission, sends a build to external testers or
removes testers. Under `serve`, the CLI's own terminal confirmations answer no, with one exception: the **owner
actions** (`owner.play_rollout` share / halt / resume / complete, `owner.ios_phased` on / pause / resume /
complete, `owner.reply_send` one approved draft, `owner.testflight_testers` adds the testers of
`.storebound/testers.csv`, `owner.prices_import` and `owner.prices_play_products` / `_play_subscriptions` / `_apple_subscriptions` with `--allow-price-changes`,
`owner.ppo_start` / `owner.ppo_stop`, and **sending for review**: `owner.apple_submit` (`apple submit --build n`),
`owner.apple_resubmit` (`apple resubmit --build n [--resolve-iaps]`), `owner.apple_iap_submit` (`apple iap-submit
[--with-version]`) and `owner.play_production` (`play release --version-code n --production completed | inProgress
| draft`)). They are desktop-only (never MCP tools), dry runs from the window like every write, and their real run
needs the host token. Only then serve sets `STOREBOUND_OWNER_CONFIRMED` for that one child, which answers the
command's question, and adds the owner-only flags (`--yes` of apple submit / resubmit, `--allow-price-changes`);
`OWNER_ALLOWED_ARGS` names the one action each such flag belongs to and a dry run never carries one. Builds and
versionCodes are picked by number in the window, never "the latest". The native dialog names the action on its
button ("Yes: Submit for App Review"); for the submit actions it says that the app goes to review and may go live
by itself once approved. Play's "Send changes for review" (Publishing overview) has no API: the Releases tab shows
its console plan and a deep link instead. `tests/desktop-d3.test.ts`, `tests/serve.test.ts` and
`src-tauri/tests/d3_writes.rs` pin the token binding of every write the window offers and that the MCP server has
none of these.
- The webview gets no plugin API. It may call the app commands (each re-checks the window label and the page origin
in Rust) and listen to two events. Strict CSP, no remote content. `src-tauri/tests/security.rs` pins all of it.
- Store keys (Play service account JSON, App Store Connect key id, issuer id and .p8) are picked in native dialogs,
@ -158,14 +167,31 @@ Each write is a dry run, then the native dialog, then the real run, with one pro
- **Listings tab:** Play listing text, App Store version and text, Play graphics, App Store screenshots and
previews; local render jobs (screenshots, previews, icons, gallery).
- **Catalog tab:** Play products and subscriptions, App Store IAPs and subscriptions, price export.
- **Catalog tab:** Play products and subscriptions, App Store IAPs and subscriptions, price export; price changes of
live products (`owner.prices_play_products`, `owner.prices_play_subscriptions`, `owner.prices_apple_subscriptions`, owner actions: a normal sync holds them back and exits 3, shown as "Waiting
for your decision").
- **Prices tab:** the price sheet compared with the stores and applied (`owner.prices_import`, an owner action).
- **App info tab:** Play Data safety upload, App Store app info, export compliance, App Review details.
- **App info tab:** Play Data safety upload (the deletion question as the CSV answers it and where the answer comes
from), App Store app info, export compliance, App Review details; "Console steps without an API": every form of
`console plan` (App Store app record, age rating, App Privacy; Play Create app, store settings category, every App
content card, content rating, target audience, production countries, production release) with its plan panel
(start page, steps, answer sheet, never-press buttons, Copy plan for an AI agent) and the read-only check
(`console.verify`, page text pasted or the API), plus "Fill in console" where the scripted path exists.
- **Growth tab:** analytics snapshot and report request, PPO create and treatment upload; PPO start / stop
(`owner.ppo_start`, `owner.ppo_stop`, owner actions).
- **Store art tab:** render, review page.
- **Releases tab:** rollout and phased release owner actions.
- **TestFlight tab:** What to Test, internal groups, testers.
- **Releases tab:** rollout and phased release owner actions; **Send for review**: App Store submission state from
`apple status` (waiting / in review, UNRESOLVED_ISSUES with its items, empty drafts labelled harmless), the uploaded
builds by number, Submit for review / Resubmit (with the rejected items to mark resolved) / in-app purchases; Google
Play versionCodes by number, Send to production (everyone, staged, or a draft for a never-published app), the
managed-publishing warning and the console plans for production countries and "Send changes for review". Each
button shows the plan (dry run) in the window first (`ui/OwnerAction.tsx`), then the native dialog; progress lines
of the real run stream into the panel.
- **TestFlight tab:** What to Test, internal groups, testers, "Create missing groups" (`apple testflight groups
sync`, dry run first).
- **Dependencies screen:** the Android SDK as `play build` finds it (`system.tools` `androidSdk`).
- **Job toasts:** the command's progress lines; upload lines ("312/890 MB (35%), part 4/12") drive the bar, and the
last 40 lines are in the toast's log.
- **Reviews tab:** reply editor (`reviews.reply`), approve, send (owner action).
### The same model in the terminal
@ -224,6 +250,13 @@ and account names only), the same file the desktop reads. A workspace account's
| `apple appinfo`, `apple encryption`, `apple review-details` | App info: Push buttons (confirm flow) |
| `console fill <form> --dry --json` / `console fill <form> --json` (desktop-only `console.fill`) | App info: "Fill in console" (answers panel, native dialog, visible browser the owner saves in) |
| `apple ppo status / create / upload / start / stop` | Growth: tests table, create, upload, Start / Stop owner actions |
| `apple status --json` (review submissions, UNRESOLVED_ISSUES items, empty drafts, builds) | Releases: Send for review, App Store card |
| `apple submit --build n`, `apple resubmit --build n [--resolve-iaps]`, `apple iap-submit [--with-version]` | Releases: Submit for review / Resubmit / Submit in-app purchases (owner actions) |
| `play status --json`, `play release --version-code n --production ...` | Releases: Google Play card, Send to production (owner action) |
| `console plan <form> --json`, `console verify <form> --json` | App info: Console steps (every form); Releases: production countries, Send changes for review |
| `apple testflight groups sync` | TestFlight: Create missing groups |
| `play products` / `play subscriptions` / `apple subscriptions --allow-price-changes` | Catalog: Price changes (owner action) |
| `doctor` Android SDK | Dependencies: Android SDK card |
| Play store listing experiments | no API: Growth links Play Console and the variant renders |
| `analytics compare --json`, `snapshot`, `setup` | Growth: chart (reach, installs, conversion, listing changes as markers), before / after table, snapshot and setup buttons |
| `shots gallery --json`, `inspect --render` (new) | Store art: grid per variant / language / size, issues, lightbox; images load lazily one at a time as data: URLs (never cached) |