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.
Files changed (170) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +119 -0
  3. package/app/profile-session.ts +812 -0
  4. package/core/config-template.json +41 -0
  5. package/dist/core/agent-summary.d.ts +15 -0
  6. package/dist/core/agent-summary.js +177 -0
  7. package/dist/core/artifact-contract.d.ts +151 -0
  8. package/dist/core/artifact-contract.js +897 -0
  9. package/dist/core/artifact-layout.d.ts +56 -0
  10. package/dist/core/artifact-layout.js +61 -0
  11. package/dist/core/artifact-writer.d.ts +44 -0
  12. package/dist/core/artifact-writer.js +55 -0
  13. package/dist/core/comparison.d.ts +133 -0
  14. package/dist/core/comparison.js +294 -0
  15. package/dist/core/evidence-interpreter.d.ts +28 -0
  16. package/dist/core/evidence-interpreter.js +69 -0
  17. package/dist/core/execution-plan.d.ts +44 -0
  18. package/dist/core/execution-plan.js +95 -0
  19. package/dist/core/planner.d.ts +132 -0
  20. package/dist/core/planner.js +812 -0
  21. package/dist/core/ports.d.ts +198 -0
  22. package/dist/core/ports.js +146 -0
  23. package/dist/core/run-index.d.ts +62 -0
  24. package/dist/core/run-index.js +143 -0
  25. package/dist/core/schema-validator.d.ts +86 -0
  26. package/dist/core/schema-validator.js +407 -0
  27. package/dist/index.d.ts +11 -0
  28. package/dist/index.js +27 -0
  29. package/dist/runner/agent-device-driver.d.ts +126 -0
  30. package/dist/runner/agent-device-driver.js +168 -0
  31. package/dist/runner/agent-device.d.ts +295 -0
  32. package/dist/runner/agent-device.js +1271 -0
  33. package/dist/runner/android-adb-driver.d.ts +175 -0
  34. package/dist/runner/android-adb-driver.js +399 -0
  35. package/dist/runner/android-adb.d.ts +254 -0
  36. package/dist/runner/android-adb.js +1618 -0
  37. package/dist/runner/argent-driver.d.ts +183 -0
  38. package/dist/runner/argent-driver.js +297 -0
  39. package/dist/runner/argent.d.ts +349 -0
  40. package/dist/runner/argent.js +1211 -0
  41. package/dist/runner/check-plan.d.ts +45 -0
  42. package/dist/runner/check-plan.js +210 -0
  43. package/dist/runner/cli.d.ts +20 -0
  44. package/dist/runner/cli.js +23 -0
  45. package/dist/runner/compare-latest.d.ts +99 -0
  46. package/dist/runner/compare-latest.js +233 -0
  47. package/dist/runner/compare.d.ts +58 -0
  48. package/dist/runner/compare.js +157 -0
  49. package/dist/runner/demo-loop.d.ts +45 -0
  50. package/dist/runner/demo-loop.js +170 -0
  51. package/dist/runner/example-android-live.d.ts +137 -0
  52. package/dist/runner/example-android-live.js +454 -0
  53. package/dist/runner/example-ios-live.d.ts +137 -0
  54. package/dist/runner/example-ios-live.js +471 -0
  55. package/dist/runner/host-doctor.d.ts +131 -0
  56. package/dist/runner/host-doctor.js +628 -0
  57. package/dist/runner/init-project.d.ts +88 -0
  58. package/dist/runner/init-project.js +263 -0
  59. package/dist/runner/ios-simctl-driver.d.ts +69 -0
  60. package/dist/runner/ios-simctl-driver.js +97 -0
  61. package/dist/runner/ios-simctl.d.ts +254 -0
  62. package/dist/runner/ios-simctl.js +1415 -0
  63. package/dist/runner/live-android.d.ts +137 -0
  64. package/dist/runner/live-android.js +539 -0
  65. package/dist/runner/live-comparison.d.ts +67 -0
  66. package/dist/runner/live-comparison.js +147 -0
  67. package/dist/runner/live-ios.d.ts +137 -0
  68. package/dist/runner/live-ios.js +460 -0
  69. package/dist/runner/live-proof-summary.d.ts +263 -0
  70. package/dist/runner/live-proof-summary.js +465 -0
  71. package/dist/runner/live-proof.d.ts +467 -0
  72. package/dist/runner/live-proof.js +920 -0
  73. package/dist/runner/local-env.d.ts +64 -0
  74. package/dist/runner/local-env.js +155 -0
  75. package/dist/runner/profile-android.d.ts +82 -0
  76. package/dist/runner/profile-android.js +671 -0
  77. package/dist/runner/profile-ios.d.ts +108 -0
  78. package/dist/runner/profile-ios.js +532 -0
  79. package/dist/runner/profile-mobile.d.ts +254 -0
  80. package/dist/runner/profile-mobile.js +1307 -0
  81. package/dist/runner/validate-project.d.ts +273 -0
  82. package/dist/runner/validate-project.js +1501 -0
  83. package/docs/adapters.md +145 -0
  84. package/docs/api.md +94 -0
  85. package/docs/authoring.md +196 -0
  86. package/docs/concepts.md +136 -0
  87. package/docs/consumer-rehearsal.md +115 -0
  88. package/docs/contracts.md +267 -0
  89. package/docs/live-proofs.md +270 -0
  90. package/docs/principles.md +46 -0
  91. package/examples/event-logs/app-startup-baseline.log +4 -0
  92. package/examples/event-logs/app-startup-current.log +4 -0
  93. package/examples/minimal-app/README.md +70 -0
  94. package/examples/mobile-app/README.md +302 -0
  95. package/examples/mobile-app/app.json +22 -0
  96. package/examples/mobile-app/asl/package-scripts.json +32 -0
  97. package/examples/mobile-app/asl.config.json +37 -0
  98. package/examples/mobile-app/event-logs/android-app-startup.log +4 -0
  99. package/examples/mobile-app/event-logs/android-open-close-cycle.log +12 -0
  100. package/examples/mobile-app/event-logs/android-scroll-settle.log +12 -0
  101. package/examples/mobile-app/event-logs/app-startup.log +4 -0
  102. package/examples/mobile-app/event-logs/open-close-cycle.log +12 -0
  103. package/examples/mobile-app/event-logs/scroll-settle.log +12 -0
  104. package/examples/mobile-app/index.ts +20 -0
  105. package/examples/mobile-app/metro.config.js +20 -0
  106. package/examples/mobile-app/package.json +62 -0
  107. package/examples/mobile-app/patches/expo-modules-jsi@56.0.10.patch +19 -0
  108. package/examples/mobile-app/plugins/with-ios-build-compat.js +271 -0
  109. package/examples/mobile-app/pnpm-lock.yaml +4440 -0
  110. package/examples/mobile-app/runner-manifests/evidence-provider.json +79 -0
  111. package/examples/mobile-app/runner-manifests/primary-runner.json +19 -0
  112. package/examples/mobile-app/scenarios/android/app-startup-video.json +73 -0
  113. package/examples/mobile-app/scenarios/android/app-startup.json +44 -0
  114. package/examples/mobile-app/scenarios/android/open-close-cycle.json +54 -0
  115. package/examples/mobile-app/scenarios/android/scroll-settle.json +49 -0
  116. package/examples/mobile-app/scenarios/ios/app-startup.json +44 -0
  117. package/examples/mobile-app/scenarios/ios/open-close-cycle.json +54 -0
  118. package/examples/mobile-app/scenarios/ios/scroll-settle.json +49 -0
  119. package/examples/mobile-app/scenarios/mobile/app-startup.json +91 -0
  120. package/examples/mobile-app/scenarios/mobile/open-close-cycle.json +160 -0
  121. package/examples/mobile-app/scenarios/mobile/scroll-settle.json +148 -0
  122. package/examples/mobile-app/scripts/asl-capture-accessibility-provider.mjs +112 -0
  123. package/examples/mobile-app/scripts/asl-capture-profiler-provider.mjs +127 -0
  124. package/examples/mobile-app/src/devtools/profile-session.ts +7 -0
  125. package/examples/mobile-app/src/example-screen.tsx +322 -0
  126. package/examples/mobile-app/tsconfig.json +16 -0
  127. package/examples/mobile-app/tsconfig.typecheck.json +13 -0
  128. package/examples/runners/README.md +44 -0
  129. package/examples/runners/adb-android.json +25 -0
  130. package/examples/runners/agent-device-android.json +27 -0
  131. package/examples/runners/agent-device-ios.json +27 -0
  132. package/examples/runners/argent-android.json +32 -0
  133. package/examples/runners/argent-ios.json +32 -0
  134. package/examples/runners/argent-react-profiler-provider.json +15 -0
  135. package/examples/runners/axe-accessibility-provider.json +24 -0
  136. package/examples/runners/manual-log-ingest.json +9 -0
  137. package/examples/runners/rozenite-profiler-provider.json +9 -0
  138. package/examples/runners/script-accessibility-provider.json +24 -0
  139. package/examples/runners/script-memory-provider.json +24 -0
  140. package/examples/runners/script-network-provider.json +24 -0
  141. package/examples/runners/script-profiler-provider.json +30 -0
  142. package/examples/runners/xcodebuildmcp-ios.json +29 -0
  143. package/examples/scenarios/ios/app-startup.json +28 -0
  144. package/examples/scenarios/ios/open-close-cycle.json +35 -0
  145. package/examples/scenarios/mobile/app-startup.json +72 -0
  146. package/examples/scenarios/mobile/media-open-close.json +141 -0
  147. package/examples/scenarios/mobile/open-close-cycle.json +135 -0
  148. package/examples/scenarios/mobile/scroll-settle.json +106 -0
  149. package/package.json +240 -0
  150. package/schemas/budget-verdict.schema.json +115 -0
  151. package/schemas/causal-run.schema.json +279 -0
  152. package/schemas/comparison.schema.json +196 -0
  153. package/schemas/health.schema.json +108 -0
  154. package/schemas/live-proof-set.schema.json +195 -0
  155. package/schemas/live-proof.schema.json +413 -0
  156. package/schemas/manifest.schema.json +204 -0
  157. package/schemas/metrics.schema.json +137 -0
  158. package/schemas/project-validation.schema.json +343 -0
  159. package/schemas/runner-capabilities.schema.json +217 -0
  160. package/schemas/scenario.schema.json +400 -0
  161. package/schemas/verdict.schema.json +88 -0
  162. package/templates/evidence-provider.json +83 -0
  163. package/templates/gitignore-snippet +9 -0
  164. package/templates/integration-readme.md +125 -0
  165. package/templates/mobile-scenario.json +133 -0
  166. package/templates/package-scripts.json +32 -0
  167. package/templates/primary-runner.json +19 -0
  168. package/templates/project.config.json +37 -0
  169. package/templates/scripts/asl-capture-accessibility-provider.mjs +112 -0
  170. 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
+ }