adb-ready 0.3.4 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +92 -1
- package/README.md +37 -4
- package/dist/cli.js +4727 -406
- package/docs/RELEASING.md +2 -1
- package/docs/apps-and-evidence.md +11 -0
- package/docs/configuration.md +8 -0
- package/docs/dev-sessions.md +124 -3
- package/docs/getting-started.md +3 -0
- package/docs/logs-and-context.md +12 -1
- package/docs/troubleshooting.md +25 -0
- package/docs/ui-automation.md +31 -17
- package/package.json +4 -2
- package/schema/agent-tools-v1.json +4 -4
- package/schema/config-v1.schema.json +1 -0
- package/dist/cli.js.map +0 -132
package/docs/RELEASING.md
CHANGED
|
@@ -24,7 +24,8 @@ The workflow does not use a long-lived npm write token.
|
|
|
24
24
|
Release evidence has three tiers:
|
|
25
25
|
|
|
26
26
|
- **Every release:** the complete fixture, unit, integration, runtime, package,
|
|
27
|
-
documentation, privacy, and release-artifact verification gate must
|
|
27
|
+
documentation, privacy, coverage, and release-artifact verification gate must
|
|
28
|
+
pass. Pull requests must also satisfy the 95% changed-line coverage gate.
|
|
28
29
|
- **Device-behavior changes:** rerun every affected workflow on a real target
|
|
29
30
|
and record the exact host, target, Android version, and transport. A
|
|
30
31
|
documentation, metadata, or machine-output-only patch does not manufacture
|
|
@@ -15,6 +15,9 @@ adb-ready app info
|
|
|
15
15
|
|
|
16
16
|
Resolution prefers an explicit `APP_ID`, then project configuration and
|
|
17
17
|
detected Android project metadata. Every resolved result includes provenance.
|
|
18
|
+
Unavailable optional package metadata, such as an application without an
|
|
19
|
+
Android `versionName`, is omitted from structured output instead of being
|
|
20
|
+
reported as a literal sentinel value.
|
|
18
21
|
If equally valid candidates remain, ADB Ready asks for an explicit choice
|
|
19
22
|
instead of selecting the first package.
|
|
20
23
|
|
|
@@ -134,6 +137,13 @@ symlink outside that root and never replaces an existing file unless `--force`
|
|
|
134
137
|
is explicit. Files are written through a private temporary path and published
|
|
135
138
|
only after validation.
|
|
136
139
|
|
|
140
|
+
For a recording, validation means more than finding an MP4 filename or header:
|
|
141
|
+
the container must be structurally readable and its video track must contain a
|
|
142
|
+
non-zero timeline with multiple frames. The result reports the measured media
|
|
143
|
+
duration and frame count. If Android emits a one-frame, zero-duration recording
|
|
144
|
+
while the display is static, ADB Ready rejects it with `SCREEN_RECORD_EMPTY`
|
|
145
|
+
instead of publishing unusable evidence; create visible activity and retry.
|
|
146
|
+
|
|
137
147
|
Some multi-display Android builds, including foldables, emit a short textual
|
|
138
148
|
warning before the screenshot bytes. ADB Ready removes only a bounded text
|
|
139
149
|
preamble and still requires a valid PNG signature before publishing the file.
|
|
@@ -142,6 +152,7 @@ The result contains:
|
|
|
142
152
|
|
|
143
153
|
- a project-relative path;
|
|
144
154
|
- media type and byte size;
|
|
155
|
+
- measured duration and video frame count for recordings;
|
|
145
156
|
- SHA-256 digest;
|
|
146
157
|
- selected target and capture-command provenance.
|
|
147
158
|
|
package/docs/configuration.md
CHANGED
|
@@ -69,6 +69,7 @@ existing file unless `--force` is explicit. Use `--dry-run` first.
|
|
|
69
69
|
| `packageManager` | `npm`, `pnpm`, `yarn`, or `bun` |
|
|
70
70
|
| `command` | `{ "executable": string, "args": string[], "cwd"?: string }` |
|
|
71
71
|
| `reversePorts` | integers or `{ "device": number, "host"?: number }` objects |
|
|
72
|
+
| `autoReverseLocalhost` | detect explicit localhost URLs in Expo `EXPO_PUBLIC_*` variables; defaults to `true` |
|
|
72
73
|
| `logs` | enable the session's targeted log stream |
|
|
73
74
|
| `cleanupPorts` | remove only mappings created by this session |
|
|
74
75
|
| `watch` | monitor and recover target, port, and log health |
|
|
@@ -80,6 +81,12 @@ existing file unless `--force` is explicit. Use `--dry-run` first.
|
|
|
80
81
|
Unknown keys and invalid nested values fail validation rather than being
|
|
81
82
|
silently ignored.
|
|
82
83
|
|
|
84
|
+
`init` detects and writes `packageManager` only for Expo, React Native, and
|
|
85
|
+
Capacitor presets, where it selects the project CLI. Flutter and native Gradle
|
|
86
|
+
use their own launchers, so an unrelated package-manager executable available
|
|
87
|
+
on the host is not recorded as project configuration. An explicit
|
|
88
|
+
`--package-manager` override is still preserved.
|
|
89
|
+
|
|
83
90
|
## Profiles
|
|
84
91
|
|
|
85
92
|
Profiles can inherit from one named parent. Cycles and missing references are
|
|
@@ -134,6 +141,7 @@ Supported environment variables include:
|
|
|
134
141
|
| `ADB_READY_PRESET` | development preset |
|
|
135
142
|
| `ADB_READY_PACKAGE_MANAGER` | package manager |
|
|
136
143
|
| `ADB_READY_REVERSE_PORTS` | comma-separated device ports |
|
|
144
|
+
| `ADB_READY_AUTO_REVERSE_LOCALHOST` | boolean Expo localhost-service discovery override |
|
|
137
145
|
| `ADB_READY_DEV_LOGS` | boolean |
|
|
138
146
|
| `ADB_READY_CLEANUP_PORTS` | boolean |
|
|
139
147
|
| `ADB_READY_DEV_WATCH` | boolean |
|
package/docs/dev-sessions.md
CHANGED
|
@@ -8,13 +8,18 @@ local diagnostic record.
|
|
|
8
8
|
|
|
9
9
|
| Preset | Detection | Default command | Default reverse port |
|
|
10
10
|
| --- | --- | --- | --- |
|
|
11
|
-
| Expo | `expo` dependency | project `start` script
|
|
11
|
+
| Expo | `expo` dependency | project `start` script without framework device selection, otherwise `expo start` | `8081` |
|
|
12
12
|
| React Native | `react-native` dependency | project `android` script, otherwise React Native CLI | `8081` |
|
|
13
13
|
| Flutter | `pubspec.yaml` | `flutter run -d <selected-target>` | none |
|
|
14
14
|
| Capacitor | `@capacitor/android` or `@capacitor/core` dependency | Capacitor CLI for the selected target | none |
|
|
15
15
|
| Gradle | wrapper or Gradle build file | wrapper `installDebug` | none |
|
|
16
16
|
| Custom | explicit config or `--` | exact executable and argument array | none |
|
|
17
17
|
|
|
18
|
+
Flutter requires the Flutter SDK's `flutter` executable on `PATH`. Native
|
|
19
|
+
Gradle projects use their checked-in `gradlew` or `gradlew.bat` Wrapper; ADB
|
|
20
|
+
Ready reports either missing prerequisite directly instead of suggesting an
|
|
21
|
+
unrelated custom command.
|
|
22
|
+
|
|
18
23
|
Select a preset when detection is intentionally unavailable or ambiguous:
|
|
19
24
|
|
|
20
25
|
```bash
|
|
@@ -28,7 +33,7 @@ adb-ready dev --preset gradle --device emulator-5554
|
|
|
28
33
|
An exact command after `--` wins over preset command resolution:
|
|
29
34
|
|
|
30
35
|
```bash
|
|
31
|
-
adb-ready dev -- bun x expo start --host lan --port 8081
|
|
36
|
+
adb-ready dev -- bun x expo start --host lan --port 8081
|
|
32
37
|
```
|
|
33
38
|
|
|
34
39
|
No shell is inserted. Quoting, wildcard, pipe, and substitution syntax are
|
|
@@ -39,6 +44,8 @@ therefore passed as literal arguments instead of being executed unexpectedly.
|
|
|
39
44
|
One selected transport is used for the entire session:
|
|
40
45
|
|
|
41
46
|
- every direct ADB command uses its exact serial or transport ID;
|
|
47
|
+
- Expo's default workflow resolves its deep link from Metro and opens it through
|
|
48
|
+
that exact transport instead of delegating target selection to Expo;
|
|
42
49
|
- the child command receives `ANDROID_SERIAL`;
|
|
43
50
|
- hooks receive `ANDROID_SERIAL`, `ADB_READY_SESSION_ID`,
|
|
44
51
|
`ADB_READY_PRESET`, and `ADB_READY_TARGET_ID`; and
|
|
@@ -62,6 +69,84 @@ Disable cleanup only when the mapping should intentionally outlive the process:
|
|
|
62
69
|
adb-ready dev --no-cleanup-ports
|
|
63
70
|
```
|
|
64
71
|
|
|
72
|
+
## Expo localhost services
|
|
73
|
+
|
|
74
|
+
Android's `localhost` belongs to the selected target, not the development host.
|
|
75
|
+
For Expo projects, ADB Ready therefore resolves the same development `.env`
|
|
76
|
+
files as Expo and inspects public variables whose values are explicit
|
|
77
|
+
`http://`, `https://`, `ws://`, or `wss://` loopback URLs. For example,
|
|
78
|
+
`EXPO_PUBLIC_API_URL=http://localhost:8000` adds `tcp:8000 → tcp:8000` to the
|
|
79
|
+
session and verifies host port `8000` before reporting ready.
|
|
80
|
+
|
|
81
|
+
Detection is deliberately bounded:
|
|
82
|
+
|
|
83
|
+
- only `EXPO_PUBLIC_*` variables are inspected;
|
|
84
|
+
- only `localhost`, `127.0.0.1`, and `[::1]` URLs with explicit ports qualify;
|
|
85
|
+
- the URL value is never retained or printed—results expose only the variable
|
|
86
|
+
name, port, and loaded `.env` basenames;
|
|
87
|
+
- an explicit mapping for the same device port always wins; and
|
|
88
|
+
- cleanup still removes only mappings created by the current session.
|
|
89
|
+
|
|
90
|
+
Preview the resolved mappings without touching ADB:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
adb-ready dev --dry-run --json
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Disable this behavior for an intentionally different network topology:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
adb-ready dev --no-auto-reverse-localhost
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The same switch is available to `adb-ready init`. It can also be persisted as
|
|
103
|
+
`dev.autoReverseLocalhost: false` or set with
|
|
104
|
+
`ADB_READY_AUTO_REVERSE_LOCALHOST=false`.
|
|
105
|
+
|
|
106
|
+
## Existing Metro servers
|
|
107
|
+
|
|
108
|
+
For Expo and React Native, ADB Ready checks the local host behind the default
|
|
109
|
+
device port `8081` before launching the project command. It attaches only when
|
|
110
|
+
`/status` returns Metro's exact running-status response. An open port alone is
|
|
111
|
+
not sufficient evidence.
|
|
112
|
+
|
|
113
|
+
An attached Metro server remains externally owned:
|
|
114
|
+
|
|
115
|
+
- ADB Ready does not start, restart, send terminal controls to, or stop it.
|
|
116
|
+
- `Ctrl+C` ends only the ADB Ready session and cleans only mappings created by
|
|
117
|
+
that session.
|
|
118
|
+
- Human, plain, JSON, and NDJSON results identify the external attachment.
|
|
119
|
+
- Session health checks detect when the external server disappears, but recovery
|
|
120
|
+
never restarts a process ADB Ready does not own.
|
|
121
|
+
- A non-Metro service on the configured host port fails with
|
|
122
|
+
`DEVELOPMENT_SERVICE_CONFLICT` and an actionable explanation.
|
|
123
|
+
|
|
124
|
+
Run Metro in its original terminal when you need its native reload or developer
|
|
125
|
+
controls. A newly started Metro process continues to receive its controls
|
|
126
|
+
directly through ADB Ready.
|
|
127
|
+
|
|
128
|
+
## Expo target isolation
|
|
129
|
+
|
|
130
|
+
Expo's `--android` startup path can enumerate and mutate every attached Android
|
|
131
|
+
transport, even when `ANDROID_SERIAL` names one device. ADB Ready therefore
|
|
132
|
+
does not add `--android` to detected Expo commands. After Metro passes
|
|
133
|
+
readiness, ADB Ready:
|
|
134
|
+
|
|
135
|
+
1. asks Expo's public `/_expo/open` endpoint for the Android deep link, with a
|
|
136
|
+
bounded `/_expo/link` fallback for Expo 55;
|
|
137
|
+
2. routes local-network Metro URLs through the verified reverse mapping while
|
|
138
|
+
preserving public tunnel URLs;
|
|
139
|
+
3. resolves the installed URL handler on the selected transport; and
|
|
140
|
+
4. opens that exact component with target-scoped ADB before reporting ready.
|
|
141
|
+
|
|
142
|
+
Missing Expo Go/development builds, malformed server responses, and rejected
|
|
143
|
+
launches fail as `EXPO_LAUNCH_FAILED`; ADB Ready does not silently try another
|
|
144
|
+
device. A command supplied after `--` remains an explicit open-world override,
|
|
145
|
+
so omit `--android` when ADB Ready should retain launch ownership. Expo's native
|
|
146
|
+
`a`/`shift+a` shortcuts likewise belong to Expo and can invoke its own device
|
|
147
|
+
selection; the ADB Ready control bar intentionally advertises only target-safe
|
|
148
|
+
runtime controls.
|
|
149
|
+
|
|
65
150
|
## Health and recovery
|
|
66
151
|
|
|
67
152
|
Once ready, the session watches:
|
|
@@ -70,6 +155,23 @@ Once ready, the session watches:
|
|
|
70
155
|
- required reverse mappings; and
|
|
71
156
|
- the owned logcat stream when logs are enabled.
|
|
72
157
|
|
|
158
|
+
Successful readiness and health polls are background work: they do not compete
|
|
159
|
+
with framework logs and are not retained in the durable session journal.
|
|
160
|
+
Failures, state changes, and recovery actions remain visible and recorded.
|
|
161
|
+
|
|
162
|
+
Readiness checks and the complete session gate are separate. A host port or
|
|
163
|
+
custom assertion may pass without proving that the framework launch succeeded.
|
|
164
|
+
ADB Ready emits `ready` only after every configured check and target-specific
|
|
165
|
+
launch succeeds while the owned development command is not already failing. If
|
|
166
|
+
that command fails first, its actionable redacted error is promoted into the
|
|
167
|
+
final problem instead of briefly presenting the session as ready.
|
|
168
|
+
|
|
169
|
+
Foreground, activity, and unlocked checks parse the complete target-scoped
|
|
170
|
+
Android state returned by `dumpsys`, including current Android 16 fields. When a
|
|
171
|
+
contract does not pass, human output identifies every failed or unsupported
|
|
172
|
+
assertion with its observed detail; JSON and NDJSON retain every assertion
|
|
173
|
+
result for CI and agents.
|
|
174
|
+
|
|
73
175
|
Recovery waits for a bounded stabilization period, attempts to reacquire the
|
|
74
176
|
same target, restores only missing session mappings, restarts the targeted log
|
|
75
177
|
stream when necessary, and verifies the complete state independently.
|
|
@@ -98,13 +200,32 @@ Configure the budget explicitly:
|
|
|
98
200
|
|
|
99
201
|
Set `dev.watch` to `false` only for a deliberately one-shot child process.
|
|
100
202
|
|
|
203
|
+
## Live terminal controls
|
|
204
|
+
|
|
205
|
+
An interactive `adb-ready dev` session shows a compact control bar after it
|
|
206
|
+
becomes ready. ADB Ready preserves the framework's native terminal input rather
|
|
207
|
+
than intercepting or redefining it:
|
|
208
|
+
|
|
209
|
+
- Expo shows `r` reload, `m` developer menu, `j` debugger, and `?` commands.
|
|
210
|
+
- Flutter shows `r` hot reload, `R` hot restart, and `h` commands.
|
|
211
|
+
- Other presets state that framework input is active without promising
|
|
212
|
+
unsupported shortcuts.
|
|
213
|
+
- `Ctrl+C` stops the owned child and performs the normal verified cleanup.
|
|
214
|
+
- Health monitoring is stopped and awaited before intentional child or port
|
|
215
|
+
teardown, so cancellation cannot be recorded as a device degradation or a
|
|
216
|
+
recovery attempt.
|
|
217
|
+
|
|
218
|
+
The control bar is never rendered by `run`, JSON/NDJSON output, redirected
|
|
219
|
+
streams, CI, `--non-interactive`, or `--quiet`. This keeps scripts deterministic
|
|
220
|
+
and leaves arbitrary child input untouched.
|
|
221
|
+
|
|
101
222
|
## Lifecycle hooks
|
|
102
223
|
|
|
103
224
|
Supported phases are:
|
|
104
225
|
|
|
105
226
|
```text
|
|
106
227
|
beforeDev → onTargetReady → onPortsReady → onReady
|
|
107
|
-
→ onChildExit → finally
|
|
228
|
+
→ onChildExit (owned child only) → finally
|
|
108
229
|
```
|
|
109
230
|
|
|
110
231
|
Hooks are executable/argument arrays, not shell strings. Each hook may set a
|
package/docs/getting-started.md
CHANGED
|
@@ -27,6 +27,9 @@ version:
|
|
|
27
27
|
npx adb-ready doctor
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
+
Run `npx adb-ready` without a command for the interactive workflow home. Its
|
|
31
|
+
layout automatically switches to a compact form in narrow terminal panes.
|
|
32
|
+
|
|
30
33
|
The full source build can be tested from a repository checkout:
|
|
31
34
|
|
|
32
35
|
```bash
|
package/docs/logs-and-context.md
CHANGED
|
@@ -36,10 +36,18 @@ Available filters:
|
|
|
36
36
|
| `--exclude-tag TAG` | Suppress a tag; repeat to exclude more |
|
|
37
37
|
| `--level PRIORITY` | Minimum `V`, `D`, `I`, `W`, `E`, `F`, `A`, or silent `S` priority |
|
|
38
38
|
| `--buffer NAME` | Read `main`, `system`, or `crash`; repeat for more |
|
|
39
|
-
| `--tail COUNT` | Begin with the most recent record count |
|
|
39
|
+
| `--tail COUNT` | Begin with the most recent matching record count |
|
|
40
40
|
| `--since TIMESTAMP` | Pass an Android logcat timestamp boundary |
|
|
41
41
|
| `--max-records COUNT` | Bound records retained in the final result |
|
|
42
42
|
|
|
43
|
+
The same tag cannot be passed to both `--tag` and `--exclude-tag`. ADB Ready
|
|
44
|
+
rejects that contradictory request before accessing ADB so an exclusion can
|
|
45
|
+
never appear to succeed while logcat returns the tag.
|
|
46
|
+
|
|
47
|
+
`--tail` is applied after package, process, tag, priority, and buffer filters.
|
|
48
|
+
With a live stream, ADB Ready snapshots the matching history and overlaps the
|
|
49
|
+
follow boundary so records written during setup are neither lost nor repeated.
|
|
50
|
+
|
|
43
51
|
Unparsed lines are preserved. Output arriving on `stderr` is not automatically
|
|
44
52
|
classified as an error; severity comes from source semantics. Fatal Android
|
|
45
53
|
exceptions, native crashes, ANRs, and React Native fatal errors become
|
|
@@ -117,6 +125,9 @@ Before persistence or export, ADB Ready:
|
|
|
117
125
|
- redacts known token, credential, pairing-code, URL, and path patterns;
|
|
118
126
|
- replaces observed device and project identities with short SHA-256
|
|
119
127
|
fingerprints;
|
|
128
|
+
- preserves operational transport IDs and bounds short literal matches to
|
|
129
|
+
complete identifier tokens, preventing unrelated timestamps, ports, hashes,
|
|
130
|
+
and correlation IDs from being altered;
|
|
120
131
|
- honors additional environment names configured in
|
|
121
132
|
`dev.journal.redactEnvironment`;
|
|
122
133
|
- bounds both the in-memory journal and saved session history; and
|
package/docs/troubleshooting.md
CHANGED
|
@@ -34,7 +34,10 @@ adb-ready context --since 5m --only problems,recovery,logs
|
|
|
34
34
|
| `UI_NOT_IDLE` | Android UI Automator could not observe a quiet accessibility window | Pause continuous UI changes or navigate to a stable screen, then retry |
|
|
35
35
|
| `SESSION_RECOVERY_FAILED` | The bounded target/port recovery budget was exhausted | Inspect `problems`, network state, and saved recovery events |
|
|
36
36
|
| `SESSION_PERSISTENCE_FAILED` | The private session record could not be written | Check user-state directory permissions and capacity |
|
|
37
|
+
| `FRAMEWORK_LAUNCHER_NOT_FOUND` | The detected Flutter or Gradle project has no runnable launcher | Install Flutter and expose `flutter` on PATH, or restore the project's checked-in Gradle Wrapper |
|
|
37
38
|
| `CHILD_PROCESS_FAILED` | The project command exited unsuccessfully | Inspect child output, targeted logs, and preserved exit code |
|
|
39
|
+
| `DEVELOPMENT_SERVICE_CONFLICT` | Metro's configured host port belongs to another service | Stop that service or map device port `8081` to the actual Metro host port |
|
|
40
|
+
| `EXPO_LAUNCH_FAILED` | Expo could not provide a valid link or the selected target has no matching runtime | Install the project development build or Expo Go on that target, then retry |
|
|
38
41
|
|
|
39
42
|
## ADB is installed but not found
|
|
40
43
|
|
|
@@ -92,6 +95,28 @@ ADB Ready will reuse an exact mapping, but it will not overwrite a different
|
|
|
92
95
|
host destination. Remove the old mapping only when you know which tool owns it,
|
|
93
96
|
or choose a different device port.
|
|
94
97
|
|
|
98
|
+
## An Expo app cannot reach its localhost API
|
|
99
|
+
|
|
100
|
+
Run an offline preview and check whether the API port appears in the requested
|
|
101
|
+
reverse mappings:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
adb-ready dev --dry-run --json
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
ADB Ready automatically detects explicit loopback URLs in `EXPO_PUBLIC_*`
|
|
108
|
+
variables using Expo's development `.env` resolution. If the application builds
|
|
109
|
+
its URL dynamically, uses a non-public variable, or omits the URL port, declare
|
|
110
|
+
the mapping explicitly:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
adb-ready dev --port 8000
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
The host service must already be listening on that port. ADB Ready verifies it
|
|
117
|
+
before reporting the session ready; it does not start an unknown backend on the
|
|
118
|
+
user's behalf.
|
|
119
|
+
|
|
95
120
|
## A session will not recover
|
|
96
121
|
|
|
97
122
|
Recovery is intentionally bounded and identity-safe. It will not connect an
|
package/docs/ui-automation.md
CHANGED
|
@@ -29,13 +29,20 @@ ADB Ready does not silently disable device-wide animations.
|
|
|
29
29
|
adb-ready ui audit --json --non-interactive
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
The audit reports enabled
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
32
|
+
The audit reports enabled controls that have no effective human-readable label,
|
|
33
|
+
and controls that have no resource ID for a stable selector. Effective labels
|
|
34
|
+
include text, hints, and content descriptions on the control, its descendants,
|
|
35
|
+
or an actionable ancestor. Structural focus and scrolling containers are not
|
|
36
|
+
misreported as controls merely because they are focusable or scrollable.
|
|
37
|
+
|
|
38
|
+
Every finding includes its rule rationale and confidence. A partial hierarchy
|
|
39
|
+
reduces the confidence of missing-label findings instead of presenting
|
|
40
|
+
incomplete evidence as definitive. The audit returns exact current references,
|
|
41
|
+
attributes, and bounded totals; it deliberately does not invent a subjective
|
|
42
|
+
quality score. A missing label is an accessibility warning. A missing stable ID
|
|
43
|
+
is an automation advisory; effective text and content-description labels remain
|
|
44
|
+
usable, while a resource ID or Compose test tag exposed through
|
|
45
|
+
`testTagsAsResourceId` is more resilient to copy changes.
|
|
39
46
|
|
|
40
47
|
## Tap and long-press
|
|
41
48
|
|
|
@@ -47,8 +54,11 @@ adb-ready ui long-press 'id=com.example:id/item'
|
|
|
47
54
|
```
|
|
48
55
|
|
|
49
56
|
ADB Ready resolves a fresh hierarchy and refuses to guess when a selector has
|
|
50
|
-
zero or multiple matches.
|
|
51
|
-
|
|
57
|
+
zero or multiple matches. When unique text or a content description belongs to
|
|
58
|
+
a non-clickable label inside an enabled clickable row, ADB Ready taps the
|
|
59
|
+
nearest actionable ancestor. Structured results report both the label that
|
|
60
|
+
matched and the action node that received the tap. Prefer a current reference
|
|
61
|
+
when the exact observed snapshot matters:
|
|
52
62
|
|
|
53
63
|
```bash
|
|
54
64
|
adb-ready ui tap ui:7c4a31b8d2ef:14
|
|
@@ -81,10 +91,12 @@ adb-ready ui clear 'id=com.example:id/search'
|
|
|
81
91
|
`get` requires one unambiguous match and returns its semantic values, state,
|
|
82
92
|
and bounds. `fill` and `clear` focus that exact enabled field, select its
|
|
83
93
|
existing value, replace it, then inspect the hierarchy again. A visible normal
|
|
84
|
-
field is successful only when its post-action value matches.
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
94
|
+
field is successful only when its post-action value matches. Android may expose
|
|
95
|
+
an empty field's hint as accessibility text; ADB Ready reads the separate
|
|
96
|
+
platform `hint` attribute so a declared placeholder is not mistaken for a
|
|
97
|
+
remaining value. Password and custom fields can accept input without exposing
|
|
98
|
+
their value; those calls stay successful but report `verified: false` and
|
|
99
|
+
`text-not-observable`, so the next screen state should be asserted explicitly.
|
|
88
100
|
|
|
89
101
|
Safe replacement requires the target's Android `input keycombination`
|
|
90
102
|
capability. ADB Ready checks it before touching the screen and returns a
|
|
@@ -96,14 +108,16 @@ appending to an unknown value.
|
|
|
96
108
|
```bash
|
|
97
109
|
adb-ready ui swipe up
|
|
98
110
|
adb-ready ui swipe 900 1200 180 1200
|
|
99
|
-
adb-ready ui scroll
|
|
111
|
+
adb-ready ui scroll down 'id=com.example:id/results'
|
|
100
112
|
adb-ready ui type "person@example.com" --submit
|
|
101
113
|
adb-ready ui press back
|
|
102
114
|
```
|
|
103
115
|
|
|
104
|
-
Direction swipes
|
|
105
|
-
|
|
106
|
-
|
|
116
|
+
Direction swipes describe the physical finger gesture and use screen-relative
|
|
117
|
+
points, so they work across display sizes. `scroll` describes content/viewport
|
|
118
|
+
navigation instead: `scroll down` reveals content below by sending an upward
|
|
119
|
+
finger gesture. It can constrain that navigation to one enabled accessibility
|
|
120
|
+
node whose `scrollable` property is true; without a selector it uses the screen.
|
|
107
121
|
Supported keys are `back`, `home`, `enter`, `menu`, `volume-up`, and
|
|
108
122
|
`volume-down`.
|
|
109
123
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "adb-ready",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Agent-ready Android CLI for reliable ADB sessions, app automation, and verified evidence.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"files": [
|
|
12
12
|
"CHANGELOG.md",
|
|
13
13
|
"COMPATIBILITY.md",
|
|
14
|
-
"dist",
|
|
14
|
+
"dist/cli.js",
|
|
15
15
|
"docs",
|
|
16
16
|
"examples",
|
|
17
17
|
"LICENSE",
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
"ui:check": "bun run scripts/ui-playground.ts --all --non-interactive",
|
|
35
35
|
"test": "bun test",
|
|
36
36
|
"test:coverage": "bun test --coverage && bun run scripts/coverage-check.mjs",
|
|
37
|
+
"test:coverage:diff": "bun run scripts/coverage-diff-check.mjs",
|
|
37
38
|
"test:commands": "bun run build && bun run scripts/command-matrix.mjs",
|
|
38
39
|
"test:package-managers": "bun run build && bun run scripts/package-manager-smoke.mjs",
|
|
39
40
|
"test:integration": "bun test tests/integration",
|
|
@@ -101,6 +102,7 @@
|
|
|
101
102
|
"yarn": "1.22.22"
|
|
102
103
|
},
|
|
103
104
|
"dependencies": {
|
|
105
|
+
"@expo/env": "2.4.3",
|
|
104
106
|
"@modelcontextprotocol/server": "2.0.0",
|
|
105
107
|
"zod": "4.5.4"
|
|
106
108
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"title": "ADB Ready agent tool contract",
|
|
3
3
|
"schemaVersion": 1,
|
|
4
|
-
"packageVersion": "0.
|
|
4
|
+
"packageVersion": "0.4.0",
|
|
5
5
|
"protocolVersion": "2025-11-25",
|
|
6
6
|
"transport": "stdio",
|
|
7
7
|
"tools": [
|
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
},
|
|
129
129
|
{
|
|
130
130
|
"name": "audit_ui",
|
|
131
|
-
"description": "Audit
|
|
131
|
+
"description": "Audit real Android controls for effective labels and stable automation IDs, with bounded findings, confidence, and rule rationale.",
|
|
132
132
|
"inputSchema": {
|
|
133
133
|
"type": "object",
|
|
134
134
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -298,7 +298,7 @@
|
|
|
298
298
|
},
|
|
299
299
|
{
|
|
300
300
|
"name": "clear_ui",
|
|
301
|
-
"description": "Focus one semantic editable field, clear its value, and verify the observable value.",
|
|
301
|
+
"description": "Focus one semantic editable field, clear its value, and verify the observable value or declared hint-only state.",
|
|
302
302
|
"inputSchema": {
|
|
303
303
|
"type": "object",
|
|
304
304
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -2375,7 +2375,7 @@
|
|
|
2375
2375
|
},
|
|
2376
2376
|
{
|
|
2377
2377
|
"name": "scroll_ui",
|
|
2378
|
-
"description": "
|
|
2378
|
+
"description": "Navigate content in a display-relative direction within the screen or one unique semantic scroll container, then compare UI state.",
|
|
2379
2379
|
"inputSchema": {
|
|
2380
2380
|
"type": "object",
|
|
2381
2381
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|