zig-mobile-runner 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 (225) hide show
  1. package/CHANGELOG.md +484 -0
  2. package/CONTRIBUTING.md +42 -0
  3. package/FEATURES.md +112 -0
  4. package/LICENSE +21 -0
  5. package/README.md +255 -0
  6. package/SECURITY.md +34 -0
  7. package/build.zig +38 -0
  8. package/build.zig.zon +7 -0
  9. package/clients/README.md +144 -0
  10. package/clients/go/README.md +24 -0
  11. package/clients/go/examples/fake-session/main.go +93 -0
  12. package/clients/go/go.mod +3 -0
  13. package/clients/go/zmr/client.go +432 -0
  14. package/clients/kotlin/README.md +35 -0
  15. package/clients/kotlin/build.gradle.kts +35 -0
  16. package/clients/kotlin/settings.gradle.kts +15 -0
  17. package/clients/kotlin/src/main/kotlin/dev/zmr/FakeSession.kt +86 -0
  18. package/clients/kotlin/src/main/kotlin/dev/zmr/ZmrClient.kt +67 -0
  19. package/clients/python/README.md +29 -0
  20. package/clients/python/examples/fake_session.py +48 -0
  21. package/clients/python/pyproject.toml +13 -0
  22. package/clients/python/zmr_client.py +202 -0
  23. package/clients/rust/Cargo.lock +107 -0
  24. package/clients/rust/Cargo.toml +10 -0
  25. package/clients/rust/README.md +19 -0
  26. package/clients/rust/examples/fake_session.rs +70 -0
  27. package/clients/rust/src/lib.rs +461 -0
  28. package/clients/swift/Package.swift +16 -0
  29. package/clients/swift/README.md +36 -0
  30. package/clients/swift/Sources/ZMRClient/ZMRClient.swift +114 -0
  31. package/clients/swift/Sources/ZMRFakeSession/main.swift +86 -0
  32. package/clients/typescript/README.md +34 -0
  33. package/clients/typescript/examples/fake-session.mjs +36 -0
  34. package/clients/typescript/index.d.ts +144 -0
  35. package/clients/typescript/index.mjs +192 -0
  36. package/clients/typescript/package.json +8 -0
  37. package/docs/adr/0001-agent-native-runner-boundary.md +31 -0
  38. package/docs/adr/0002-app-local-zmr-contract.md +39 -0
  39. package/docs/adr/0003-ios-simulator-xctest-shim.md +41 -0
  40. package/docs/adr/0004-benchmark-claims-and-baseline-collection.md +37 -0
  41. package/docs/adr/README.md +12 -0
  42. package/docs/ai-agents.md +156 -0
  43. package/docs/app-integration.md +316 -0
  44. package/docs/benchmarking.md +275 -0
  45. package/docs/client-installation.md +141 -0
  46. package/docs/clients.md +98 -0
  47. package/docs/config.md +175 -0
  48. package/docs/demo.md +259 -0
  49. package/docs/dsl.md +57 -0
  50. package/docs/install.md +233 -0
  51. package/docs/market-positioning.md +70 -0
  52. package/docs/npm.md +359 -0
  53. package/docs/protocol-fixtures/README.md +8 -0
  54. package/docs/protocol-fixtures/core-session.requests.jsonl +8 -0
  55. package/docs/protocol-fixtures/core-session.responses.jsonl +8 -0
  56. package/docs/protocol-versioning.md +65 -0
  57. package/docs/protocol.md +560 -0
  58. package/docs/publication.md +77 -0
  59. package/docs/release-audit.md +99 -0
  60. package/docs/release-candidate.md +111 -0
  61. package/docs/release-evidence.md +188 -0
  62. package/docs/release-notes-template.md +58 -0
  63. package/docs/roadmap.md +334 -0
  64. package/docs/scenario-authoring.md +88 -0
  65. package/docs/shipping.md +170 -0
  66. package/docs/trace-privacy.md +88 -0
  67. package/docs/troubleshooting.md +256 -0
  68. package/examples/android-app-auth-probe.json +89 -0
  69. package/examples/android-app-error-state.json +13 -0
  70. package/examples/android-app-login-smoke.json +192 -0
  71. package/examples/android-app-onboarding.json +12 -0
  72. package/examples/android-app-referral-deep-link.json +12 -0
  73. package/examples/android-shim-smoke.json +19 -0
  74. package/examples/demo-failure.json +12 -0
  75. package/examples/demo-fake.json +14 -0
  76. package/examples/ios-dev-client-open-link.json +26 -0
  77. package/examples/ios-dev-client-route-snapshot.json +24 -0
  78. package/examples/ios-shim-smoke.json +23 -0
  79. package/examples/ios-smoke.json +9 -0
  80. package/go.work +3 -0
  81. package/npm/agents.mjs +183 -0
  82. package/npm/app-config.mjs +95 -0
  83. package/npm/build-zmr.mjs +21 -0
  84. package/npm/commands.mjs +104 -0
  85. package/npm/generated-files.mjs +50 -0
  86. package/npm/index.mjs +75 -0
  87. package/npm/init-app.mjs +80 -0
  88. package/npm/package-scripts.mjs +72 -0
  89. package/npm/postinstall.mjs +21 -0
  90. package/npm/scaffold.mjs +179 -0
  91. package/npm/scenarios.mjs +93 -0
  92. package/npm/setup.mjs +69 -0
  93. package/npm/wizard.mjs +117 -0
  94. package/npm/zmr.mjs +23 -0
  95. package/package.json +114 -0
  96. package/prebuilds/darwin-arm64/zmr +0 -0
  97. package/prebuilds/darwin-x64/zmr +0 -0
  98. package/prebuilds/linux-arm64/zmr +0 -0
  99. package/prebuilds/linux-x64/zmr +0 -0
  100. package/schemas/README.md +26 -0
  101. package/schemas/action-result.schema.json +27 -0
  102. package/schemas/capabilities-output.schema.json +98 -0
  103. package/schemas/devices-output.schema.json +25 -0
  104. package/schemas/doctor-output.schema.json +51 -0
  105. package/schemas/explain-output.schema.json +51 -0
  106. package/schemas/import-output.schema.json +23 -0
  107. package/schemas/init-output.schema.json +71 -0
  108. package/schemas/json-rpc.schema.json +55 -0
  109. package/schemas/release-manifest.schema.json +43 -0
  110. package/schemas/release-readiness-output.schema.json +127 -0
  111. package/schemas/run-output.schema.json +43 -0
  112. package/schemas/scenario.schema.json +128 -0
  113. package/schemas/schemas-output.schema.json +26 -0
  114. package/schemas/semantic-snapshot.schema.json +116 -0
  115. package/schemas/snapshot.schema.json +60 -0
  116. package/schemas/trace-event.schema.json +14 -0
  117. package/schemas/trace-manifest.schema.json +59 -0
  118. package/schemas/validate-output.schema.json +42 -0
  119. package/schemas/version-output.schema.json +23 -0
  120. package/schemas/zmr-config.schema.json +75 -0
  121. package/scripts/android-emulator.sh +126 -0
  122. package/scripts/assert-ios-physical-ready.sh +213 -0
  123. package/scripts/benchmark-command.sh +307 -0
  124. package/scripts/benchmark.sh +359 -0
  125. package/scripts/benchmark_gate.py +117 -0
  126. package/scripts/benchmark_result_row.py +88 -0
  127. package/scripts/compare-benchmarks.py +288 -0
  128. package/scripts/create-android-demo-app.sh +342 -0
  129. package/scripts/create-ios-demo-app.sh +261 -0
  130. package/scripts/demo-android-real.sh +232 -0
  131. package/scripts/demo-ios-real.sh +270 -0
  132. package/scripts/demo.sh +464 -0
  133. package/scripts/device-matrix.sh +338 -0
  134. package/scripts/ensure-ios-shim-target.rb +237 -0
  135. package/scripts/install-android-shim.sh +281 -0
  136. package/scripts/install-ios-shim.sh +589 -0
  137. package/scripts/pilot-gate.sh +560 -0
  138. package/scripts/release-readiness.py +838 -0
  139. package/scripts/release-readiness.sh +91 -0
  140. package/scripts/run-android-pilot.sh +561 -0
  141. package/scripts/run-ios-pilot.sh +509 -0
  142. package/shims/android/README.md +21 -0
  143. package/shims/android/ZMRShimInstrumentedTest.java +152 -0
  144. package/shims/android/protocol.md +18 -0
  145. package/shims/ios/README.md +50 -0
  146. package/shims/ios/ZMRShim.swift +110 -0
  147. package/shims/ios/ZMRShimUITestCase.swift +475 -0
  148. package/shims/ios/protocol.md +74 -0
  149. package/skills/zmr-mobile-testing/SKILL.md +127 -0
  150. package/src/android.zig +344 -0
  151. package/src/android_device_info.zig +99 -0
  152. package/src/android_emulator.zig +154 -0
  153. package/src/android_screen_recording.zig +112 -0
  154. package/src/android_shell.zig +112 -0
  155. package/src/bundle.zig +124 -0
  156. package/src/bundle_redaction.zig +272 -0
  157. package/src/bundle_tar.zig +123 -0
  158. package/src/cli_devices.zig +97 -0
  159. package/src/cli_doctor.zig +114 -0
  160. package/src/cli_import.zig +70 -0
  161. package/src/cli_info.zig +39 -0
  162. package/src/cli_init.zig +72 -0
  163. package/src/cli_output.zig +467 -0
  164. package/src/cli_run.zig +259 -0
  165. package/src/cli_serve.zig +287 -0
  166. package/src/cli_trace.zig +111 -0
  167. package/src/cli_validate.zig +41 -0
  168. package/src/command.zig +211 -0
  169. package/src/config.zig +305 -0
  170. package/src/config_diagnostics.zig +212 -0
  171. package/src/config_paths.zig +49 -0
  172. package/src/device_registry.zig +37 -0
  173. package/src/doctor.zig +412 -0
  174. package/src/doctor_hints.zig +52 -0
  175. package/src/errors.zig +55 -0
  176. package/src/fake_device.zig +163 -0
  177. package/src/health.zig +28 -0
  178. package/src/importer.zig +343 -0
  179. package/src/importer_json.zig +100 -0
  180. package/src/importer_model.zig +103 -0
  181. package/src/ios.zig +399 -0
  182. package/src/ios_devices.zig +219 -0
  183. package/src/ios_lifecycle.zig +72 -0
  184. package/src/ios_shim.zig +242 -0
  185. package/src/ios_snapshot.zig +20 -0
  186. package/src/json_fields.zig +80 -0
  187. package/src/json_rpc.zig +150 -0
  188. package/src/json_rpc_methods.zig +318 -0
  189. package/src/json_rpc_observation.zig +31 -0
  190. package/src/json_rpc_params.zig +52 -0
  191. package/src/json_rpc_protocol.zig +110 -0
  192. package/src/json_rpc_trace.zig +73 -0
  193. package/src/main.zig +135 -0
  194. package/src/mcp.zig +234 -0
  195. package/src/mcp_protocol.zig +64 -0
  196. package/src/mcp_trace.zig +83 -0
  197. package/src/report.zig +346 -0
  198. package/src/report_html.zig +63 -0
  199. package/src/report_values.zig +27 -0
  200. package/src/run_options.zig +152 -0
  201. package/src/runner.zig +280 -0
  202. package/src/runner_actions.zig +109 -0
  203. package/src/runner_config.zig +6 -0
  204. package/src/runner_diagnostics.zig +268 -0
  205. package/src/runner_events.zig +170 -0
  206. package/src/runner_native.zig +88 -0
  207. package/src/runner_waits.zig +300 -0
  208. package/src/scaffold.zig +472 -0
  209. package/src/scenario.zig +346 -0
  210. package/src/scenario_fields.zig +50 -0
  211. package/src/schema_registry.zig +53 -0
  212. package/src/selector.zig +84 -0
  213. package/src/semantic.zig +171 -0
  214. package/src/trace.zig +315 -0
  215. package/src/trace_json.zig +340 -0
  216. package/src/trace_summary.zig +218 -0
  217. package/src/trace_summary_diagnostic.zig +202 -0
  218. package/src/types.zig +120 -0
  219. package/src/uiautomator.zig +164 -0
  220. package/src/validation.zig +187 -0
  221. package/src/version.zig +22 -0
  222. package/viewer/app.js +373 -0
  223. package/viewer/index.html +126 -0
  224. package/viewer/parser.js +233 -0
  225. package/viewer/styles.css +585 -0
@@ -0,0 +1,270 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ SOURCE="${BASH_SOURCE[0]}"
5
+ while [[ -h "$SOURCE" ]]; do
6
+ SOURCE_DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)"
7
+ SOURCE="$(readlink "$SOURCE")"
8
+ if [[ "$SOURCE" != /* ]]; then
9
+ SOURCE="$SOURCE_DIR/$SOURCE"
10
+ fi
11
+ done
12
+
13
+ ROOT="$(cd -P "$(dirname "$SOURCE")/.." && pwd)"
14
+ OUT="/tmp/zmr-ios-demo-$(date +%Y%m%d-%H%M%S)"
15
+ APP_NAME="ZMRDemo"
16
+ APP_ID="com.example.mobiletest"
17
+ DEVICE="booted"
18
+ DEPLOYMENT_TARGET="16.0"
19
+ RUNS="1"
20
+ TRACE_ROOT=""
21
+ XCRUN="${XCRUN:-xcrun}"
22
+ AUTO_BOOT_SIMULATOR=1
23
+ CLEANUP_BUILD_PRODUCTS=0
24
+ DRY_RUN=0
25
+
26
+ usage() {
27
+ cat <<'USAGE'
28
+ Usage:
29
+ scripts/demo-ios-real.sh [options]
30
+
31
+ Creates a generic public iOS simulator demo app, builds it, and runs the real
32
+ ZMR iOS pilot with the generated XCTest shim.
33
+
34
+ Options:
35
+ --out <dir> Demo app output directory. Default: /tmp/zmr-ios-demo-<timestamp>.
36
+ --name <name> App target name. Default: ZMRDemo.
37
+ --app-id <id> App bundle id. Default: com.example.mobiletest.
38
+ --device <udid|booted> Simulator target. Default: booted.
39
+ --deployment-target <ver> iOS deployment target. Default: 16.0.
40
+ --runs <n> Pilot run count. Default: 1.
41
+ --trace-root <dir> Trace output directory. Default: <out>/traces/pilot.
42
+ --xcrun <path> xcrun path. Default: xcrun.
43
+ --no-auto-boot-simulator Require an already booted simulator.
44
+ --cleanup-build-products Remove generated DerivedData after pilot traces are written.
45
+ --dry-run Print commands without executing them.
46
+ -h, --help Show this help.
47
+ USAGE
48
+ }
49
+
50
+ die() {
51
+ echo "error: $*" >&2
52
+ exit 2
53
+ }
54
+
55
+ require_value() {
56
+ local flag="$1"
57
+ local value="${2-}"
58
+ if [[ -z "$value" || "$value" == --* ]]; then
59
+ die "$flag requires a value"
60
+ fi
61
+ printf '%s\n' "$value"
62
+ }
63
+
64
+ quote_cmd() {
65
+ local quoted=()
66
+ local arg
67
+ for arg in "$@"; do
68
+ quoted+=("$(printf '%q' "$arg")")
69
+ done
70
+ printf '%s\n' "${quoted[*]}"
71
+ }
72
+
73
+ run() {
74
+ echo "+ $(quote_cmd "$@")"
75
+ if [[ "$DRY_RUN" -eq 0 ]]; then
76
+ "$@"
77
+ fi
78
+ }
79
+
80
+ available_ios_simulators() {
81
+ "$XCRUN" simctl list devices available --json | python3 -c '
82
+ import json
83
+ import sys
84
+
85
+ data = json.load(sys.stdin)
86
+ for runtime, devices in data.get("devices", {}).items():
87
+ if "iOS" not in runtime:
88
+ continue
89
+ for device in devices:
90
+ if device.get("isAvailable", True) and device.get("state") in ("Shutdown", "Booted"):
91
+ udid = device.get("udid")
92
+ if udid:
93
+ print(udid)
94
+ '
95
+ }
96
+
97
+ simulator_is_booted() {
98
+ local wanted="${1:-}"
99
+ local booted_text
100
+ booted_text="$("$XCRUN" simctl list devices booted 2>/dev/null || true)"
101
+ if [[ -z "$wanted" || "$wanted" == "booted" ]]; then
102
+ [[ "$booted_text" == *"(Booted)"* ]]
103
+ return
104
+ fi
105
+ [[ "$booted_text" == *"$wanted"* && "$booted_text" == *"(Booted)"* ]]
106
+ }
107
+
108
+ ensure_ios_simulator_ready() {
109
+ if [[ "$AUTO_BOOT_SIMULATOR" -eq 0 ]]; then
110
+ return 0
111
+ fi
112
+
113
+ run "$XCRUN" simctl list devices booted
114
+ if [[ "$DRY_RUN" -eq 1 ]]; then
115
+ if [[ "$DEVICE" == "booted" ]]; then
116
+ echo "+ auto boot first available iOS simulator when no simulator is booted"
117
+ echo "+ try available iOS simulators until one boots"
118
+ else
119
+ echo "+ auto boot iOS simulator $DEVICE when it is not booted"
120
+ fi
121
+ run "$XCRUN" simctl bootstatus "$DEVICE" -b
122
+ return 0
123
+ fi
124
+
125
+ if simulator_is_booted "$DEVICE"; then
126
+ run "$XCRUN" simctl bootstatus "$DEVICE" -b
127
+ return 0
128
+ fi
129
+
130
+ local boot_target="$DEVICE"
131
+ if [[ "$DEVICE" == "booted" ]]; then
132
+ local candidates=()
133
+ local listed_candidate
134
+ while IFS= read -r listed_candidate; do
135
+ [[ -n "$listed_candidate" ]] && candidates+=("$listed_candidate")
136
+ done < <(available_ios_simulators)
137
+ if [[ "${#candidates[@]}" -eq 0 ]]; then
138
+ die "no available iOS simulator found to boot"
139
+ fi
140
+ local candidate status
141
+ for candidate in "${candidates[@]}"; do
142
+ echo "+ $(quote_cmd "$XCRUN" simctl boot "$candidate")"
143
+ set +e
144
+ "$XCRUN" simctl boot "$candidate"
145
+ status=$?
146
+ set -e
147
+ if [[ "$status" -eq 0 ]]; then
148
+ run "$XCRUN" simctl bootstatus "$candidate" -b
149
+ return 0
150
+ fi
151
+ echo "warning: failed to boot iOS simulator $candidate; trying next available simulator" >&2
152
+ done
153
+ die "no available iOS simulator could be booted"
154
+ fi
155
+
156
+ run "$XCRUN" simctl boot "$boot_target"
157
+ run "$XCRUN" simctl bootstatus "$boot_target" -b
158
+ }
159
+
160
+ while [[ $# -gt 0 ]]; do
161
+ case "$1" in
162
+ --out)
163
+ OUT="$(require_value "$1" "${2-}")"
164
+ shift 2
165
+ ;;
166
+ --name)
167
+ APP_NAME="$(require_value "$1" "${2-}")"
168
+ shift 2
169
+ ;;
170
+ --app-id)
171
+ APP_ID="$(require_value "$1" "${2-}")"
172
+ shift 2
173
+ ;;
174
+ --device)
175
+ DEVICE="$(require_value "$1" "${2-}")"
176
+ shift 2
177
+ ;;
178
+ --deployment-target)
179
+ DEPLOYMENT_TARGET="$(require_value "$1" "${2-}")"
180
+ shift 2
181
+ ;;
182
+ --runs)
183
+ RUNS="$(require_value "$1" "${2-}")"
184
+ shift 2
185
+ ;;
186
+ --trace-root)
187
+ TRACE_ROOT="$(require_value "$1" "${2-}")"
188
+ shift 2
189
+ ;;
190
+ --xcrun)
191
+ XCRUN="$(require_value "$1" "${2-}")"
192
+ shift 2
193
+ ;;
194
+ --no-auto-boot-simulator)
195
+ AUTO_BOOT_SIMULATOR=0
196
+ shift
197
+ ;;
198
+ --cleanup-build-products)
199
+ CLEANUP_BUILD_PRODUCTS=1
200
+ shift
201
+ ;;
202
+ --dry-run)
203
+ DRY_RUN=1
204
+ shift
205
+ ;;
206
+ -h|--help)
207
+ usage
208
+ exit 0
209
+ ;;
210
+ *)
211
+ die "unknown argument: $1"
212
+ ;;
213
+ esac
214
+ done
215
+
216
+ [[ -n "$OUT" ]] || die "--out must not be empty"
217
+ [[ "$APP_NAME" =~ ^[A-Za-z_][A-Za-z0-9_]*$ ]] || die "--name must be a valid Swift identifier"
218
+ [[ "$RUNS" =~ ^[0-9]+$ && "$RUNS" -ge 1 ]] || die "--runs must be a positive integer"
219
+
220
+ if [[ -z "$TRACE_ROOT" ]]; then
221
+ TRACE_ROOT="$OUT/traces/pilot"
222
+ fi
223
+
224
+ PROJECT_PATH="$OUT/ios/$APP_NAME.xcodeproj"
225
+ DERIVED_DATA="$OUT/DerivedData"
226
+ APP_PATH="$DERIVED_DATA/Build/Products/Debug-iphonesimulator/$APP_NAME.app"
227
+ IOS_SHIM="$OUT/.zmr/ios-shim"
228
+
229
+ echo "iOS real demo app: $OUT"
230
+ echo "iOS real demo traces: $TRACE_ROOT"
231
+ if [[ "$DRY_RUN" -eq 1 ]]; then
232
+ echo "DRY RUN: commands will be printed but not executed"
233
+ fi
234
+
235
+ run "$ROOT/scripts/create-ios-demo-app.sh" \
236
+ --out "$OUT" \
237
+ --name "$APP_NAME" \
238
+ --bundle-id "$APP_ID" \
239
+ --deployment-target "$DEPLOYMENT_TARGET"
240
+
241
+ run xcodebuild \
242
+ -project "$PROJECT_PATH" \
243
+ -scheme "$APP_NAME" \
244
+ -destination "generic/platform=iOS Simulator" \
245
+ -configuration Debug \
246
+ -derivedDataPath "$DERIVED_DATA" \
247
+ build
248
+
249
+ ensure_ios_simulator_ready
250
+
251
+ run "$ROOT/scripts/run-ios-pilot.sh" \
252
+ --app-root "$OUT" \
253
+ --app-path "$APP_PATH" \
254
+ --device "$DEVICE" \
255
+ --app-id "$APP_ID" \
256
+ --xcrun "$XCRUN" \
257
+ --ios-shim "$IOS_SHIM" \
258
+ --runs "$RUNS" \
259
+ --trace-root "$TRACE_ROOT"
260
+
261
+ if [[ "$CLEANUP_BUILD_PRODUCTS" -eq 1 ]]; then
262
+ run rm -rf "$DERIVED_DATA"
263
+ fi
264
+
265
+ cat <<EOF
266
+
267
+ iOS real demo complete.
268
+ App directory: $OUT
269
+ Trace directory: $TRACE_ROOT
270
+ EOF