README is a short front page (about 120 lines) with one real visual per section; every former section moved unchanged into docs/*.md with a docs/README.md index (journey, rejections, getting-started, commands, growth, studios, store-art, listing-languages, api, skills, mcp, safety, faq, project). The site tells the same story on one page: the teaser in the hero, real CLI output as text, the desktop app as a section with light/dark captures of eight screens and the per-system downloads (desktop/latest.json); /desktop/ redirects to /#download. New capture tools: tools/site-desktop-shots.ts (fixture-mode desktop frames) and tools/site-term-shots.ts (real CLI output as text and WebP). tests/docs-links.test.ts checks README, docs and site links resolve.
114 lines
7.3 KiB
Markdown
114 lines
7.3 KiB
Markdown
# Getting started
|
|
|
|
## 5-minute quick start
|
|
|
|
You need [Bun](https://bun.sh) 1.1+ (and `ffmpeg` for icons, screenshots and video).
|
|
|
|
```sh
|
|
cd my-app
|
|
bun add -d storebound playwright # or: bun add -d git+https://git.crt.fyi/CRT/storebound.git playwright
|
|
bunx storebound init # --profile app (default) | subscription-app | game: config, store/*.md, declarations, privacy policy, .storebound/ (gitignored)
|
|
# fill in storebound.config.ts and the store/ files
|
|
bunx storebound check # offline: config, copy limits, Data safety answers, products, files
|
|
```
|
|
|
|
Add credentials (below), then walk the journey with dry runs first:
|
|
|
|
```sh
|
|
bunx storebound apple bundle --dry
|
|
bunx storebound play listing --dry
|
|
bunx storebound play products --dry && bunx storebound apple iap --dry
|
|
bunx storebound apple subscriptions --dry && bunx storebound play subscriptions --dry
|
|
bunx storebound apple review-details --dry # contact + demo account from .storebound/ (masked) + notes
|
|
bunx storebound play data-safety --dry --csv store/data-safety.csv
|
|
bunx storebound apple appinfo --dry
|
|
bunx storebound icons --dry
|
|
bunx storebound shots capture && bunx storebound shots render && bunx storebound shots gallery
|
|
bunx storebound validate # read-only: what still blocks a submission, per store, in fix order
|
|
bunx storebound catalog diff # read-only: products + subscriptions on both stores vs the config, prices per region
|
|
```
|
|
|
|
After launch:
|
|
|
|
```sh
|
|
bunx storebound apple testflight what-to-test --build 42 --dry # then distribute --build 42 --group Team
|
|
bunx storebound health --weekly # vitals + diagnostics, .storebound/health/<date>.md
|
|
bunx storebound reviews draft # reply drafts in .storebound/replies/, then reviews send
|
|
bunx storebound prices export && bunx storebound prices import --dry
|
|
bunx storebound analytics snapshot && bunx storebound analytics compare
|
|
```
|
|
|
|
Or ask your agent: "take my app to Google Play and the App Store", "fill in the store questionnaires", "set up the
|
|
in-app purchases and a yearly subscription with a free trial on both stores", "do both stores sell the same
|
|
catalog", "the reviewer could not sign in", "make store screenshots in 5 languages", "is my app ready to submit", "why was my
|
|
update rejected", "put build 42 on TestFlight", "how are our crash rates", "answer the new reviews", "did the new
|
|
screenshots help". The matching skill takes over.
|
|
|
|
## Coming from fastlane
|
|
|
|
`storebound import fastlane` turns an existing fastlane setup into storebound files. It only reads (no Ruby is run),
|
|
never overwrites anything and prints what it could not map:
|
|
|
|
```sh
|
|
bunx storebound import fastlane --dry # the plan + report; default --dir: fastlane/, ios/fastlane/, android/fastlane/
|
|
bunx storebound import fastlane # writes the files below; an existing file gets a <name>.imported.<ext> copy
|
|
bunx storebound init # adds the remaining templates, keeps the imported files
|
|
bunx storebound check
|
|
```
|
|
|
|
| fastlane | storebound |
|
|
|---|---|
|
|
| Appfile `app_identifier`, `package_name` | `apple.bundleId`, `play.packageName` |
|
|
| deliver `metadata/<locale>/*.txt` (+ `default/`) | `store/appstore.md` per App Store locale; URLs, copyright, categories and review notes in the config |
|
|
| supply `metadata/android/<lang>/*.txt`, newest `changelogs/<versionCode>.txt` | `store/listing.md` per Play language |
|
|
| deliver and supply language folders | `languages[]` with both store codes (`tr` + `tr-TR`, `zh-Hans` + `zh-CN`, `he` + `iw-IL`) |
|
|
| `screenshots/<locale>/`, `images/phoneScreenshots/`, `tenInchScreenshots/` | `store/shots/frames/<lang>/<phone\|tablet>/NN.png` with a `folder` capture source |
|
|
| supply `icon`, `featureGraphic` | `play.icon`, `store/renders/<lang>/feature/1024x500.*` |
|
|
|
|
Keys and accounts are never copied: `json_key_file`, the API key, team ids, the App Review contact and demo account are
|
|
named in the report with where they go (`.storebound/credentials.json`). Submission and release flags, `price_tier`,
|
|
the age rating config, lanes and signing (`match`) are listed with their storebound counterpart. The
|
|
`migrate-from-fastlane` skill walks an agent through it.
|
|
|
|
## Credentials (never in the repo)
|
|
|
|
Read from environment variables, or from `.storebound/credentials.json` in your project (gitignored by `init`):
|
|
|
|
| name | what |
|
|
|---|---|
|
|
| `PLAY_SERVICE_ACCOUNT` | path to the Google Cloud service account JSON key (or the JSON itself) with access to your app in Play Console |
|
|
| `ASC_KEY_ID`, `ASC_ISSUER_ID` | App Store Connect API team key (Users and Access > Integrations) |
|
|
| `ASC_P8` | path to `AuthKey_<id>.p8` (default `~/.appstoreconnect/private_keys/AuthKey_<id>.p8`) |
|
|
| `ASC_VENDOR_NUMBER` | vendor number for `reports apple-sales` / `apple-finance` (Payments and Financial Reports) |
|
|
| `ANDROID_KEYSTORE`, `ANDROID_KEYSTORE_PASSWORD`, `ANDROID_KEY_ALIAS`, `ANDROID_KEY_PASSWORD` | upload key for `play build` (path to the .jks / .p12 and its passwords; handed to Gradle through the environment) |
|
|
| `reviewContact` | (file only) App Review contact name / phone / email |
|
|
| `reviewDemoAccount` / `REVIEW_DEMO_USER`, `REVIEW_DEMO_PASSWORD` | demo account for App Review (`reviewAccess.signInRequired`); never in the config or the repo, masked in logs |
|
|
|
|
Several store accounts on one machine: credential profiles (`~/.storebound/credentials/<profile>.json`, the same names
|
|
except the per-app upload keystore)
|
|
picked with `--account <profile>` or by a workspace ([Many apps and studios](studios.md#many-apps-and-studios)).
|
|
|
|
|
|
## Install for your AI tool
|
|
|
|
Every route gives the agent the same skills and the same MCP tools. Nothing here requires Claude: the skills are
|
|
plain Markdown and the CLI is a normal command.
|
|
|
|
| tool | install |
|
|
|---|---|
|
|
| Claude Code | `/plugin marketplace add https://git.crt.fyi/CRT/storebound.git` then `/plugin install storebound@crtkafa` (skills, MCP server, `storebound` on PATH). Or per project: `bunx storebound install --agent claude` |
|
|
| OpenAI Codex | `bunx storebound install --agent codex` (skills in `.agents/skills`, MCP in `.codex/config.toml`; Codex reads that file for trusted projects). The repo is also a Codex plugin (`.codex-plugin/plugin.json`, skills only) |
|
|
| Gemini CLI | `gemini extensions install https://git.crt.fyi/CRT/storebound.git` (skills, MCP server, `GEMINI.md`). Or `bunx storebound install --agent gemini` |
|
|
| Cursor | `bunx storebound install --agent cursor` (skills in `.agents/skills`, `.cursor/mcp.json`); the repo's `.cursor/rules/storebound.mdc` is an agent-requested rule you can copy |
|
|
| VS Code / GitHub Copilot | `bunx storebound install --agent copilot` (skills in `.github/skills`, `.vscode/mcp.json`) |
|
|
| Windsurf (Devin Desktop) | `bunx storebound install --agent windsurf` (skills in `.agents/skills`, MCP in your global `mcp_config.json`) |
|
|
| OpenCode | `bunx storebound install --agent opencode` (skills in `.opencode/skills`, `opencode.json`) |
|
|
| anything that reads `AGENTS.md` | copy or link `AGENTS.md` (rules + skill index) and use the CLI |
|
|
|
|
`install` takes several agents at once (`--agent codex,cursor`), `--dry` to preview, `--no-skills` / `--no-mcp`,
|
|
and `--command "<cmd>"` to choose how the MCP server starts. It only adds or updates the `storebound` entry and its
|
|
own skill folders; everything else in those files stays as it is, and re-running it is safe.
|
|
|
|
---
|
|
|
|
[All docs](README.md) · [README](../README.md)
|