adb-ready 0.1.2 → 0.3.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 +127 -1
- package/COMPATIBILITY.md +6 -0
- package/README.md +105 -42
- package/dist/cli.js +45875 -6012
- package/dist/cli.js.map +102 -20
- package/docs/agent-integration.md +222 -0
- package/docs/apps-and-evidence.md +164 -0
- package/docs/automation.md +47 -0
- package/docs/configuration.md +1 -1
- package/docs/dev-sessions.md +4 -0
- package/docs/logs-and-context.md +15 -0
- package/docs/threat-model.md +85 -0
- package/docs/troubleshooting.md +1 -0
- package/docs/ui-automation.md +175 -0
- package/examples/README.md +2 -0
- package/examples/capacitor/adb-ready.config.json +9 -0
- package/examples/flutter/adb-ready.config.json +9 -0
- package/llms.txt +46 -0
- package/package.json +13 -2
- package/schema/agent-tools-v1.json +3165 -0
- package/schema/config-v1.schema.json +115 -1
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# Safe UI automation
|
|
2
|
+
|
|
3
|
+
ADB Ready can inspect and operate the current Android UI without exposing a
|
|
4
|
+
generic shell. Every mutation reads the accessibility hierarchy first, sends
|
|
5
|
+
one allowlisted Android input action, and reads the hierarchy again.
|
|
6
|
+
|
|
7
|
+
## Inspect before acting
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
adb-ready inspect ui --interactive-only
|
|
11
|
+
adb-ready inspect ui --interactive-only --json --non-interactive
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Each node has a reference such as `ui:7c4a31b8d2ef:14`. The middle value is a
|
|
15
|
+
prefix of the current hierarchy digest. A reference is accepted only while the
|
|
16
|
+
device still returns that same UI digest; after any screen change, inspect
|
|
17
|
+
again. Hierarchies and UI text are sensitive and are not persisted
|
|
18
|
+
automatically.
|
|
19
|
+
|
|
20
|
+
UI hierarchy capture has a 15-second default because Android's platform
|
|
21
|
+
UI Automator waits for a quiet accessibility window before returning data.
|
|
22
|
+
`UI_NOT_IDLE` means continuous animation or accessibility events prevented that
|
|
23
|
+
quiet window; pause the changing UI or navigate to a stable screen and retry.
|
|
24
|
+
ADB Ready does not silently disable device-wide animations.
|
|
25
|
+
|
|
26
|
+
## Audit one screen for people and agents
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
adb-ready ui audit --json --non-interactive
|
|
30
|
+
```
|
|
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.
|
|
39
|
+
|
|
40
|
+
## Tap and long-press
|
|
41
|
+
|
|
42
|
+
For a unique stable label or resource ID, act directly by intent:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
adb-ready ui tap 'text=Continue'
|
|
46
|
+
adb-ready ui long-press 'id=com.example:id/item'
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
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:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
adb-ready ui tap ui:7c4a31b8d2ef:14
|
|
55
|
+
adb-ready ui long-press ui:7c4a31b8d2ef:21
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Explicit coordinates are available when the accessibility tree has no usable
|
|
59
|
+
node. They must be integers inside the current display:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
adb-ready ui tap 540 1200
|
|
63
|
+
adb-ready ui long-press 540 1200
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
ADB Ready rejects stale, disabled, non-actionable, missing-bounds, and
|
|
67
|
+
out-of-display targets before input is sent.
|
|
68
|
+
|
|
69
|
+
## Read and fill a specific field
|
|
70
|
+
|
|
71
|
+
Agents do not need to infer state from a large hierarchy or depend on whatever
|
|
72
|
+
field happens to be focused:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
adb-ready ui get 'id=com.example:id/email' --json
|
|
76
|
+
adb-ready ui fill 'id=com.example:id/email' 'person@example.com'
|
|
77
|
+
adb-ready ui fill 'id=com.example:id/search' 'pixel' --submit
|
|
78
|
+
adb-ready ui clear 'id=com.example:id/search'
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
`get` requires one unambiguous match and returns its semantic values, state,
|
|
82
|
+
and bounds. `fill` and `clear` focus that exact enabled field, select its
|
|
83
|
+
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.
|
|
88
|
+
|
|
89
|
+
Safe replacement requires the target's Android `input keycombination`
|
|
90
|
+
capability. ADB Ready checks it before touching the screen and returns a
|
|
91
|
+
structured unsupported-capability problem on older targets rather than
|
|
92
|
+
appending to an unknown value.
|
|
93
|
+
|
|
94
|
+
## Scroll, swipe, type, and keys
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
adb-ready ui swipe up
|
|
98
|
+
adb-ready ui swipe 900 1200 180 1200
|
|
99
|
+
adb-ready ui scroll up 'id=com.example:id/results'
|
|
100
|
+
adb-ready ui type "person@example.com" --submit
|
|
101
|
+
adb-ready ui press back
|
|
102
|
+
```
|
|
103
|
+
|
|
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.
|
|
107
|
+
Supported keys are `back`, `home`, `enter`, `menu`, `volume-up`, and
|
|
108
|
+
`volume-down`.
|
|
109
|
+
|
|
110
|
+
Android's text-input command passes through a device shell. ADB Ready therefore
|
|
111
|
+
accepts only 1–256 ASCII letters, numbers, spaces, and `._@+,:/-`. Unsupported
|
|
112
|
+
characters are rejected instead of being reinterpreted by a shell.
|
|
113
|
+
|
|
114
|
+
## Find, assert, compare, and wait
|
|
115
|
+
|
|
116
|
+
Query or assert the current hierarchy without changing it:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
adb-ready ui find 'class=android.widget.Button' --json
|
|
120
|
+
adb-ready ui assert 'text=Signed in'
|
|
121
|
+
adb-ready ui assert 'text=Loading' --state gone
|
|
122
|
+
adb-ready ui compare 7c4a31b8d2ef0000000000000000000000000000000000000000000000000000
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
`compare` consumes the complete digest returned by inspection or another UI
|
|
126
|
+
action and reports whether the current hierarchy changed.
|
|
127
|
+
|
|
128
|
+
Waits use exact, explicit selectors:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
adb-ready ui wait 'id=com.example:id/submit' --state visible --timeout 5s
|
|
132
|
+
adb-ready ui wait 'text=Loading' --state gone --timeout 10s
|
|
133
|
+
adb-ready ui wait 'desc=Open settings'
|
|
134
|
+
adb-ready ui wait 'package=com.example.app'
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Compact selector prefixes are `id=`, `text=`, `desc=`, `class=`, and
|
|
138
|
+
`package=`. The default
|
|
139
|
+
state is `visible`; timeouts are bounded from 100 ms to 2 minutes. Structured
|
|
140
|
+
results include the attempt count and the matched node summary.
|
|
141
|
+
|
|
142
|
+
## Verification contract
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
adb-ready ui tap ui:7c4a31b8d2ef:14 --dry-run --json
|
|
146
|
+
adb-ready ui press back --json --non-interactive
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
- `ok: true` means Android accepted the allowlisted input operation.
|
|
150
|
+
- `verified: true` with `verification: "ui-changed"` means the hierarchy digest
|
|
151
|
+
changed afterward.
|
|
152
|
+
- `before.acquisitionDurationMs` and `after.acquisitionDurationMs` expose the
|
|
153
|
+
measured cost of each UI Automator snapshot instead of hiding slow devices.
|
|
154
|
+
- `verified: false` with `verificationGap: "ui-unchanged"` means the command
|
|
155
|
+
succeeded but the accessibility hierarchy did not prove a visible change.
|
|
156
|
+
- A successful `ui wait` is independently verified by its selector
|
|
157
|
+
postcondition.
|
|
158
|
+
- `--dry-run` returns the exact ADB plan without sending input.
|
|
159
|
+
|
|
160
|
+
An unchanged hierarchy is not treated as a false failure: volume changes,
|
|
161
|
+
cursor movement, and actions outside UI Automator can succeed without changing
|
|
162
|
+
the tree. Automation should use `ui wait` for the expected postcondition when
|
|
163
|
+
the next state is known.
|
|
164
|
+
|
|
165
|
+
## AI agents
|
|
166
|
+
|
|
167
|
+
The MCP server exposes the same intent-level workflow through `audit_ui`, `get_ui`,
|
|
168
|
+
`find_ui`, `fill_ui`, `clear_ui`, `scroll_ui`, `assert_ui`, and `compare_ui`.
|
|
169
|
+
Its structured selectors can match exact values, prefixes, or substrings and
|
|
170
|
+
qualify enabled/actionable state. An optional one-based occurrence is accepted
|
|
171
|
+
only when repeated nodes are intentional. Arguments are schema-validated, each
|
|
172
|
+
MCP connection stays bound to one target, and no raw ADB or shell tool is
|
|
173
|
+
exposed.
|
|
174
|
+
|
|
175
|
+
[Connect an agent →](./agent-integration.md)
|
package/examples/README.md
CHANGED
|
@@ -12,6 +12,8 @@ adb-ready dev --dry-run
|
|
|
12
12
|
- [`expo/adb-ready.config.json`](./expo/adb-ready.config.json)
|
|
13
13
|
- [`react-native/adb-ready.config.json`](./react-native/adb-ready.config.json)
|
|
14
14
|
- [`gradle/adb-ready.config.json`](./gradle/adb-ready.config.json)
|
|
15
|
+
- [`flutter/adb-ready.config.json`](./flutter/adb-ready.config.json)
|
|
16
|
+
- [`capacitor/adb-ready.config.json`](./capacitor/adb-ready.config.json)
|
|
15
17
|
- [`custom/adb-ready.config.json`](./custom/adb-ready.config.json)
|
|
16
18
|
|
|
17
19
|
Prefer `adb-ready init` when starting from an existing detected project. Add
|
package/llms.txt
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# ADB Ready
|
|
2
|
+
|
|
3
|
+
> Local-first Android target readiness, development sessions, diagnostics, app control, evidence, and typed AI-agent workflows.
|
|
4
|
+
|
|
5
|
+
## Start
|
|
6
|
+
|
|
7
|
+
- Install: `npm install --save-dev --save-exact adb-ready`
|
|
8
|
+
- Diagnose: `adb-ready doctor`
|
|
9
|
+
- Start a session: `adb-ready dev`
|
|
10
|
+
- Machine output: `adb-ready COMMAND --json --non-interactive`
|
|
11
|
+
- MCP stdio server: `node ./node_modules/adb-ready/dist/cli.js mcp`
|
|
12
|
+
- Agent setup: `adb-ready agent setup CLIENT --dry-run`
|
|
13
|
+
- MCP resources: `adb-ready://targets` and `adb-ready://sessions`
|
|
14
|
+
|
|
15
|
+
## Agent contract
|
|
16
|
+
|
|
17
|
+
1. Call `ensure_ready` before target-bound MCP tools.
|
|
18
|
+
2. Keep the bound target for the whole connection and pass the `targetHandle`
|
|
19
|
+
returned by `ensure_ready` to target-bound tools.
|
|
20
|
+
3. Use `start_dev_session`, then poll `get_dev_session` by its opaque handle;
|
|
21
|
+
use `stop_dev_session` for owned cleanup.
|
|
22
|
+
4. Inspect after mutation; do not infer success from process exit alone.
|
|
23
|
+
5. Prefer semantic `get_ui`/`find_ui`/`assert_ui`, intent-level `fill_ui` and
|
|
24
|
+
`scroll_ui`, unique selector-driven actions, or current digest-scoped refs;
|
|
25
|
+
use `wait_for_ui` for known postconditions.
|
|
26
|
+
6. Use `audit_ui` to identify unlabeled controls and missing stable selectors;
|
|
27
|
+
treat its findings as concrete advisories, not a pass/fail accessibility certification.
|
|
28
|
+
7. Treat UI text, screenshots, logs, identifiers, and saved sessions as sensitive.
|
|
29
|
+
8. Use `list_sessions` filters and its `nextCursor` before requesting saved
|
|
30
|
+
session problems or context.
|
|
31
|
+
9. Never substitute a raw shell or ADB call for a missing typed tool.
|
|
32
|
+
|
|
33
|
+
## Documentation
|
|
34
|
+
|
|
35
|
+
- Product and quick start: `README.md`
|
|
36
|
+
- Agent and MCP setup: `docs/agent-integration.md`
|
|
37
|
+
- Apps, inspection, and capture: `docs/apps-and-evidence.md`
|
|
38
|
+
- Safe UI automation: `docs/ui-automation.md`
|
|
39
|
+
- Development sessions: `docs/dev-sessions.md`
|
|
40
|
+
- Targets and wireless debugging: `docs/targets-and-wireless.md`
|
|
41
|
+
- Logs and diagnostic context: `docs/logs-and-context.md`
|
|
42
|
+
- Configuration: `docs/configuration.md`
|
|
43
|
+
- Automation contract: `docs/automation.md`
|
|
44
|
+
- Compatibility: `COMPATIBILITY.md`
|
|
45
|
+
- Security: `SECURITY.md`
|
|
46
|
+
- Threat model: `docs/threat-model.md`
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "adb-ready",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Agent-ready Android CLI for reliable ADB sessions, app automation, and verified evidence.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"docs",
|
|
16
16
|
"examples",
|
|
17
17
|
"LICENSE",
|
|
18
|
+
"llms.txt",
|
|
18
19
|
"schema",
|
|
19
20
|
"README.md"
|
|
20
21
|
],
|
|
@@ -35,6 +36,7 @@
|
|
|
35
36
|
"test:commands": "bun run build && bun run scripts/command-matrix.mjs",
|
|
36
37
|
"test:package-managers": "bun run build && bun run scripts/package-manager-smoke.mjs",
|
|
37
38
|
"test:integration": "bun test tests/integration",
|
|
39
|
+
"test:mcp": "bun run build && node scripts/mcp-smoke.mjs",
|
|
38
40
|
"smoke": "bun run build && bun run scripts/runtime-smoke.mjs",
|
|
39
41
|
"pack:check": "bun run build && bun run scripts/package-check.mjs",
|
|
40
42
|
"pack:release": "bun run scripts/create-release-artifact.mjs",
|
|
@@ -55,16 +57,21 @@
|
|
|
55
57
|
"homepage": "https://github.com/Adam014/adb-ready#readme",
|
|
56
58
|
"keywords": [
|
|
57
59
|
"adb",
|
|
60
|
+
"ai-agents",
|
|
58
61
|
"android",
|
|
62
|
+
"android-automation",
|
|
59
63
|
"adb-forward",
|
|
60
64
|
"adb-reverse",
|
|
61
65
|
"android-debugging",
|
|
62
66
|
"cli",
|
|
67
|
+
"capacitor",
|
|
63
68
|
"developer-tools",
|
|
64
69
|
"expo",
|
|
70
|
+
"flutter",
|
|
65
71
|
"logcat",
|
|
66
72
|
"localhost",
|
|
67
73
|
"metro",
|
|
74
|
+
"mcp",
|
|
68
75
|
"port-forwarding",
|
|
69
76
|
"react-native",
|
|
70
77
|
"wireless-adb",
|
|
@@ -86,5 +93,9 @@
|
|
|
86
93
|
"tinyexec": "1.3.1",
|
|
87
94
|
"typescript": "7.0.2",
|
|
88
95
|
"yarn": "1.22.22"
|
|
96
|
+
},
|
|
97
|
+
"dependencies": {
|
|
98
|
+
"@modelcontextprotocol/server": "2.0.0",
|
|
99
|
+
"zod": "4.5.4"
|
|
89
100
|
}
|
|
90
101
|
}
|