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/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 pass.
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
 
@@ -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 |
@@ -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 with `--android`, otherwise Expo CLI | `8081` |
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 --android
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
@@ -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
@@ -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
@@ -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
@@ -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 actionable nodes that have no visible text or
33
- content description, and nodes that have no resource ID for a stable selector.
34
- It returns the exact current references and attributes, plus bounded totals;
35
- it deliberately does not invent a subjective quality score. A missing label is
36
- an accessibility warning. A missing stable ID is an automation advisory—use a
37
- resource ID or expose a Compose test tag through `testTagsAsResourceId` where
38
- appropriate.
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. Prefer a current reference when the exact observed
51
- snapshot matters:
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. Password and
85
- custom fields can accept input without exposing their value; those calls stay
86
- successful but report `verified: false` and `text-not-observable`, so the next
87
- screen state should be asserted explicitly.
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 up 'id=com.example:id/results'
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 use screen-relative points, so they work across display
105
- sizes. `scroll` can constrain that gesture to one enabled accessibility node
106
- whose `scrollable` property is true; without a selector it uses the screen.
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.4",
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.3.4",
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 the current screen for enabled actionable nodes without human-readable labels or stable automation IDs.",
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": "Scroll the screen or one unique semantic scroll container in a display-relative direction, then compare UI state.",
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",
@@ -203,6 +203,7 @@
203
203
  ]
204
204
  }
205
205
  },
206
+ "autoReverseLocalhost": { "type": "boolean" },
206
207
  "logs": { "type": "boolean" },
207
208
  "cleanupPorts": { "type": "boolean" },
208
209
  "watch": { "type": "boolean" },