mobile-debug-mcp 0.36.0 → 0.37.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/README.md +10 -0
- package/agent-plugin/.antigravity-plugin/plugin.json +1 -1
- package/agent-plugin/.claude-plugin/plugin.json +2 -2
- package/agent-plugin/.codex-plugin/plugin.json +1 -1
- package/agent-plugin/.cursor-plugin/plugin.json +2 -2
- package/agent-plugin/.mcp.json +1 -1
- package/agent-plugin/cursor/.cursor-plugin/plugin.json +2 -2
- package/agent-plugin/cursor/skills/mobile-debug-mcp/SKILL.md +10 -2
- package/agent-plugin/mcp.json +1 -1
- package/agent-plugin/mcp_config.json +1 -1
- package/agent-plugin/plugin.json +1 -1
- package/agent-plugin/skills/mobile-debug-mcp/SKILL.md +10 -2
- package/dist/contracts/device-readiness.js +1 -0
- package/dist/interact/waits/ui-change-wait.js +9 -2
- package/dist/interact/waits/ui-wait.js +7 -3
- package/dist/manage/index.js +3 -0
- package/dist/observe/device-readiness.js +116 -0
- package/dist/observe/evidence.js +31 -0
- package/dist/observe/ios-trace/sessions.js +5 -3
- package/dist/observe/readiness-service.js +21 -9
- package/dist/observe/readiness.js +30 -0
- package/dist/observe/screenshot-encoding.js +4 -0
- package/dist/observe/snapshot-collection.js +7 -2
- package/dist/server/definitions/manage.js +3 -2
- package/dist/server/handlers/action-execution.js +23 -14
- package/dist/server/handlers/compact-interaction.js +106 -0
- package/dist/server/handlers/compact-state.js +47 -0
- package/dist/server/handlers/input.js +2 -0
- package/dist/server/handlers/interact.js +2 -0
- package/dist/server/handlers/interaction-diagnostics.js +62 -0
- package/dist/server/handlers/journey.js +18 -20
- package/dist/server/handlers/observe.js +2 -1
- package/dist/server/handlers/tool-handlers.js +9 -5
- package/dist/server/schemas/interaction-diagnostics.js +9 -0
- package/dist/server/tool-definitions.js +9 -4
- package/dist/server-core.js +5 -2
- package/dist/server.js +1 -1
- package/dist/system/android.js +19 -15
- package/dist/system/index.js +2 -1
- package/dist/utils/android/utils.js +7 -16
- package/dist/utils/app-installation.js +77 -0
- package/dist/utils/benchmark-metrics.js +43 -0
- package/dist/utils/exec.js +4 -0
- package/dist/utils/ios/utils.js +4 -11
- package/dist/utils/resolve-device.js +3 -2
- package/dist/utils/timing.js +3 -3
- package/docs/CHANGELOG.md +25 -0
- package/docs/benchmarks/README.md +1 -0
- package/docs/benchmarks/end-to-end-latency/README.md +98 -0
- package/docs/benchmarks/end-to-end-latency/android-snapshot-pair.json +6532 -0
- package/docs/benchmarks/end-to-end-latency/android-snapshot-pair.md +30 -0
- package/docs/benchmarks/end-to-end-latency/baseline-attempt-1.json +15901 -0
- package/docs/benchmarks/end-to-end-latency/baseline-attempt-1.md +14 -0
- package/docs/benchmarks/end-to-end-latency/baseline.json +233843 -0
- package/docs/benchmarks/end-to-end-latency/baseline.md +21 -0
- package/docs/benchmarks/end-to-end-latency/investigation.md +128 -0
- package/docs/benchmarks/end-to-end-latency/ios-smoke.json +84 -0
- package/docs/benchmarks/end-to-end-latency/ios-smoke.md +9 -0
- package/docs/benchmarks/end-to-end-latency/smoke.json +19601 -0
- package/docs/benchmarks/end-to-end-latency/smoke.md +21 -0
- package/docs/specs/031-ios-system-traces/plan.md +28 -0
- package/docs/specs/033-device-readiness-blockers/android-evidence.json +437 -0
- package/docs/specs/033-device-readiness-blockers/android-physical-evidence.json +28 -0
- package/docs/specs/033-device-readiness-blockers/android-physical-power-evidence.json +29 -0
- package/docs/specs/033-device-readiness-blockers/intent.md +41 -0
- package/docs/specs/033-device-readiness-blockers/ios-investigation.md +55 -0
- package/docs/specs/033-device-readiness-blockers/ios-probe-evidence.json +24 -0
- package/docs/specs/033-device-readiness-blockers/ios-tool-evidence.json +73 -0
- package/docs/specs/033-device-readiness-blockers/plan.md +249 -0
- package/docs/specs/033-device-readiness-blockers/spec.md +134 -0
- package/docs/specs/034-app-installation-status/intent.md +41 -0
- package/docs/specs/034-app-installation-status/native-evidence.json +654 -0
- package/docs/specs/034-app-installation-status/plan.md +73 -0
- package/docs/specs/034-app-installation-status/spec.md +114 -0
- package/docs/specs/035-compact-interaction-results/baseline.md +45 -0
- package/docs/specs/035-compact-interaction-results/intent.md +38 -0
- package/docs/specs/035-compact-interaction-results/plan.md +43 -0
- package/docs/specs/035-compact-interaction-results/spec.md +118 -0
- package/docs/specs/035-compact-interaction-results/verification.md +111 -0
- package/docs/specs/036-end-to-end-interaction-latency/android-snapshot-amendment.md +60 -0
- package/docs/specs/036-end-to-end-interaction-latency/android-snapshot-plan.md +32 -0
- package/docs/specs/036-end-to-end-interaction-latency/intent.md +37 -0
- package/docs/specs/036-end-to-end-interaction-latency/plan.md +59 -0
- package/docs/specs/036-end-to-end-interaction-latency/spec.md +126 -0
- package/docs/specs/036-end-to-end-interaction-latency/verification.md +87 -0
- package/docs/tools/TOOLS.md +1 -0
- package/docs/tools/compact-interactions.md +56 -0
- package/docs/tools/correlated-evidence.md +6 -0
- package/docs/tools/interact.md +17 -8
- package/docs/tools/manage.md +10 -2
- package/docs/tools/observe.md +42 -2
- package/docs/tools/system.md +6 -0
- package/package.json +1 -1
- package/src/contracts/device-readiness.ts +8 -0
- package/src/interact/waits/ui-change-wait.ts +7 -2
- package/src/interact/waits/ui-wait.ts +6 -3
- package/src/manage/index.ts +2 -0
- package/src/observe/device-readiness.ts +96 -0
- package/src/observe/evidence.ts +30 -1
- package/src/observe/ios-trace/sessions.ts +4 -2
- package/src/observe/readiness-service.ts +21 -9
- package/src/observe/readiness.ts +33 -0
- package/src/observe/screenshot-encoding.ts +4 -0
- package/src/observe/snapshot-collection.ts +7 -2
- package/src/server/common.ts +2 -2
- package/src/server/definitions/manage.ts +3 -2
- package/src/server/handlers/action-execution.ts +22 -14
- package/src/server/handlers/compact-interaction.ts +91 -0
- package/src/server/handlers/compact-state.ts +43 -0
- package/src/server/handlers/input.ts +2 -0
- package/src/server/handlers/interact.ts +2 -0
- package/src/server/handlers/interaction-diagnostics.ts +50 -0
- package/src/server/handlers/journey.ts +15 -17
- package/src/server/handlers/observe.ts +2 -1
- package/src/server/handlers/payload.ts +2 -1
- package/src/server/handlers/tool-handlers.ts +9 -5
- package/src/server/schemas/interaction-diagnostics.ts +10 -0
- package/src/server/tool-definitions.ts +8 -4
- package/src/server-core.ts +5 -2
- package/src/server.ts +1 -1
- package/src/system/android.ts +18 -11
- package/src/system/index.ts +2 -1
- package/src/types.ts +2 -0
- package/src/utils/android/utils.ts +8 -10
- package/src/utils/app-installation.ts +73 -0
- package/src/utils/benchmark-metrics.ts +42 -0
- package/src/utils/exec.ts +5 -0
- package/src/utils/ios/utils.ts +4 -10
- package/src/utils/resolve-device.ts +4 -2
- package/src/utils/timing.ts +3 -2
- package/test/device/automated/debugger/runtime.android.test.ts +5 -0
- package/test/device/automated/debugger/runtime.ios.test.ts +7 -1
- package/test/device/automated/interact/compact-results.smoke.ts +58 -0
- package/test/device/automated/latency/end-to-end-environment.ts +61 -0
- package/test/device/automated/latency/end-to-end-report.ts +90 -0
- package/test/device/automated/latency/end-to-end-session.ts +98 -0
- package/test/device/automated/latency/end-to-end.ts +149 -0
- package/test/device/automated/latency/owned-transport.ts +81 -0
- package/test/device/automated/latency/snapshot-pair.ts +143 -0
- package/test/device/automated/latency-ios/benchmark.ts +126 -0
- package/test/device/automated/observe/correlated-evidence.smoke.ts +7 -5
- package/test/device/automated/observe/device-readiness-cleanup.ts +14 -0
- package/test/device/automated/observe/device-readiness.android.smoke.ts +78 -0
- package/test/device/automated/observe/ios-system-trace.smoke.ts +2 -2
- package/test/device/automated/observe/system-trace.smoke.ts +2 -2
- package/test/fixtures/contracts/tool-definitions.json +51 -15
- package/test/fixtures/latency-journey-app/build.ts +3 -3
- package/test/unit/debugger/handle-guards.test.ts +2 -1
- package/test/unit/interact/ui-change-readiness-interruption.test.ts +37 -0
- package/test/unit/observe/capture_debug_snapshot.test.ts +66 -12
- package/test/unit/observe/device-readiness-cleanup.test.ts +24 -0
- package/test/unit/observe/device-readiness.test.ts +97 -0
- package/test/unit/observe/ios-trace-sessions.test.ts +23 -0
- package/test/unit/observe/readiness-retained-blockers.test.ts +40 -0
- package/test/unit/server/compact-interaction.test.ts +87 -0
- package/test/unit/server/compact-journey-evidence.test.ts +40 -0
- package/test/unit/server/compact-review-regressions.test.ts +78 -0
- package/test/unit/server/conditional_actions.test.ts +7 -3
- package/test/unit/server/correlated-evidence.test.ts +18 -6
- package/test/unit/server/end-to-end-report.test.ts +46 -0
- package/test/unit/server/input-device-readiness.test.ts +55 -0
- package/test/unit/server/interaction-diagnostics.test.ts +45 -0
- package/test/unit/server/owned-benchmark-transport.test.ts +32 -0
- package/test/unit/server/readiness-retained-deadline.test.ts +32 -0
- package/test/unit/server/readiness.test.ts +24 -1
- package/test/unit/server/run_journey.test.ts +2 -1
- package/test/unit/server/selector_tap_target.test.ts +2 -1
- package/test/unit/server/system-trace.test.ts +6 -4
- package/test/unit/utils/app-installation.test.ts +78 -0
- package/test/unit/utils/benchmark-metrics.test.ts +36 -0
- package/test/unit/utils/resolve_device.test.ts +11 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
{
|
|
2
|
+
"tool": "get_app_readiness",
|
|
3
|
+
"server": {
|
|
4
|
+
"name": "mobile-debug-mcp",
|
|
5
|
+
"version": "0.36.0"
|
|
6
|
+
},
|
|
7
|
+
"runtime": "v23.11.0",
|
|
8
|
+
"result": {
|
|
9
|
+
"success": true,
|
|
10
|
+
"device": {
|
|
11
|
+
"platform": "ios",
|
|
12
|
+
"id": "F9243BAF-62A8-4990-8A99-17F527F56FDA",
|
|
13
|
+
"osVersion": "iOS 26.4",
|
|
14
|
+
"model": "iPhone 17 Pro",
|
|
15
|
+
"simulator": true,
|
|
16
|
+
"booted": true
|
|
17
|
+
},
|
|
18
|
+
"readiness": {
|
|
19
|
+
"state": "settled",
|
|
20
|
+
"scope": "device_ui",
|
|
21
|
+
"basis": "observed",
|
|
22
|
+
"captured_at_ms": 1793823964160,
|
|
23
|
+
"snapshot_session_id": "cd4bc1e2-b26c-40f6-a50e-27472dc00a29",
|
|
24
|
+
"snapshot_revision": 1,
|
|
25
|
+
"sample_count": 2,
|
|
26
|
+
"stable_for_ms": 2846.7576670000003,
|
|
27
|
+
"evidence": [
|
|
28
|
+
{
|
|
29
|
+
"code": "INSUFFICIENT_SAMPLES",
|
|
30
|
+
"source": "ui_tree",
|
|
31
|
+
"captured_at_ms": 1793823961313,
|
|
32
|
+
"snapshot_revision": 1
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"code": "SNAPSHOT_STABLE",
|
|
36
|
+
"source": "ui_tree",
|
|
37
|
+
"captured_at_ms": 1793823964160,
|
|
38
|
+
"snapshot_revision": 1
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"limitations": [
|
|
42
|
+
"NORMALIZED_UI_ONLY",
|
|
43
|
+
"FOREGROUND_APP_UNVERIFIED",
|
|
44
|
+
"UNRESPONSIVE_SIGNAL_UNSUPPORTED",
|
|
45
|
+
"MANAGED_DEBUGGER_ONLY"
|
|
46
|
+
],
|
|
47
|
+
"capabilities": {
|
|
48
|
+
"loading": true,
|
|
49
|
+
"transitioning": true,
|
|
50
|
+
"settled": true,
|
|
51
|
+
"unresponsive": false,
|
|
52
|
+
"debugger_paused": true
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"device_readiness": {
|
|
56
|
+
"wakefulness": "unknown",
|
|
57
|
+
"lock_state": "unsupported",
|
|
58
|
+
"input_ready": null,
|
|
59
|
+
"blockers": [],
|
|
60
|
+
"evidence": [
|
|
61
|
+
{
|
|
62
|
+
"code": "DEVICE_LOCK_SIGNAL_UNSUPPORTED",
|
|
63
|
+
"source": "coredevice",
|
|
64
|
+
"captured_at_ms": 1793823962013
|
|
65
|
+
}
|
|
66
|
+
],
|
|
67
|
+
"limitations": [
|
|
68
|
+
"DEVICE_WAKEFULNESS_UNVERIFIED"
|
|
69
|
+
]
|
|
70
|
+
},
|
|
71
|
+
"elapsed_ms": 5987.550583
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
# Implementation and verification plan
|
|
2
|
+
|
|
3
|
+
Scope: [intent](intent.md), [approved specification](spec.md). User approved the
|
|
4
|
+
revised contract with “ok, lets proceed” on 2026-11-04.
|
|
5
|
+
|
|
6
|
+
Status: implementation and supported virtual-device checks complete on
|
|
7
|
+
2026-11-05, including the trace shutdown repair below. Default idb compatibility
|
|
8
|
+
and hardware-specific coverage remain separate limitations.
|
|
9
|
+
|
|
10
|
+
## Implementation
|
|
11
|
+
|
|
12
|
+
- [x] Add typed, bounded device-state probes with conservative Android parsing and
|
|
13
|
+
capability-based iOS lock evidence; reuse subprocess and operation budgets.
|
|
14
|
+
- [x] Integrate evidence into readiness services, predicate waits, and shared action
|
|
15
|
+
responses, retaining dispatch outcomes and compact/journey evidence.
|
|
16
|
+
- [x] Cover parsing, partial failure, recovery, deadlines, debugger precedence,
|
|
17
|
+
targeting and serialization with self-running unit tests.
|
|
18
|
+
- [x] Update tool docs, descriptions, README and changelog. Review all changed callers.
|
|
19
|
+
|
|
20
|
+
## Verification
|
|
21
|
+
|
|
22
|
+
Node >=22 (CI Node 22); native Android ADB and local Xcode for iOS probes.
|
|
23
|
+
|
|
24
|
+
| Criteria | Check |
|
|
25
|
+
| --- | --- |
|
|
26
|
+
| 1, 2: launch, awake/asleep/locked/recovery | Updated server against explicit Android emulator; sleep disposable emulator, launch Settings, inspect readiness, restore awake state |
|
|
27
|
+
| 2: transition/conflict/missing fields | Deterministic parser fixtures and failed native probes |
|
|
28
|
+
| 3: blocker gating and unknown compatibility | Readiness/predicate wait unit integration |
|
|
29
|
+
| 4: debugger, targeting, timestamps, compact/journey | Shared action and probe unit integration; existing debugger guard tests |
|
|
30
|
+
| 5: required checks | `npm run verify`, `npm run test:device` |
|
|
31
|
+
| iOS boundary | Updated probe against explicitly booted iPhone 17 Pro simulator; verify capability rejection and unknown wakefulness, then shutdown |
|
|
32
|
+
|
|
33
|
+
Device suite is Android-focused and may contain opt-in checks; record skips.
|
|
34
|
+
Physical iOS unavailable; do not claim physical support. CI additionally compiles
|
|
35
|
+
the Java worker with JDK 17 and checks package contents; the latest results below
|
|
36
|
+
supersede the initial unrun status.
|
|
37
|
+
Use existing Settings app for launch reproduction, no user app data changes.
|
|
38
|
+
Restore emulator wake state and shutdown any simulator booted for this task.
|
|
39
|
+
|
|
40
|
+
## Results
|
|
41
|
+
|
|
42
|
+
Implementation and required baseline verification completed; detailed evidence
|
|
43
|
+
and later PR repairs follow. Remaining platform risks: vendor-specific Android output,
|
|
44
|
+
extra probe latency, iOS capability differences, and budget expiry during probes.
|
|
45
|
+
No publication, release, or protected-branch change is planned.
|
|
46
|
+
|
|
47
|
+
## Implementation results
|
|
48
|
+
|
|
49
|
+
Implemented the separate device-readiness contract, Android power/keyguard
|
|
50
|
+
parsers, capability-based iOS lock query, pre-observation wait gating, and shared
|
|
51
|
+
launch/input response evidence. Known blockers break UI-stability continuity;
|
|
52
|
+
recovery requires fresh UI samples. Compact actions and journey action steps
|
|
53
|
+
retain the evidence; the separate adjust_control result also carries it. Dispatch success and verification controls retain their
|
|
54
|
+
existing meanings. Updated tool descriptions and their full compatibility
|
|
55
|
+
fixture, README, tool docs, and changelog.
|
|
56
|
+
|
|
57
|
+
Focused review covered resolved-device ownership, no cross-call cache, partial
|
|
58
|
+
probe failure, conservative parsing, response preservation on observation
|
|
59
|
+
failure, debugger priority, and operation-budget clipping. CoreDevice requires
|
|
60
|
+
its own timeout argument to be >=5 seconds; the parent process enforces the
|
|
61
|
+
1,000 ms probe deadline. Android 17 repeats a numeric wakefulness enum in a later
|
|
62
|
+
vendor section: parsing now isolates the named current-state section. Both
|
|
63
|
+
runtime discoveries have deterministic regression coverage. No raw native dumps
|
|
64
|
+
are included in the response or retained evidence.
|
|
65
|
+
|
|
66
|
+
## Initial device evidence — 2026-11-04
|
|
67
|
+
|
|
68
|
+
Local server version 0.36.0, modified checkout based on
|
|
69
|
+
`46f86bae52f09be4499867ac581f9308d3892e41`, Node v23.11.0 (supported >=22).
|
|
70
|
+
This is local source/built-server evidence, not a published package or hosted CI.
|
|
71
|
+
|
|
72
|
+
- **PASS — Android emulator 16, emulator-5554:** started awake/unlocked;
|
|
73
|
+
observed a real transitioning-to-asleep state, launched Settings with
|
|
74
|
+
verification disabled, and established successful dispatch alongside
|
|
75
|
+
DEVICE_ASLEEP. Readiness wait returned READINESS_TIMEOUT while asleep, then
|
|
76
|
+
passed after wake-up with fresh settled UI evidence. Restored awake/unlocked
|
|
77
|
+
and Home. [Evidence](android-evidence.json).
|
|
78
|
+
- **PASS — Pixel 9 Pro, Android 17:** passive state read established
|
|
79
|
+
DEVICE_LOCKED and input_ready=false. No input or state changes were sent.
|
|
80
|
+
The first power sample was conservatively unknown because of duplicate
|
|
81
|
+
vendor-debug fields; the scoped parser subsequently observed awake/unlocked
|
|
82
|
+
with both timestamped signals. These are separate observations of natural
|
|
83
|
+
device changes, not an automated lock/unlock journey.
|
|
84
|
+
[Lock evidence](android-physical-evidence.json),
|
|
85
|
+
[power evidence](android-physical-power-evidence.json).
|
|
86
|
+
- **PASS — iPhone 17 Pro simulator, iOS 26.4:** updated native probe and actual
|
|
87
|
+
get_app_readiness MCP call returned lock_state=unsupported from CoreDevice's
|
|
88
|
+
matching capability rejection, wakefulness=unknown, and input_ready=null.
|
|
89
|
+
UI readiness could still report settled without claiming input readiness.
|
|
90
|
+
Simulator restored to shutdown. [Probe](ios-probe-evidence.json),
|
|
91
|
+
[MCP result](ios-tool-evidence.json).
|
|
92
|
+
- **UNRUN — real locked emulator journey:** this emulator wakes unlocked;
|
|
93
|
+
security settings were not changed. Locked classifier evidence exists on the
|
|
94
|
+
physical Pixel, and locked wait gating has deterministic integration coverage.
|
|
95
|
+
- **UNRUN — physical iOS, live debugger-paused reproduction, true iOS sleep and
|
|
96
|
+
lock/unlock recovery:** no physical iOS device; opt-in debugger fixtures were
|
|
97
|
+
not run. Managed debugger precedence is covered by deterministic tests, not
|
|
98
|
+
claimed as a new live debugger journey.
|
|
99
|
+
|
|
100
|
+
## Initial verification results — 2026-11-04
|
|
101
|
+
|
|
102
|
+
- `npm run verify`: passed, including the rerun after the Android 17 parser
|
|
103
|
+
refinement. Final lint/build and focused action tests also passed after review. Includes lint, size/dependency checks, TypeScript build,
|
|
104
|
+
complete unit suite, and agent-plugin consistency.
|
|
105
|
+
- Focused device-readiness parser/probe/action tests, readiness tool/wait tests,
|
|
106
|
+
and compact journey tests: passed. Covers partial probe failure, explicit
|
|
107
|
+
unknown/unsupported outcomes, targeting, timestamps, expired budgets, no raw
|
|
108
|
+
error leakage, blocker gating, fresh recovery, and dispatch preservation.
|
|
109
|
+
- `npm run test:device`: passed with a booted iOS simulator. Android/iOS
|
|
110
|
+
screenshots, logs, trees and correlated-evidence checks passed; Android system
|
|
111
|
+
tracing passed with cleanup. Optional coroutine/Kotlin/debugger/interaction
|
|
112
|
+
fixtures and iOS tracing were unrun. The new explicit emulator readiness
|
|
113
|
+
journey was run separately with MCP_READINESS_DEVICE=emulator-5554.
|
|
114
|
+
Initial suite invocation without a booted simulator failed at the iOS
|
|
115
|
+
screenshot prerequisite; booting the simulator resolved that prerequisite.
|
|
116
|
+
- `git diff --check` and changed documentation relative-path checks: passed.
|
|
117
|
+
- CI uses Node 22, plus JDK 17 worker compilation/package checks. These extra
|
|
118
|
+
hosted checks were not run here. No commit, push, release or publication.
|
|
119
|
+
|
|
120
|
+
The GitHub project status move remains unconfirmed; CLI project access lacks
|
|
121
|
+
read:project, and browser actions were interrupted by concurrent user navigation.
|
|
122
|
+
No ticket completion or remote publication is claimed.
|
|
123
|
+
|
|
124
|
+
## PR #104 review repairs — 2026-11-04
|
|
125
|
+
|
|
126
|
+
Lightweight fixes restoring the approved contract, based on the four attached
|
|
127
|
+
unresolved review threads at head `b78268b`:
|
|
128
|
+
|
|
129
|
+
- Reset UI-change candidate, change kind and stability timestamp when a device
|
|
130
|
+
blocker skips sampling. A deterministic clock test proves the full change
|
|
131
|
+
stability window must elapse again after recovery.
|
|
132
|
+
- Retain last-known blocked power/keyguard axes within the same wait when a
|
|
133
|
+
later probe is inconclusive, including original evidence timestamps and new
|
|
134
|
+
failure limitations. Fresh conclusive evidence clears each axis independently.
|
|
135
|
+
Regression tests cover partial recovery, expired probes and READINESS_TIMEOUT.
|
|
136
|
+
- Preserve the native tap/swipe response's resolved device in the action result.
|
|
137
|
+
No new target resolution or guarded-selection change. Tested implicit,
|
|
138
|
+
explicit and already-resolved targeting in debug/compact responses.
|
|
139
|
+
- Attempt every emulator restoration command independently and always close the
|
|
140
|
+
client in a nested finally. Aggregate failures after all attempts; report PASS
|
|
141
|
+
only after successful cleanup. Injected failures cover each ADB step and close.
|
|
142
|
+
|
|
143
|
+
All three production regressions were demonstrated to fail against the original
|
|
144
|
+
PR head and pass with these fixes. `npm run verify`, focused regressions and
|
|
145
|
+
final lint passed. Device verification results are recorded below.
|
|
146
|
+
|
|
147
|
+
PR repair verification used local Node v23.11.0 and server 0.36.0. On Android 16
|
|
148
|
+
`emulator-5554`, the updated stdio MCP server reported DEVICE_ASLEEP alongside
|
|
149
|
+
successful start_app, ordinary tap and swipe dispatches. The readiness wait
|
|
150
|
+
returned READINESS_TIMEOUT with DEVICE_ASLEEP still present, then recovered
|
|
151
|
+
awake/unlocked; all restoration commands and client close completed. The first
|
|
152
|
+
device-suite attempt timed out at the initial readiness RPC before state
|
|
153
|
+
changes. A focused retry passed, as did the same journey in the serial suite
|
|
154
|
+
retry. No timeout or assertion was weakened. Failed-cleanup paths were verified
|
|
155
|
+
with injected failures rather than disconnecting a real emulator.
|
|
156
|
+
|
|
157
|
+
The serial `MCP_READINESS_DEVICE=emulator-5554 npm run test:device` run passed,
|
|
158
|
+
including Android/iOS screenshots, logs, UI trees, correlated evidence and
|
|
159
|
+
Android trace cleanup. The iPhone 17 Pro iOS 26.4 simulator was temporarily
|
|
160
|
+
booted and restored to shutdown. Optional coroutine/Kotlin/debugger/interaction
|
|
161
|
+
fixtures and iOS tracing remained unrun. Hosted CI/JDK 17 package checks remain
|
|
162
|
+
separate from these local results. `git diff --check` passed.
|
|
163
|
+
|
|
164
|
+
## Additional checks without physical devices — 2026-11-05
|
|
165
|
+
|
|
166
|
+
Requested follow-up: run remaining checks on emulators/simulators and record
|
|
167
|
+
limits explicitly. No physical device was selected. Existing fixture tests now
|
|
168
|
+
also assert the new device_readiness DEBUGGER_PAUSED blocker and input_ready=false,
|
|
169
|
+
and immediate DEBUGGER_PAUSED from wait_for_app_ready on both platforms.
|
|
170
|
+
|
|
171
|
+
- **PASS — Android emulator debugger**, including the real 60-second pause limit,
|
|
172
|
+
paused readiness and wait blockers, source/locals/stepping, recovery and owned
|
|
173
|
+
resource cleanup. JDK 17.0.11, emulator-5554, Android API 36, extended mode.
|
|
174
|
+
Log: `/tmp/readiness-extra-android-debugger-retry.log`.
|
|
175
|
+
- **PASS — iOS simulator debugger**, including paused readiness and wait blockers,
|
|
176
|
+
async/cancellation, real pause expiry, disconnect and shutdown recovery, and
|
|
177
|
+
fixture cleanup. iPhone 17 Pro simulator, iOS 26.4, Xcode 27.2 (27B52),
|
|
178
|
+
Swift-enabled LLDB, extended mode. Fixture-only command-file triggers are used;
|
|
179
|
+
this proves debugger/readiness behaviour, not successful iOS HID tap delivery.
|
|
180
|
+
Log: `/tmp/readiness-extra-ios-debugger-retry.log`.
|
|
181
|
+
|
|
182
|
+
The first Android extended run failed its expiry assertion with paused state and
|
|
183
|
+
pending cleanup after pause_limit was selected; its unchanged-deadline retry
|
|
184
|
+
passed. The first iOS attempt timed out during fixture installation; the retry
|
|
185
|
+
passed without increasing the install timeout. These initial failures remain
|
|
186
|
+
recorded in `/tmp/readiness-extra-android-debugger.log` and
|
|
187
|
+
`/tmp/readiness-extra-ios-debugger.log`; they are not counted as passes.
|
|
188
|
+
|
|
189
|
+
- **PASS — Android interaction fixture:** clickable/visible waits, stored handles,
|
|
190
|
+
selector journey, enabled-state assertion and labelled SeekBar convergence.
|
|
191
|
+
Log: `/tmp/readiness-extra-interaction.log`.
|
|
192
|
+
- **PASS — Kotlin locals fixture:** known values before/after assignments,
|
|
193
|
+
stale-frame rejection, UI recovery and owned-forward cleanup. Kotlin/stdlib
|
|
194
|
+
2.0.21 and JDK 17.0.11. Log: `/tmp/readiness-extra-kotlin.log`.
|
|
195
|
+
- **PASS — coroutine fixture:** source stops around suspension, dispatch-thread
|
|
196
|
+
locals, completion, cancellation/finally, pause guards and cleanup. Uses the
|
|
197
|
+
same compiler plus coroutines 1.9.0. No logical coroutine-stack claim.
|
|
198
|
+
Log: `/tmp/readiness-extra-coroutine.log`.
|
|
199
|
+
- **PASS — local CI-equivalent extras:** JDK 17 worker compilation and all 23
|
|
200
|
+
package inventory entries from the current CI workflow. Hosted unit checks
|
|
201
|
+
for PR #104 head `28d73ff` were also confirmed successful.
|
|
202
|
+
|
|
203
|
+
All Android fixtures ran sequentially on emulator-5554, and removed their own
|
|
204
|
+
packages, temporary builds and debugger forwards. No production source changes
|
|
205
|
+
were required. The default iOS trace runner verified capture/cancel/expiry/shutdown cleanup but
|
|
206
|
+
failed its input journey: the installed idb_companion 1.1.8 expects SimulatorKit
|
|
207
|
+
under Developer/Library/PrivateFrameworks, absent in Xcode 27.2. A direct input
|
|
208
|
+
probe confirmed that error. No production or installed Xcode files were changed.
|
|
209
|
+
|
|
210
|
+
Using the documented test-owned Xcode path alias and isolated companion, the
|
|
211
|
+
traced tap-to-Done journey passed with 53 exported sample rows; cancellation,
|
|
212
|
+
expiry, stale-ID rejection and failed-journey handling also passed. The same
|
|
213
|
+
run failed the final server-shutdown partial-directory assertion, so the overall
|
|
214
|
+
compatibility trace run remains **FAIL / partial**, not a pass. A subsequent
|
|
215
|
+
resource check found no recorder processes or owned trace directories left.
|
|
216
|
+
Logs/evidence: `/tmp/readiness-extra-ios-trace.log`,
|
|
217
|
+
`/tmp/readiness-extra-ios-trace.json`,
|
|
218
|
+
`/tmp/readiness-extra-ios-trace-compatible.log` and
|
|
219
|
+
`/tmp/readiness-extra-ios-trace-compatible.json`.
|
|
220
|
+
|
|
221
|
+
Remaining software follow-up: investigate the intermittent iOS trace shutdown
|
|
222
|
+
cleanup assertion and provide a compatible default idb HID backend. True iOS
|
|
223
|
+
sleep/lock recovery cannot be established by this simulator's unsupported lock
|
|
224
|
+
probe and unverified wakefulness signal; physical iOS remains outside this
|
|
225
|
+
verification run. The default emulator's secure-lock journey was not enabled by
|
|
226
|
+
changing security settings; locked wait gating has deterministic coverage and
|
|
227
|
+
prior passive Pixel evidence. No new hardware validation is claimed.
|
|
228
|
+
|
|
229
|
+
Final `npm run verify` passed with the new Android/iOS paused-readiness
|
|
230
|
+
assertions. Changed documentation paths and `git diff --check` passed. The
|
|
231
|
+
compatibility companion, alias and local JDK compilation output were removed,
|
|
232
|
+
and the test-owned simulator was restored to shutdown. The verification-only
|
|
233
|
+
test changes and this plan update remain local and uncommitted.
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
### iOS trace shutdown issue repaired — 2026-11-05
|
|
237
|
+
|
|
238
|
+
The shutdown finalizer now removes discarded files after a stop error if the
|
|
239
|
+
owned recorder has exited; it retains the failure reason and never removes a
|
|
240
|
+
possibly live recorder's directory. Regression tests failed on the old code and
|
|
241
|
+
passed with the fix. The full simulator trace journey then passed its original
|
|
242
|
+
shutdown assertion, with 59 exported sample rows and complete cleanup.
|
|
243
|
+
`npm run verify` passed. See [trace repair record](../031-ios-system-traces/plan.md#shutdown-cleanup-repair--2026-11-05).
|
|
244
|
+
This supersedes the earlier failed shutdown check; the default idb compatibility
|
|
245
|
+
limitation and hardware-only coverage remain explicitly separate.
|
|
246
|
+
|
|
247
|
+
The shutdown repair also passed the baseline device suite. Temporary verification
|
|
248
|
+
resources were removed and the simulator restored to shutdown. The repair and
|
|
249
|
+
verification updates are local and uncommitted.
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# Specification: device readiness blockers
|
|
2
|
+
|
|
3
|
+
Status: approved. User accepted the revised specification with “ok, lets proceed”
|
|
4
|
+
in the current chat on 2026-11-04; implementation is authorised for this scope.
|
|
5
|
+
Intent: [approved intent](intent.md), user response “ok”, 2026-11-04.
|
|
6
|
+
Source: [issue #101](https://github.com/clivejefferies/mobile-debug-tools/issues/101).
|
|
7
|
+
|
|
8
|
+
## Behaviour
|
|
9
|
+
|
|
10
|
+
Keep launch dispatch, normalized UI stability, and device accessibility distinct.
|
|
11
|
+
Successful `start_app` / `restart_app` dispatch does not establish app visibility,
|
|
12
|
+
unlocked state, or input readiness. Existing success, verification, and
|
|
13
|
+
`observed_app.matchedTarget` fields retain their meanings. Device observations
|
|
14
|
+
must never upgrade dispatch success into proof that the app is usable.
|
|
15
|
+
|
|
16
|
+
Add `device_readiness` to launch/restart results, interaction action results,
|
|
17
|
+
`get_app_readiness`, `wait_for_app_ready`, and readiness-enabled
|
|
18
|
+
`wait_for_ui` / `wait_for_ui_change` results. Preserve it in compact and debug
|
|
19
|
+
responses, including failures after target resolution. Journey action steps use
|
|
20
|
+
the same representation. Ordinary waits without `requireReady` keep their
|
|
21
|
+
predicate semantics. No new tools or input parameters are introduced.
|
|
22
|
+
|
|
23
|
+
The additive object has:
|
|
24
|
+
|
|
25
|
+
- `wakefulness`: `awake | asleep | transitioning | unknown | unsupported`.
|
|
26
|
+
- `lock_state`: `locked | unlocked | unknown | unsupported`.
|
|
27
|
+
- `input_ready`: `false | null`. False means an observed device blocker; null
|
|
28
|
+
means readiness is not established. Awake/unlocked alone never yields true.
|
|
29
|
+
- `blockers`: zero or more of `DEVICE_ASLEEP`, `DEVICE_LOCKED`,
|
|
30
|
+
`DEVICE_TRANSITIONING`, `DEBUGGER_PAUSED`.
|
|
31
|
+
- `evidence`: at most eight entries containing `code`, `source`, and host
|
|
32
|
+
epoch `captured_at_ms`. No raw command output or UI text.
|
|
33
|
+
- `limitations`: bounded codes for unavailable, unsupported, conflicting, or
|
|
34
|
+
failed observations. Each axis has an explicit value even when unavailable.
|
|
35
|
+
|
|
36
|
+
Each successful native sample carries its own timestamp. An unknown axis has
|
|
37
|
+
no invented timestamp. Evidence is scoped to the explicitly resolved device
|
|
38
|
+
and current operation, with no cross-call cache. Observations describe their
|
|
39
|
+
capture time; they cannot guarantee the device remains unchanged afterward.
|
|
40
|
+
|
|
41
|
+
## Platform evidence
|
|
42
|
+
|
|
43
|
+
Android uses bounded, explicitly targeted ADB reads of `dumpsys power` and
|
|
44
|
+
`dumpsys window policy`. Parse recognized current-state fields only. Awake and
|
|
45
|
+
asleep require explicit wakefulness evidence; a wakefulness-change flag yields
|
|
46
|
+
transitioning. Dozing is treated as asleep for input readiness. Keyguard showing
|
|
47
|
+
means locked even if occluded; explicit non-showing means unlocked. Missing,
|
|
48
|
+
unrecognized, contradictory, or truncated fields produce unknown for the
|
|
49
|
+
affected axis. Device keyguard capability alone is not lock-state evidence.
|
|
50
|
+
Retain independent evidence when one probe fails. Unknown Android variants must
|
|
51
|
+
not be classified by text labels, screenshots, or command success alone.
|
|
52
|
+
|
|
53
|
+
iOS support is determined per signal and target, not by a blanket platform
|
|
54
|
+
assumption. Apple's `devicectl device info lockState` provides a lock-state
|
|
55
|
+
probe, but the tested iOS 26.4 simulator explicitly rejects it with CoreDevice
|
|
56
|
+
error 1001 and feature `com.apple.coredevice.feature.getlockstate`. That explicit
|
|
57
|
+
capability rejection yields unsupported for the lock axis; ordinary probe errors
|
|
58
|
+
yield unknown. A recognized successful structured response may establish lock
|
|
59
|
+
state only once its semantics and compatibility have been verified. Physical
|
|
60
|
+
iOS integration is outside this ticket's existing simulator-only lifecycle path;
|
|
61
|
+
the command's existence does not establish physical-device support in this MCP.
|
|
62
|
+
|
|
63
|
+
For the tested simulator, wakefulness remains unknown: display information is
|
|
64
|
+
available, but neither `simctl io enumerate` port power nor devicectl backlight
|
|
65
|
+
state reliably distinguished an accepted display-off command in this experiment.
|
|
66
|
+
Return `DEVICE_WAKEFULNESS_UNVERIFIED`, not an inferred awake/asleep state.
|
|
67
|
+
Simulator boot status, launch PID, SpringBoard labels, and a static tree do not
|
|
68
|
+
prove awake/unlocked state. No private iOS APIs, helper app, or security-setting
|
|
69
|
+
changes are introduced. See [iOS investigation](ios-investigation.md).
|
|
70
|
+
|
|
71
|
+
## Integration, precedence, and failure
|
|
72
|
+
|
|
73
|
+
Keep the existing `ReadinessSummary.state` enum and UI evidence unchanged for
|
|
74
|
+
compatibility, but a known device blocker prevents readiness-wait success even
|
|
75
|
+
if the UI appears settled. `get_app_readiness` may successfully report an
|
|
76
|
+
observed blocker; a readiness wait continues within its existing budget to allow
|
|
77
|
+
natural recovery. At expiry it returns `READINESS_TIMEOUT` with last evidence.
|
|
78
|
+
Managed debugger pause retains existing immediate `DEBUGGER_PAUSED` behaviour
|
|
79
|
+
and guard precedence. Combine available blockers without replacing debugger
|
|
80
|
+
session evidence or triggering a UI read while that guard blocks one.
|
|
81
|
+
|
|
82
|
+
Unsupported/unknown device observations do not prevent existing settled-UI wait
|
|
83
|
+
success; documentation must make clear that this still does not prove input
|
|
84
|
+
readiness. After observation failure, never reuse a previous known clear state
|
|
85
|
+
to claim the device is clear. A later fresh sample can establish recovery.
|
|
86
|
+
|
|
87
|
+
For actions, collect one post-action device sample within the existing action
|
|
88
|
+
budget, including verification mode `none`; do not add a UI-tree read for this
|
|
89
|
+
feature. Preserve dispatch outcomes on observation failure and expose unknown
|
|
90
|
+
with a limitation. A sleeping/locked result does not introduce a new input guard
|
|
91
|
+
or retry. Calls already blocked by the debugger retain their existing failure.
|
|
92
|
+
If target resolution fails, return unknown with a target-unavailable limitation.
|
|
93
|
+
|
|
94
|
+
Each native probe has a maximum 1,000 ms timeout, clipped to the remaining
|
|
95
|
+
operation budget. No additional timeout window, retry, detached subprocess, or
|
|
96
|
+
automatic device selection is allowed. Existing cancellation and child-process
|
|
97
|
+
cleanup apply. Do not begin a probe after budget expiry.
|
|
98
|
+
|
|
99
|
+
## Acceptance and verification
|
|
100
|
+
|
|
101
|
+
1. Reproduce launch while asleep/locked on a disposable Android emulator where
|
|
102
|
+
practical; record dispatch outcome separately from device-state evidence.
|
|
103
|
+
2. Verify awake/unlocked, asleep, locked, transition/conflict, missing fields,
|
|
104
|
+
probe failure, expiry, and recovery. Use real-device evidence for supported
|
|
105
|
+
stable states and deterministic fixtures for fleeting transitions.
|
|
106
|
+
3. Verify a stable lock-screen tree cannot complete a readiness-enabled wait;
|
|
107
|
+
unknown/unsupported remains explicit without changing ordinary predicates.
|
|
108
|
+
4. Verify managed debugger precedence, targeting, timestamp freshness, compact
|
|
109
|
+
serialization, journey propagation, and absence of raw dumps in responses.
|
|
110
|
+
5. Run `npm run verify` and applicable `npm run test:device`; report exact device,
|
|
111
|
+
server build, outcomes, cleanup, and unrun platforms. No claim of iOS state
|
|
112
|
+
detection is made without matching runtime evidence.
|
|
113
|
+
|
|
114
|
+
## Ownership, security, and investigation evidence
|
|
115
|
+
|
|
116
|
+
Affects readiness services/contracts, action execution/serialization, lifecycle
|
|
117
|
+
results, tool descriptions, tools documentation, README, and changelog. Reuse
|
|
118
|
+
existing budgets, subprocess helpers, and resolved-device context. Raw system
|
|
119
|
+
dumps can include private metadata: parse locally and retain only enumerated
|
|
120
|
+
flags. Never unlock, wake, or alter security settings automatically. Verification
|
|
121
|
+
may sleep/wake a disposable emulator and must restore its starting state; do not
|
|
122
|
+
change the user's physical phone for reproduction.
|
|
123
|
+
|
|
124
|
+
On 2026-11-04, connected MCP discovery reported an Android 16 emulator
|
|
125
|
+
`emulator-5554`, a physical Android phone, and no booted iOS simulator. Read-only
|
|
126
|
+
ADB probes on the emulator exposed `mWakefulness=Awake`,
|
|
127
|
+
`mWakefulnessChanging=false`, and keyguard `showing=false` / `mIsShowing=false`.
|
|
128
|
+
These establish available baseline fields only; sleeping/locked reproduction
|
|
129
|
+
and updated-server verification remain unrun. Local sandboxed simctl access
|
|
130
|
+
failed to connect to CoreSimulator, so it supplies no iOS runtime evidence.
|
|
131
|
+
|
|
132
|
+
The user approved this complete revised contract, including additive fields,
|
|
133
|
+
known-blocker wait gating, and per-signal iOS unknown/unsupported behaviour,
|
|
134
|
+
with “ok, lets proceed” on 2026-11-04.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Intent: trustworthy app installation status
|
|
2
|
+
|
|
3
|
+
Status: intent approved; specification pending.
|
|
4
|
+
Originator: GitHub issue #98; author identity not independently checked.
|
|
5
|
+
Captured: 2026-11-05.
|
|
6
|
+
Source: https://github.com/clivejefferies/mobile-debug-tools/issues/98
|
|
7
|
+
|
|
8
|
+
## Problem
|
|
9
|
+
|
|
10
|
+
Agent feedback reported `appInstalled: false` while Modul8 was installed and
|
|
11
|
+
running. The original device, app context and query are not yet established.
|
|
12
|
+
Current code can represent missing app context or failed installation queries
|
|
13
|
+
as absence; Android system status also queries without explicit device targeting.
|
|
14
|
+
These findings explain possible failure paths, not a reproduction of the report.
|
|
15
|
+
|
|
16
|
+
## Desired outcome and scope
|
|
17
|
+
|
|
18
|
+
Make installation reporting trustworthy for MCP clients using device inventory
|
|
19
|
+
and system status on Android and iOS. Distinguish confirmed installed, confirmed
|
|
20
|
+
absent and unknown/check-failed results, with explicit app and device context
|
|
21
|
+
and the scope of the check. Review device selection consumers so unknown status
|
|
22
|
+
cannot be mistaken for confirmed absence or used as unsupported targeting evidence.
|
|
23
|
+
|
|
24
|
+
Success includes meaningful coverage for installed/running and absent apps,
|
|
25
|
+
missing app context, multiple devices and failed queries. Reproduce the original
|
|
26
|
+
inconsistency where practical, otherwise document the evidence and limits.
|
|
27
|
+
Align tool descriptions and diagnostics with the accepted contract.
|
|
28
|
+
|
|
29
|
+
## Constraints and open questions
|
|
30
|
+
|
|
31
|
+
Preserve existing compatibility where possible; any response-contract change
|
|
32
|
+
requires specification approval. Use bounded, device-specific queries and avoid
|
|
33
|
+
installing, removing or launching user apps merely to check installation.
|
|
34
|
+
Automatic installation, broader readiness changes and expanded platform support
|
|
35
|
+
are excluded. Investigation will establish reliable absence evidence on each
|
|
36
|
+
supported platform and how legacy `appInstalled` maps to unknown results.
|
|
37
|
+
|
|
38
|
+
## Approval
|
|
39
|
+
|
|
40
|
+
The user approved the captured intent with “yes” in this chat on 2026-11-05.
|
|
41
|
+
This approves the problem and scope; response contracts await specification approval.
|