Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions website/docs/build-caches.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ or Android target, Stim regenerates the current workspace's JavaScript and
assets in a copy of the artifact. If that swap fails, it builds fresh. iOS
physical-device Release runs always build fresh.

### EAS development builds

With `--eas-profile <name>`, Stim downloads a compatible EAS development build
and uses EAS CLI's artifact cache directly. It does not add another Stim cache
copy or compile locally on a miss. See [EAS development builds](./eas-builds.md)
for profile selection, device support, and cache behavior.

### Optional artifact providers

The provider integration is implemented, but Stim ships no network provider
Expand Down
23 changes: 16 additions & 7 deletions website/docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,12 @@ project is reused.
```text
stim ios [--scheme <name>] [--configuration <name>] [--device-type <name>] [--runtime <version>]
[--device [udid]] [--wait <seconds> | --no-wait] [--remote <proxy|eas>]
[--no-metro-check] [--no-build-cache] [--json]
[--eas-profile <name>] [--no-metro-check] [--no-build-cache] [--json]
```

Builds or restores the iOS app. Stim then boots an owned simulator, installs the
app, opens it, and checks launch logs. The build always runs on the local
machine, including remote-device workflows.
app, opens it, and checks launch logs. Native builds run locally by default;
`--eas-profile` downloads an existing EAS development build.

- `--configuration <name>` selects an Xcode configuration. The default is Debug.
- `--scheme <name>` selects an exact shared Xcode scheme when the automatic
Expand All @@ -118,16 +118,21 @@ machine, including remote-device workflows.
Only with `--device`; cannot be combined with `--wait`.
- `--remote proxy` uses a configured Agent Device daemon.
- `--remote eas` uses an EAS remote simulator.
- `--eas-profile <name>` selects a compatible [EAS development build](./eas-builds.md),
including with `--device`. A miss stops and prints an EAS build command;
cloud builds require authorization. Cannot be combined with `--scheme`,
`--configuration`, or `--no-build-cache`.
- `--no-metro-check` skips the Debug dev-server gate.
- `--no-build-cache` ignores cached artifacts and replaces the matching entry.
- `--json` prints one stable result object on stdout.

A non-Debug configuration embeds its JavaScript bundle.

A device build is local-tier only. Its cache key ends `-device`, so it cannot
A locally compiled device build is local-tier only. Its cache key ends `-device`, so it cannot
collide with a simulator build, and no build-cache provider or Expo remote cache
is read or written on a `--device` run, because every entry they hold is keyed
for the simulator.
is read or written on that path, because every entry they hold is keyed
for the simulator. `--eas-profile <name> --device` uses EAS CLI's artifact cache and
installs the signed app without re-signing it.

A `--device` run installs with `devicectl device install app` and launches with
`devicectl device process launch`. Every device install is signed, Debug
Expand Down Expand Up @@ -163,7 +168,7 @@ into cached iOS physical-device builds.
```text
stim android [--variant <name>] [--system-image <id>] [--device [serial]]
[--wait <seconds> | --no-wait] [--remote <proxy|eas>]
[--no-metro-check] [--no-build-cache] [--json]
[--eas-profile <name>] [--no-metro-check] [--no-build-cache] [--json]
```

Builds or restores the Android app. Stim then boots an owned emulator, installs
Expand All @@ -184,6 +189,10 @@ the app, opens it, and checks launch logs.
cannot be combined with `--wait`.
- `--remote proxy` uses a configured Agent Device daemon.
- `--remote eas` uses an EAS remote emulator.
- `--eas-profile <name>` selects a compatible [EAS development build](./eas-builds.md),
including with `--device`. A miss stops and prints an EAS build command;
cloud builds require authorization. Cannot be combined with `--variant` or
`--no-build-cache`.
- `--no-metro-check` skips the Debug dev-server gate.
- `--no-build-cache` ignores cached artifacts and replaces the matching entry.
- `--json` prints one stable result object on stdout.
Expand Down
163 changes: 163 additions & 0 deletions website/docs/eas-builds.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
---
title: 'EAS development builds'
description: 'Download a compatible EAS build and run it with Stim'
---

import StimTabs from '@site/src/components/StimTabs';
import PromptBox from '@site/src/components/PromptBox';

Commands use `stim`. If it is not installed globally, replace `stim` with
`npx stim`.

If your Expo project builds with EAS, Stim can download a matching development
build and run it on a simulator, emulator, or connected phone. EAS supplies the
native app; Stim manages the workspace's device, Metro port, installation,
launch checks, and logs. Matching worktrees can reuse the same build while
loading their own JavaScript from Metro.

## Ask your agent

Replace `ios-simulator` with your project's EAS profile name:

<PromptBox
title="Run an EAS development build"
response={`Trailhead launched on stim-trailhead (iPhone 17 / iOS 26.5).
com.appandflow.trailhead · ready · EAS build · errors clean`}

>

{`Use Stim to run this app on an iOS simulator with the EAS profile ios-simulator. Reuse a compatible build. If none matches, show me the EAS build command and ask before starting a cloud build. Check the app logs for errors after launch.`}
</PromptBox>

The response is illustrative. For Android, ask for an Android emulator and name
its profile. For hardware, ask for your connected iPhone or Android phone and
use a device-compatible profile.

## Choose a profile

Install EAS CLI and authenticate with `eas login` or `EXPO_TOKEN`. Your Expo
project needs installed JavaScript dependencies, `expo-dev-client`, and a link
to the intended EAS project in `extra.eas.projectId`. See Expo's
[development build setup](https://docs.expo.dev/develop/development-builds/introduction/?buildenv=build-with-eas)
if these are missing.

The selected `eas.json` profile must resolve to `developmentClient: true` and
`distribution: "internal"`. For example:

```json title="eas.json"
{
"build": {
"development": {
"developmentClient": true,
"distribution": "internal"
},
"ios-simulator": {
"extends": "development",
"ios": { "simulator": true }
}
}
}
```

Use `ios-simulator` for an iOS simulator and `development` for an Android
emulator or a physical device. iOS device profiles must omit `ios.simulator`
or set it to `false`.

Select EAS explicitly with `--eas-profile`. Having an `eas.json` file does not
change Stim's default local build behavior. Profile inheritance and native
fingerprinting use EAS CLI. If the profile overrides `ios.buildConfiguration`,
it must be `Debug`; an `android.gradleCommand` override must assemble a single
Debug APK, such as `:app:assembleDebug`.

## Download and run

<StimTabs
code={`stim start
stim ios --eas-profile ios-simulator
stim logs --errors`}
/>

For Android:

<StimTabs code={`stim android --eas-profile development`} />

Stim finds the latest finished build matching the EAS project, profile, native
fingerprint, platform, and target type. It downloads the `.app` or `.apk`,
installs it, and connects it to this workspace's Metro server. It skips local
native compilation. You still need the [host tools](./requirements.md) to run
the selected simulator, emulator, or phone.

Metro uses your local environment. Set any app-variant or other environment
variables before `stim start`; resolving an EAS profile does not apply its
environment to Metro.

This mode supports development builds. Release builds are not supported:
matching native inputs does not establish that a release build contains the
current workspace's JavaScript. `--scheme`, `--configuration`, `--variant`, and
`--no-build-cache` cannot be combined with `--eas-profile`.

`--eas-profile` selects where the app comes from. The separate `--remote eas`
option selects an [EAS-hosted device](./owned-devices.md#remote-devices), which
has its own session costs.

## When no build matches

Stim stops with `STIM_EAS_BUILD_MISSING` and prints the command for the selected
platform and profile, for example:

```bash
npx eas-cli build --platform ios --profile ios-simulator
```

Cloud builds may incur charges. An agent should run this command only when you
have authorized the build. After it finishes, retry the same Stim command.
Stim never starts a cloud build automatically or falls back to local compilation
in this mode. There is no build-on-miss flag.

Authentication, network, and download failures produce `STIM_EAS_UNAVAILABLE`
with the EAS command to inspect. They do not trigger a build.

## Connected devices

<StimTabs
code={`stim ios --eas-profile development --device
stim android --eas-profile development --device`}
/>

Use the command for your phone's platform. Add its UDID or serial after
`--device` to select a particular phone. The usual
[device selection and lease rules](./commands.md#device-lock-and-device-unlock)
apply.

For iOS, the app must contain a development-client URL scheme and an unexpired
provisioning profile that includes the phone's UDID. Stim installs the signed
app without re-signing it. The phone must be able to reach Metro over the LAN.

If the provisioning profile does not cover the phone, Stim points to EAS CLI:

```bash
npx eas-cli device:create
npx eas-cli build --platform ios --profile development
```

Register the phone if needed, then run the build with authorization for the
cloud build and signing changes. Run EAS interactively so it can refresh the
provisioning profile, then retry the same Stim command. Registration alone does
not update a previously built app. Expo's
[internal distribution guide](https://docs.expo.dev/build/internal-distribution/)
covers device registration and provisioning.

## Cache reuse

EAS CLI caches downloaded, extracted artifacts by project and build ID. Stim
uses that cache directly without storing another copy. Each run still contacts
EAS to find the latest matching build, including rebuilds with updated signing
profiles. Native fingerprint generation uploads fingerprint metadata to EAS;
this path requires EAS access even when the artifact is already on disk.

In JSON output, `cacheHit: "remote"` identifies the EAS build source, including
when EAS CLI reuses its local cache. Stim's `buildCache` and `remoteBuildCache`
settings do not control this cache, and `stim gc` does not clean it.

For reference text matching your installed version, run
`stim guide lifecycle eas`.
11 changes: 11 additions & 0 deletions website/docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ com.appandflow.trailhead · ready · cache hit · 58.8s · errors clean`}
>
{`Run the app on an iPhone 17 simulator with iOS 26.5.`}
</PromptBox>
<PromptBox
title="Use an EAS build"
response={`Trailhead launched on stim-trailhead (iPhone 17 / iOS 26.5).
com.appandflow.trailhead · ready · EAS build · errors clean`}
>
{`Use Stim to run this app on an iOS simulator with the EAS profile ios-simulator. Reuse a compatible build. If none matches, show me the EAS build command and ask before starting a cloud build. Check the app logs for errors after launch.`}
</PromptBox>
<PromptBox
title="Run on a connected phone"
response={`Trailhead launched on the connected iPhone.
Expand Down Expand Up @@ -115,6 +122,10 @@ Before and After recordings captured; named assertion passed; PR opened with the
</PromptBox>
</PromptGrid>

The EAS prompt assumes an `ios-simulator` profile. Replace it with your
project's profile name; see [EAS development builds](./eas-builds.md) for setup,
Android and device examples, and build-miss behavior.

## Run work in parallel

The current checkout is the default. An agent creates a separate worktree only
Expand Down
6 changes: 4 additions & 2 deletions website/docs/owned-devices.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,10 @@ Stim supports two optional remote backends:
- `proxy` connects through an Agent Device daemon that already owns a session.
- `eas` creates and owns an EAS simulator session.

The app still builds on the local machine. `stim start --remote` creates the
Metro route required by the remote device. Remote EAS sessions can incur cost.
The app builds locally by default; `--eas-profile` can instead download an
[EAS development build](./eas-builds.md). `stim start --remote` creates the
Metro route required by the remote device. Remote EAS sessions can incur cost
independently of the build source.

## Cleanup behavior

Expand Down
10 changes: 10 additions & 0 deletions website/docs/requirements.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,13 @@ gems and runs `bundle exec pod install`. Run `stim doctor` to check the setup.
- The `proxy` backend needs an Agent Device daemon URL and token.
- The `eas` backend needs the EAS CLI, an authenticated Expo account, and a
configured EAS project. EAS simulator use can be billable.

## EAS development builds

`--eas-profile` needs EAS CLI, an authenticated Expo account, and a linked Expo
project with an internal development profile. It downloads an existing build
and skips local native compilation, so CocoaPods and Gradle compilation setup
are not needed for this path. Keep the host tools needed to run the selected
device: Xcode and an installed runtime for a local iOS simulator, or the Android
SDK and system image for an emulator. See [EAS development builds](./eas-builds.md)
for setup and connected-device requirements.
2 changes: 1 addition & 1 deletion website/sidebars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const sidebars: SidebarsConfig = {
type: 'category',
label: 'Understand Stim',
collapsed: false,
items: ['build-caches', 'worktrees', 'owned-devices', 'dev-server-and-logs'],
items: ['build-caches', 'eas-builds', 'worktrees', 'owned-devices', 'dev-server-and-logs'],
},
{
type: 'category',
Expand Down
Loading