Skip to main content

rork-local

Preview an iOS app in a live simulator tab and publish it to TestFlight or the App Store with rork-local. Use when the user wants to run rork-local, see their app in the browser-based simulator, capture or frame App Store screenshots, or publish a built .ipa via the asc CLI from localhost.

Aller à l'installation

Informations de source

Dépôt
rorkai/rork-local
Dernière activité de la source
16 juillet 2026 à 18:57
Langue détectée de SKILL.md
anglais
Étoiles
12
Forks
6

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Explorateur de fichiers
2 fichiers

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
rork-local
description
Preview an iOS app in a live simulator tab and publish it to TestFlight or the App Store with rork-local. Use when the user wants to run rork-local, see their app in the browser-based simulator, capture or frame App Store screenshots, or publish a built .ipa via the asc CLI from localhost.
license
Apache-2.0
# rork-local rork-local serves a localhost web UI (default `http://localhost:3131`) with a live iOS simulator stream (via serve-sim) plus one-click App Store Connect publishing and screenshot tooling (via the `asc` CLI). Everything the UI does is also exposed as a plain HTTP API, so you can drive it end to end with `curl`. ## Prerequisites - macOS with Xcode command line tools (`xcrun simctl`), Node.js 20+. - The `asc` CLI on `PATH`, or `ASC_BIN=/path/to/asc` in the environment. - `asc auth login` completed once (publishing and app-ID detection call the App Store Connect API). Check with `asc auth status`. - Optional: `asc web auth login` for creating brand-new App Store Connect apps. - Optional: `pipx install "koubou==0.18.1"` for screenshot framing. ## Start Run from the iOS app project's directory (detection scans the cwd): ```sh npx rork-local # → http://localhost:3131 PORT=4000 npx rork-local # custom port npx rork-local /path/to/app-project # explicit project dir ``` Startup boots a simulator if none is running, starts the serve-sim helper, and auto-detects publish config (bundle ID, version, newest .ipa, ASC app ID, beta groups) from the project. User overrides live in `rork.config.json` in the directory rork-local was launched from; screenshots and editor state live in `<project>/.rork-local/`. The UI at `/` embeds the simulator (`/.sim`), a Publish popover, an App Store submission wizard, and a Screenshots panel. ## HTTP API All endpoints are JSON over `http://localhost:3131` (adjust for PORT). ### Status and configuration ```sh # Booted device, asc binary + version, merged config/detection, current job curl -s localhost:3131/api/status # Force a re-scan of the project (picks up freshly built .ipa files) curl -s -X POST localhost:3131/api/config/detect # Point detection at a different project directory (persists to rork.config.json) curl -s -X POST localhost:3131/api/config/project \ -H 'content-type: application/json' -d '{"dir":"/path/to/app"}' # Auth health: apiKey = `asc auth` (publishing), web = `asc web auth` (app creation) curl -s localhost:3131/api/auth # TestFlight beta groups for an explicit app ID → {"groups":["External Testers",…]} curl -s "localhost:3131/api/groups?app=6759231657" ``` This endpoint returns `500` when `asc` is not installed and `502` when an attempted `asc` lookup fails, so callers can distinguish an app with no groups from a local setup, transient, or authentication failure. `GET /api/status` → `{ device, asc, config, detected, job }`. `detected.values` holds the merged autofill (`appId`, `ipa`, `group`, `version`; explicit config wins over detection), `detected.betaGroups` lists TestFlight groups, and `job` is the current job status (see below). ### Publishing One asc job runs at a time (`409` if busy). Job kinds: `publish`, `screenshots-upload`, `app-create`. Job states: `idle | running | success | error`. ```sh # TestFlight (group is required for TestFlight) curl -s -X POST localhost:3131/api/publish \ -H 'content-type: application/json' \ -d '{"target":"testflight","appId":"6759231657","ipa":"build/MyApp.ipa","group":"External Testers","wait":true}' # App Store (optionally submit for review) curl -s -X POST localhost:3131/api/publish \ -H 'content-type: application/json' \ -d '{"target":"appstore","appId":"6759231657","ipa":"build/MyApp.ipa","version":"1.2.0","submit":true}' # Cancel the running job curl -s -X POST localhost:3131/api/publish/cancel # Live logs: SSE stream (events: `status` with JobStatus, `line` with {t,stream,text}). # Replays buffered lines on connect, so late attachment is fine. curl -sN localhost:3131/api/publish/stream ``` Poll `GET /api/status` and inspect `.job.state` / `.job.exitCode` if you don't want to hold the SSE stream open. ### Screenshots ```sh # List raw, framed, and listing (editor-made) screenshots, the supported frame # devices, and the valid slide dimensions per App Store device type curl -s localhost:3131/api/screenshots # Capture the booted simulator's screen (name optional) curl -s -X POST localhost:3131/api/screenshots/capture \ -H 'content-type: application/json' -d '{"name":"home"}' # Frame a raw capture into a marketing bezel (requires koubou) curl -s -X POST localhost:3131/api/screenshots/frame \ -H 'content-type: application/json' \ -d '{"name":"home","device":"iphone-17-pro","title":"Track everything"}' # Delete a screenshot (kind: raw | framed | listing) curl -s -X DELETE localhost:3131/api/screenshots/raw/home # Upload shots to an App Store version (runs as a job). # source: framed | raw | listing (slides exported from the screenshot editor) curl -s -X POST localhost:3131/api/screenshots/upload \ -H 'content-type: application/json' \ -d '{"appId":"6759231657","version":"1.2.0","deviceType":"IPHONE_61","source":"framed"}' ``` Image files are served at `/shots/raw/<file>.png`, `/shots/framed/<file>.png`, and `/shots/listing/<file>.png`. ### Screenshot editor slides The web UI ships a manual slide editor (screenshots drawer → "Open editor"): background + headline + device-framed capture composed on a canvas at exact App Store resolution. Its API surface: ```sh # Save one exported slide PNG (base64 or data URL) into the listing set. # The PNG's dimensions must match the device type (see slideSizes in # GET /api/screenshots) or the request is rejected with 400. curl -s -X POST localhost:3131/api/screenshots/slide \ -H 'content-type: application/json' \ -d "{\"name\":\"slide-01\",\"deviceType\":\"IPHONE_65\",\"png\":\"$(base64 -i slide.png)\"}" # Read / persist the editor deck state (slides layout JSON; the client owns # the slide schema — the server just stores it) curl -s localhost:3131/api/screenshots/deck curl -s -X PUT localhost:3131/api/screenshots/deck \ -H 'content-type: application/json' \ -d '{"deviceType":"IPHONE_65","selected":0,"slides":[]}' ``` Saved slides upload with `POST /api/screenshots/upload` using `"source":"listing"` and the matching `deviceType`. ### First publish (no App Store Connect app yet) Requires a cached web session from `asc web auth login`: ```sh curl -s -X POST localhost:3131/api/apps/create \ -H 'content-type: application/json' \ -d '{"name":"My App","bundleId":"com.example.myapp","sku":"MYAPP123"}' ``` Runs as an `app-create` job; on success `job.result.appId` carries the new app ID. ## Tips - Empty publish fields? Check `detected.notes` in `/api/status` — it explains what was (not) found, and `POST /api/config/project` retargets detection. - The simulator preview at `/.sim` is the embedded serve-sim UI; use the serve-sim skill/CLI for taps, gestures, and camera injection. - `503`/no response right after start: the server boots the simulator first; retry after a few seconds.
Voir sur GitHub