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.
- package/CHANGELOG.md +162 -3
- package/FEATURES.md +50 -7
- package/README.md +133 -7
- package/build.zig.zon +3 -3
- package/clients/README.md +60 -3
- package/clients/go/README.md +12 -0
- package/clients/go/zmr/client.go +142 -0
- package/clients/kotlin/README.md +18 -1
- package/clients/kotlin/build.gradle.kts +1 -1
- package/clients/kotlin/src/main/kotlin/dev/zmr/ZmrClient.kt +76 -1
- package/clients/python/README.md +19 -0
- package/clients/python/pyproject.toml +1 -1
- package/clients/python/zmr_client.py +33 -0
- package/clients/rust/Cargo.lock +1 -1
- package/clients/rust/Cargo.toml +1 -1
- package/clients/rust/README.md +25 -1
- package/clients/rust/src/lib.rs +201 -0
- package/clients/swift/README.md +18 -0
- package/clients/swift/Sources/ZMRClient/ZMRClient.swift +82 -0
- package/clients/typescript/README.md +16 -0
- package/clients/typescript/index.d.ts +12 -0
- package/clients/typescript/index.mjs +16 -0
- package/clients/typescript/package.json +1 -1
- package/docs/agent-discovery.md +202 -0
- package/docs/ai-agents.md +87 -6
- package/docs/benchmarking.md +10 -3
- package/docs/clients.md +10 -6
- package/docs/demo.md +4 -0
- package/docs/expo-smoke.md +79 -0
- package/docs/install.md +3 -2
- package/docs/npm.md +58 -4
- package/docs/production-readiness.md +123 -0
- package/docs/protocol-fixtures/core-session.responses.jsonl +1 -1
- package/docs/protocol.md +215 -16
- package/docs/scenario-authoring.md +3 -0
- package/docs/troubleshooting.md +1 -1
- package/npm/agents.mjs +16 -0
- package/npm/build-zmr.mjs +1 -1
- package/npm/commands.mjs +9 -5
- package/npm/postinstall.mjs +28 -2
- package/npm/verify-publish.mjs +36 -0
- package/package.json +2 -1
- package/prebuilds/darwin-arm64/zmr +0 -0
- package/prebuilds/darwin-x64/zmr +0 -0
- package/prebuilds/linux-arm64/zmr +0 -0
- package/prebuilds/linux-x64/zmr +0 -0
- package/schemas/README.md +4 -0
- package/schemas/discover-output.schema.json +83 -0
- package/schemas/draft-output.schema.json +58 -0
- package/schemas/explore-output.schema.json +94 -0
- package/schemas/inspect-output.schema.json +88 -0
- package/schemas/run-output.schema.json +2 -0
- package/scripts/install-ios-shim.sh +79 -14
- package/scripts/release-readiness.py +43 -0
- package/scripts/run-android-pilot.sh +35 -9
- package/scripts/run-ios-pilot.sh +11 -4
- package/shims/ios/ZMRShim.swift +3 -0
- package/shims/ios/ZMRShimUITestCase.swift +41 -11
- package/skills/zmr-mobile-testing/SKILL.md +28 -3
- package/src/cli_discover.zig +239 -0
- package/src/cli_draft.zig +924 -0
- package/src/cli_explore.zig +136 -0
- package/src/cli_inspect.zig +310 -0
- package/src/cli_output.zig +26 -2
- package/src/cli_run.zig +28 -0
- package/src/cli_trace.zig +8 -0
- package/src/errors.zig +9 -0
- package/src/ios.zig +11 -4
- package/src/ios_lifecycle.zig +36 -0
- package/src/ios_shim.zig +42 -0
- package/src/json_rpc_methods.zig +85 -11
- package/src/json_rpc_params.zig +8 -0
- package/src/json_rpc_protocol.zig +1 -1
- package/src/json_rpc_trace.zig +112 -0
- package/src/main.zig +24 -2
- package/src/mcp.zig +209 -6
- package/src/mcp_protocol.zig +29 -1
- package/src/mcp_trace.zig +126 -4
- package/src/report.zig +186 -0
- package/src/runner.zig +26 -4
- package/src/runner_actions.zig +10 -0
- package/src/runner_diagnostics.zig +31 -1
- package/src/runner_events.zig +70 -7
- package/src/runner_native.zig +17 -1
- package/src/runner_waits.zig +82 -19
- package/src/scaffold.zig +28 -12
- package/src/scenario.zig +32 -4
- package/src/schema_registry.zig +4 -0
- 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
|
-
##
|
|
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
|
|
315
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
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
|
|
93
|
-
want a machine-readable readiness
|
|
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.
|
|
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,
|
|
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
|
|
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`,
|
|
122
|
-
`
|
|
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.
|
|
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
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,
|
|
23
|
-
|
|
24
|
-
|
|
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
|
|
package/clients/go/README.md
CHANGED
|
@@ -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:
|