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
5 changes: 5 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,11 @@ actions, safety rules, or topic routing change. The static
skill changes only when its activation description or single routing command
changes.

When adding or changing a user-facing feature, update the affected website
pages under `website/docs/` and their command examples alongside the CLI guides.
Include a copyable agent prompt when it helps users try the feature. Keep
website behavior, flags, defaults, and limitations aligned with the implementation.

Document command invocation once in each human-facing installation entry
point. Show the no-install form, `npx stim <command>`, and the global
install, `npm install --global stim`. The static skill is only a router and
Expand Down
3 changes: 2 additions & 1 deletion packages/stim-cli/src/__tests__/guide.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -474,11 +474,12 @@ test('the settings guide documents every configurable optimization', () => {
}
});

test('EAS guidance routes agents to the profile and preserves the paid-build authorization boundary', () => {
test('EAS guidance requires profile clarification when needed and authorization for paid builds', () => {
const agent = renderTopic('agent');
expect(agent).toContain('stim guide lifecycle eas');
const eas = renderSection('lifecycle', 'eas');
expect(eas).toContain('--eas-profile');
expect(eas).toMatch(/no\s+compatible profile or the choice is ambiguous, ask the user/);
expect(eas).toContain('fingerprint:generate uploads fingerprint metadata');
expect(eas).toMatch(/session authorizes the potentially billable/);
expect(eas).toContain('STIM_EAS_BUILD_MISSING');
Expand Down
5 changes: 3 additions & 2 deletions packages/stim-cli/src/guide/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,10 @@ them. It preserves source, custom launcher settings, and the shared ccache.
stim start
stim ios # or: stim android

For a project using EAS development builds, select the agreed profile with
For a project using EAS development builds, read stim guide lifecycle eas to
select a profile from eas.json for the requested target, then run
stim ios --eas-profile <name> or stim android --eas-profile <name>.
Read stim guide lifecycle eas before using this path. A miss stops with
Ask the user if the profile choice is ambiguous. A miss stops with
STIM_EAS_BUILD_MISSING and an EAS build command. Run that command only when the
session authorizes the potentially billable build, then retry Stim. The
presence of eas.json does not select EAS or authorize building.
Expand Down
9 changes: 9 additions & 0 deletions packages/stim-cli/src/guide/lifecycle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,15 @@ android.gradleCommand must be a single :app:assemble<Variant>Debug task producin
an APK. Install eas-cli and authenticate with eas login
or EXPO_TOKEN. The Expo app must already be linked to the intended EAS project.

Use the profile the user names. Otherwise inspect eas.json, including extends
and platform overrides, for the requested platform, simulator or physical
device, and app variant or environment. Choose a profile only when those
requirements identify one compatible development profile. If there is no
compatible profile or the choice is ambiguous, ask the user. Profile names
alone do not establish compatibility. Confirm the resolved settings with
npx eas-cli config --platform <ios|android> --profile <name> --json --non-interactive.
Pass the selected name to --eas-profile; the CLI does not infer it.

Stim delegates profile inheritance, environment resolution and fingerprinting
to EAS CLI. fingerprint:generate uploads fingerprint metadata to EAS. It does
not start a native build. EAS access is needed even when the artifact is
Expand Down
4 changes: 4 additions & 0 deletions website/docs/agent-skills.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ sidebar_position: 4
description: 'Install the small Stim workflow skill for coding agents'
---

:::note[Command examples]

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

:::

Install the bundled skill from the repository:

```bash
Expand Down
8 changes: 7 additions & 1 deletion website/docs/android-cas.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,15 @@ assertion failures stop the script. All fixture data remains available.
## Application integration

After building the Stim checkout, use its CLI with a disposable React Native/Expo
worktree and a private `STIM_HOME`. Commands use `stim`; replace it with
worktree and a private `STIM_HOME`.

:::note[Command examples]

Commands use `stim`; replace it with
`npx stim` if it is not installed globally.

:::

For persistent selection, merge this into `$STIM_HOME/config.json` (default
`~/.stim/config.json`). The same `optimizations` object in `.stim.json` can
override machine defaults per app when placed beside the app's `package.json`.
Expand Down
4 changes: 4 additions & 0 deletions website/docs/build-caches.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@ description: 'How Stim keeps worktree builds warm'

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

:::note[Command examples]

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

:::

Stim shares four types of work across projects and git worktrees:

| Layer | What it avoids |
Expand Down
4 changes: 4 additions & 0 deletions website/docs/build-optimizations.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@ description: 'Control native artifact reuse, compiler caches, PCH, and Metro cac

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

:::note[Command examples]

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

:::

Stim enables build optimizations by default. Use the `optimizations` settings to
disable individual layers when debugging or to opt into experimental compiler
caching. For an overview of the layers, see [build speed and caches](./build-caches.md).
Expand Down
4 changes: 4 additions & 0 deletions website/docs/cache-packages.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ sidebar_position: 5
description: 'Optional npm packages for builds that run outside Stim'
---

:::note[Command examples]

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

:::

Stim supplies its own cache arguments when it runs Metro and native builds. A
project does not need these packages for `stim start`, `stim ios`, or
`stim android`.
Expand Down
37 changes: 27 additions & 10 deletions website/docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@ description: 'Every Stim command and option'

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

:::note[Command examples]

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

:::

Run `stim <command> --help` for parser help. Run `stim guide` for the full
reference that ships with the installed version.

Expand All @@ -30,6 +34,15 @@ restarts it. Use it when an error screen remains after a fix, not after every
JavaScript edit. It also recovers an Android app whose first bundle failed; an
iOS app in that state never connects to Metro, so reload cannot reach it.

## Named device slots

`ios`, `android`, `device lock`, `device unlock`, `logs`, and `stop` accept
`--slot <name>`. Omitting it selects the default target for a device run;
plain `logs` and `stop` still cover the whole workspace. `status` lists every
slot. Slots can hold multiple simulators of the same model as well as physical
devices. See [multiple devices with slots](./owned-devices.md#multiple-devices-with-slots)
for commands, a copyable agent prompt, and shared-server limitations.

## `doctor`

```text
Expand Down Expand Up @@ -88,7 +101,7 @@ project is reused.
## `ios`

```text
stim ios [--scheme <name>] [--configuration <name>] [--device-type <name>] [--runtime <version>]
stim ios [--slot <name>] [--scheme <name>] [--configuration <name>] [--device-type <name>] [--runtime <version>]
[--device [udid]] [--wait <seconds> | --no-wait] [--remote <proxy|eas>]
[--eas-profile <name>] [--no-metro-check] [--no-build-cache] [--json]
```
Expand Down Expand Up @@ -166,7 +179,7 @@ into cached iOS physical-device builds.
## `android`

```text
stim android [--variant <name>] [--system-image <id>] [--device [serial]]
stim android [--slot <name>] [--variant <name>] [--system-image <id>] [--device [serial]]
[--wait <seconds> | --no-wait] [--remote <proxy|eas>]
[--eas-profile <name>] [--no-metro-check] [--no-build-cache] [--json]
```
Expand Down Expand Up @@ -258,7 +271,7 @@ device and inspect `stim logs --errors` before claiming recovery.
## `logs`

```text
stim logs [--source <metro|client|device|build|all...>]
stim logs [--slot <name>] [--source <metro|client|device|build|all...>]
[--level <debug|info|warn|error|fatal>] [--since <duration>]
[--grep <expression>] [--tail <count>] [--errors]
[--follow] [--json]
Expand All @@ -278,23 +291,26 @@ result.
## `stop`

```text
stim stop [--json]
stim stop [--slot <name>] [--json]
```

Stops the supervisor and log collectors. It shuts down the owned local device,
ends an owned remote session, and frees the port. A local device stays assigned
for reuse. An external server on the reserved port is left running, and a
Without `--slot`, stops the supervisor and all log collectors, shuts down every
owned local device, ends an owned remote session, and frees the port. Owned
local devices stay assigned for reuse. An external server on the reserved port is left running, and a
process whose ownership cannot be verified is not signalled.

With `--slot <name>`, stops only that slot's owned devices and collectors and
releases its leases. Metro, the reserved port, and sibling slots keep running.

On a physical iPhone, stopping the log collector closes the running app.
`stop` also releases this workspace's device leases. It never uninstalls the
app or shuts down the phone; hardware has no owned-device registry entry.

## `device lock` and `device unlock`

```text
stim device lock <ios|android> [id] [--for <duration>] [--wait <seconds>] [--json]
stim device unlock [ios|android] [--json]
stim device lock <ios|android> [id] [--slot <name>] [--for <duration>] [--wait <seconds>] [--json]
stim device unlock [ios|android] [--slot <name>] [--json]
```

Leases a connected physical device to this workspace, so another workspace's
Expand All @@ -310,7 +326,8 @@ free one in id order. The same rule serves `ios --device` and
`android --device` with no id, so two devices on one machine no longer refuse.

`unlock` releases every lease this workspace holds, or only the platform
named; releasing nothing is not an error. A `--device` run takes a lease of
named. Adding `--slot <name>` restricts release to that slot; releasing nothing
is not an error. A `--device` run takes a lease of
its own for the length of the run, so `lock` is for holding a device across
runs, such as a device-tool session. `stim status` lists every lease on the
machine.
Expand Down
4 changes: 4 additions & 0 deletions website/docs/dev-server-and-logs.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@ description: 'A supervised Metro server and a queryable launch timeline'

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

:::note[Command examples]

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

:::

`stim start` reserves a port for the workspace and starts its React Native or
Expo dev server under a detached supervisor. The command exits only after the
server answers and Stim verifies its project identity.
Expand Down
16 changes: 11 additions & 5 deletions website/docs/eas-builds.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@ 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';

:::note[Command examples]

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,
Expand All @@ -17,7 +21,7 @@ loading their own JavaScript from Metro.

## Ask your agent

Replace `ios-simulator` with your project's EAS profile name:
Name the platform and target you want:

<PromptBox
title="Run an EAS development build"
Expand All @@ -26,12 +30,14 @@ 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.`}
{`Run the app on an iOS simulator using an EAS build.`}
</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.
The response is illustrative. Ask for an Android emulator or connected phone to
change the target. With the Stim skill installed, the agent can inspect
`eas.json` and choose a compatible development profile. If none fits or several
remain plausible, it should ask. You can also name a profile for a specific app
variant. New cloud builds still require your authorization.

## Choose a profile

Expand Down
9 changes: 5 additions & 4 deletions website/docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ com.appandflow.trailhead · ready · cache hit · 58.8s · errors clean`}
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.`}
{`Run the app on an iOS simulator using an EAS build.`}
</PromptBox>
<PromptBox
title="Run on a connected phone"
Expand Down Expand Up @@ -122,9 +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.
The agent can choose a compatible EAS profile for the requested target. It
should ask if none fits or the choice is ambiguous. See
[EAS development builds](./eas-builds.md) for setup, Android and device examples,
and build-miss behavior.

## Run work in parallel

Expand Down
Loading
Loading