desktop editors: edit in place what App Store Connect and Play Console let the owner edit (listings per language for both stores with live counters and the check / scan rules, store details, App info, age rating, App Review, Play store settings, Data safety and App Privacy answers, promotion blocks, catalog names / prices / offers, TestFlight information, scene order); storebound edit (project.edit) saves into the config by path keeping comments and formatting, the listing files and the review contact, dry run with the diff and the checks first; Apply shows each store's dry run in the window; unsaved edits survive tab switches with undo / redo; tests/edit.test.ts, apps/desktop/tests/edits.test.ts, boot check editor case

This commit is contained in:
CRTkafa 2026-10-14 00:35:29 +08:00
parent 714352ec18
commit 3cea2af4e1
37 changed files with 3020 additions and 54 deletions

View file

@ -14,6 +14,7 @@ run in the background with a log (`storebound shots render > .storebound/render.
| `mcp` | local | stdio MCP server wrapping the commands |
| `serve --stdio` | local | JSON-RPC session for the storebound desktop app (see [Desktop machine interface](mcp.md#desktop-machine-interface)) |
| `inspect [--json]` | local | offline summary of the config: name, store ids, languages, products |
| `edit --ops '<json>' [--dry] [--json]` | local | edit the app folder's sources of truth: config values by path (comments and formatting kept), listing fields per store and language, the App Review contact; dry run with old -> new, the diff and the checks (store limits, keyword and metadata rules, the whole config validated); `--show --json` lists what the desktop editors show. Never commits |
| `check` | local | config, copy limits, data safety, products, subscriptions, profile (delete-account URL, demo account, terms URL), files; warns on untranslated release notes |
| `catalog diff [--store] [--threshold 10]` | API, read-only | one catalog vs both stores: missing / extra / mismatched products and subscriptions, US and override prices, locales, offers, per-region price differences between the stores; exit 1 on mismatches |
| `check --aso` | local | keyword audit: App Store keyword field rules, Play stuffing / claims |

View file

@ -190,6 +190,40 @@ host state file (`overrides_set`, every key checked in `workspace.rs`).
- Reset: native confirmation, then every saved state of the app is removed; the shared credential profiles and the
app folder list stay (the CLI uses them).
### Editors (console parity)
Everything the stores' consoles let the owner edit and storebound can write is edited in the window; the parity table
is [console-parity.md](console-parity.md).
- **Where:** Listings (texts per language for both stores side by side, store details: URLs, contact, copyright, promo
video), App info (App Store categories, age rating answers, content rights, price, export compliance, App Review
sign-in, notes and contact; Play category, countries, managed publishing, target ages, delete-account page; Data
safety and App Privacy answers; promoted purchases, custom product pages, in-app events), Catalog (each product and
subscription: names and descriptions per language, USD price, reference name, review note, offers), TestFlight (What
to Test per locale, Beta App Description, Beta App Review notes, groups), Store art (scene order, the frame of each
scene).
- **While typing:** live counters against the store limits (characters, as the consoles count them) and the checks of
`check --aso` and `scan` (`cli/lib/listing-rules.ts`, the same code: required fields, keyword field rules, other
platforms, other apps' names, prices and claims, placeholder text, beta wording, keyword stuffing); URLs and emails.
- **Unsaved edits** (`src/lib/edits.ts`) live outside the tabs for the whole session: switching tabs or apps keeps
them, the tab shows a dot, undo / redo / discard, and reloading the window with unsaved edits asks first.
- **Save** ("Review and save"): the dry run of `project.edit` (`storebound edit --ops`, `cli/edit.ts`) in the window
shows old -> new, the diff per file and the checks; an error blocks the save. Save then goes through the native
dialog and writes the files: `storebound.config.ts` by path as a text edit (`cli/lib/config-path.ts`: comments,
order, quotes and formatting stay, only the value changes; the edited config is loaded and validated like `check`
before anything is written), `store/listing.md` / `store/appstore.md` field blocks (`cli/lib/listing-edit.ts`), the
App Review contact in `.storebound/credentials.json` (masked everywhere, the demo account password is never read).
A folder under version control shows the files as uncommitted; storebound never commits.
- **Apply to the stores:** each store write's dry run (old -> new per store and language) is shown in the window
first, then the native dialog, then the real run. Price changes of live products stay the owner's price decision.
- **Pull from the store** (`play.listing_pull`, `apple.listing_pull`): the live texts into the files, the diff in the
dialog first; unsaved edits stay pending on top.
- **Store-only apps** (no folder) stay read-only in the window: a store write sends what the files hold (see
console-parity.md).
- `tests/edit.test.ts` (round trips, checks, dry run, CLI), `apps/desktop/tests/edits.test.ts` (unsaved edits, undo),
and the boot check's editor case (edit a field, counter and limit check, review, save: the fixture file changes by
one line, the config keeps its comments, Apply shows the dry run per language).
### Writes in the window
Each write is a dry run, then the native dialog, then the real run, with one progress toast and Cancel: