One product per machine: the CLI and the desktop app share one version, the store accounts and the app folder list

- one version: package.json's version is the desktop app's too (desktopVersion removed); tools/desktop-version.ts
  keeps the plugin manifests and the app's copies equal, desktop-release publish refuses another version, release
  order app first then npm publish; the unpublished desktop 0.1.0 candidate is noted in the docs and CHANGELOG
- storebound desktop installs (per user, no admin: macOS DMG -> /Applications or ~/Applications, Windows NSIS /S,
  Linux AppImage + .desktop with the storebound:// handler), updates an older app, notes a newer one (downgrade only
  with --force), asks once ([Y/n], --yes, exit 3 without a terminal), opens on the folder; --dry / --json / --download;
  the install steps are pure plans (cli/lib/desktop-install.ts); the version's own manifest dl/<version>/latest.json
- credentials: one store, the CLI's credential profiles in ~/.storebound/credentials; the desktop writes and reads
  them (profiles.rs, files 0600), moves old keychain accounts into profiles on first start, shows profiles the CLI
  made; precedence env > named profile > project file > default profile; config `account`, "account" in the
  project's credentials.json; storebound accounts list | import (dedup by key id / service account e-mail, key files
  copied 0600, project file keeps keystore and review contact, backup, --dry, never prints values) | use
- app folders: one list ~/.storebound/projects.json shared by the desktop (registry.rs), storebound desktop,
  apps folders | add | remove, ws init and ws without a workspace file
- desktop: notice when a folder pins another storebound version; storebound-desktop --version
- tests: version drift, desktop decisions and per-OS plans, credential precedence and import, registry (TS + Rust),
  keychain migration and profile round trip (Rust), boot check with old keychain state and the new shared state
This commit is contained in:
CRTkafa 2026-10-13 06:17:31 +08:00
parent bba46b5c7f
commit d2ce185441
60 changed files with 2443 additions and 246 deletions

View file

@ -48,7 +48,8 @@ Every rule, what it proves and what only a reviewer can see: [docs/rejections.md
Every app and game you ship on Google Play and the App Store side by side: releases, charts, catalog and prices,
crash health, reviews, TestFlight and the rejection checks. Send for review from there too: a dry run first, then a
confirm, then your click. Same storebound underneath; store keys stay in the system keychain.
confirm, then your click. Same storebound underneath, same version number as the CLI, and the same store accounts
and app folders as your terminal (`~/.storebound`).
![storebound desktop, Releases › Send for review: the dry run of the submission with the build picked by number and the confirm step](https://git.crt.fyi/CRT/storebound/raw/branch/main/site/img/desktop/send-for-review-dark.webp)
@ -64,8 +65,8 @@ confirm, then your click. Same storebound underneath; store keys stay in the sys
</details>
Download for macOS, Windows and Linux: [storebound.dev/#download](https://storebound.dev/#download), or
`storebound desktop --download` (checks the signature, never installs). Internals: [docs/desktop.md](https://git.crt.fyi/CRT/storebound/src/branch/main/docs/desktop.md).
`npx storebound desktop` installs it for you (macOS, Windows, Linux; signature checked, no admin rights) and opens it on
the current app folder. Manual downloads: [storebound.dev/#download](https://storebound.dev/#download). Internals: [docs/desktop.md](https://git.crt.fyi/CRT/storebound/src/branch/main/docs/desktop.md).
## Works with your AI, safe by design
@ -84,16 +85,18 @@ You need [Node](https://nodejs.org) 20+ or [Bun](https://bun.sh) 1.1+ (and `ffmp
```sh
cd my-app
npm i -D storebound playwright # or: bun add -d storebound playwright
npx storebound init # --profile app (default) | subscription-app | game (Bun: bunx storebound init)
npx storebound install --agent claude # or codex, cursor, gemini, copilot, windsurf, opencode
npx storebound check # offline: config, limits, Data safety, products, files
npx storebound init # storebound.config.ts + .storebound/ in this project (--profile app | subscription-app | game)
npx storebound desktop # installs the desktop app once (asks first) and opens it on this folder
```
Every `npx storebound ...` below works as `bunx storebound ...` too.
One product, installed once per machine: the CLI (`npx` / `bunx`) and the desktop app have the same version, the same
store accounts (`~/.storebound/credentials`, `npx storebound accounts`) and the same list of app folders. Each project
has its `storebound.config.ts` and a gitignored `.storebound/` (upload keystore, review contact). Then
`npx storebound install --agent claude` (or codex, cursor, gemini, copilot, windsurf, opencode) and
`npx storebound check`. Every `npx storebound ...` works as `bunx storebound ...` too.
Then ask your agent: "take my app to Google Play and the App Store". Claude Code plugin, credentials, coming from
fastlane: [docs/getting-started.md](https://git.crt.fyi/CRT/storebound/src/branch/main/docs/getting-started.md). Desktop app: [storebound.dev/#download](https://storebound.dev/#download).
fastlane: [docs/getting-started.md](https://git.crt.fyi/CRT/storebound/src/branch/main/docs/getting-started.md).
## What it covers