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,222 @@
|
|
|
1
|
+
# AI agent integration
|
|
2
|
+
|
|
3
|
+
ADB Ready exposes Android workflows to local AI agents through a typed Model
|
|
4
|
+
Context Protocol (MCP) server. The agent works with the same deterministic
|
|
5
|
+
target, application identity, verification rules, and structured problems as
|
|
6
|
+
the CLI—without receiving a generic shell or raw ADB command.
|
|
7
|
+
|
|
8
|
+
## Install and verify
|
|
9
|
+
|
|
10
|
+
Pin ADB Ready in the Android project the agent will work on:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install --save-dev --save-exact adb-ready
|
|
14
|
+
node ./node_modules/adb-ready/dist/cli.js doctor
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The MCP server uses standard input/output and must be started from the project
|
|
18
|
+
root:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
node ./node_modules/adb-ready/dist/cli.js mcp
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Do not run that command by hand for normal use; the MCP client starts and stops
|
|
25
|
+
it. ADB Ready does not open an MCP network listener.
|
|
26
|
+
|
|
27
|
+
## Connect an agent
|
|
28
|
+
|
|
29
|
+
Preview the exact project change first, then apply it:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
adb-ready agent setup codex --dry-run
|
|
33
|
+
adb-ready agent setup codex
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Replace `codex` with `claude-code`, `cursor`, or `vscode`. Existing unrelated
|
|
37
|
+
configuration is preserved. An existing `adb-ready` entry with different
|
|
38
|
+
settings is reported as a conflict and is never replaced automatically.
|
|
39
|
+
|
|
40
|
+
### Codex
|
|
41
|
+
|
|
42
|
+
Create a project-scoped `.codex/config.toml`:
|
|
43
|
+
|
|
44
|
+
```toml
|
|
45
|
+
[mcp_servers.adb_ready]
|
|
46
|
+
command = "node"
|
|
47
|
+
args = ["./node_modules/adb-ready/dist/cli.js", "mcp"]
|
|
48
|
+
default_tools_approval_mode = "writes"
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Codex CLI, the Codex IDE extension, and the ChatGPT desktop app share Codex MCP
|
|
52
|
+
configuration. See the [official Codex MCP guide](https://learn.chatgpt.com/docs/extend/mcp).
|
|
53
|
+
|
|
54
|
+
### Claude Code
|
|
55
|
+
|
|
56
|
+
Run this from the project root:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
claude mcp add --scope project adb-ready -- node ./node_modules/adb-ready/dist/cli.js mcp
|
|
60
|
+
claude mcp get adb-ready
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Claude Code stores project-scoped servers in `.mcp.json` and asks users to
|
|
64
|
+
approve them. See the [official Claude Code MCP guide](https://docs.anthropic.com/en/docs/claude-code/mcp).
|
|
65
|
+
|
|
66
|
+
### Cursor
|
|
67
|
+
|
|
68
|
+
Create `.cursor/mcp.json`:
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"mcpServers": {
|
|
73
|
+
"adb-ready": {
|
|
74
|
+
"command": "node",
|
|
75
|
+
"args": ["./node_modules/adb-ready/dist/cli.js", "mcp"]
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
See the [official Cursor MCP guide](https://docs.cursor.com/context/model-context-protocol).
|
|
82
|
+
|
|
83
|
+
### VS Code and GitHub Copilot
|
|
84
|
+
|
|
85
|
+
Create `.vscode/mcp.json`:
|
|
86
|
+
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"servers": {
|
|
90
|
+
"adb-ready": {
|
|
91
|
+
"type": "stdio",
|
|
92
|
+
"command": "node",
|
|
93
|
+
"args": ["${workspaceFolder}/node_modules/adb-ready/dist/cli.js", "mcp"]
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
See the [official VS Code MCP guide](https://code.visualstudio.com/docs/agent-customization/mcp-servers).
|
|
100
|
+
|
|
101
|
+
### Windsurf
|
|
102
|
+
|
|
103
|
+
Windsurf currently keeps MCP configuration in a user-scoped file. Generate a
|
|
104
|
+
project-bound snippet and merge it through Windsurf MCP settings:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
adb-ready agent setup windsurf
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
ADB Ready deliberately does not edit this global file. The generated entry
|
|
111
|
+
uses an absolute local package path and `ADB_READY_MCP_PROJECT_ROOT` so Cascade
|
|
112
|
+
still resolves the intended project. See the [official Windsurf MCP guide](https://docs.windsurf.com/windsurf/cascade/mcp).
|
|
113
|
+
|
|
114
|
+
### Other MCP clients
|
|
115
|
+
|
|
116
|
+
Generate a standard `mcpServers` entry:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
adb-ready agent setup generic
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Merge the result at the location required by the client and ensure the server
|
|
123
|
+
starts in the Android project root.
|
|
124
|
+
|
|
125
|
+
## Recommended agent workflow
|
|
126
|
+
|
|
127
|
+
Ask the agent to follow this sequence:
|
|
128
|
+
|
|
129
|
+
1. Call `doctor` when host or ADB health is unknown.
|
|
130
|
+
2. Call `ensure_ready`; provide an exact device serial, configured alias, or
|
|
131
|
+
transport ID when more than one ready target exists.
|
|
132
|
+
3. Start the configured stack with `start_dev_session` when it is not already
|
|
133
|
+
running; retain its task handle and poll `get_dev_session` without holding a
|
|
134
|
+
tool call open.
|
|
135
|
+
4. Resolve the project app with `resolve_app`.
|
|
136
|
+
5. Use `inspect_app` or `inspect_ui` for bounded current evidence.
|
|
137
|
+
6. Perform one typed action, then inspect again instead of assuming success.
|
|
138
|
+
7. Use `get_session_problems` or `compile_debug_context` for an existing
|
|
139
|
+
development session.
|
|
140
|
+
|
|
141
|
+
The first successful `ensure_ready` binds one target to that MCP connection and
|
|
142
|
+
returns a `targetHandle`. Pass that handle to later target-bound calls when the
|
|
143
|
+
client supports workflow state. A stale or cross-connection handle is rejected,
|
|
144
|
+
and later tools cannot silently switch targets. When no ready target exists,
|
|
145
|
+
`ensure_ready` may reconnect an explicit network endpoint or the single
|
|
146
|
+
unambiguous paired service; it never guesses among multiple devices.
|
|
147
|
+
|
|
148
|
+
Tool calls within one MCP connection are executed in submission order. This
|
|
149
|
+
prevents parallel agent requests from interleaving target binding, UI snapshots,
|
|
150
|
+
or device mutations. Separate MCP connections remain independent.
|
|
151
|
+
|
|
152
|
+
## Tool surface
|
|
153
|
+
|
|
154
|
+
| Capability | MCP tools |
|
|
155
|
+
| --- | --- |
|
|
156
|
+
| Host and target readiness | `doctor`, `list_targets`, `ensure_ready` |
|
|
157
|
+
| Durable development lifecycle | `start_dev_session`, `get_dev_session`, `stop_dev_session` |
|
|
158
|
+
| App identity and lifecycle | `resolve_app`, `install_app`, `launch_app`, `restart_app`, `open_url` |
|
|
159
|
+
| Current evidence | `inspect_app`, `inspect_ui`, `capture_screenshot` |
|
|
160
|
+
| Safe UI queries and actions | `audit_ui`, `get_ui`, `find_ui`, `assert_ui`, `compare_ui`, `tap_ui`, `long_press_ui`, `scroll_ui`, `swipe_ui`, `fill_ui`, `clear_ui`, `type_text_ui`, `press_key_ui`, `wait_for_ui` |
|
|
161
|
+
| Saved diagnostics | `list_sessions`, `get_session_problems`, `compile_debug_context` |
|
|
162
|
+
|
|
163
|
+
MCP resources keep larger read-only context outside tool calls:
|
|
164
|
+
|
|
165
|
+
| Resource | Content |
|
|
166
|
+
| --- | --- |
|
|
167
|
+
| `adb-ready://targets` | current target inventory and this connection's bound target |
|
|
168
|
+
| `adb-ready://sessions` | bounded saved-session manifests |
|
|
169
|
+
| `adb-ready://sessions/{sessionId}` | one session manifest |
|
|
170
|
+
| `adb-ready://sessions/{sessionId}/events/{offset}/{limit}` | a page of up to 200 redacted events |
|
|
171
|
+
| `adb-ready://sessions/{sessionId}/context` | a bounded redacted Markdown context document |
|
|
172
|
+
|
|
173
|
+
Every tool advertises an output schema and returns the same versioned result
|
|
174
|
+
envelope used by CLI JSON output. Screenshot capture additionally returns MCP
|
|
175
|
+
`image` content so a vision-capable agent can inspect the pixels directly; the
|
|
176
|
+
verified project-local PNG remains the evidence source of record.
|
|
177
|
+
|
|
178
|
+
The npm package also ships `schema/agent-tools-v1.json`, generated from the
|
|
179
|
+
server's real `tools/list` response during every build. Integrations can inspect
|
|
180
|
+
version-matched input and output schemas plus safety annotations without
|
|
181
|
+
starting ADB.
|
|
182
|
+
|
|
183
|
+
`list_sessions` is project-scoped by default and supports status, preset,
|
|
184
|
+
recency, and result-count filters. When more matches remain, pass its opaque
|
|
185
|
+
`nextCursor` back as `cursor`; an expired cursor fails explicitly instead of
|
|
186
|
+
silently restarting the list.
|
|
187
|
+
|
|
188
|
+
## Safety boundary
|
|
189
|
+
|
|
190
|
+
- There is no arbitrary command, shell, or raw ADB tool.
|
|
191
|
+
- MCP tool arguments are schema-validated before execution.
|
|
192
|
+
- Local APK installation accepts only a real path inside the project.
|
|
193
|
+
- Screenshots require an explicit tool call and are stored as project files.
|
|
194
|
+
- UI hierarchy and app inspection are marked sensitive and remain bounded.
|
|
195
|
+
- UI references are checked against a fresh hierarchy digest before mutation;
|
|
196
|
+
stale references are rejected.
|
|
197
|
+
- Data clearing and uninstall are intentionally absent from the agent surface.
|
|
198
|
+
- Tool annotations help clients request approval, but ADB Ready enforces its
|
|
199
|
+
own target, path, and destructive-action rules.
|
|
200
|
+
- Durable development handles are random, project-scoped, heartbeat-checked,
|
|
201
|
+
and can signal only the owned managed process recorded for that handle.
|
|
202
|
+
- Nothing is uploaded by ADB Ready. The selected AI client controls what tool
|
|
203
|
+
results it sends to its model provider.
|
|
204
|
+
|
|
205
|
+
Review the client configuration before approving it and keep write-capable
|
|
206
|
+
tools behind the client's approval policy. See [Security](../SECURITY.md) for
|
|
207
|
+
the complete trust model.
|
|
208
|
+
|
|
209
|
+
## Runtime alternatives
|
|
210
|
+
|
|
211
|
+
The published bundle is smoke-tested as an MCP stdio server under Node.js, Bun,
|
|
212
|
+
and Deno against the legacy 2025-11-25 and modern 2026-07-28 protocol eras.
|
|
213
|
+
Replace the command and arguments when Node.js is not your chosen runtime:
|
|
214
|
+
|
|
215
|
+
```text
|
|
216
|
+
Bun: bun ./node_modules/adb-ready/dist/cli.js mcp
|
|
217
|
+
Deno: deno run -A ./node_modules/adb-ready/dist/cli.js mcp
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
Deno's `-A` grants the local server the filesystem, process, environment, and
|
|
221
|
+
network access required to find project metadata and invoke ADB. Use the
|
|
222
|
+
client's sandbox controls when a narrower host boundary is required.
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# Apps and evidence
|
|
2
|
+
|
|
3
|
+
ADB Ready resolves project identity locally when possible, then binds
|
|
4
|
+
target-based app operations and evidence to one deterministic Android target.
|
|
5
|
+
It reports success only after the requested postcondition is observed.
|
|
6
|
+
|
|
7
|
+
## App identity
|
|
8
|
+
|
|
9
|
+
Inspect the project app without hard-coding its package name:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
adb-ready app resolve
|
|
13
|
+
adb-ready app info
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Resolution prefers an explicit `APP_ID`, then project configuration and
|
|
17
|
+
detected Android project metadata. Every resolved result includes provenance.
|
|
18
|
+
If equally valid candidates remain, ADB Ready asks for an explicit choice
|
|
19
|
+
instead of selecting the first package.
|
|
20
|
+
|
|
21
|
+
Explicit, configured, Gradle, Expo, and manifest identity can be resolved with
|
|
22
|
+
no running emulator, connected phone, or ADB binary. Only the final
|
|
23
|
+
installed-package fallback requires a target.
|
|
24
|
+
|
|
25
|
+
Set a stable project value when detection is not sufficient:
|
|
26
|
+
|
|
27
|
+
```json
|
|
28
|
+
{
|
|
29
|
+
"app": {
|
|
30
|
+
"android": {
|
|
31
|
+
"package": "com.example.app"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
List installed packages when investigating a target:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
adb-ready apps list
|
|
41
|
+
adb-ready apps list --system --filter google
|
|
42
|
+
adb-ready apps list --all --json --non-interactive
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
User packages are the default. Enumeration and machine output are bounded.
|
|
46
|
+
|
|
47
|
+
## App lifecycle
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
adb-ready app install ./android/app/build/outputs/apk/debug/app-debug.apk --replace
|
|
51
|
+
adb-ready app install ./splits/base.apk ./splits/config.arm64_v8a.apk ./splits/config.en.apk
|
|
52
|
+
adb-ready app launch
|
|
53
|
+
adb-ready app restart
|
|
54
|
+
adb-ready app stop
|
|
55
|
+
adb-ready open 'myapp://orders/42' --package com.example.app
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Pass all files from one split APK set together; ADB Ready uses Android's
|
|
59
|
+
`install-multiple` operation and verifies the installed package afterward.
|
|
60
|
+
Android App Bundles (`.aab`) and APK Set archives (`.apks`) are not directly
|
|
61
|
+
installable. Generate device-specific APKs with the Android build tool that
|
|
62
|
+
created them, then pass those `.apk` files explicitly.
|
|
63
|
+
|
|
64
|
+
- Installation accepts one ordinary APK or an explicit complete split APK set.
|
|
65
|
+
`.apks`, `.aab`, and implicit downloads are not accepted yet.
|
|
66
|
+
- Install, launch, stop, restart, and explicit deep-link handlers are checked
|
|
67
|
+
after ADB accepts the request.
|
|
68
|
+
- `restart` is a verified stop followed by a verified launch.
|
|
69
|
+
- Add `--activity .MainActivity` only when Android cannot resolve a launchable
|
|
70
|
+
activity.
|
|
71
|
+
- Add `--grant-runtime-permissions` to an install only when that behavior is
|
|
72
|
+
intended.
|
|
73
|
+
|
|
74
|
+
Preview exact target-scoped ADB operations without changing the device:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
adb-ready app restart --dry-run --json
|
|
78
|
+
adb-ready app clear-data --dry-run
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
`clear-data` and `uninstall` are destructive. Interactive use requires a
|
|
82
|
+
confirmation; automation must pass `--allow-destructive`. A dry run never asks
|
|
83
|
+
for destructive approval because it performs no mutation.
|
|
84
|
+
|
|
85
|
+
## Structured inspection
|
|
86
|
+
|
|
87
|
+
Build a compact snapshot of the project app, foreground state, and a small
|
|
88
|
+
classified log window:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
adb-ready inspect app
|
|
92
|
+
adb-ready inspect app com.example.app --json --non-interactive
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Screenshots are deliberately not captured by this read-only command. The
|
|
96
|
+
result reports `adb-ready capture screenshot` as the explicit next action so
|
|
97
|
+
sensitive pixels never enter evidence or AI context implicitly.
|
|
98
|
+
|
|
99
|
+
Read the current Android accessibility hierarchy:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
adb-ready inspect ui --interactive-only
|
|
103
|
+
adb-ready inspect ui --max-depth 20 --json --non-interactive
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The snapshot is capped at 2,000 nodes and includes a SHA-256 digest. Each node
|
|
107
|
+
reference contains a prefix of that digest, so callers can distinguish stale
|
|
108
|
+
references after the UI changes. `--interactive-only` keeps enabled actionable
|
|
109
|
+
nodes; `--max-depth` accepts 1–100. Secure windows and missing accessibility
|
|
110
|
+
data are reported as unavailable rather than as an empty successful snapshot.
|
|
111
|
+
|
|
112
|
+
UI text and hierarchy data are marked `sensitive: true`. They are returned only
|
|
113
|
+
by the explicit inspect command and are never included in diagnostic AI context
|
|
114
|
+
automatically.
|
|
115
|
+
|
|
116
|
+
## Evidence capture
|
|
117
|
+
|
|
118
|
+
Capture a PNG directly from the selected target:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
adb-ready capture screenshot
|
|
122
|
+
adb-ready capture screenshot --out artifacts/login.png
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Capture a bounded MP4 recording:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
adb-ready capture screen-record --duration 15s
|
|
129
|
+
adb-ready capture screen-record --duration 30s --out artifacts/repro.mp4
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Evidence paths are relative to the current project. A capture never follows a
|
|
133
|
+
symlink outside that root and never replaces an existing file unless `--force`
|
|
134
|
+
is explicit. Files are written through a private temporary path and published
|
|
135
|
+
only after validation.
|
|
136
|
+
|
|
137
|
+
Some multi-display Android builds, including foldables, emit a short textual
|
|
138
|
+
warning before the screenshot bytes. ADB Ready removes only a bounded text
|
|
139
|
+
preamble and still requires a valid PNG signature before publishing the file.
|
|
140
|
+
|
|
141
|
+
The result contains:
|
|
142
|
+
|
|
143
|
+
- a project-relative path;
|
|
144
|
+
- media type and byte size;
|
|
145
|
+
- SHA-256 digest;
|
|
146
|
+
- selected target and capture-command provenance.
|
|
147
|
+
|
|
148
|
+
Binary data is stored as a file rather than embedded into JSON or AI context.
|
|
149
|
+
Screenshots and recordings can contain private information; ADB Ready does not
|
|
150
|
+
upload or implicitly attach them to diagnostic context.
|
|
151
|
+
|
|
152
|
+
## Target selection and automation
|
|
153
|
+
|
|
154
|
+
All commands accept the standard target selectors:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
adb-ready app info --device SERIAL
|
|
158
|
+
adb-ready capture screenshot --transport-id ID
|
|
159
|
+
adb-ready app restart --last
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Use `--json --non-interactive` for one versioned result on `stdout`, or
|
|
163
|
+
`--format ndjson` for structured progress plus the final result. Human progress
|
|
164
|
+
and errors remain on `stderr`.
|
package/docs/automation.md
CHANGED
|
@@ -19,6 +19,14 @@ adb-ready logs --format ndjson --non-interactive
|
|
|
19
19
|
| `ndjson` | one versioned event per line, followed by the command result where applicable; saved timelines end with an event-count summary instead of duplicating the full event array |
|
|
20
20
|
| `markdown` | bounded diagnostic context; only valid for `context` |
|
|
21
21
|
|
|
22
|
+
Calling the root with `--json` returns a small product/capability overview. It
|
|
23
|
+
does not probe ADB or load project configuration, which makes it safe for an
|
|
24
|
+
agent or integration to identify the installed CLI first:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
adb-ready --json
|
|
28
|
+
```
|
|
29
|
+
|
|
22
30
|
Machine data is written to `stdout`. Human progress and diagnostics are written
|
|
23
31
|
to `stderr`. `--quiet` hides successful human output without hiding failures.
|
|
24
32
|
|
|
@@ -43,6 +51,12 @@ JSON commands return this top-level shape:
|
|
|
43
51
|
Consumers must ignore unknown additive fields and event types within the same
|
|
44
52
|
schema version.
|
|
45
53
|
|
|
54
|
+
The npm package includes two versioned public artifacts:
|
|
55
|
+
|
|
56
|
+
- `schema/config-v1.schema.json` validates project configuration; and
|
|
57
|
+
- `schema/agent-tools-v1.json` catalogs every MCP tool's generated input and
|
|
58
|
+
output schemas plus safety annotations for the matching package version.
|
|
59
|
+
|
|
46
60
|
## Event envelope
|
|
47
61
|
|
|
48
62
|
NDJSON events include:
|
|
@@ -111,6 +125,39 @@ adb-ready dev --port 8081 --dry-run --json
|
|
|
111
125
|
Plan steps declare their risk. A dry run performs no pairing, connection,
|
|
112
126
|
mapping, hook, or child-process mutation.
|
|
113
127
|
|
|
128
|
+
## Run one bounded verification
|
|
129
|
+
|
|
130
|
+
Use `run` when CI or an agent must prove a workflow and then exit instead of
|
|
131
|
+
leaving a development server open:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
adb-ready run --preset expo --run-timeout 10m -- \
|
|
135
|
+
maestro '--device={target.serial}' test .maestro/smoke.yaml
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
ADB Ready selects and exclusively leases one target, prepares the configured
|
|
139
|
+
ports and development command, waits for every readiness assertion, runs the
|
|
140
|
+
exact command after `--`, and cleans only the resources it created. It never
|
|
141
|
+
retries a failed product assertion as if it were an infrastructure failure.
|
|
142
|
+
|
|
143
|
+
The literal `{target.serial}` inside a verification argument is replaced only
|
|
144
|
+
after ADB Ready selects and leases the target. The child also receives the
|
|
145
|
+
same value as `ANDROID_SERIAL` and `ADB_READY_TARGET_SERIAL`. This keeps tools
|
|
146
|
+
such as Maestro pinned explicitly without invoking a shell; tools that already
|
|
147
|
+
honor `ANDROID_SERIAL`, including common Gradle/ADB workflows, need no placeholder.
|
|
148
|
+
|
|
149
|
+
Every executed run prints the path to a project-local evidence directory under
|
|
150
|
+
`.adb-ready/artifacts/`. Its manifest references the structured result,
|
|
151
|
+
timeline, problems, focused logcat, bounded AI context, JUnit XML, and a concise
|
|
152
|
+
GitHub Actions summary. The evidence remains available when readiness or the
|
|
153
|
+
verification command fails.
|
|
154
|
+
|
|
155
|
+
Preview the complete project plan before a device is allocated:
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
adb-ready run --preset expo --dry-run --json -- npm run test:e2e
|
|
159
|
+
```
|
|
160
|
+
|
|
114
161
|
## CI example
|
|
115
162
|
|
|
116
163
|
```yaml
|
package/docs/configuration.md
CHANGED
|
@@ -65,7 +65,7 @@ existing file unless `--force` is explicit. Use `--dry-run` first.
|
|
|
65
65
|
|
|
66
66
|
| Field | Values or shape |
|
|
67
67
|
| --- | --- |
|
|
68
|
-
| `preset` | `expo`, `react-native`, `gradle`, or `custom` |
|
|
68
|
+
| `preset` | `expo`, `react-native`, `flutter`, `capacitor`, `gradle`, or `custom` |
|
|
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 |
|
package/docs/dev-sessions.md
CHANGED
|
@@ -10,6 +10,8 @@ local diagnostic record.
|
|
|
10
10
|
| --- | --- | --- | --- |
|
|
11
11
|
| Expo | `expo` dependency | project `start` script with `--android`, otherwise Expo CLI | `8081` |
|
|
12
12
|
| React Native | `react-native` dependency | project `android` script, otherwise React Native CLI | `8081` |
|
|
13
|
+
| Flutter | `pubspec.yaml` | `flutter run -d <selected-target>` | none |
|
|
14
|
+
| Capacitor | `@capacitor/android` or `@capacitor/core` dependency | Capacitor CLI for the selected target | none |
|
|
13
15
|
| Gradle | wrapper or Gradle build file | wrapper `installDebug` | none |
|
|
14
16
|
| Custom | explicit config or `--` | exact executable and argument array | none |
|
|
15
17
|
|
|
@@ -18,6 +20,8 @@ Select a preset when detection is intentionally unavailable or ambiguous:
|
|
|
18
20
|
```bash
|
|
19
21
|
adb-ready dev --preset expo
|
|
20
22
|
adb-ready dev --preset react-native --package-manager pnpm
|
|
23
|
+
adb-ready dev --preset flutter
|
|
24
|
+
adb-ready dev --preset capacitor
|
|
21
25
|
adb-ready dev --preset gradle --device emulator-5554
|
|
22
26
|
```
|
|
23
27
|
|
package/docs/logs-and-context.md
CHANGED
|
@@ -57,6 +57,18 @@ adb-ready sessions events SESSION_ID --format ndjson
|
|
|
57
57
|
adb-ready problems SESSION_ID
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
+
Find the useful run without scanning a long global list:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
adb-ready sessions list --status failed --since 24h --limit 5
|
|
64
|
+
adb-ready sessions list --preset expo
|
|
65
|
+
adb-ready sessions list --all-projects
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
History is scoped to the current project by default. Status, time, preset, and
|
|
69
|
+
count filters apply before output; `--all-projects` is an explicit escape hatch
|
|
70
|
+
for a machine-wide audit.
|
|
71
|
+
|
|
60
72
|
When the ID is omitted, the latest saved session is selected. Default retention
|
|
61
73
|
keeps at most 30 finalized sessions, 14 days, and 20 MiB. Active sessions are
|
|
62
74
|
not pruned as finalized history.
|
|
@@ -88,6 +100,9 @@ Available filters are `problems`, `recovery`, `logs`, `child`, `state`, `target`
|
|
|
88
100
|
and `ports`. The compiler prioritizes structured problems, failures, warnings,
|
|
89
101
|
recovery, and nearby diagnostic output within the requested character budget.
|
|
90
102
|
It reports how many events were filtered or omitted.
|
|
103
|
+
Repeated successful health checks are represented once with their count and
|
|
104
|
+
final timestamp. The stored NDJSON remains complete, so compact AI context does
|
|
105
|
+
not discard diagnostic evidence.
|
|
91
106
|
|
|
92
107
|
Use JSON when another local tool should consume the result envelope:
|
|
93
108
|
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Threat model
|
|
2
|
+
|
|
3
|
+
ADB Ready runs locally with the same Android access as the selected ADB server.
|
|
4
|
+
Its security goal is to make that authority explicit, narrow, target-bound, and
|
|
5
|
+
observable; it cannot sandbox ADB, the Android device, a project command, or an
|
|
6
|
+
AI client that already has broader host access.
|
|
7
|
+
|
|
8
|
+
## Trust boundaries
|
|
9
|
+
|
|
10
|
+
| Boundary | ADB Ready assumes | ADB Ready enforces |
|
|
11
|
+
| --- | --- | --- |
|
|
12
|
+
| CLI caller | arguments may be malformed or automated | strict parsing, no implicit shell, bounded values, explicit destructive approval |
|
|
13
|
+
| ADB server and device | may be remote, stale, unavailable, or return hostile text | exact target selection, postcondition checks, output bounds, terminal sanitization |
|
|
14
|
+
| Project filesystem | may contain symlinks, existing files, or untrusted config | root containment, schema validation, atomic writes, no overwrite by default |
|
|
15
|
+
| Session storage | contains sensitive diagnostics | per-user location, bounded retention, redaction, restrictive file modes |
|
|
16
|
+
| MCP client | chooses what reaches a model provider | local stdio only, typed tools, one bound target, no generic shell/raw ADB |
|
|
17
|
+
| npm and CI | dependencies and release credentials can be attacked | pinned lockfile, package allowlist, short-lived OIDC publishing, provenance |
|
|
18
|
+
|
|
19
|
+
## Protected assets
|
|
20
|
+
|
|
21
|
+
- pairing codes, environment secrets, logs, screenshots, and UI text;
|
|
22
|
+
- the identity and state of the intended Android target and app;
|
|
23
|
+
- project files and existing ADB port mappings;
|
|
24
|
+
- the integrity of the published npm package and its command/tool contracts.
|
|
25
|
+
|
|
26
|
+
## Main threats and controls
|
|
27
|
+
|
|
28
|
+
### Command and input injection
|
|
29
|
+
|
|
30
|
+
Child commands use an executable plus argument array without an implicit shell.
|
|
31
|
+
MCP exposes allowlisted workflows rather than command execution. Android text
|
|
32
|
+
input accepts only a conservative character set; key actions map to numeric
|
|
33
|
+
allowlisted keycodes.
|
|
34
|
+
|
|
35
|
+
### Wrong-target mutation
|
|
36
|
+
|
|
37
|
+
Every target-aware operation uses an exact ADB serial or transport ID. Ambiguous
|
|
38
|
+
selection fails. An MCP connection binds one target and refuses a silent
|
|
39
|
+
switch. UI references include the current hierarchy digest and are revalidated
|
|
40
|
+
immediately before mutation.
|
|
41
|
+
|
|
42
|
+
### Unsafe file mutation
|
|
43
|
+
|
|
44
|
+
Capture and setup paths are constrained to the project, checked for unsafe
|
|
45
|
+
symlinks, written atomically, and not replaced without an explicit policy. MCP
|
|
46
|
+
APK installation accepts only an existing project-local file.
|
|
47
|
+
|
|
48
|
+
### Secret or terminal escape disclosure
|
|
49
|
+
|
|
50
|
+
Human output is terminal-sanitized. Stored diagnostic events are bounded and
|
|
51
|
+
redacted. Pairing codes use protected input or stdin and never enter process
|
|
52
|
+
arguments. Screenshots and UI hierarchies require explicit calls and never join
|
|
53
|
+
AI context automatically.
|
|
54
|
+
|
|
55
|
+
### Unbounded or misleading automation
|
|
56
|
+
|
|
57
|
+
Process output, recordings, UI trees, session storage, context, retries, and
|
|
58
|
+
waits are bounded. Results distinguish process acceptance (`ok`) from observed
|
|
59
|
+
postconditions (`verified`). An unchanged UI is reported as a verification gap,
|
|
60
|
+
not silently upgraded to verified success.
|
|
61
|
+
|
|
62
|
+
### Network exposure
|
|
63
|
+
|
|
64
|
+
The 0.2 MCP server uses stdio and opens no listener. ADB itself may connect to a
|
|
65
|
+
local or remote server selected by the user; that existing authority is outside
|
|
66
|
+
ADB Ready's isolation boundary.
|
|
67
|
+
|
|
68
|
+
## Intentionally absent
|
|
69
|
+
|
|
70
|
+
- arbitrary shell or raw ADB MCP tools;
|
|
71
|
+
- automatic downloads, mutable `latest` execution, or implicit tool installs;
|
|
72
|
+
- MCP data clearing and uninstall operations;
|
|
73
|
+
- autonomous destructive recovery;
|
|
74
|
+
- automatic screenshot or UI-text upload.
|
|
75
|
+
|
|
76
|
+
## Residual risk
|
|
77
|
+
|
|
78
|
+
A trusted ADB server can control connected Android targets, and an approved AI
|
|
79
|
+
client may transmit tool results under its own provider policy. Accessibility
|
|
80
|
+
hierarchies can expose on-screen personal data. Project commands and installed
|
|
81
|
+
APKs execute with their normal platform authority. Users must review targets,
|
|
82
|
+
MCP approvals, artifacts, and captured evidence accordingly.
|
|
83
|
+
|
|
84
|
+
Report a vulnerability through the private channel in the
|
|
85
|
+
[Security Policy](../SECURITY.md).
|
package/docs/troubleshooting.md
CHANGED
|
@@ -31,6 +31,7 @@ adb-ready context --since 5m --only problems,recovery,logs
|
|
|
31
31
|
| `MULTIPLE_WIRELESS_ENDPOINTS` | Discovery returned ambiguous services | Pass one exact `HOST:PORT` |
|
|
32
32
|
| `PORT_MAPPING_CONFLICT` | Another mapping owns the requested listen port | Inspect `ports ... list`; remove or change it explicitly |
|
|
33
33
|
| `LOG_PACKAGE_NOT_RUNNING` | Package filtering could not resolve a live process | Launch the app or use another package/PID |
|
|
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 |
|
|
34
35
|
| `SESSION_RECOVERY_FAILED` | The bounded target/port recovery budget was exhausted | Inspect `problems`, network state, and saved recovery events |
|
|
35
36
|
| `SESSION_PERSISTENCE_FAILED` | The private session record could not be written | Check user-state directory permissions and capacity |
|
|
36
37
|
| `CHILD_PROCESS_FAILED` | The project command exited unsuccessfully | Inspect child output, targeted logs, and preserved exit code |
|