agent-scenario-loop 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +119 -0
- package/app/profile-session.ts +812 -0
- package/core/config-template.json +41 -0
- package/dist/core/agent-summary.d.ts +15 -0
- package/dist/core/agent-summary.js +177 -0
- package/dist/core/artifact-contract.d.ts +151 -0
- package/dist/core/artifact-contract.js +897 -0
- package/dist/core/artifact-layout.d.ts +56 -0
- package/dist/core/artifact-layout.js +61 -0
- package/dist/core/artifact-writer.d.ts +44 -0
- package/dist/core/artifact-writer.js +55 -0
- package/dist/core/comparison.d.ts +133 -0
- package/dist/core/comparison.js +294 -0
- package/dist/core/evidence-interpreter.d.ts +28 -0
- package/dist/core/evidence-interpreter.js +69 -0
- package/dist/core/execution-plan.d.ts +44 -0
- package/dist/core/execution-plan.js +95 -0
- package/dist/core/planner.d.ts +132 -0
- package/dist/core/planner.js +812 -0
- package/dist/core/ports.d.ts +198 -0
- package/dist/core/ports.js +146 -0
- package/dist/core/run-index.d.ts +62 -0
- package/dist/core/run-index.js +143 -0
- package/dist/core/schema-validator.d.ts +86 -0
- package/dist/core/schema-validator.js +407 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +27 -0
- package/dist/runner/agent-device-driver.d.ts +126 -0
- package/dist/runner/agent-device-driver.js +168 -0
- package/dist/runner/agent-device.d.ts +295 -0
- package/dist/runner/agent-device.js +1271 -0
- package/dist/runner/android-adb-driver.d.ts +175 -0
- package/dist/runner/android-adb-driver.js +399 -0
- package/dist/runner/android-adb.d.ts +254 -0
- package/dist/runner/android-adb.js +1618 -0
- package/dist/runner/argent-driver.d.ts +183 -0
- package/dist/runner/argent-driver.js +297 -0
- package/dist/runner/argent.d.ts +349 -0
- package/dist/runner/argent.js +1211 -0
- package/dist/runner/check-plan.d.ts +45 -0
- package/dist/runner/check-plan.js +210 -0
- package/dist/runner/cli.d.ts +20 -0
- package/dist/runner/cli.js +23 -0
- package/dist/runner/compare-latest.d.ts +99 -0
- package/dist/runner/compare-latest.js +233 -0
- package/dist/runner/compare.d.ts +58 -0
- package/dist/runner/compare.js +157 -0
- package/dist/runner/demo-loop.d.ts +45 -0
- package/dist/runner/demo-loop.js +170 -0
- package/dist/runner/example-android-live.d.ts +137 -0
- package/dist/runner/example-android-live.js +454 -0
- package/dist/runner/example-ios-live.d.ts +137 -0
- package/dist/runner/example-ios-live.js +471 -0
- package/dist/runner/host-doctor.d.ts +131 -0
- package/dist/runner/host-doctor.js +628 -0
- package/dist/runner/init-project.d.ts +88 -0
- package/dist/runner/init-project.js +263 -0
- package/dist/runner/ios-simctl-driver.d.ts +69 -0
- package/dist/runner/ios-simctl-driver.js +97 -0
- package/dist/runner/ios-simctl.d.ts +254 -0
- package/dist/runner/ios-simctl.js +1415 -0
- package/dist/runner/live-android.d.ts +137 -0
- package/dist/runner/live-android.js +539 -0
- package/dist/runner/live-comparison.d.ts +67 -0
- package/dist/runner/live-comparison.js +147 -0
- package/dist/runner/live-ios.d.ts +137 -0
- package/dist/runner/live-ios.js +460 -0
- package/dist/runner/live-proof-summary.d.ts +263 -0
- package/dist/runner/live-proof-summary.js +465 -0
- package/dist/runner/live-proof.d.ts +467 -0
- package/dist/runner/live-proof.js +920 -0
- package/dist/runner/local-env.d.ts +64 -0
- package/dist/runner/local-env.js +155 -0
- package/dist/runner/profile-android.d.ts +82 -0
- package/dist/runner/profile-android.js +671 -0
- package/dist/runner/profile-ios.d.ts +108 -0
- package/dist/runner/profile-ios.js +532 -0
- package/dist/runner/profile-mobile.d.ts +254 -0
- package/dist/runner/profile-mobile.js +1307 -0
- package/dist/runner/validate-project.d.ts +273 -0
- package/dist/runner/validate-project.js +1501 -0
- package/docs/adapters.md +145 -0
- package/docs/api.md +94 -0
- package/docs/authoring.md +196 -0
- package/docs/concepts.md +136 -0
- package/docs/consumer-rehearsal.md +115 -0
- package/docs/contracts.md +267 -0
- package/docs/live-proofs.md +270 -0
- package/docs/principles.md +46 -0
- package/examples/event-logs/app-startup-baseline.log +4 -0
- package/examples/event-logs/app-startup-current.log +4 -0
- package/examples/minimal-app/README.md +70 -0
- package/examples/mobile-app/README.md +302 -0
- package/examples/mobile-app/app.json +22 -0
- package/examples/mobile-app/asl/package-scripts.json +32 -0
- package/examples/mobile-app/asl.config.json +37 -0
- package/examples/mobile-app/event-logs/android-app-startup.log +4 -0
- package/examples/mobile-app/event-logs/android-open-close-cycle.log +12 -0
- package/examples/mobile-app/event-logs/android-scroll-settle.log +12 -0
- package/examples/mobile-app/event-logs/app-startup.log +4 -0
- package/examples/mobile-app/event-logs/open-close-cycle.log +12 -0
- package/examples/mobile-app/event-logs/scroll-settle.log +12 -0
- package/examples/mobile-app/index.ts +20 -0
- package/examples/mobile-app/metro.config.js +20 -0
- package/examples/mobile-app/package.json +62 -0
- package/examples/mobile-app/patches/expo-modules-jsi@56.0.10.patch +19 -0
- package/examples/mobile-app/plugins/with-ios-build-compat.js +271 -0
- package/examples/mobile-app/pnpm-lock.yaml +4440 -0
- package/examples/mobile-app/runner-manifests/evidence-provider.json +79 -0
- package/examples/mobile-app/runner-manifests/primary-runner.json +19 -0
- package/examples/mobile-app/scenarios/android/app-startup-video.json +73 -0
- package/examples/mobile-app/scenarios/android/app-startup.json +44 -0
- package/examples/mobile-app/scenarios/android/open-close-cycle.json +54 -0
- package/examples/mobile-app/scenarios/android/scroll-settle.json +49 -0
- package/examples/mobile-app/scenarios/ios/app-startup.json +44 -0
- package/examples/mobile-app/scenarios/ios/open-close-cycle.json +54 -0
- package/examples/mobile-app/scenarios/ios/scroll-settle.json +49 -0
- package/examples/mobile-app/scenarios/mobile/app-startup.json +91 -0
- package/examples/mobile-app/scenarios/mobile/open-close-cycle.json +160 -0
- package/examples/mobile-app/scenarios/mobile/scroll-settle.json +148 -0
- package/examples/mobile-app/scripts/asl-capture-accessibility-provider.mjs +112 -0
- package/examples/mobile-app/scripts/asl-capture-profiler-provider.mjs +127 -0
- package/examples/mobile-app/src/devtools/profile-session.ts +7 -0
- package/examples/mobile-app/src/example-screen.tsx +322 -0
- package/examples/mobile-app/tsconfig.json +16 -0
- package/examples/mobile-app/tsconfig.typecheck.json +13 -0
- package/examples/runners/README.md +44 -0
- package/examples/runners/adb-android.json +25 -0
- package/examples/runners/agent-device-android.json +27 -0
- package/examples/runners/agent-device-ios.json +27 -0
- package/examples/runners/argent-android.json +32 -0
- package/examples/runners/argent-ios.json +32 -0
- package/examples/runners/argent-react-profiler-provider.json +15 -0
- package/examples/runners/axe-accessibility-provider.json +24 -0
- package/examples/runners/manual-log-ingest.json +9 -0
- package/examples/runners/rozenite-profiler-provider.json +9 -0
- package/examples/runners/script-accessibility-provider.json +24 -0
- package/examples/runners/script-memory-provider.json +24 -0
- package/examples/runners/script-network-provider.json +24 -0
- package/examples/runners/script-profiler-provider.json +30 -0
- package/examples/runners/xcodebuildmcp-ios.json +29 -0
- package/examples/scenarios/ios/app-startup.json +28 -0
- package/examples/scenarios/ios/open-close-cycle.json +35 -0
- package/examples/scenarios/mobile/app-startup.json +72 -0
- package/examples/scenarios/mobile/media-open-close.json +141 -0
- package/examples/scenarios/mobile/open-close-cycle.json +135 -0
- package/examples/scenarios/mobile/scroll-settle.json +106 -0
- package/package.json +240 -0
- package/schemas/budget-verdict.schema.json +115 -0
- package/schemas/causal-run.schema.json +279 -0
- package/schemas/comparison.schema.json +196 -0
- package/schemas/health.schema.json +108 -0
- package/schemas/live-proof-set.schema.json +195 -0
- package/schemas/live-proof.schema.json +413 -0
- package/schemas/manifest.schema.json +204 -0
- package/schemas/metrics.schema.json +137 -0
- package/schemas/project-validation.schema.json +343 -0
- package/schemas/runner-capabilities.schema.json +217 -0
- package/schemas/scenario.schema.json +400 -0
- package/schemas/verdict.schema.json +88 -0
- package/templates/evidence-provider.json +83 -0
- package/templates/gitignore-snippet +9 -0
- package/templates/integration-readme.md +125 -0
- package/templates/mobile-scenario.json +133 -0
- package/templates/package-scripts.json +32 -0
- package/templates/primary-runner.json +19 -0
- package/templates/project.config.json +37 -0
- package/templates/scripts/asl-capture-accessibility-provider.mjs +112 -0
- package/templates/scripts/asl-capture-profiler-provider.mjs +127 -0
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
# Example Mobile App
|
|
2
|
+
|
|
3
|
+
This is the neutral Expo dogfood app for Agent Scenario Loop. It exists to prove the package contract with app-owned truth events before public release work.
|
|
4
|
+
|
|
5
|
+
The app surface is intentionally small:
|
|
6
|
+
|
|
7
|
+
- startup emits launch-to-ready milestones
|
|
8
|
+
- card open-close emits repeated interaction milestones
|
|
9
|
+
- scroll-settle emits list movement and settled-state milestones
|
|
10
|
+
|
|
11
|
+
Release checks use the committed Android and iOS profile-event logs in `event-logs/` so package validation stays deterministic. Android adb capture and iOS simctl capture can also launch the package, collect runtime evidence, and feed the same scenario artifacts through the profile runners.
|
|
12
|
+
|
|
13
|
+
The app is intentionally private and minimal. It uses a direct Expo entrypoint, a safe-area provider, and one screen so iOS and Android drivers can launch the same app surface without creating product-specific fixtures.
|
|
14
|
+
|
|
15
|
+
The iOS app uses `plugins/with-ios-build-compat.js` during Expo prebuild. That plugin generates the scene lifecycle shape required by newer iOS simulator runtimes and keeps generated Pods on the app deployment target. The app also declares `@expo/metro-runtime` directly because strict pnpm installs do not let Expo resolve transitive Metro runtime imports across package boundaries.
|
|
16
|
+
|
|
17
|
+
## Consumer Scaffold
|
|
18
|
+
|
|
19
|
+
The example app also carries the same project-local files a consuming app gets from `asl-init`:
|
|
20
|
+
|
|
21
|
+
- `src/devtools/profile-session.ts`: local app helper entrypoint used by the screen
|
|
22
|
+
- `runner-manifests/primary-runner.json`: portable iOS and Android runner capability manifest
|
|
23
|
+
- `runner-manifests/evidence-provider.json`: optional accessibility, profiler, memory, and network provider manifest
|
|
24
|
+
- `scenarios/mobile/app-startup.json`: portable startup scenario used for project validation
|
|
25
|
+
- `scenarios/mobile/open-close-cycle.json`: portable repeated interaction scenario profiled on both iOS and Android
|
|
26
|
+
- `scenarios/mobile/scroll-settle.json`: portable feed scroll scenario profiled on both iOS and Android
|
|
27
|
+
- `asl/package-scripts.json`: public CLI snippets that a consuming app can merge into `package.json`
|
|
28
|
+
|
|
29
|
+
Validate the example app exactly like a consumer project:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pnpm asl:validate
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The app-local `asl:*` scripts build the package from the repo root, then call the compiled public CLIs from the example app directory.
|
|
36
|
+
|
|
37
|
+
Start the example app on Android with:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
pnpm install
|
|
41
|
+
pnpm android
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
From the package root, the same launch command is available as:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pnpm example:app:android
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Keep Metro running after this command opens the app.
|
|
51
|
+
|
|
52
|
+
Prepare the generated iOS project with:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pnpm ios:prebuild
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
From the package root, the same prebuild command is available as:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
pnpm example:app:ios:prebuild
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The generated `ios/` directory stays ignored. Commit the Expo config, package metadata, scenarios, patches, and config plugins that reproduce it, not the generated native output.
|
|
65
|
+
|
|
66
|
+
Run the generated iOS app from the package root with:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
pnpm example:app:ios
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Set `ASL_EXAMPLE_XCODE_DEVELOPER_DIR` before this command when the local default Xcode is not the Xcode you want the example app to use.
|
|
73
|
+
|
|
74
|
+
For an isolated Metro server that does not collide with another React Native app on `8081`, start Metro from the package root with:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pnpm example:app:start:isolated
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The isolated command binds Metro to `localhost:8097` and clears Metro cache state for the example app. If the iOS simulator falls back to another Metro server, write the React Native packager override before launching the app:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
pnpm example:app:ios:metro-port
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
The command targets the booted simulator and the example app bundle id by default. Override them with environment variables when needed:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
ASL_EXAMPLE_IOS_DEVICE=<simulator-udid> ASL_EXAMPLE_METRO_PORT=8097 pnpm example:app:ios:metro-port
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
For Expo dev-client builds, set `ASL_EXAMPLE_ANDROID_DEV_CLIENT_URL` or `ASL_EXAMPLE_IOS_DEV_CLIENT_URL` to the example app's dev-client URL for the same Metro port. Android live runners open that URL before profile-session deep links; iOS live runners open it after launching the native shell and before collecting stored profile-session evidence.
|
|
93
|
+
|
|
94
|
+
If a selected Xcode beta cannot run the current Expo/RN toolchain cleanly, point `ASL_EXAMPLE_XCODE_DEVELOPER_DIR` at a stable Xcode developer directory before running the iOS Metro-port, live proof, or raw local iOS build commands.
|
|
95
|
+
|
|
96
|
+
## Files
|
|
97
|
+
|
|
98
|
+
- `index.ts`: direct Expo entrypoint and safe-area provider
|
|
99
|
+
- `src/example-screen.tsx`: scenario surface wired to the local profile-session helper
|
|
100
|
+
- `package.json`, `app.json`, `tsconfig.json`: private Expo app configuration
|
|
101
|
+
- `metro.config.js`: allows the app to import the package helper from the repo/package root
|
|
102
|
+
- `asl.config.json`: runner config for example app artifact output
|
|
103
|
+
- `asl/package-scripts.json`: consumer-facing package-script snippets, including portable agent-device and Argent interaction proof commands
|
|
104
|
+
- `runner-manifests/*.json`: project-local runner and provider capability manifests
|
|
105
|
+
- `scripts/asl-capture-accessibility-provider.mjs`: deterministic accessibility provider command used by provider-profile scripts
|
|
106
|
+
- `scripts/asl-capture-profiler-provider.mjs`: deterministic profiler, memory, and network provider command used by provider-profile scripts
|
|
107
|
+
- `scenarios/mobile/app-startup.json`: portable consumer-validation scenario
|
|
108
|
+
- `scenarios/mobile/open-close-cycle.json`: portable open-close scenario backed by committed iOS and Android fixture logs
|
|
109
|
+
- `scenarios/mobile/scroll-settle.json`: portable scroll-settle scenario backed by committed iOS and Android fixture logs
|
|
110
|
+
- `scenarios/android/*.json`: Android profile scenario manifests
|
|
111
|
+
- `scenarios/ios/*.json`: iOS profile scenario manifests
|
|
112
|
+
- `event-logs/*.log`: deterministic profile-event evidence fixtures
|
|
113
|
+
|
|
114
|
+
## Fixture Proof
|
|
115
|
+
|
|
116
|
+
Run one example scenario through the package runner:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
pnpm example:profile:startup
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
From inside `examples/mobile-app`, the consumer-shaped scripts are:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
pnpm asl:validate
|
|
126
|
+
pnpm asl:check:ios
|
|
127
|
+
pnpm asl:check:android
|
|
128
|
+
pnpm asl:profile:ios
|
|
129
|
+
pnpm asl:profile:android
|
|
130
|
+
pnpm asl:profile:ios:provider
|
|
131
|
+
pnpm asl:profile:android:provider
|
|
132
|
+
pnpm asl:agent-device:check
|
|
133
|
+
pnpm asl:agent-device:ios
|
|
134
|
+
pnpm asl:agent-device:android
|
|
135
|
+
pnpm asl:argent:check
|
|
136
|
+
pnpm asl:argent:ios
|
|
137
|
+
pnpm asl:argent:android
|
|
138
|
+
ASL_ARGENT_BIN=/path/to/argent pnpm asl:argent:android
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
The `*:provider` scripts execute `runner-manifests/evidence-provider.json`, which runs the deterministic provider scripts and inventories generated accessibility, profiler, memory, and network evidence in `manifest.artifacts.evidenceAttachments`.
|
|
142
|
+
|
|
143
|
+
For repeated local runs, put machine-specific runner values in an ignored `.asl.local.env` file at the example app or repo root instead of repeating inline environment variables. ASL CLIs load the nearest `.asl.local.env` without overriding already-exported values:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
ASL_HOST_DOCTOR_REQUIRE=android,ios,agent-device,argent
|
|
147
|
+
ASL_AGENT_DEVICE_REQUIRED_PLATFORMS=ios,android
|
|
148
|
+
ASL_ANDROID_AGENT_DEVICE_SESSION=android-example
|
|
149
|
+
ASL_IOS_AGENT_DEVICE_SESSION=default
|
|
150
|
+
ASL_EXAMPLE_IOS_DEV_CLIENT_URL=asl-example://expo-development-client/?url=http%3A%2F%2Flocalhost%3A8097
|
|
151
|
+
ASL_ARGENT_BIN=pnpm
|
|
152
|
+
ASL_ARGENT_BASE_ARGS="dlx @swmansion/argent run"
|
|
153
|
+
ASL_ARGENT_IOS_SIMCTL_SCREENSHOT_FALLBACK=1
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
The `asl:agent-device:*` and `asl:argent:*` scripts are portable interaction proof lanes. They require the corresponding external tool and a running device or simulator, but they write the same ASL health, verdict, raw, capture, and summary artifacts. `asl:agent-device:check` verifies the configured agent-device command surface, device discovery, and active sessions before a scenario starts, writing availability artifacts under `artifacts/asl/agent-device-check`; set `ASL_AGENT_DEVICE_REQUIRED_PLATFORMS=ios,android` when both OS targets must be booted. Active sessions are preserved in `raw/agent-device-availability.json` and summarized in `agent-summary.md`, so a sidecar run can reuse the right Android or iOS session instead of borrowing a default session bound to the wrong target. `asl:argent:check` verifies the configured Argent command and ASL-required tool surface before any device scenario starts, writing availability artifacts under `artifacts/asl/argent-check`. For Argent, prefer a real `argent` executable on PATH, or set `ASL_ARGENT_BIN=/path/to/argent` when the package manager installed it somewhere else. `ASL_ARGENT_BIN=npx` with `ASL_ARGENT_BASE_ARGS="--yes @swmansion/argent run"` is supported as a wrapper shape, but run `pnpm asl:argent:check` before relying on it. Argent uses `--udid` for both iOS simulators and Android emulators, and ASL resolves the iOS `booted` shorthand to the concrete simulator UDID before invoking Argent.
|
|
157
|
+
|
|
158
|
+
Live proof and inspection scripts are also available from the app directory:
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
pnpm asl:android:live
|
|
162
|
+
pnpm asl:live-proof:android
|
|
163
|
+
pnpm asl:ios:live
|
|
164
|
+
pnpm asl:live-proof:ios
|
|
165
|
+
pnpm asl:live-proof:both
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
The live scripts pass `--compare-latest --fail-on-regression`, so they write comparison context by default and exit nonzero only when a comparable trusted baseline regresses. The live-proof inspection scripts also pass `--fail-on-regression` for already-written aggregate proof files. `asl:live-proof:both` requires both Android and iOS proof artifacts, writes `artifacts/asl/live-proof-set/live-proof-set.json` plus `agent-summary.md`, and fails if either platform is missing, either proof status failed, or either proof regressed. Set `ASL_REQUIRE_LIVE_PROOF_ARTIFACTS=1` for a final local gate that also requires referenced summaries, comparison outputs, and captures to exist on disk. This keeps the dogfood example aligned with the package scaffold and makes regression evidence a real gate by default.
|
|
169
|
+
|
|
170
|
+
For suffixed live runs, point the inspection script at the generated proof file:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
ASL_EXAMPLE_ANDROID_LIVE_PROOF=artifacts/asl/android-live/_live-proof/android-live-proof-dogfood/live-proof.json pnpm asl:live-proof:android
|
|
174
|
+
ASL_EXAMPLE_ANDROID_LIVE_PROOF=artifacts/asl/android-live/_live-proof/android-live-proof-dogfood/live-proof.json \
|
|
175
|
+
ASL_EXAMPLE_IOS_LIVE_PROOF=artifacts/asl/ios-live/_live-proof/ios-live-proof-dogfood/live-proof.json \
|
|
176
|
+
pnpm asl:live-proof:both
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
The runner writes `health.json`, `verdict.json`, `agent-summary.md`, `metrics.json`, `causal-run.json`, and raw evidence under the printed run directory.
|
|
180
|
+
|
|
181
|
+
Additional fixture-backed profiles:
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
pnpm example:profile:open-close
|
|
185
|
+
pnpm example:profile:scroll
|
|
186
|
+
pnpm example:profile:android:startup
|
|
187
|
+
pnpm example:profile:android:open-close
|
|
188
|
+
pnpm example:profile:android:scroll
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Android Capture
|
|
192
|
+
|
|
193
|
+
With an emulator or device online and the example app installed, the Android runner can own the capture window before writing profile artifacts. The full proof command starts with adb/package preflight, runs every canonical Android example scenario, and prints the `agent-summary.md` path for each run:
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
pnpm example:android:live
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
The aggregate command writes `_live-proof/android-live-proof/live-proof.json` and `_live-proof/android-live-proof/agent-summary.md` under the Android artifact root as the batch entrypoint.
|
|
200
|
+
|
|
201
|
+
When `agent-device` or Argent is available, attach the same startup interaction assertion as a sidecar proof:
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
ASL_EXAMPLE_ANDROID_AGENT_DEVICE_SESSION=<name> pnpm example:android:live:agent-device
|
|
205
|
+
pnpm example:android:live:argent
|
|
206
|
+
ASL_EXAMPLE_ANDROID_AGENT_DEVICE_SESSION=<name> pnpm example:android:live:runners
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
The sidecar scripts use stable run suffixes so they do not overwrite the direct Android proof. They write `_live-proof/android-live-proof-agent-device`, `_live-proof/android-live-proof-argent`, or `_live-proof/android-live-proof-runners`; point `ASL_EXAMPLE_ANDROID_LIVE_PROOF` at one of those files when you want `pnpm asl:live-proof:android` or `pnpm asl:live-proof:both` to inspect a sidecar proof instead of the direct proof.
|
|
210
|
+
|
|
211
|
+
Named agent-device sessions default to `reuse`, where the session owns target selection. If your direct Android serial is correct but the default agent-device session is bound elsewhere, set `ASL_EXAMPLE_ANDROID_AGENT_DEVICE_SESSION_MODE=bind` with `ASL_EXAMPLE_ANDROID_AGENT_DEVICE_SESSION=<name>` so the sidecar session still receives the configured serial.
|
|
212
|
+
|
|
213
|
+
For Argent without a global binary, set `ASL_ARGENT_BIN=/path/to/argent` to the installed executable. The `npx --yes @swmansion/argent run` wrapper shape is supported through `ASL_ARGENT_BIN=npx` and `ASL_ARGENT_BASE_ARGS="--yes @swmansion/argent run"`, but verify it with `pnpm asl:argent:check` before relying on it.
|
|
214
|
+
|
|
215
|
+
The adb profile scenarios run before sidecar proofs. This keeps app-owned profile events, logs, screenshots, metrics, and verdicts independent from any UI automation session opened by agent-device or Argent.
|
|
216
|
+
|
|
217
|
+
The live Android commands assume the isolated Metro server is on port `8097`. They configure adb reverse and the app's React Native debug host as `localhost:8097` before launch, so the example app does not accidentally load another app's Metro bundle from the default `8081` port. To apply only that Android Metro routing setup, run:
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
pnpm example:app:android:metro-port
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
Override the target package or debug host when needed:
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
ASL_EXAMPLE_ANDROID_APP_ID=<package-name> ASL_EXAMPLE_ANDROID_DEBUG_HOST=<host:port> pnpm example:app:android:metro-port
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
The root example live scripts pass `--compare-latest --fail-on-regression` by default. Missing same-lane baselines are recorded as skipped comparison evidence; real regressions exit nonzero after artifacts are written. Pass a run suffix when you want preserved live artifact directories for before/after comparison:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
pnpm example:android:live -- --run-suffix before-change
|
|
233
|
+
pnpm example:android:live -- --run-suffix after-change
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
The individual live commands remain useful while debugging one scenario:
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
pnpm example:profile:android:live:startup
|
|
240
|
+
pnpm example:profile:android:live:open-close
|
|
241
|
+
pnpm example:profile:android:live:scroll
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
The command targets live in the scenario `adapterOptions.androidAdb.commands` block, while the app handles them through `registerProfileCommandTargetHandler`. If adb, the package, or the device is unavailable, the adb capture folder gets a failed `health.json` and the profile run stops before making timing claims.
|
|
245
|
+
|
|
246
|
+
The example Android live proof uses a short `--launch-wait-ms` delay before sending profile-session deep links so React Native has time to attach its deep-link listener after cold launch. Expo dev-client builds can also pass `--android-dev-client-url` or set `ASL_EXAMPLE_ANDROID_DEV_CLIENT_URL` so the runner opens the Metro session before profile-session links. Add `--android-dev-client-ready-pattern 'Running "main"'` or `ASL_EXAMPLE_ANDROID_DEV_CLIENT_READY_PATTERN='Running "main"'` when the dev client needs bounded logcat proof that the JS bundle is ready. Keep those waits separate from `--command-wait-ms`, which waits after app-handled profile commands, and `--wait-ms`, which controls the final logcat capture window.
|
|
247
|
+
|
|
248
|
+
Use `--android-profile-session-storage` only when the app has mounted the ASL AsyncStorage profile-session bridge and Android URL events are not reliable enough for startup control. Storage-backed Android sessions use the selected device clock for `startedAt`, so app-emitted milestone offsets remain meaningful even when the host and emulator clocks differ.
|
|
249
|
+
|
|
250
|
+
If direct `adb devices` works but the Node-based runner reports no online device and raw `adb-devices.txt` mentions the adb daemon or `Operation not permitted`, rerun with adb daemon permissions before treating the failure as an app, package, or emulator issue.
|
|
251
|
+
|
|
252
|
+
`scenarios/android/app-startup-video.json` is an opt-in variant that adds an optional `record` capture step. Use it when you want adb to preserve `captures.video` for a startup run without making video part of the default live proof.
|
|
253
|
+
|
|
254
|
+
## iOS Capture
|
|
255
|
+
|
|
256
|
+
With the example app installed on a booted iOS simulator and Metro connected, the iOS runner can own a simctl capture window before writing profile artifacts. The live commands use storage-backed profile-session and command seeding, so they do not depend on iOS unified logs carrying JavaScript console output:
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
pnpm example:ios:live
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
The aggregate command runs simctl preflight, startup, open-close, and scroll-settle. It also writes `_live-proof/ios-live-proof/live-proof.json` and `_live-proof/ios-live-proof/agent-summary.md` under the iOS artifact root as the batch entrypoint.
|
|
263
|
+
|
|
264
|
+
When `agent-device` or Argent is available, attach the same startup interaction assertion as a sidecar proof:
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
ASL_EXAMPLE_IOS_AGENT_DEVICE_SESSION=<name> pnpm example:ios:live:agent-device
|
|
268
|
+
pnpm example:ios:live:argent
|
|
269
|
+
ASL_EXAMPLE_IOS_AGENT_DEVICE_SESSION=<name> pnpm example:ios:live:runners
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
The sidecar scripts use stable run suffixes so they do not overwrite the direct iOS proof. They write `_live-proof/ios-live-proof-agent-device`, `_live-proof/ios-live-proof-argent`, or `_live-proof/ios-live-proof-runners`; point `ASL_EXAMPLE_IOS_LIVE_PROOF` at one of those files when you want `pnpm asl:live-proof:ios` or `pnpm asl:live-proof:both` to inspect a sidecar proof instead of the direct proof.
|
|
273
|
+
|
|
274
|
+
Named agent-device sessions default to `reuse`, where the session owns target selection. If your direct simulator UDID is correct but the default agent-device session is bound elsewhere, set `ASL_EXAMPLE_IOS_AGENT_DEVICE_SESSION_MODE=bind` with `ASL_EXAMPLE_IOS_AGENT_DEVICE_SESSION=<name>` so the sidecar session still receives the configured UDID.
|
|
275
|
+
|
|
276
|
+
For Argent without a global binary, set `ASL_ARGENT_BIN=/path/to/argent` to the installed executable. The `npx --yes @swmansion/argent run` wrapper shape is supported through `ASL_ARGENT_BIN=npx` and `ASL_ARGENT_BASE_ARGS="--yes @swmansion/argent run"`, but verify it with `pnpm asl:argent:check` before relying on it.
|
|
277
|
+
|
|
278
|
+
The simctl profile scenarios run before sidecar proofs. This keeps stored app truth events, screenshots, metrics, and verdicts independent from any UI automation session opened by agent-device or Argent. When Argent can launch and inspect the iOS app but its screenshot backend is unavailable, the iOS live proof keeps the Argent warning and attaches a simctl screenshot fallback under the same interaction proof captures.
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
pnpm example:profile:ios:live:startup
|
|
282
|
+
pnpm example:profile:ios:live:open-close
|
|
283
|
+
pnpm example:profile:ios:live:scroll
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
The root example live scripts pass `--compare-latest --fail-on-regression` by default. Pass a run suffix when you want preserved iOS live artifact directories:
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
pnpm example:ios:live -- --run-suffix after-change
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
If global `xcode-select` points at a beta Xcode whose simulator services are not ready, set `ASL_EXAMPLE_XCODE_DEVELOPER_DIR` before the Node runner starts:
|
|
293
|
+
|
|
294
|
+
```bash
|
|
295
|
+
ASL_EXAMPLE_XCODE_DEVELOPER_DIR=<xcode-app>/Contents/Developer pnpm example:ios:live -- --device <booted-simulator-udid>
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
If direct `xcrun simctl list devices` works but the Node-based runner reports `ios_simctl_unavailable`, the runner may be inside an agent sandbox without CoreSimulator access. Rerun with simulator/CoreSimulator permissions before treating the failure as an app or Xcode setup regression.
|
|
299
|
+
|
|
300
|
+
Each command writes simctl capture evidence under `artifacts/example-mobile-app/ios/_ios-simctl-captures/<run-id>`, collects stored app truth events into `raw/ios-profile-events.log`, then writes scenario artifacts under the matching scenario run directory.
|
|
301
|
+
|
|
302
|
+
The command targets live in the scenario `adapterOptions.iosSimctl.commands` block, while the app handles them through `registerProfileCommandTargetHandler`. If simctl, the installed app, or the simulator is unavailable, the simctl capture folder gets a failed `health.json` and the profile run stops before making timing claims.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"expo": {
|
|
3
|
+
"name": "ASL Example Mobile",
|
|
4
|
+
"slug": "asl-example-mobile",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"orientation": "portrait",
|
|
7
|
+
"scheme": "asl-example",
|
|
8
|
+
"platforms": [
|
|
9
|
+
"ios",
|
|
10
|
+
"android"
|
|
11
|
+
],
|
|
12
|
+
"ios": {
|
|
13
|
+
"bundleIdentifier": "dev.agent-scenario-loop.example"
|
|
14
|
+
},
|
|
15
|
+
"android": {
|
|
16
|
+
"package": "dev.agentscenarioloop.example"
|
|
17
|
+
},
|
|
18
|
+
"plugins": [
|
|
19
|
+
"./plugins/with-ios-build-compat"
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"asl:check:ios": "asl-check-plan --scenario scenarios/mobile/app-startup.json --runner runner-manifests/primary-runner.json --provider runner-manifests/evidence-provider.json --platform ios --out artifacts/asl/plan/app-startup-ios",
|
|
3
|
+
"asl:check:android": "asl-check-plan --scenario scenarios/mobile/app-startup.json --runner runner-manifests/primary-runner.json --provider runner-manifests/evidence-provider.json --platform android --out artifacts/asl/plan/app-startup-android",
|
|
4
|
+
"asl:validate": "asl-validate-project --root . --platform all --out artifacts/asl/project-validation",
|
|
5
|
+
"asl:host:doctor": "asl-host-doctor --out artifacts/asl/host-doctor",
|
|
6
|
+
"asl:profile:ios": "asl-profile-ios --config asl.config.json --scenario scenarios/ios/app-startup.json --events event-logs/app-startup.log --comparison-lane app-startup-ios-fixture --out artifacts/asl/ios --run-id app-startup-ios-fixture",
|
|
7
|
+
"asl:profile:android": "asl-profile-android --config asl.config.json --scenario scenarios/android/app-startup.json --events event-logs/android-app-startup.log --comparison-lane app-startup-android-fixture --out artifacts/asl/android --run-id app-startup-android-fixture",
|
|
8
|
+
"asl:profile:ios:provider": "asl-profile-ios --config asl.config.json --scenario scenarios/ios/app-startup.json --events event-logs/app-startup.log --provider runner-manifests/evidence-provider.json --comparison-lane app-startup-ios-provider --out artifacts/asl/ios --run-id app-startup-ios-provider",
|
|
9
|
+
"asl:profile:android:provider": "asl-profile-android --config asl.config.json --scenario scenarios/android/app-startup.json --events event-logs/android-app-startup.log --provider runner-manifests/evidence-provider.json --comparison-lane app-startup-android-provider --out artifacts/asl/android --run-id app-startup-android-provider",
|
|
10
|
+
"asl:agent-device:check": "asl-agent-device --check --out artifacts/asl/agent-device-check",
|
|
11
|
+
"asl:agent-device:ios": "asl-agent-device --platform ios ${ASL_IOS_AGENT_DEVICE_SESSION:+--session $ASL_IOS_AGENT_DEVICE_SESSION} ${ASL_IOS_AGENT_DEVICE_SESSION_MODE:+--session-mode $ASL_IOS_AGENT_DEVICE_SESSION_MODE} ${ASL_IOS_UDID:+--udid $ASL_IOS_UDID} ${ASL_AGENT_DEVICE_COMMAND_TIMEOUT_MS:+--command-timeout-ms $ASL_AGENT_DEVICE_COMMAND_TIMEOUT_MS} --scenario scenarios/mobile/app-startup.json --app ${ASL_IOS_APP_ID:-dev.agent-scenario-loop.example} --open --wait-ms 1000 --out artifacts/asl/agent-device-ios --run-id app-startup-ios-agent-device",
|
|
12
|
+
"asl:agent-device:android": "asl-agent-device --platform android ${ASL_ANDROID_AGENT_DEVICE_SESSION:+--session $ASL_ANDROID_AGENT_DEVICE_SESSION} ${ASL_ANDROID_AGENT_DEVICE_SESSION_MODE:+--session-mode $ASL_ANDROID_AGENT_DEVICE_SESSION_MODE} ${ASL_ANDROID_SERIAL:+--serial $ASL_ANDROID_SERIAL} ${ASL_AGENT_DEVICE_COMMAND_TIMEOUT_MS:+--command-timeout-ms $ASL_AGENT_DEVICE_COMMAND_TIMEOUT_MS} --scenario scenarios/mobile/app-startup.json --app ${ASL_ANDROID_APP_ID:-dev.agentscenarioloop.example} --open --wait-ms 1000 --out artifacts/asl/agent-device-android --run-id app-startup-android-agent-device",
|
|
13
|
+
"asl:argent:check": "asl-argent --check --out artifacts/asl/argent-check",
|
|
14
|
+
"asl:argent:ios": "asl-argent --platform ios ${ASL_ARGENT_BIN:+--argent $ASL_ARGENT_BIN} ${ASL_ARGENT_BASE_ARGS:+--base-args \"$ASL_ARGENT_BASE_ARGS\"} ${ASL_ARGENT_DEVICE_FLAG:+--device-flag $ASL_ARGENT_DEVICE_FLAG} ${ASL_ARGENT_APP_FLAG:+--app-flag $ASL_ARGENT_APP_FLAG} ${ASL_ARGENT_COMMAND_TIMEOUT_MS:+--command-timeout-ms $ASL_ARGENT_COMMAND_TIMEOUT_MS} ${ASL_ARGENT_IOS_SIMCTL_SCREENSHOT_FALLBACK:+--ios-simctl-screenshot-fallback} ${ASL_XCRUN_PATH:+--xcrun $ASL_XCRUN_PATH} --scenario scenarios/mobile/app-startup.json --app ${ASL_IOS_APP_ID:-dev.agent-scenario-loop.example} --device ${ASL_IOS_UDID:-booted} --out artifacts/asl/argent-ios --run-id app-startup-ios-argent",
|
|
15
|
+
"asl:argent:android": "asl-argent --platform android ${ASL_ARGENT_BIN:+--argent $ASL_ARGENT_BIN} ${ASL_ARGENT_BASE_ARGS:+--base-args \"$ASL_ARGENT_BASE_ARGS\"} ${ASL_ARGENT_DEVICE_FLAG:+--device-flag $ASL_ARGENT_DEVICE_FLAG} ${ASL_ARGENT_APP_FLAG:+--app-flag $ASL_ARGENT_APP_FLAG} ${ASL_ARGENT_COMMAND_TIMEOUT_MS:+--command-timeout-ms $ASL_ARGENT_COMMAND_TIMEOUT_MS} --scenario scenarios/mobile/app-startup.json --app ${ASL_ANDROID_APP_ID:-dev.agentscenarioloop.example} --device ${ASL_ANDROID_SERIAL:-emulator-5554} --out artifacts/asl/argent-android --run-id app-startup-android-argent",
|
|
16
|
+
"asl:android:live": "asl-live-android --config asl.config.json --scenario scenarios/mobile/app-startup.json --out artifacts/asl/android-live ${ASL_ANDROID_SERIAL:+--serial $ASL_ANDROID_SERIAL} ${ASL_ANDROID_APP_ID:+--package $ASL_ANDROID_APP_ID} ${ASL_ANDROID_REACT_NATIVE_DEBUG_HOST:+--react-native-debug-host $ASL_ANDROID_REACT_NATIVE_DEBUG_HOST} --compare-latest --fail-on-regression",
|
|
17
|
+
"asl:android:live:agent-device": "asl-live-android --config asl.config.json --scenario scenarios/mobile/app-startup.json --out artifacts/asl/android-live ${ASL_ANDROID_SERIAL:+--serial $ASL_ANDROID_SERIAL} ${ASL_ANDROID_APP_ID:+--package $ASL_ANDROID_APP_ID} ${ASL_ANDROID_REACT_NATIVE_DEBUG_HOST:+--react-native-debug-host $ASL_ANDROID_REACT_NATIVE_DEBUG_HOST} ${ASL_ANDROID_AGENT_DEVICE_SESSION:+--agent-device-session $ASL_ANDROID_AGENT_DEVICE_SESSION} ${ASL_ANDROID_AGENT_DEVICE_SESSION_MODE:+--agent-device-session-mode $ASL_ANDROID_AGENT_DEVICE_SESSION_MODE} --run-suffix agent-device --agent-device-proof --compare-latest --fail-on-regression",
|
|
18
|
+
"asl:android:live:argent": "asl-live-android --config asl.config.json --scenario scenarios/mobile/app-startup.json --out artifacts/asl/android-live ${ASL_ANDROID_SERIAL:+--serial $ASL_ANDROID_SERIAL} ${ASL_ANDROID_APP_ID:+--package $ASL_ANDROID_APP_ID} ${ASL_ANDROID_REACT_NATIVE_DEBUG_HOST:+--react-native-debug-host $ASL_ANDROID_REACT_NATIVE_DEBUG_HOST} --run-suffix argent --argent-proof --compare-latest --fail-on-regression",
|
|
19
|
+
"asl:android:live:runners": "asl-live-android --config asl.config.json --scenario scenarios/mobile/app-startup.json --out artifacts/asl/android-live ${ASL_ANDROID_SERIAL:+--serial $ASL_ANDROID_SERIAL} ${ASL_ANDROID_APP_ID:+--package $ASL_ANDROID_APP_ID} ${ASL_ANDROID_REACT_NATIVE_DEBUG_HOST:+--react-native-debug-host $ASL_ANDROID_REACT_NATIVE_DEBUG_HOST} ${ASL_ANDROID_AGENT_DEVICE_SESSION:+--agent-device-session $ASL_ANDROID_AGENT_DEVICE_SESSION} ${ASL_ANDROID_AGENT_DEVICE_SESSION_MODE:+--agent-device-session-mode $ASL_ANDROID_AGENT_DEVICE_SESSION_MODE} --run-suffix runners --agent-device-proof --argent-proof --compare-latest --fail-on-regression",
|
|
20
|
+
"asl:ios:live": "asl-live-ios --config asl.config.json --scenario scenarios/mobile/app-startup.json --out artifacts/asl/ios-live ${ASL_IOS_UDID:+--device $ASL_IOS_UDID} ${ASL_IOS_APP_ID:+--bundle $ASL_IOS_APP_ID} --compare-latest --fail-on-regression",
|
|
21
|
+
"asl:ios:live:agent-device": "asl-live-ios --config asl.config.json --scenario scenarios/mobile/app-startup.json --out artifacts/asl/ios-live ${ASL_IOS_UDID:+--device $ASL_IOS_UDID} ${ASL_IOS_APP_ID:+--bundle $ASL_IOS_APP_ID} ${ASL_IOS_AGENT_DEVICE_SESSION:+--agent-device-session $ASL_IOS_AGENT_DEVICE_SESSION} ${ASL_IOS_AGENT_DEVICE_SESSION_MODE:+--agent-device-session-mode $ASL_IOS_AGENT_DEVICE_SESSION_MODE} --run-suffix agent-device --agent-device-proof --compare-latest --fail-on-regression",
|
|
22
|
+
"asl:ios:live:argent": "asl-live-ios --config asl.config.json --scenario scenarios/mobile/app-startup.json --out artifacts/asl/ios-live ${ASL_IOS_UDID:+--device $ASL_IOS_UDID} ${ASL_IOS_APP_ID:+--bundle $ASL_IOS_APP_ID} --run-suffix argent --argent-proof --compare-latest --fail-on-regression",
|
|
23
|
+
"asl:ios:live:runners": "asl-live-ios --config asl.config.json --scenario scenarios/mobile/app-startup.json --out artifacts/asl/ios-live ${ASL_IOS_UDID:+--device $ASL_IOS_UDID} ${ASL_IOS_APP_ID:+--bundle $ASL_IOS_APP_ID} ${ASL_IOS_AGENT_DEVICE_SESSION:+--agent-device-session $ASL_IOS_AGENT_DEVICE_SESSION} ${ASL_IOS_AGENT_DEVICE_SESSION_MODE:+--agent-device-session-mode $ASL_IOS_AGENT_DEVICE_SESSION_MODE} --run-suffix runners --agent-device-proof --argent-proof --compare-latest --fail-on-regression",
|
|
24
|
+
"asl:profile:ios:live": "asl-profile-ios --config asl.config.json --scenario scenarios/mobile/app-startup.json --simctl-capture --profile-session --profile-session-storage --launch --comparison-lane app-startup-ios-live --out artifacts/asl/ios --run-id app-startup-ios-live",
|
|
25
|
+
"asl:profile:android:live": "asl-profile-android --config asl.config.json --scenario scenarios/mobile/app-startup.json --adb-capture --profile-session --clear-logcat --launch --comparison-lane app-startup-android-live --out artifacts/asl/android --run-id app-startup-android-live",
|
|
26
|
+
"asl:compare:ios": "asl-compare-latest --root artifacts/asl/ios --scenario app-startup --current ${ASL_COMPARE_IOS_CURRENT:?set_ASL_COMPARE_IOS_CURRENT} --out artifacts/asl/ios/comparisons/app-startup --fail-on-regression",
|
|
27
|
+
"asl:compare:android": "asl-compare-latest --root artifacts/asl/android --scenario app-startup --current ${ASL_COMPARE_ANDROID_CURRENT:?set_ASL_COMPARE_ANDROID_CURRENT} --out artifacts/asl/android/comparisons/app-startup --fail-on-regression",
|
|
28
|
+
"asl:live-proof:android": "asl-live-proof --file ${ASL_ANDROID_LIVE_PROOF:-artifacts/asl/android-live/_live-proof/android-live-proof/live-proof.json} --fail-on-regression",
|
|
29
|
+
"asl:live-proof:ios": "asl-live-proof --file ${ASL_IOS_LIVE_PROOF:-artifacts/asl/ios-live/_live-proof/ios-live-proof/live-proof.json} --fail-on-regression",
|
|
30
|
+
"asl:live-proof:both": "asl-live-proof --file ${ASL_ANDROID_LIVE_PROOF:-artifacts/asl/android-live/_live-proof/android-live-proof/live-proof.json} --file ${ASL_IOS_LIVE_PROOF:-artifacts/asl/ios-live/_live-proof/ios-live-proof/live-proof.json} --require-platforms android,ios --out artifacts/asl/live-proof-set --fail-on-regression ${ASL_REQUIRE_LIVE_PROOF_ARTIFACTS:+--require-artifacts}",
|
|
31
|
+
"asl:live-proof": "asl-live-proof --file ${ASL_LIVE_PROOF:?set_ASL_LIVE_PROOF} --fail-on-regression"
|
|
32
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"projectName": "asl-example-mobile-app",
|
|
3
|
+
"app": {
|
|
4
|
+
"displayName": "ASL Example",
|
|
5
|
+
"scheme": "asl-example",
|
|
6
|
+
"profileSessionScheme": "asl-example",
|
|
7
|
+
"iosBundleId": "dev.agent-scenario-loop.example",
|
|
8
|
+
"iosConflictingBundleIds": [],
|
|
9
|
+
"androidPackage": "dev.agentscenarioloop.example",
|
|
10
|
+
"ios": {
|
|
11
|
+
"xcodeScheme": "ASL Example",
|
|
12
|
+
"launchConfiguration": "Debug",
|
|
13
|
+
"profileConfiguration": "Release"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"paths": {
|
|
17
|
+
"artifactRoot": "artifacts/example-mobile-app",
|
|
18
|
+
"androidArtifactsRoot": "artifacts/example-mobile-app/android",
|
|
19
|
+
"iosArtifactsRoot": "artifacts/example-mobile-app/ios",
|
|
20
|
+
"scenarioRoot": "scenarios/mobile"
|
|
21
|
+
},
|
|
22
|
+
"drivers": {
|
|
23
|
+
"default": "fixture-log-ingest",
|
|
24
|
+
"supported": ["fixture-log-ingest", "adb", "ios-simctl", "agent-device", "argent", "xcodebuildmcp"]
|
|
25
|
+
},
|
|
26
|
+
"versionControl": {
|
|
27
|
+
"commit": [
|
|
28
|
+
"examples/mobile-app/**",
|
|
29
|
+
"examples/scenarios/**",
|
|
30
|
+
"schemas/**"
|
|
31
|
+
],
|
|
32
|
+
"ignore": [
|
|
33
|
+
"artifacts/example-mobile-app/**",
|
|
34
|
+
"local simulator recordings, screenshots, and profiler exports"
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
2026-01-01T00:10:00.000Z example-android [profile-event] {"event":"app_launch_requested","scenario":"app-startup","runId":"android-example-startup","iteration":1,"atMs":0}
|
|
2
|
+
2026-01-01T00:10:01.020Z example-android [profile-event] {"event":"home_ready","scenario":"app-startup","runId":"android-example-startup","iteration":1,"atMs":1020}
|
|
3
|
+
2026-01-01T00:10:01.230Z example-android [profile-event] {"event":"startup_idle_observed","scenario":"app-startup","runId":"android-example-startup","iteration":1,"atMs":1230}
|
|
4
|
+
2026-01-01T00:10:01.330Z example-android [profile-event] {"event":"startup_complete","scenario":"app-startup","runId":"android-example-startup","iteration":1,"atMs":1330}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
2026-01-01T00:11:00.000Z example-android [profile-event] {"event":"card_open_requested","scenario":"open-close-cycle","runId":"android-example-open-close","iteration":1,"atMs":0}
|
|
2
|
+
2026-01-01T00:11:00.420Z example-android [profile-event] {"event":"card_opened","scenario":"open-close-cycle","runId":"android-example-open-close","iteration":1,"atMs":420}
|
|
3
|
+
2026-01-01T00:11:00.780Z example-android [profile-event] {"event":"card_close_requested","scenario":"open-close-cycle","runId":"android-example-open-close","iteration":1,"atMs":780}
|
|
4
|
+
2026-01-01T00:11:01.120Z example-android [profile-event] {"event":"card_dismissed","scenario":"open-close-cycle","runId":"android-example-open-close","iteration":1,"atMs":1120}
|
|
5
|
+
2026-01-01T00:11:02.000Z example-android [profile-event] {"event":"card_open_requested","scenario":"open-close-cycle","runId":"android-example-open-close","iteration":2,"atMs":2000}
|
|
6
|
+
2026-01-01T00:11:02.450Z example-android [profile-event] {"event":"card_opened","scenario":"open-close-cycle","runId":"android-example-open-close","iteration":2,"atMs":2450}
|
|
7
|
+
2026-01-01T00:11:02.810Z example-android [profile-event] {"event":"card_close_requested","scenario":"open-close-cycle","runId":"android-example-open-close","iteration":2,"atMs":2810}
|
|
8
|
+
2026-01-01T00:11:03.170Z example-android [profile-event] {"event":"card_dismissed","scenario":"open-close-cycle","runId":"android-example-open-close","iteration":2,"atMs":3170}
|
|
9
|
+
2026-01-01T00:11:04.000Z example-android [profile-event] {"event":"card_open_requested","scenario":"open-close-cycle","runId":"android-example-open-close","iteration":3,"atMs":4000}
|
|
10
|
+
2026-01-01T00:11:04.480Z example-android [profile-event] {"event":"card_opened","scenario":"open-close-cycle","runId":"android-example-open-close","iteration":3,"atMs":4480}
|
|
11
|
+
2026-01-01T00:11:04.850Z example-android [profile-event] {"event":"card_close_requested","scenario":"open-close-cycle","runId":"android-example-open-close","iteration":3,"atMs":4850}
|
|
12
|
+
2026-01-01T00:11:05.230Z example-android [profile-event] {"event":"card_dismissed","scenario":"open-close-cycle","runId":"android-example-open-close","iteration":3,"atMs":5230}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
2026-01-01T00:12:00.000Z example-android [profile-event] {"event":"feed_scroll_started","scenario":"scroll-settle","runId":"android-example-scroll","iteration":1,"atMs":0}
|
|
2
|
+
2026-01-01T00:12:00.340Z example-android [profile-event] {"event":"feed_first_content_visible","scenario":"scroll-settle","runId":"android-example-scroll","iteration":1,"atMs":340}
|
|
3
|
+
2026-01-01T00:12:00.690Z example-android [profile-event] {"event":"feed_scroll_settle_requested","scenario":"scroll-settle","runId":"android-example-scroll","iteration":1,"atMs":690}
|
|
4
|
+
2026-01-01T00:12:00.920Z example-android [profile-event] {"event":"feed_scroll_settled","scenario":"scroll-settle","runId":"android-example-scroll","iteration":1,"atMs":920}
|
|
5
|
+
2026-01-01T00:12:02.000Z example-android [profile-event] {"event":"feed_scroll_started","scenario":"scroll-settle","runId":"android-example-scroll","iteration":2,"atMs":2000}
|
|
6
|
+
2026-01-01T00:12:02.360Z example-android [profile-event] {"event":"feed_first_content_visible","scenario":"scroll-settle","runId":"android-example-scroll","iteration":2,"atMs":2360}
|
|
7
|
+
2026-01-01T00:12:02.720Z example-android [profile-event] {"event":"feed_scroll_settle_requested","scenario":"scroll-settle","runId":"android-example-scroll","iteration":2,"atMs":2720}
|
|
8
|
+
2026-01-01T00:12:02.970Z example-android [profile-event] {"event":"feed_scroll_settled","scenario":"scroll-settle","runId":"android-example-scroll","iteration":2,"atMs":2970}
|
|
9
|
+
2026-01-01T00:12:04.000Z example-android [profile-event] {"event":"feed_scroll_started","scenario":"scroll-settle","runId":"android-example-scroll","iteration":3,"atMs":4000}
|
|
10
|
+
2026-01-01T00:12:04.390Z example-android [profile-event] {"event":"feed_first_content_visible","scenario":"scroll-settle","runId":"android-example-scroll","iteration":3,"atMs":4390}
|
|
11
|
+
2026-01-01T00:12:04.760Z example-android [profile-event] {"event":"feed_scroll_settle_requested","scenario":"scroll-settle","runId":"android-example-scroll","iteration":3,"atMs":4760}
|
|
12
|
+
2026-01-01T00:12:05.010Z example-android [profile-event] {"event":"feed_scroll_settled","scenario":"scroll-settle","runId":"android-example-scroll","iteration":3,"atMs":5010}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
2026-01-01T00:00:00.000Z example [profile-event] {"event":"app_launch_requested","scenario":"app-startup","runId":"example-startup","iteration":1,"atMs":0}
|
|
2
|
+
2026-01-01T00:00:00.940Z example [profile-event] {"event":"home_ready","scenario":"app-startup","runId":"example-startup","iteration":1,"atMs":940}
|
|
3
|
+
2026-01-01T00:00:01.130Z example [profile-event] {"event":"startup_idle_observed","scenario":"app-startup","runId":"example-startup","iteration":1,"atMs":1130}
|
|
4
|
+
2026-01-01T00:00:01.220Z example [profile-event] {"event":"startup_complete","scenario":"app-startup","runId":"example-startup","iteration":1,"atMs":1220}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
2026-01-01T00:01:00.000Z example [profile-event] {"event":"card_open_requested","scenario":"open-close-cycle","runId":"example-open-close","iteration":1,"atMs":0}
|
|
2
|
+
2026-01-01T00:01:00.380Z example [profile-event] {"event":"card_opened","scenario":"open-close-cycle","runId":"example-open-close","iteration":1,"atMs":380}
|
|
3
|
+
2026-01-01T00:01:00.720Z example [profile-event] {"event":"card_close_requested","scenario":"open-close-cycle","runId":"example-open-close","iteration":1,"atMs":720}
|
|
4
|
+
2026-01-01T00:01:01.040Z example [profile-event] {"event":"card_dismissed","scenario":"open-close-cycle","runId":"example-open-close","iteration":1,"atMs":1040}
|
|
5
|
+
2026-01-01T00:01:02.000Z example [profile-event] {"event":"card_open_requested","scenario":"open-close-cycle","runId":"example-open-close","iteration":2,"atMs":2000}
|
|
6
|
+
2026-01-01T00:01:02.410Z example [profile-event] {"event":"card_opened","scenario":"open-close-cycle","runId":"example-open-close","iteration":2,"atMs":2410}
|
|
7
|
+
2026-01-01T00:01:02.760Z example [profile-event] {"event":"card_close_requested","scenario":"open-close-cycle","runId":"example-open-close","iteration":2,"atMs":2760}
|
|
8
|
+
2026-01-01T00:01:03.120Z example [profile-event] {"event":"card_dismissed","scenario":"open-close-cycle","runId":"example-open-close","iteration":2,"atMs":3120}
|
|
9
|
+
2026-01-01T00:01:04.000Z example [profile-event] {"event":"card_open_requested","scenario":"open-close-cycle","runId":"example-open-close","iteration":3,"atMs":4000}
|
|
10
|
+
2026-01-01T00:01:04.440Z example [profile-event] {"event":"card_opened","scenario":"open-close-cycle","runId":"example-open-close","iteration":3,"atMs":4440}
|
|
11
|
+
2026-01-01T00:01:04.800Z example [profile-event] {"event":"card_close_requested","scenario":"open-close-cycle","runId":"example-open-close","iteration":3,"atMs":4800}
|
|
12
|
+
2026-01-01T00:01:05.180Z example [profile-event] {"event":"card_dismissed","scenario":"open-close-cycle","runId":"example-open-close","iteration":3,"atMs":5180}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
2026-01-01T00:02:00.000Z example [profile-event] {"event":"feed_scroll_started","scenario":"scroll-settle","runId":"example-scroll","iteration":1,"atMs":0}
|
|
2
|
+
2026-01-01T00:02:00.300Z example [profile-event] {"event":"feed_first_content_visible","scenario":"scroll-settle","runId":"example-scroll","iteration":1,"atMs":300}
|
|
3
|
+
2026-01-01T00:02:00.620Z example [profile-event] {"event":"feed_scroll_settle_requested","scenario":"scroll-settle","runId":"example-scroll","iteration":1,"atMs":620}
|
|
4
|
+
2026-01-01T00:02:00.830Z example [profile-event] {"event":"feed_scroll_settled","scenario":"scroll-settle","runId":"example-scroll","iteration":1,"atMs":830}
|
|
5
|
+
2026-01-01T00:02:02.000Z example [profile-event] {"event":"feed_scroll_started","scenario":"scroll-settle","runId":"example-scroll","iteration":2,"atMs":2000}
|
|
6
|
+
2026-01-01T00:02:02.320Z example [profile-event] {"event":"feed_first_content_visible","scenario":"scroll-settle","runId":"example-scroll","iteration":2,"atMs":2320}
|
|
7
|
+
2026-01-01T00:02:02.660Z example [profile-event] {"event":"feed_scroll_settle_requested","scenario":"scroll-settle","runId":"example-scroll","iteration":2,"atMs":2660}
|
|
8
|
+
2026-01-01T00:02:02.890Z example [profile-event] {"event":"feed_scroll_settled","scenario":"scroll-settle","runId":"example-scroll","iteration":2,"atMs":2890}
|
|
9
|
+
2026-01-01T00:02:04.000Z example [profile-event] {"event":"feed_scroll_started","scenario":"scroll-settle","runId":"example-scroll","iteration":3,"atMs":4000}
|
|
10
|
+
2026-01-01T00:02:04.350Z example [profile-event] {"event":"feed_first_content_visible","scenario":"scroll-settle","runId":"example-scroll","iteration":3,"atMs":4350}
|
|
11
|
+
2026-01-01T00:02:04.690Z example [profile-event] {"event":"feed_scroll_settle_requested","scenario":"scroll-settle","runId":"example-scroll","iteration":3,"atMs":4690}
|
|
12
|
+
2026-01-01T00:02:04.930Z example [profile-event] {"event":"feed_scroll_settled","scenario":"scroll-settle","runId":"example-scroll","iteration":3,"atMs":4930}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { registerRootComponent } from 'expo';
|
|
3
|
+
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
|
4
|
+
|
|
5
|
+
import { ExampleScreen } from './src/example-screen';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Wraps the example scenario surface in native safe-area context.
|
|
9
|
+
*
|
|
10
|
+
* @returns {React.ReactElement}
|
|
11
|
+
*/
|
|
12
|
+
function ExampleApp(): React.ReactElement {
|
|
13
|
+
return React.createElement(
|
|
14
|
+
SafeAreaProvider,
|
|
15
|
+
null,
|
|
16
|
+
React.createElement(ExampleScreen),
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
registerRootComponent(ExampleApp);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const path = require('node:path');
|
|
2
|
+
const { getDefaultConfig } = require('expo/metro-config');
|
|
3
|
+
|
|
4
|
+
const projectRoot = __dirname;
|
|
5
|
+
const packageRoot = path.resolve(projectRoot, '..', '..');
|
|
6
|
+
const config = getDefaultConfig(projectRoot);
|
|
7
|
+
|
|
8
|
+
config.watchFolders = Array.from(new Set([...(config.watchFolders ?? []), packageRoot]));
|
|
9
|
+
config.resolver.nodeModulesPaths = [
|
|
10
|
+
path.resolve(projectRoot, 'node_modules'),
|
|
11
|
+
path.resolve(packageRoot, 'node_modules'),
|
|
12
|
+
];
|
|
13
|
+
config.resolver.extraNodeModules = {
|
|
14
|
+
...(config.resolver.extraNodeModules ?? {}),
|
|
15
|
+
react: path.resolve(projectRoot, 'node_modules/react'),
|
|
16
|
+
'react/jsx-dev-runtime': path.resolve(projectRoot, 'node_modules/react/jsx-dev-runtime.js'),
|
|
17
|
+
'react/jsx-runtime': path.resolve(projectRoot, 'node_modules/react/jsx-runtime.js'),
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
module.exports = config;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agent-scenario-loop-example-mobile-app",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"main": "index.ts",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"asl:check:android": "pnpm --dir ../.. build && node ../../dist/runner/check-plan.js --scenario scenarios/mobile/app-startup.json --runner runner-manifests/primary-runner.json --provider runner-manifests/evidence-provider.json --platform android --out artifacts/asl/plan/app-startup-android",
|
|
8
|
+
"asl:check:ios": "pnpm --dir ../.. build && node ../../dist/runner/check-plan.js --scenario scenarios/mobile/app-startup.json --runner runner-manifests/primary-runner.json --provider runner-manifests/evidence-provider.json --platform ios --out artifacts/asl/plan/app-startup-ios",
|
|
9
|
+
"asl:host:doctor": "pnpm --dir ../.. build && node ../../dist/runner/host-doctor.js --out artifacts/asl/host-doctor",
|
|
10
|
+
"asl:android:live": "pnpm --dir ../.. build && node ../../dist/runner/example-android-live.js --config asl.config.json --out artifacts/asl/android-live --compare-latest --fail-on-regression",
|
|
11
|
+
"asl:android:live:agent-device": "pnpm --dir ../.. build && node ../../dist/runner/example-android-live.js --config asl.config.json --out artifacts/asl/android-live ${ASL_ANDROID_AGENT_DEVICE_SESSION:+--agent-device-session $ASL_ANDROID_AGENT_DEVICE_SESSION} ${ASL_ANDROID_AGENT_DEVICE_SESSION_MODE:+--agent-device-session-mode $ASL_ANDROID_AGENT_DEVICE_SESSION_MODE} --run-suffix agent-device --agent-device-proof --compare-latest --fail-on-regression",
|
|
12
|
+
"asl:android:live:argent": "pnpm --dir ../.. build && node ../../dist/runner/example-android-live.js --config asl.config.json --out artifacts/asl/android-live --run-suffix argent --argent-proof --compare-latest --fail-on-regression",
|
|
13
|
+
"asl:android:live:runners": "pnpm --dir ../.. build && node ../../dist/runner/example-android-live.js --config asl.config.json --out artifacts/asl/android-live ${ASL_ANDROID_AGENT_DEVICE_SESSION:+--agent-device-session $ASL_ANDROID_AGENT_DEVICE_SESSION} ${ASL_ANDROID_AGENT_DEVICE_SESSION_MODE:+--agent-device-session-mode $ASL_ANDROID_AGENT_DEVICE_SESSION_MODE} --run-suffix runners --agent-device-proof --argent-proof --compare-latest --fail-on-regression",
|
|
14
|
+
"asl:ios:live": "if [ -n \"${ASL_EXAMPLE_XCODE_DEVELOPER_DIR:-}\" ]; then export DEVELOPER_DIR=\"$ASL_EXAMPLE_XCODE_DEVELOPER_DIR\"; fi; pnpm --dir ../.. build && node ../../dist/runner/example-ios-live.js --config asl.config.json --out artifacts/asl/ios-live --compare-latest --fail-on-regression",
|
|
15
|
+
"asl:ios:live:agent-device": "if [ -n \"${ASL_EXAMPLE_XCODE_DEVELOPER_DIR:-}\" ]; then export DEVELOPER_DIR=\"$ASL_EXAMPLE_XCODE_DEVELOPER_DIR\"; fi; pnpm --dir ../.. build && node ../../dist/runner/example-ios-live.js --config asl.config.json --out artifacts/asl/ios-live ${ASL_IOS_AGENT_DEVICE_SESSION:+--agent-device-session $ASL_IOS_AGENT_DEVICE_SESSION} ${ASL_IOS_AGENT_DEVICE_SESSION_MODE:+--agent-device-session-mode $ASL_IOS_AGENT_DEVICE_SESSION_MODE} --run-suffix agent-device --agent-device-proof --compare-latest --fail-on-regression",
|
|
16
|
+
"asl:ios:live:argent": "if [ -n \"${ASL_EXAMPLE_XCODE_DEVELOPER_DIR:-}\" ]; then export DEVELOPER_DIR=\"$ASL_EXAMPLE_XCODE_DEVELOPER_DIR\"; fi; pnpm --dir ../.. build && node ../../dist/runner/example-ios-live.js --config asl.config.json --out artifacts/asl/ios-live --run-suffix argent --argent-proof --compare-latest --fail-on-regression",
|
|
17
|
+
"asl:ios:live:runners": "if [ -n \"${ASL_EXAMPLE_XCODE_DEVELOPER_DIR:-}\" ]; then export DEVELOPER_DIR=\"$ASL_EXAMPLE_XCODE_DEVELOPER_DIR\"; fi; pnpm --dir ../.. build && node ../../dist/runner/example-ios-live.js --config asl.config.json --out artifacts/asl/ios-live ${ASL_IOS_AGENT_DEVICE_SESSION:+--agent-device-session $ASL_IOS_AGENT_DEVICE_SESSION} ${ASL_IOS_AGENT_DEVICE_SESSION_MODE:+--agent-device-session-mode $ASL_IOS_AGENT_DEVICE_SESSION_MODE} --run-suffix runners --agent-device-proof --argent-proof --compare-latest --fail-on-regression",
|
|
18
|
+
"asl:live-proof:android": "pnpm --dir ../.. build && node ../../dist/runner/live-proof.js --file ${ASL_EXAMPLE_ANDROID_LIVE_PROOF:-artifacts/asl/android-live/_live-proof/android-live-proof/live-proof.json} --fail-on-regression",
|
|
19
|
+
"asl:live-proof:ios": "pnpm --dir ../.. build && node ../../dist/runner/live-proof.js --file ${ASL_EXAMPLE_IOS_LIVE_PROOF:-artifacts/asl/ios-live/_live-proof/ios-live-proof/live-proof.json} --fail-on-regression",
|
|
20
|
+
"asl:live-proof:both": "pnpm --dir ../.. build && node ../../dist/runner/live-proof.js --file ${ASL_EXAMPLE_ANDROID_LIVE_PROOF:-artifacts/asl/android-live/_live-proof/android-live-proof/live-proof.json} --file ${ASL_EXAMPLE_IOS_LIVE_PROOF:-artifacts/asl/ios-live/_live-proof/ios-live-proof/live-proof.json} --require-platforms android,ios --out artifacts/asl/live-proof-set --fail-on-regression ${ASL_REQUIRE_LIVE_PROOF_ARTIFACTS:+--require-artifacts}",
|
|
21
|
+
"asl:agent-device:check": "pnpm --dir ../.. build && node ../../dist/runner/agent-device.js --check --out artifacts/asl/agent-device-check",
|
|
22
|
+
"asl:agent-device:android": "pnpm --dir ../.. build && node ../../dist/runner/agent-device.js --platform android ${ASL_ANDROID_AGENT_DEVICE_SESSION:+--session $ASL_ANDROID_AGENT_DEVICE_SESSION} ${ASL_ANDROID_AGENT_DEVICE_SESSION_MODE:+--session-mode $ASL_ANDROID_AGENT_DEVICE_SESSION_MODE} ${ASL_ANDROID_SERIAL:+--serial $ASL_ANDROID_SERIAL} ${ASL_AGENT_DEVICE_COMMAND_TIMEOUT_MS:+--command-timeout-ms $ASL_AGENT_DEVICE_COMMAND_TIMEOUT_MS} --scenario scenarios/mobile/app-startup.json --app ${ASL_ANDROID_APP_ID:-dev.agentscenarioloop.example} --open --wait-ms 1000 --out artifacts/asl/agent-device-android --run-id app-startup-android-agent-device",
|
|
23
|
+
"asl:agent-device:ios": "pnpm --dir ../.. build && node ../../dist/runner/agent-device.js --platform ios ${ASL_IOS_AGENT_DEVICE_SESSION:+--session $ASL_IOS_AGENT_DEVICE_SESSION} ${ASL_IOS_AGENT_DEVICE_SESSION_MODE:+--session-mode $ASL_IOS_AGENT_DEVICE_SESSION_MODE} ${ASL_IOS_UDID:+--udid $ASL_IOS_UDID} ${ASL_AGENT_DEVICE_COMMAND_TIMEOUT_MS:+--command-timeout-ms $ASL_AGENT_DEVICE_COMMAND_TIMEOUT_MS} --scenario scenarios/mobile/app-startup.json --app ${ASL_IOS_APP_ID:-dev.agent-scenario-loop.example} --open --wait-ms 1000 --out artifacts/asl/agent-device-ios --run-id app-startup-ios-agent-device",
|
|
24
|
+
"asl:argent:check": "pnpm --dir ../.. build && node ../../dist/runner/argent.js --check --out artifacts/asl/argent-check",
|
|
25
|
+
"asl:argent:android": "pnpm --dir ../.. build && node ../../dist/runner/argent.js --platform android ${ASL_ARGENT_BIN:+--argent $ASL_ARGENT_BIN} ${ASL_ARGENT_BASE_ARGS:+--base-args \"$ASL_ARGENT_BASE_ARGS\"} ${ASL_ARGENT_DEVICE_FLAG:+--device-flag $ASL_ARGENT_DEVICE_FLAG} ${ASL_ARGENT_APP_FLAG:+--app-flag $ASL_ARGENT_APP_FLAG} ${ASL_ARGENT_COMMAND_TIMEOUT_MS:+--command-timeout-ms $ASL_ARGENT_COMMAND_TIMEOUT_MS} --scenario scenarios/mobile/app-startup.json --app ${ASL_ANDROID_APP_ID:-dev.agentscenarioloop.example} --device ${ASL_ANDROID_SERIAL:-emulator-5554} --out artifacts/asl/argent-android --run-id app-startup-android-argent",
|
|
26
|
+
"asl:argent:ios": "pnpm --dir ../.. build && node ../../dist/runner/argent.js --platform ios ${ASL_ARGENT_BIN:+--argent $ASL_ARGENT_BIN} ${ASL_ARGENT_BASE_ARGS:+--base-args \"$ASL_ARGENT_BASE_ARGS\"} ${ASL_ARGENT_DEVICE_FLAG:+--device-flag $ASL_ARGENT_DEVICE_FLAG} ${ASL_ARGENT_APP_FLAG:+--app-flag $ASL_ARGENT_APP_FLAG} ${ASL_ARGENT_COMMAND_TIMEOUT_MS:+--command-timeout-ms $ASL_ARGENT_COMMAND_TIMEOUT_MS} ${ASL_ARGENT_IOS_SIMCTL_SCREENSHOT_FALLBACK:+--ios-simctl-screenshot-fallback} ${ASL_XCRUN_PATH:+--xcrun $ASL_XCRUN_PATH} --scenario scenarios/mobile/app-startup.json --app ${ASL_IOS_APP_ID:-dev.agent-scenario-loop.example} --device ${ASL_IOS_UDID:-booted} --out artifacts/asl/argent-ios --run-id app-startup-ios-argent",
|
|
27
|
+
"asl:compare:android": "pnpm --dir ../.. build && node ../../dist/runner/compare-latest.js --root artifacts/asl/android --scenario app-startup --current ${ASL_COMPARE_ANDROID_CURRENT:?set_ASL_COMPARE_ANDROID_CURRENT} --out artifacts/asl/android/comparisons/app-startup --fail-on-regression",
|
|
28
|
+
"asl:compare:ios": "pnpm --dir ../.. build && node ../../dist/runner/compare-latest.js --root artifacts/asl/ios --scenario app-startup --current ${ASL_COMPARE_IOS_CURRENT:?set_ASL_COMPARE_IOS_CURRENT} --out artifacts/asl/ios/comparisons/app-startup --fail-on-regression",
|
|
29
|
+
"asl:live-proof": "pnpm --dir ../.. build && node ../../dist/runner/live-proof.js --file ${ASL_LIVE_PROOF:?set_ASL_LIVE_PROOF} --fail-on-regression",
|
|
30
|
+
"asl:profile:android": "pnpm --dir ../.. build && node ../../dist/runner/profile-android.js --config asl.config.json --scenario scenarios/android/app-startup.json --events event-logs/android-app-startup.log --comparison-lane app-startup-android-fixture --out artifacts/asl/android --run-id app-startup-android-fixture",
|
|
31
|
+
"asl:profile:android:live": "pnpm --dir ../.. build && node ../../dist/runner/profile-android.js --config asl.config.json --scenario scenarios/mobile/app-startup.json --adb-capture --profile-session --clear-logcat --launch --comparison-lane app-startup-android-live --out artifacts/asl/android --run-id app-startup-android-live",
|
|
32
|
+
"asl:profile:android:provider": "pnpm --dir ../.. build && node ../../dist/runner/profile-android.js --config asl.config.json --scenario scenarios/android/app-startup.json --events event-logs/android-app-startup.log --provider runner-manifests/evidence-provider.json --comparison-lane app-startup-android-provider --out artifacts/asl/android --run-id app-startup-android-provider",
|
|
33
|
+
"asl:profile:ios": "pnpm --dir ../.. build && node ../../dist/runner/profile-ios.js --config asl.config.json --scenario scenarios/ios/app-startup.json --events event-logs/app-startup.log --comparison-lane app-startup-ios-fixture --out artifacts/asl/ios --run-id app-startup-ios-fixture",
|
|
34
|
+
"asl:profile:ios:live": "if [ -n \"${ASL_EXAMPLE_XCODE_DEVELOPER_DIR:-}\" ]; then export DEVELOPER_DIR=\"$ASL_EXAMPLE_XCODE_DEVELOPER_DIR\"; fi; pnpm --dir ../.. build && node ../../dist/runner/profile-ios.js --config asl.config.json --scenario scenarios/mobile/app-startup.json --simctl-capture --profile-session --profile-session-storage --launch --comparison-lane app-startup-ios-live --out artifacts/asl/ios --run-id app-startup-ios-live",
|
|
35
|
+
"asl:profile:ios:provider": "pnpm --dir ../.. build && node ../../dist/runner/profile-ios.js --config asl.config.json --scenario scenarios/ios/app-startup.json --events event-logs/app-startup.log --provider runner-manifests/evidence-provider.json --comparison-lane app-startup-ios-provider --out artifacts/asl/ios --run-id app-startup-ios-provider",
|
|
36
|
+
"asl:validate": "pnpm --dir ../.. build && node ../../dist/runner/validate-project.js --root . --platform all --out artifacts/asl/project-validation",
|
|
37
|
+
"android": "expo run:android",
|
|
38
|
+
"ios": "expo run:ios",
|
|
39
|
+
"ios:prebuild": "expo prebuild --platform ios",
|
|
40
|
+
"start": "expo start",
|
|
41
|
+
"typecheck": "tsc -p tsconfig.typecheck.json --noEmit"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"@expo/metro-runtime": "56.0.15",
|
|
45
|
+
"@react-native-async-storage/async-storage": "2.2.0",
|
|
46
|
+
"expo": "^56.0.11",
|
|
47
|
+
"expo-linking": "~56.0.14",
|
|
48
|
+
"react": "19.2.3",
|
|
49
|
+
"react-native": "0.85.3",
|
|
50
|
+
"react-native-gesture-handler": "~2.31.2",
|
|
51
|
+
"react-native-safe-area-context": "~5.7.0"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@types/react": "~19.2.14",
|
|
55
|
+
"typescript": "~6.0.3"
|
|
56
|
+
},
|
|
57
|
+
"pnpm": {
|
|
58
|
+
"patchedDependencies": {
|
|
59
|
+
"expo-modules-jsi@56.0.10": "patches/expo-modules-jsi@56.0.10.patch"
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|