{"_id":"@agustin-perticaro/store-pilot","_rev":"2-af2191815f0750851ae06c4043018760","name":"@agustin-perticaro/store-pilot","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.0":{"name":"@agustin-perticaro/store-pilot","version":"1.0.0","keywords":["aso","app-store-optimization","fastlane","expo","react-native","app-store","google-play","screenshots","keywords","store-upload","cli"],"author":{"name":"Agustin Perticaro"},"license":"MIT","_id":"@agustin-perticaro/store-pilot@1.0.0","maintainers":[{"name":"agustin-perticaro","email":"pertix2000@gmail.com"}],"homepage":"https://github.com/agustinperticaro/store-pilot#readme","bugs":{"url":"https://github.com/agustinperticaro/store-pilot/issues"},"bin":{"store-pilot":"bin/store-pilot.js"},"dist":{"shasum":"eb13e82da679706426a0c0c1e493fd0e077c0144","tarball":"https://registry.npmjs.org/@agustin-perticaro/store-pilot/-/store-pilot-1.0.0.tgz","fileCount":11,"integrity":"sha512-TjGv+53BLAQRaKB6nR0DvMh5mZf4b7Q3r1sEDH+BTZfBB3RAESay5Dl4JFGsiLRKmX1UnsuUMFhbwuVcZSokvg==","signatures":[{"sig":"MEUCICM6N10+asCZWmaAPxcpB2whMY7yWkBGAUzZQU7kUgUhAiEAwtmi1DQEUB6XWRcNqzpX9rg9YOy5WMmdsLWy6lOxogk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":57986},"type":"module","engines":{"node":">=18.0.0"},"scripts":{"test":"node bin/store-pilot.js --help","prepublishOnly":"node bin/store-pilot.js --version"},"_npmUser":{"name":"agustin-perticaro","email":"pertix2000@gmail.com"},"repository":{"url":"git+https://github.com/agustinperticaro/store-pilot.git","type":"git"},"_npmVersion":"11.6.1","description":"CLI to automate ASO, builds, and store uploads for Expo/React Native projects without EAS","directories":{},"_nodeVersion":"24.11.0","dependencies":{"ora":"^8.0.1","chalk":"^5.3.0","dotenv":"^16.4.5","fs-extra":"^11.2.0","inquirer":"^9.2.0","commander":"^12.0.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/store-pilot_1.0.0_1773410099305_0.8775969896952103","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@agustin-perticaro/store-pilot","version":"1.0.1","description":"Stop wasting hours in App Store Connect, Google Play Console, and Figma. One command to generate keywords, screenshots, build, and ship your Expo app to both stores.","bin":{"store-pilot":"bin/store-pilot.js"},"type":"module","scripts":{"test":"node bin/store-pilot.js --help","prepublishOnly":"node bin/store-pilot.js --version"},"dependencies":{"chalk":"^5.3.0","commander":"^12.0.0","dotenv":"^16.4.5","fs-extra":"^11.2.0","inquirer":"^9.2.0","ora":"^8.0.1"},"engines":{"node":">=18.0.0"},"keywords":["aso","app-store-optimization","fastlane","expo","react-native","app-store","google-play","screenshots","keywords","store-upload","cli"],"repository":{"type":"git","url":"git+https://github.com/agustinperticaro/store-pilot.git"},"homepage":"https://github.com/agustinperticaro/store-pilot#readme","bugs":{"url":"https://github.com/agustinperticaro/store-pilot/issues"},"author":{"name":"Agustin Perticaro"},"license":"MIT","_id":"@agustin-perticaro/store-pilot@1.0.1","_nodeVersion":"24.11.0","_npmVersion":"11.6.1","dist":{"integrity":"sha512-41o+ijCNHftGS9XiqiFA+cCXn4SU9jIfA/CePP51o4lwmQJhF5aZhyEznnEobYRiM8Ui1VRCIx/IN3bkxXj8sg==","shasum":"7dee0a19d7ddbad06c86e5e1ab5c4001069a0b7a","tarball":"https://registry.npmjs.org/@agustin-perticaro/store-pilot/-/store-pilot-1.0.1.tgz","fileCount":11,"unpackedSize":59288,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIFxZH4R+6TqYqdsQJHJQQnG4+xirp9lgKxPCPI37/FLtAiEAzF2A8RX2ZvjBdJPj3p0s0Y8EI7gXrTn4fxYGNpD9d0w="}]},"_npmUser":{"name":"agustin-perticaro","email":"pertix2000@gmail.com"},"directories":{},"maintainers":[{"name":"agustin-perticaro","email":"pertix2000@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/store-pilot_1.0.1_1773420751121_0.02338897962759967"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-13T13:54:59.209Z","modified":"2026-03-13T16:52:31.392Z","1.0.0":"2026-03-13T13:54:59.478Z","1.0.1":"2026-03-13T16:52:31.270Z"},"bugs":{"url":"https://github.com/agustinperticaro/store-pilot/issues"},"author":{"name":"Agustin Perticaro"},"license":"MIT","homepage":"https://github.com/agustinperticaro/store-pilot#readme","keywords":["aso","app-store-optimization","fastlane","expo","react-native","app-store","google-play","screenshots","keywords","store-upload","cli"],"repository":{"type":"git","url":"git+https://github.com/agustinperticaro/store-pilot.git"},"description":"Stop wasting hours in App Store Connect, Google Play Console, and Figma. One command to generate keywords, screenshots, build, and ship your Expo app to both stores.","maintainers":[{"name":"agustin-perticaro","email":"pertix2000@gmail.com"}],"readme":"# store-pilot\n\n**Stop wasting hours in App Store Connect, Google Play Console, and Figma every time you release.**\n\nOne command to generate keywords, create screenshots, build, and ship your Expo/React Native app to both stores — without EAS.\n\nNo more manually filling metadata fields. No more designing screenshots in Figma. No more switching between consoles. Just run `store-pilot ship` and go grab a coffee.\n\n---\n\n## Why store-pilot?\n\n| Without store-pilot | With store-pilot |\n|---|---|\n| Open Figma → design 12+ screenshots manually | `store-pilot screenshots` |\n| Open App Store Connect → fill every field | `store-pilot ship` handles it |\n| Open Google Play Console → fill the same info again | Automatic via fastlane metadata |\n| Research keywords manually | `store-pilot keywords` with AI-powered ASO |\n| Repeat everything for each language | One command for all languages |\n| ~3-4 hours per release | ~5 minutes |\n\n---\n\n## Installation\n\n```bash\nnpm install -g @agustin-perticaro/store-pilot\n```\n\nRequires Node.js ≥ 18, Ruby + Bundler, and fastlane installed.\n\n```bash\ngem install fastlane\n```\n\n---\n\n## Setup (once per project)\n\n```bash\ncd your-expo-project\nstore-pilot init\n```\n\n`init` auto-detects your `app.json`, asks questions, and generates:\n\n- `fastlane/Appfile` — identifies your app\n- `fastlane/Fastfile` — all automated lanes\n- `fastlane/Matchfile` — iOS certificate management\n- `fastlane/metadata/` — complete structure per language\n- `.env.store-pilot` — your credentials (DO NOT commit)\n- `.env.store-pilot.example` — safe template for the repo\n- `store-pilot-scripts/` — standalone scripts\n\n### Configure iOS certificates (once)\n\n```bash\nstore-pilot match-setup\n```\n\nUses fastlane match: creates and stores your certificates in a private git repo. Any team Mac can sync them with `bundle exec fastlane match appstore --readonly`.\n\n---\n\n## Required Credentials\n\nFill in `.env.store-pilot` with:\n\n| Variable | Where to get it |\n|---|---|\n| `ASC_KEY_ID` | App Store Connect → Users → API Keys |\n| `ASC_ISSUER_ID` | Same page |\n| `ASC_KEY_PATH` | The downloaded `.p8` file |\n| `MATCH_PASSWORD` | Password you chose in match-setup |\n| `GOOGLE_PLAY_JSON_KEY_PATH` | Play Console → Settings → API Access → Service Account |\n| `ANDROID_KEYSTORE_*` | Your release keystore |\n| `APPSCREENS_API_KEY` | appscreens.io → Account → API |\n| `APPSCREENS_PROJECT_ID` | Your AppScreens project ID |\n\n---\n\n## Usage\n\n### Full pipeline (recommended)\n\n```bash\nstore-pilot ship\n```\n\nRuns in order: expo prebuild → keywords → screenshots → build iOS + Android → upload.\n\n```bash\n# iOS only, submit for review automatically\nstore-pilot ship --platform ios --submit\n\n# Android only, upload to beta\nstore-pilot ship --platform android --track beta\n\n# Skip keywords and screenshots (if unchanged)\nstore-pilot ship --skip-keywords --skip-screenshots\n```\n\n### Individual commands\n\n```bash\n# Update keywords from Astro MCP\nstore-pilot keywords\n\n# New app not published yet → use a competitor as reference\nstore-pilot keywords --competitor \"https://apps.apple.com/app/notion/id1232780281\"\n\n# Generate and download screenshots from AppScreens\nstore-pilot screenshots\n\n# Generate AND upload directly to stores\nstore-pilot screenshots --upload\n```\n\n---\n\n## Workflow for new apps (pre-publication)\n\nAstro works before publishing by using competitors as proxy:\n\n1. Find 2-3 competitor apps in the App Store\n2. Copy their URLs\n3. Run for each one:\n   ```bash\n   store-pilot keywords --competitor \"https://apps.apple.com/app/.../id123\"\n   ```\n4. store-pilot combines and ranks keywords by popularity/difficulty\n\n---\n\n## Metadata\n\nFill in the files at `fastlane/metadata/` — plain text files versioned in git:\n\n```\nfastlane/metadata/\n├── ios/\n│   ├── en-US/\n│   │   ├── name.txt               ← app name\n│   │   ├── subtitle.txt           ← subtitle (30 chars)\n│   │   ├── description.txt        ← long description\n│   │   ├── keywords.txt           ← generated by store-pilot keywords\n│   │   ├── promotional_text.txt   ← updatable without new build\n│   │   └── release_notes.txt      ← what's new in this version\n│   └── review_information/\n│       ├── first_name.txt\n│       └── ...\n└── android/\n    └── en-US/\n        ├── title.txt\n        ├── short_description.txt\n        ├── full_description.txt\n        └── changelogs/\n            └── default.txt\n```\n\n---\n\n## CI/CD (GitHub Actions)\n\n```yaml\n# .github/workflows/ship.yml\nname: Ship to stores\n\non:\n  push:\n    tags: ['v*']\n\njobs:\n  ship:\n    runs-on: macos-latest\n    steps:\n      - uses: actions/checkout@v4\n      - uses: actions/setup-node@v4\n        with:\n          node-version: '20'\n      - run: npm install -g @agustin-perticaro/store-pilot\n      - run: gem install fastlane\n      - run: store-pilot ship --skip-keywords\n        env:\n          ASC_KEY_ID: ${{ secrets.ASC_KEY_ID }}\n          ASC_ISSUER_ID: ${{ secrets.ASC_ISSUER_ID }}\n          ASC_KEY_PATH: ${{ secrets.ASC_KEY_PATH }}\n          MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}\n          GOOGLE_PLAY_JSON_KEY_PATH: ${{ secrets.GOOGLE_PLAY_JSON_KEY }}\n          ANDROID_KEYSTORE_PATH: ${{ secrets.ANDROID_KEYSTORE }}\n          ANDROID_KEYSTORE_PASS: ${{ secrets.ANDROID_KEYSTORE_PASS }}\n          ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}\n          ANDROID_KEY_PASS: ${{ secrets.ANDROID_KEY_PASS }}\n          APPSCREENS_API_KEY: ${{ secrets.APPSCREENS_API_KEY }}\n          APPSCREENS_PROJECT_ID: ${{ secrets.APPSCREENS_PROJECT_ID }}\n```\n\n> **Note:** `store-pilot keywords` uses Astro MCP which runs locally on your Mac, so that step is done on your machine before pushing. In CI it's skipped with `--skip-keywords`.\n\n---\n\n## How does it compare to EAS?\n\n| Feature | EAS | store-pilot |\n|---|---|---|\n| Cloud builds | Yes | No (local via fastlane) |\n| Upload to stores | Yes | Yes |\n| Metadata management | Basic (beta) | Full fastlane metadata |\n| **ASO keyword research** | No | Yes (via Astro MCP) |\n| **Screenshot generation** | No | Yes (via AppScreens) |\n| **Screenshot upload** | No | Yes |\n| **Full ASO pipeline** | No | Yes |\n| Cost | Free tier, then $99+/mo | Free (open source) |\n\n**EAS builds your app. store-pilot optimizes and ships it.**\n\n---\n\n## Project structure\n\n```\nstore-pilot/\n├── bin/store-pilot.js      CLI entrypoint\n├── commands/\n│   ├── init.js             scaffolding\n│   ├── keywords.js         Astro MCP → keywords.txt\n│   ├── screenshots.js      AppScreens API → assets\n│   ├── ship.js             full pipeline\n│   └── match-setup.js      certificate setup\n├── lib/\n│   └── config.js           config + env loader\n└── templates/\n    ├── scripts/             copied to project as store-pilot-scripts/\n    └── fastlane/metadata/   base metadata structure\n```\n\n---\n\n## License\n\nMIT\n","readmeFilename":"README.md"}