zeno-mobile-runner 0.1.2 → 0.1.8

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 (89) hide show
  1. package/CHANGELOG.md +162 -3
  2. package/FEATURES.md +50 -7
  3. package/README.md +133 -7
  4. package/build.zig.zon +3 -3
  5. package/clients/README.md +60 -3
  6. package/clients/go/README.md +12 -0
  7. package/clients/go/zmr/client.go +142 -0
  8. package/clients/kotlin/README.md +18 -1
  9. package/clients/kotlin/build.gradle.kts +1 -1
  10. package/clients/kotlin/src/main/kotlin/dev/zmr/ZmrClient.kt +76 -1
  11. package/clients/python/README.md +19 -0
  12. package/clients/python/pyproject.toml +1 -1
  13. package/clients/python/zmr_client.py +33 -0
  14. package/clients/rust/Cargo.lock +1 -1
  15. package/clients/rust/Cargo.toml +1 -1
  16. package/clients/rust/README.md +25 -1
  17. package/clients/rust/src/lib.rs +201 -0
  18. package/clients/swift/README.md +18 -0
  19. package/clients/swift/Sources/ZMRClient/ZMRClient.swift +82 -0
  20. package/clients/typescript/README.md +16 -0
  21. package/clients/typescript/index.d.ts +12 -0
  22. package/clients/typescript/index.mjs +16 -0
  23. package/clients/typescript/package.json +1 -1
  24. package/docs/agent-discovery.md +202 -0
  25. package/docs/ai-agents.md +87 -6
  26. package/docs/benchmarking.md +10 -3
  27. package/docs/clients.md +10 -6
  28. package/docs/demo.md +4 -0
  29. package/docs/expo-smoke.md +79 -0
  30. package/docs/install.md +3 -2
  31. package/docs/npm.md +58 -4
  32. package/docs/production-readiness.md +123 -0
  33. package/docs/protocol-fixtures/core-session.responses.jsonl +1 -1
  34. package/docs/protocol.md +215 -16
  35. package/docs/scenario-authoring.md +3 -0
  36. package/docs/troubleshooting.md +1 -1
  37. package/npm/agents.mjs +16 -0
  38. package/npm/build-zmr.mjs +1 -1
  39. package/npm/commands.mjs +9 -5
  40. package/npm/postinstall.mjs +28 -2
  41. package/npm/verify-publish.mjs +36 -0
  42. package/package.json +2 -1
  43. package/prebuilds/darwin-arm64/zmr +0 -0
  44. package/prebuilds/darwin-x64/zmr +0 -0
  45. package/prebuilds/linux-arm64/zmr +0 -0
  46. package/prebuilds/linux-x64/zmr +0 -0
  47. package/schemas/README.md +4 -0
  48. package/schemas/discover-output.schema.json +83 -0
  49. package/schemas/draft-output.schema.json +58 -0
  50. package/schemas/explore-output.schema.json +94 -0
  51. package/schemas/inspect-output.schema.json +88 -0
  52. package/schemas/run-output.schema.json +2 -0
  53. package/scripts/install-ios-shim.sh +79 -14
  54. package/scripts/release-readiness.py +43 -0
  55. package/scripts/run-android-pilot.sh +35 -9
  56. package/scripts/run-ios-pilot.sh +11 -4
  57. package/shims/ios/ZMRShim.swift +3 -0
  58. package/shims/ios/ZMRShimUITestCase.swift +41 -11
  59. package/skills/zmr-mobile-testing/SKILL.md +28 -3
  60. package/src/cli_discover.zig +239 -0
  61. package/src/cli_draft.zig +924 -0
  62. package/src/cli_explore.zig +136 -0
  63. package/src/cli_inspect.zig +310 -0
  64. package/src/cli_output.zig +26 -2
  65. package/src/cli_run.zig +28 -0
  66. package/src/cli_trace.zig +8 -0
  67. package/src/errors.zig +9 -0
  68. package/src/ios.zig +11 -4
  69. package/src/ios_lifecycle.zig +36 -0
  70. package/src/ios_shim.zig +42 -0
  71. package/src/json_rpc_methods.zig +85 -11
  72. package/src/json_rpc_params.zig +8 -0
  73. package/src/json_rpc_protocol.zig +1 -1
  74. package/src/json_rpc_trace.zig +112 -0
  75. package/src/main.zig +24 -2
  76. package/src/mcp.zig +209 -6
  77. package/src/mcp_protocol.zig +29 -1
  78. package/src/mcp_trace.zig +126 -4
  79. package/src/report.zig +186 -0
  80. package/src/runner.zig +26 -4
  81. package/src/runner_actions.zig +10 -0
  82. package/src/runner_diagnostics.zig +31 -1
  83. package/src/runner_events.zig +70 -7
  84. package/src/runner_native.zig +17 -1
  85. package/src/runner_waits.zig +82 -19
  86. package/src/scaffold.zig +28 -12
  87. package/src/scenario.zig +32 -4
  88. package/src/schema_registry.zig +4 -0
  89. package/src/version.zig +1 -1
package/CHANGELOG.md CHANGED
@@ -2,7 +2,166 @@
2
2
 
3
3
  All notable changes to Zeno Mobile Runner are tracked here.
4
4
 
5
- ## Unreleased
5
+ ## 0.1.8 (2026-06-06)
6
+
7
+ ### Changed
8
+
9
+ - `zmr-release-readiness --target production` now enforces an
10
+ `agent workflow smoke` gate, satisfied by the local release gate or
11
+ structured MCP/JSON-RPC, trace, discovery, validation, and redacted-export
12
+ evidence.
13
+
14
+ ## 0.1.7 (2026-06-06)
15
+
16
+ ### Added
17
+
18
+ - Added MCP `assert_visible`, `assert_not_visible`, and `assert_healthy` tools
19
+ so MCP agents can use assertion-grade checks without dropping to JSON-RPC.
20
+ - Added MCP `erase_text`, `hide_keyboard`, `wait_not_visible`, `wait_any`, and
21
+ `scroll_until_visible` tools so agents can cover common mobile flow control
22
+ without dropping to JSON-RPC.
23
+ - Added MCP `install_app`, `launch_app`, `stop_app`, `clear_state`, and
24
+ `swipe` tools so MCP agents can run full app lifecycle and gesture flows.
25
+ - Added MCP `open_link`, unscoped `type`, and `press_back` trace events so
26
+ trace-backed discovery sees full simple action sessions from MCP agents.
27
+ - Added MCP `trace_events` cursor metadata so MCP agents get `afterSeq`,
28
+ `nextSeq`, and `latestSeq` parity with JSON-RPC trace polling.
29
+ - Added JSON-RPC `trace.explain` and MCP `trace_explain` so live agents can
30
+ get the same failure summary, diagnostics, and next commands as
31
+ `zmr explain --json` without leaving the session.
32
+ - Added TypeScript, Python, Go, Rust, Swift, and Kotlin trace explanation helpers
33
+ so reference clients can call JSON-RPC `trace.explain` directly.
34
+ - Added `zmr explore --from-trace <trace-dir> --out <scenario.json> --goal
35
+ <goal> --include-actions --validate --json` as a review-first CLI
36
+ exploration handoff for agents. It reuses trace-backed discovery, carries the
37
+ goal in JSON, and returns explicit guardrails instead of claiming autonomous
38
+ crawling.
39
+ - Added JSON-RPC `trace.explore` and MCP `trace_explore` so live agents can
40
+ generate the same goal-carrying, review-required scenario draft without
41
+ leaving the active traced session.
42
+ - Added TypeScript `exploreTrace()`, Python `explore_trace()`, Go
43
+ `ExploreTrace()`, Rust `explore_trace()`, Swift `exploreTrace()`, and Kotlin
44
+ `exploreTrace()` helpers for the new JSON-RPC exploration method.
45
+ - Added trace discovery auditing: `trace.discover` records a `trace.discover` event
46
+ for JSON-RPC and MCP agent sessions so generated scenario candidates are
47
+ visible in the trace.
48
+ - Added `zmr draft --from-trace <trace-dir> --out <scenario.json> --json` for
49
+ trace-backed, review-first scenario drafting. The command reads the latest
50
+ semantic snapshot artifact and writes a conservative surface-smoke scenario
51
+ with `launch`, `snapshot`, and stable `assertVisible` checks only.
52
+ - Added `zmr draft --include-actions` so agent sessions can turn supported
53
+ successful trace actions into reviewable replay drafts while unsupported
54
+ events are skipped with warnings instead of guessed.
55
+ - Added `zmr discover --from-trace <trace-dir> --out <scenario.json>
56
+ --include-actions --validate --json` as the first-class trace-to-test handoff
57
+ for agents. It reuses the review-first draft engine, can validate the
58
+ generated scenario before returning, and reports `mode: "discover"` for
59
+ tooling.
60
+ - Added JSON-RPC `trace.discover` and MCP `trace_discover` so live agents can
61
+ generate the same trace-backed scenario candidate without shelling out to the
62
+ CLI after a session.
63
+ - Added JSON-RPC `scenario.validate` and MCP `scenario_validate` so agents can
64
+ validate generated or edited scenario files in-band before running them.
65
+ - Added TypeScript `discoverTrace()` and Python `discover_trace()` helpers for
66
+ the new JSON-RPC discovery method.
67
+ - Added TypeScript `validateScenario()` and Python `validate_scenario()`
68
+ helpers for in-band scenario validation.
69
+ - Added Go `DiscoverTrace()` and `ValidateScenario()` helpers so Go agents can
70
+ use the same trace-to-test and validation loop without raw JSON-RPC calls.
71
+ - Added Rust `discover_trace()` and `validate_scenario()` helpers so Rust
72
+ agents and host-side harnesses can use the same trace-to-test and validation
73
+ loop without raw JSON-RPC calls.
74
+ - Added Swift `discoverTrace()` and `validateScenario()` helpers so macOS
75
+ host-side agents can use the same trace-to-test and validation loop without
76
+ raw JSON-RPC calls.
77
+ - Added Kotlin `discoverTrace()` and `validateScenario()` helpers plus an
78
+ always-run source parity test so Kotlin host-side agents keep the same
79
+ trace-to-test and validation entry points even on machines without Gradle.
80
+ - Added a trace-backed discovery handoff to traced `zmr run --json`
81
+ `nextCommands`, so agents can generate a reviewable replay scenario directly
82
+ from a run summary.
83
+ - Added `zmr run --discover-out <scenario.json> --json` so traced runs can
84
+ write and validate the reviewable replay scenario before returning the run
85
+ summary.
86
+ - Added replay coverage metadata to `zmr draft --json`, `zmr discover --json`,
87
+ and embedded run discovery output so agents can see how many trace actions
88
+ became replay steps and how many were skipped.
89
+ - Added coordinate-complete `ui.swipe` trace replay so JSON-RPC sessions and
90
+ traced `zmr run` flows can carry swipes into generated replay scenarios
91
+ without guessing missing coordinates.
92
+ - Added traced `pressBack` replay parity for `zmr run`, so generated replay
93
+ scenarios preserve back-navigation steps from ordinary scenario runs.
94
+ - Added direction and timeout preserving `scrollUntilVisible` trace replay so
95
+ generated scenarios keep the original scroll intent from traced runs and
96
+ live agent sessions.
97
+ - Added selector and timeout preserving wait replay so trace-backed discovery
98
+ keeps successful `waitVisible`, `waitNotVisible`, and matched `waitAny`
99
+ steps from ordinary scenario runs.
100
+ - Added timeout context to native selector wait trace events and timeout
101
+ diagnostics, so real-device shim traces carry the same timing evidence as
102
+ snapshot-backed waits.
103
+ - Added replay metadata for successful `assertNoneVisible` and timed
104
+ `assertHealthy` trace events, so generated replay scenarios preserve
105
+ assertion intent instead of dropping those checks.
106
+ - Added selector and timeout preserving `assertVisible` and `assertNotVisible`
107
+ replay so trace-backed discovery keeps assertion intent distinct from waits.
108
+ - Added `zmr report --junit <report.xml>` so trace directories and benchmark
109
+ result directories can produce CI-friendly JUnit XML alongside HTML reports.
110
+ - Updated generated app report and reliability scripts to write `junit.xml`
111
+ beside `report.html` by default.
112
+ - Updated Android and iOS pilot wrappers to emit `junit.xml` beside every
113
+ generated `report.html`.
114
+ - Updated CI and tagged release workflows to retain generated run evidence as
115
+ GitHub Actions artifacts: CI keeps traces, coverage output, and the built
116
+ `zmr` binary for 14 days, while releases keep the generated `dist/` bundle
117
+ for 30 days.
118
+ - Updated artifact upload workflow steps to a Node 24-compatible
119
+ `actions/upload-artifact` major so CI stays ahead of GitHub Actions runtime
120
+ deprecations.
121
+ - Added `schemas/draft-output.schema.json` and included it in `zmr schemas
122
+ --json`.
123
+ - Added `schemas/discover-output.schema.json` and included it in `zmr schemas
124
+ --json`.
125
+
126
+ ## 0.1.6 (2026-06-05)
127
+
128
+ ### Added
129
+
130
+ - Added `zmr inspect --json` as a read-only app and agent handoff command. It
131
+ reports app-local config status, `.zmr/AGENTS.md` presence, configured
132
+ Android/iOS smoke scenarios, safe next commands, and explicit claim limits
133
+ without launching devices or writing tests.
134
+ - Added `schemas/inspect-output.schema.json` and included it in `zmr schemas
135
+ --json` for generated clients and agent tooling.
136
+
137
+ ### Changed
138
+
139
+ - Tagged release workflow now uses npm trusted publishing instead of a
140
+ long-lived `NPM_TOKEN` secret.
141
+ - Fixed the tagged release publish step so npm receives the generated local
142
+ tarball instead of interpreting the path as a GitHub package spec.
143
+ - Updated the tagged release workflow to Node 24 so npm trusted publishing can
144
+ use the GitHub Actions OIDC identity with a current npm CLI.
145
+ - Added a public production-readiness checklist that ties release, framework,
146
+ reliability, trace privacy, and agent workflow claims to concrete evidence.
147
+
148
+ ## 0.1.3 (2026-06-03)
149
+
150
+ ### Fixed
151
+
152
+ - Hardened the iOS XCTest shim for clean Expo/RN prebuilds by giving cold
153
+ `build-for-testing` runs a 90-minute default timeout with explicit progress
154
+ logging.
155
+ - Made iOS simulator `app.stop` idempotent when `simctl terminate` reports the
156
+ app is already stopped.
157
+ - Improved selector actions so native `selector.not_found` and
158
+ `selector.not_hittable` responses return a typed unavailable result instead
159
+ of failing the command parser.
160
+ - Reused a resolved booted simulator UDID across `build-for-testing` and
161
+ `test-without-building`, and cleared stale shim PID/server/destination state
162
+ when reinstalling the app-local shim.
163
+ - Avoided stale XCTest snapshot elements and replaced broad selector scans with
164
+ native predicate-based fallback queries.
6
165
 
7
166
  ## 0.1.2 (2026-05-28)
8
167
 
@@ -311,8 +470,8 @@ All notable changes to Zeno Mobile Runner are tracked here.
311
470
  - Tagged release workflow now publishes GitHub artifact attestation for release
312
471
  archives and metadata.
313
472
  - Tagged release workflow now builds the npm tarball, attests it, uploads it
314
- with the release assets, and publishes with npm provenance when `NPM_TOKEN`
315
- is configured.
473
+ with the release assets, and can publish with npm provenance from supported
474
+ CI.
316
475
  - Release manifests and checksum verification now include generated npm
317
476
  tarballs when present.
318
477
  - Native selector wait timeouts now capture one final snapshot when possible,
package/FEATURES.md CHANGED
@@ -22,7 +22,8 @@ state, and writes deterministic traces. It does not embed an LLM.
22
22
 
23
23
  - npm-first installation with `zeno-mobile-runner` as a dev dependency.
24
24
  - `npx zmr-wizard` scaffolds `.zmr/config.json`, Android and iOS smoke
25
- scenarios, optional app package scripts, and `traces/` gitignore rules.
25
+ scenarios, optional app package scripts, HTML/JUnit report scripts, and
26
+ `traces/` gitignore rules.
26
27
  - `zmr init --app` provides the same app-local bootstrap for source and archive
27
28
  installs.
28
29
  - `.zmr/config.json` is schema validated, auto-discovered from app checkouts,
@@ -34,14 +35,44 @@ state, and writes deterministic traces. It does not embed an LLM.
34
35
 
35
36
  - JSON-RPC v1 over newline-delimited stdio or localhost TCP.
36
37
  - MCP stdio server with mobile-native tools for AI agents, including semantic
37
- snapshots, selector actions, waits, trace polling, and trace export.
38
+ snapshots, selector actions, waits, assertions, trace polling, trace
39
+ exploration, trace discovery, and trace export.
38
40
  - `runner.capabilities`, `device.list`, `session.create`,
39
41
  `observe.snapshot`, `observe.semanticSnapshot`, UI actions, waits,
40
- assertions, live trace events, and redacted trace export.
42
+ assertions, scenario validation, live trace events, trace-backed exploration,
43
+ trace-backed discovery, and redacted trace export.
41
44
  - TypeScript, Python, Go, Rust, Swift, and Kotlin reference clients.
42
45
  - Machine-readable CLI output for `zmr version --json`, `zmr schemas --json`,
43
- `zmr doctor --json`, `zmr devices --json`, `zmr validate --json`,
46
+ `zmr inspect --json`, `zmr doctor --json`, `zmr devices --json`,
47
+ `zmr discover --json`, `zmr draft --json`, `zmr validate --json`,
44
48
  `zmr run --json`, and `zmr explain --json`.
49
+ - Traced `zmr run --json` output includes executable follow-up commands for
50
+ reports, failure explanation, trace-backed scenario discovery, and redacted
51
+ export.
52
+ - `zmr run --discover-out <scenario.json> --json` can generate and validate a
53
+ reviewable replay scenario from the trace immediately after the run.
54
+ - `zmr explore --from-trace --goal ... --json` gives CLI agents a
55
+ goal-carrying, review-first exploration handoff with explicit guardrails,
56
+ replay coverage, validation, and deterministic next commands.
57
+ - JSON-RPC `trace.explore` and MCP `trace_explore` expose the same
58
+ goal-carrying, review-required trace exploration from active traced sessions.
59
+ - `zmr discover --from-trace` turns a traced agent session into a reviewable
60
+ scenario candidate and can validate the generated scenario before returning.
61
+ - `zmr draft --from-trace` turns a traced semantic snapshot into a reviewable
62
+ surface-smoke scenario with conservative `assertVisible` checks.
63
+ - `zmr draft --include-actions` can turn supported successful trace actions
64
+ into a replay draft while warning instead of guessing unsupported events.
65
+ Wait replay preserves selectors and timeouts when the trace records them.
66
+ Native selector wait traces include timeout context for successful waits and
67
+ timeout diagnostics.
68
+ Assertion replay preserves `assertVisible` and `assertNotVisible` selectors
69
+ and timeouts, `assertNoneVisible` selector arrays, and `assertHealthy`
70
+ timeouts when the trace records them.
71
+ Selector scroll replay preserves direction and timeout when the trace records
72
+ them.
73
+ - Draft and discover JSON include `replay` coverage metadata so agents can
74
+ compare trace action events considered for replay, generated replay steps,
75
+ and skipped events.
45
76
  - Public JSON Schemas for scenarios, snapshots, semantic snapshots, action
46
77
  results, trace events, protocol messages, setup diagnostics, and release
47
78
  manifests.
@@ -58,6 +89,8 @@ state, and writes deterministic traces. It does not embed an LLM.
58
89
  - Wait and retry behavior around transient observation failures.
59
90
  - Import helper for a documented subset of common mobile-flow YAML commands
60
91
  into native `.zmr/*.json` scenarios.
92
+ - Trace-backed draft helper for generating reviewable surface and replay
93
+ scenarios from observed UI state and successful supported trace actions.
61
94
 
62
95
  ## Traces And Diagnostics
63
96
 
@@ -68,6 +101,10 @@ state, and writes deterministic traces. It does not embed an LLM.
68
101
  selected node details, payloads, artifact links, and snapshot replay
69
102
  controls.
70
103
  - `zmr explain` summarizes failed traces for humans and agents.
104
+ - `zmr report --junit <report.xml>` writes CI-friendly JUnit XML for trace
105
+ directories and benchmark result directories.
106
+ - Android and iOS pilot wrappers emit `junit.xml` next to generated HTML
107
+ reports, so CI can collect the same artifacts used by app-local scripts.
71
108
  - Redacted `.zmrtrace` export can replace or omit screenshots, omit screen
72
109
  recordings, and redact common secrets plus app-configured denylist fields.
73
110
 
@@ -75,6 +112,8 @@ state, and writes deterministic traces. It does not embed an LLM.
75
112
 
76
113
  - `zmr-benchmark` repeats ZMR scenarios with pass-rate, failure-count, and p95
77
114
  duration gates.
115
+ - Benchmark directories can be rendered as both HTML and JUnit XML artifacts
116
+ with `zmr report`.
78
117
  - `zmr-benchmark-command` records normalized rows for app-local baseline
79
118
  commands without hardcoding another tool.
80
119
  - `zmr-compare-benchmarks` compares candidate and baseline rows into generic
@@ -89,17 +128,21 @@ state, and writes deterministic traces. It does not embed an LLM.
89
128
  - Release archive builder with checksums, SPDX SBOM, third-party notices,
90
129
  generated Homebrew formula, and `RELEASE_MANIFEST.json`.
91
130
  - npm package tarball generation with bundled prebuilt binaries.
92
- - `zmr-release-readiness` checks repeated app/device evidence for teams that
93
- want a machine-readable readiness summary.
131
+ - `zmr-release-readiness` checks repeated app/device evidence and the
132
+ agent workflow smoke for teams that want a machine-readable readiness
133
+ summary.
94
134
  - Tagged release workflow with artifact attestation and optional npm
95
135
  provenance publishing.
136
+ - CI workflow retains run traces, coverage output, and built runner artifacts
137
+ for 14 days; tagged release workflow retains the generated `dist/` bundle
138
+ for 30 days.
96
139
  - Security, contribution, trace privacy, troubleshooting, protocol versioning,
97
140
  app integration, benchmarking, and npm packaging docs.
98
141
  - Reusable agent skill under `skills/zmr-mobile-testing/`.
99
142
 
100
143
  ## Current Limitations
101
144
 
102
- - Current release status is `0.1.2`, a public developer preview rather than
145
+ - Current release status is `0.1.8`, a public developer preview rather than
103
146
  a production-stable `1.0.0`.
104
147
  - Physical iOS log capture is still simulator-first. Physical iOS screenshots
105
148
  are available when the XCTest/XCUIAutomation shim is configured.
package/README.md CHANGED
@@ -53,10 +53,10 @@ See [docs/frameworks.md](docs/frameworks.md) and
53
53
  ## Why ZMR
54
54
 
55
55
  - **Agent-native protocol:** structured snapshots, semantic mobile trees,
56
- actions, waits, assertions, live trace events, and redacted trace export over
57
- JSON-RPC or MCP.
56
+ actions, waits, assertions, live trace events, trace explanation, and
57
+ redacted trace export over JSON-RPC or MCP.
58
58
  - **Trace-first debugging:** every run can produce screenshots, UI trees, logs,
59
- timings, action inputs, assertion results, and an HTML report.
59
+ timings, action inputs, assertion results, and HTML/JUnit reports.
60
60
  - **Fast local core:** Zig owns orchestration, subprocess control, selectors,
61
61
  waits, retries, scenario execution, and packaged binaries.
62
62
  - **App-local setup:** `.zmr/config.json`, smoke scenarios, shim commands, and
@@ -93,14 +93,35 @@ Useful commands:
93
93
  zmr version --json
94
94
  zmr schemas --json
95
95
  zmr devices --json
96
+ zmr inspect --json
97
+ zmr explore --from-trace traces/zmr-agent --out .zmr/discovered/login-smoke.json --goal "find a stable login smoke" --include-actions --validate --json
98
+ zmr discover --from-trace traces/zmr-agent --out .zmr/discovered/replay-smoke.json --include-actions --validate --json
99
+ zmr draft --from-trace traces/zmr-agent --out .zmr/discovered/surface-smoke.json --json
100
+ zmr draft --from-trace traces/zmr-agent --out .zmr/discovered/replay-smoke.json --include-actions --json
96
101
  zmr init --app --json --dir . --app-id com.example.mobiletest
97
102
  zmr validate --json .zmr/login-smoke.json
98
103
  zmr run .zmr/login-smoke.json --json --trace-dir traces/login-smoke
104
+ zmr run .zmr/login-smoke.json --json --trace-dir traces/login-smoke --discover-out .zmr/discovered/login-smoke.json
99
105
  zmr explain --json traces/login-smoke
106
+ zmr report traces/login-smoke --out traces/login-smoke/report.html --junit traces/login-smoke/junit.xml
100
107
  zmr import flow-yaml .zmr/legacy-flow.yaml --out .zmr/legacy-flow.json
101
108
  zmr export traces/login-smoke --out traces/login-smoke-redacted.zmrtrace --redact
102
109
  ```
103
110
 
111
+ For traced runs, `zmr run --json` returns executable `nextCommands` for
112
+ HTML and JUnit reporting, failure explanation, `zmr discover --from-trace`,
113
+ and redacted export so agents can continue from a run summary without guessing
114
+ the next handoff. The generated report handoff writes `report.html` and
115
+ `junit.xml` beside the trace for CI artifact collection.
116
+
117
+ When an agent should produce the reviewable scenario in the same command, add
118
+ `--discover-out .zmr/discovered/<name>.json`. ZMR still treats the generated
119
+ file as review-first: it writes from trace evidence, validates the file, and
120
+ returns the embedded `discovery` result without crawling or committing tests.
121
+ The `discovery.replay` object shows how many trace action events were
122
+ considered for replay, how many became scenario steps, and how many were
123
+ skipped.
124
+
104
125
  See [docs/scenario-authoring.md](docs/scenario-authoring.md) for selector and
105
126
  wait guidance.
106
127
 
@@ -108,6 +129,93 @@ wait guidance.
108
129
 
109
130
  Agents can use the CLI, JSON-RPC, or MCP surface. Start JSON-RPC over stdio:
110
131
 
132
+ ```bash
133
+ zmr inspect --json --dir .
134
+ ```
135
+
136
+ `zmr inspect --json` gives agents a read-only handoff for the app checkout:
137
+ config status, generated agent instructions, configured platform scenarios, and
138
+ recommended next commands. It does not launch devices or write tests.
139
+
140
+ After a live session has produced trace artifacts, agents can ask ZMR to turn
141
+ the trace into a validated, reviewable scenario candidate. `zmr explore` is
142
+ the agent-facing handoff: it records the goal, writes from existing trace
143
+ evidence, validates the candidate, and returns guardrails that make the limits
144
+ machine-readable:
145
+
146
+ ```bash
147
+ zmr explore --from-trace traces/zmr-agent \
148
+ --out .zmr/discovered/login-smoke.json \
149
+ --goal "find a stable login smoke" \
150
+ --include-actions \
151
+ --validate \
152
+ --json
153
+ ```
154
+
155
+ `zmr explore` is not an autonomous crawler. It does not launch devices, invent
156
+ missing actions, discover credentials, or commit tests. Its JSON includes
157
+ `autonomous:false`, `reviewRequired:true`, `guardrails`, and the same replay
158
+ coverage and validation fields as `zmr discover`.
159
+
160
+ When an agent wants the lower-level trace-to-test primitive directly, use
161
+ `zmr discover`:
162
+
163
+ ```bash
164
+ zmr discover --from-trace traces/zmr-agent \
165
+ --out .zmr/discovered/replay-smoke.json \
166
+ --include-actions \
167
+ --validate \
168
+ --json
169
+ ```
170
+
171
+ `zmr discover` is offline and review-first. It writes a scenario from stable
172
+ trace evidence, optionally validates it immediately, and returns next commands
173
+ for deterministic reruns. It does not crawl the app, discover credentials, or
174
+ commit tests. Its JSON includes `replay` coverage metadata so agents can report
175
+ which trace action events became replay steps and which were skipped.
176
+
177
+ For CLI-driven agent loops, `zmr run --json --trace-dir traces/zmr-agent
178
+ --discover-out .zmr/discovered/replay-smoke.json` performs the same
179
+ trace-backed discovery after the run and embeds the discover result in the run
180
+ JSON response.
181
+
182
+ For the lower-level draft primitive, agents can still ask ZMR to write a
183
+ conservative surface-smoke scenario from the latest snapshot:
184
+
185
+ ```bash
186
+ zmr draft --from-trace traces/zmr-agent \
187
+ --out .zmr/discovered/surface-smoke.json \
188
+ --json
189
+ zmr validate --json .zmr/discovered/surface-smoke.json
190
+ ```
191
+
192
+ `zmr draft` writes `launch`, `snapshot`, and `assertVisible` steps from stable
193
+ visible selectors. It does not tap controls or type into fields unless
194
+ `--include-actions` is explicitly requested.
195
+
196
+ When the trace was produced by an agent or JSON-RPC/MCP session that took typed
197
+ actions, add `--include-actions` to replay successful supported actions before
198
+ the final snapshot assertions:
199
+
200
+ ```bash
201
+ zmr draft --from-trace traces/zmr-agent \
202
+ --out .zmr/discovered/replay-smoke.json \
203
+ --include-actions \
204
+ --json
205
+ zmr validate --json .zmr/discovered/replay-smoke.json
206
+ ```
207
+
208
+ Replay drafts only use trace events with enough stable data to reproduce them,
209
+ such as launch, deep links, selector taps, selector text entry,
210
+ selector/timeout-preserving waits, back, keyboard hiding, coordinate-complete
211
+ swipes, direction/timeout-preserving selector scrolls, `assertNoneVisible`
212
+ selector arrays, selector/timeout-preserving `assertVisible` and
213
+ `assertNotVisible`, and timed `assertHealthy` checks.
214
+ Native selector wait traces include timeout context for successful waits and
215
+ timeout diagnostics.
216
+ Unsupported or underspecified events are skipped with warnings instead of guessed.
217
+ Text entry events whose text was redacted from the trace are also skipped.
218
+
111
219
  ```bash
112
220
  zmr serve --transport stdio --config .zmr/config.json --trace-dir traces/zmr-agent
113
221
  ```
@@ -118,8 +226,20 @@ Agents that support the Model Context Protocol can use the native MCP surface:
118
226
  zmr mcp --config .zmr/config.json --trace-dir traces/zmr-agent
119
227
  ```
120
228
 
121
- The MCP server exposes mobile-specific tools such as `semantic_snapshot`, `tap`,
122
- `type`, `wait_visible`, `trace_events`, and `trace_export`.
229
+ The MCP server exposes mobile-specific tools such as `semantic_snapshot`,
230
+ `install_app`, `launch_app`, `stop_app`, `clear_state`, `tap`, `type`,
231
+ `erase_text`, `hide_keyboard`, `swipe`, `press_back`, `open_link`,
232
+ `wait_visible`, `wait_not_visible`, `wait_any`, `scroll_until_visible`,
233
+ `assert_visible`, `assert_not_visible`, `assert_healthy`, `scenario_validate`,
234
+ `trace_events`, `trace_explain`, `trace_explore`, `trace_discover`, and
235
+ `trace_export`.
236
+
237
+ For agent-led discovery and test authoring, see
238
+ [docs/agent-discovery.md](docs/agent-discovery.md). ZMR supports that loop
239
+ through MCP, JSON-RPC, trace events, in-band trace discovery, offline surface
240
+ drafts, replay drafts, live and offline guarded trace exploration, and traced
241
+ run `nextCommands` today. Built-in exploration is review-first and
242
+ trace-backed, not an unbounded autonomous crawler.
123
243
 
124
244
  ## Optional Protocol Clients
125
245
 
@@ -129,7 +249,10 @@ same JSON-RPC protocol.
129
249
 
130
250
  TypeScript and Python are the most common starting points for app teams and
131
251
  agent harnesses. Go, Rust, Swift, and Kotlin clients are reference integrations
132
- for teams that want to embed the protocol from those ecosystems.
252
+ for teams that want to embed the protocol from those ecosystems. Go and Rust
253
+ also include typed trace discovery and scenario validation helpers for
254
+ host-side agent loops. Swift and Kotlin include lightweight discovery and
255
+ validation helpers for host-side automation.
133
256
 
134
257
  | Language | Entry point | Example |
135
258
  | --- | --- | --- |
@@ -153,7 +276,7 @@ and [docs/client-installation.md](docs/client-installation.md).
153
276
  | iOS physical device | Supported, validate locally | `devicectl` lifecycle plus app-local XCTest/XCUIAutomation shim; run pilots on your own app/device before relying on it in CI |
154
277
  | Cloud device farms | Not included | ZMR is focused on local and self-managed device targets in this preview |
155
278
 
156
- Current release: `0.1.2` developer preview. Protocol version:
279
+ Current release: `0.1.8` developer preview. Protocol version:
157
280
  `2026-04-28`.
158
281
 
159
282
  ## Documentation
@@ -161,8 +284,11 @@ Current release: `0.1.2` developer preview. Protocol version:
161
284
  - [FEATURES.md](FEATURES.md): complete feature list and limitations
162
285
  - [docs/install.md](docs/install.md): source, npm, Homebrew, and app setup
163
286
  - [docs/frameworks.md](docs/frameworks.md): React Native, Expo, Flutter, and native app guidance
287
+ - [docs/expo-smoke.md](docs/expo-smoke.md): reproducible Expo and iOS smoke test
288
+ - [docs/production-readiness.md](docs/production-readiness.md): release, reliability, framework, and agent-readiness gates
164
289
  - [docs/app-integration.md](docs/app-integration.md): app-side Android/iOS shims
165
290
  - [docs/scenario-authoring.md](docs/scenario-authoring.md): selectors, waits, and scenario design
291
+ - [docs/agent-discovery.md](docs/agent-discovery.md): agent-led discovery and scenario authoring loop
166
292
  - [docs/protocol.md](docs/protocol.md): JSON-RPC methods and schemas
167
293
  - [docs/ai-agents.md](docs/ai-agents.md): JSON-RPC and MCP agent workflows
168
294
  - [docs/clients.md](docs/clients.md): language client guide
package/build.zig.zon CHANGED
@@ -1,7 +1,7 @@
1
1
  .{
2
- .name = .zig_mobile_runner,
3
- .version = "0.0.1",
2
+ .name = .zeno_mobile_runner,
3
+ .version = "0.1.7",
4
4
  .minimum_zig_version = "0.15.2",
5
5
  .paths = .{""},
6
- .fingerprint = 0x5a9670ea13a33fab,
6
+ .fingerprint = 0xcc2c8187874868fc,
7
7
  }
package/clients/README.md CHANGED
@@ -19,9 +19,12 @@ actions instead of raw platform hierarchy classes.
19
19
  The TypeScript and Python clients expose the broadest app-facing control
20
20
  surface: session lifecycle, app launch/stop/link/state, snapshot and semantic
21
21
  snapshot, tap/type/erase/hide-keyboard/swipe/back/scroll, waits, assertions,
22
- trace event polling, and trace export. The Go, Rust, Swift, and Kotlin clients
23
- show the same protocol shape in other host languages and are useful starting
24
- points for custom integration work.
22
+ scenario validation, trace event polling, trace explanation, trace discovery,
23
+ trace exploration, and trace export.
24
+ The Go and Rust clients also include typed scenario validation and trace
25
+ explanation/exploration/discovery helpers. Swift and Kotlin include lightweight
26
+ trace explanation, validation, exploration, and discovery helpers for
27
+ host-side agents in those ecosystems.
25
28
  Use the `assertHealthy`/`assert_healthy` helper after launches, links, and major
26
29
  navigation steps to catch native crash overlays and development-client failures
27
30
  without hand-maintaining negative selectors in every client.
@@ -45,6 +48,7 @@ const zmr = createZmrClient({
45
48
  command: "zmr",
46
49
  args: ["serve", "--transport", "stdio", "--config", ".zmr/config.json"],
47
50
  });
51
+ const explored = await zmr.exploreTrace(".zmr/discovered/agent-goal.json", "find a stable login smoke", { includeActions: true, validate: true, force: true });
48
52
  ```
49
53
 
50
54
  ## Python
@@ -64,6 +68,8 @@ from zmr_client import ZmrClient
64
68
 
65
69
  with ZmrClient("zmr", ["serve", "--transport", "stdio", "--config", ".zmr/config.json"]) as zmr:
66
70
  snapshot = zmr.snapshot()
71
+ explanation = zmr.explain_trace()
72
+ explored = zmr.explore_trace(".zmr/discovered/agent-goal.json", "find a stable login smoke", include_actions=True, validate=True, force=True)
67
73
  ```
68
74
 
69
75
  ## Go
@@ -83,6 +89,10 @@ go run ./clients/go/examples/fake-session \
83
89
 
84
90
  ```go
85
91
  client, err := zmr.Start(ctx, "zmr", "serve", "--transport", "stdio", "--config", ".zmr/config.json")
92
+ discovered, err := client.DiscoverTrace(ctx, ".zmr/discovered/go-agent.json", zmr.TraceDiscoverOptions{IncludeActions: true, Validate: true, Force: true})
93
+ explored, err := client.ExploreTrace(ctx, ".zmr/discovered/go-goal.json", "find a stable login smoke", zmr.TraceDiscoverOptions{IncludeActions: true, Validate: true, Force: true})
94
+ validation, err := client.ValidateScenario(ctx, discovered.Out)
95
+ explanation, err := client.ExplainTrace(ctx)
86
96
  ```
87
97
 
88
98
  ## Rust
@@ -111,6 +121,20 @@ cargo run --manifest-path clients/rust/Cargo.toml --example fake_session -- \
111
121
  ```rust
112
122
  let mut client = zmr_client::Client::start("zmr", ["serve", "--transport", "stdio", "--config", ".zmr/config.json"])?;
113
123
  let snapshot = client.snapshot()?;
124
+ let discovered = client.discover_trace(".zmr/discovered/rust-agent.json", zmr_client::TraceDiscoverOptions {
125
+ include_actions: true,
126
+ validate: true,
127
+ force: true,
128
+ ..Default::default()
129
+ })?;
130
+ let explored = client.explore_trace(".zmr/discovered/rust-goal.json", "find a stable login smoke", zmr_client::TraceDiscoverOptions {
131
+ include_actions: true,
132
+ validate: true,
133
+ force: true,
134
+ ..Default::default()
135
+ })?;
136
+ let validation = client.validate_scenario(&discovered.out)?;
137
+ let explanation = client.explain_trace()?;
114
138
  ```
115
139
 
116
140
  ## Swift
@@ -128,6 +152,24 @@ git submodule add https://github.com/johnmikel/zeno-mobile-runner.git vendor/zen
128
152
  .package(path: "vendor/zeno-mobile-runner/clients/swift")
129
153
  ```
130
154
 
155
+ ```swift
156
+ let client = ZMRClient(arguments: ["serve", "--transport", "stdio", "--config", ".zmr/config.json"])
157
+ try client.start()
158
+ let out = ".zmr/discovered/swift-agent.json"
159
+ let discovered = try client.discoverTrace(
160
+ out: out,
161
+ options: TraceDiscoverOptions(includeActions: true, validate: true, force: true)
162
+ )
163
+ let explored = try client.exploreTrace(
164
+ out: ".zmr/discovered/swift-goal.json",
165
+ goal: "find a stable login smoke",
166
+ options: TraceDiscoverOptions(includeActions: true, validate: true, force: true)
167
+ )
168
+ let validation = try client.validateScenario(path: out)
169
+ let explanation = try client.explainTrace()
170
+ client.close()
171
+ ```
172
+
131
173
  Swift is useful for macOS host-side automation next to iOS app code. It is not
132
174
  an SDK embedded in the app under test.
133
175
 
@@ -140,6 +182,21 @@ git submodule add https://github.com/johnmikel/zeno-mobile-runner.git vendor/zen
140
182
  gradle -p vendor/zeno-mobile-runner/clients/kotlin build
141
183
  ```
142
184
 
185
+ ```kotlin
186
+ val out = ".zmr/discovered/kotlin-agent.json"
187
+ val discovered = client.discoverTrace(
188
+ out,
189
+ TraceDiscoverOptions(includeActions = true, validate = true, force = true)
190
+ )
191
+ val explored = client.exploreTrace(
192
+ ".zmr/discovered/kotlin-goal.json",
193
+ "find a stable login smoke",
194
+ TraceDiscoverOptions(includeActions = true, validate = true, force = true)
195
+ )
196
+ val validation = client.validateScenario(out)
197
+ val explanation = client.explainTrace()
198
+ ```
199
+
143
200
  Kotlin is useful for Android teams that want host-side orchestration in Kotlin.
144
201
  It still drives the external `zmr` binary.
145
202
 
@@ -12,6 +12,18 @@ defer client.Close()
12
12
 
13
13
  snapshot, err := client.Snapshot(ctx)
14
14
  healthy, err := client.AssertHealthy(ctx, 1000)
15
+ explanation, err := client.ExplainTrace(ctx)
16
+ discovered, err := client.DiscoverTrace(ctx, ".zmr/discovered/go-agent.json", zmr.TraceDiscoverOptions{
17
+ IncludeActions: true,
18
+ Validate: true,
19
+ Force: true,
20
+ })
21
+ explored, err := client.ExploreTrace(ctx, ".zmr/discovered/go-goal.json", "find a stable login smoke", zmr.TraceDiscoverOptions{
22
+ IncludeActions: true,
23
+ Validate: true,
24
+ Force: true,
25
+ })
26
+ validation, err := client.ValidateScenario(ctx, discovered.Out)
15
27
  ```
16
28
 
17
29
  Run the fake-session example from the repository root: