mobile-debug-mcp 0.33.0 → 0.34.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/.github/workflows/ci.yml +21 -0
- package/README.md +7 -0
- 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/README.md +4 -0
- package/agent-plugin/mcp.json +1 -1
- package/agent-plugin/plugin.json +1 -1
- package/agent-plugin/skills/mobile-debug-mcp/SKILL.md +88 -4
- package/dist/debugger/android.js +78 -0
- package/dist/debugger/guard.js +30 -0
- package/dist/debugger/sessions.js +262 -0
- package/dist/debugger/worker.js +165 -0
- package/dist/interact/index.js +16 -0
- package/dist/observe/evidence.js +9 -2
- package/dist/observe/readiness-service.js +9 -0
- package/dist/observe/readiness.js +15 -8
- package/dist/observe/system-trace-android.js +135 -0
- package/dist/observe/system-trace.js +285 -0
- package/dist/server/debugger-handlers.js +38 -0
- package/dist/server/debugger-schema.js +42 -0
- package/dist/server/journey-schema.js +1 -0
- package/dist/server/system-trace-schema.js +17 -0
- package/dist/server/tool-definitions.js +6 -1
- package/dist/server/tool-handlers.js +203 -96
- package/dist/server-core.js +3 -3
- package/dist/server.js +34 -0
- package/dist/system/index.js +5 -4
- package/dist/utils/exec.js +2 -0
- package/dist/utils/java.js +14 -12
- package/dist/utils/operation-budget.js +2 -0
- package/dist/utils/resolve-device.js +2 -0
- package/docs/CHANGELOG.md +4 -0
- package/docs/specs/023-android-system-traces/device-evidence.json +38 -0
- package/docs/specs/023-android-system-traces/emulator-recheck.json +38 -0
- package/docs/specs/023-android-system-traces/intent.md +40 -0
- package/docs/specs/023-android-system-traces/plan.md +117 -0
- package/docs/specs/023-android-system-traces/spec.md +120 -0
- package/docs/specs/024-android-heap-dump-capture/intent.md +39 -0
- package/docs/specs/025-android-runtime-debugger/intent.md +40 -0
- package/docs/specs/025-android-runtime-debugger/plan.md +104 -0
- package/docs/specs/025-android-runtime-debugger/spec.md +182 -0
- package/docs/tools/TOOLS.md +3 -1
- package/docs/tools/debugger.md +104 -0
- package/docs/tools/evidence.md +5 -2
- package/docs/tools/observe.md +12 -5
- package/docs/tools/system-traces.md +126 -0
- package/package.json +1 -1
- package/src/debugger/android.ts +65 -0
- package/src/debugger/guard.ts +26 -0
- package/src/debugger/sessions.ts +168 -0
- package/src/debugger/worker.ts +122 -0
- package/src/interact/index.ts +16 -15
- package/src/observe/evidence.ts +9 -2
- package/src/observe/readiness-service.ts +5 -0
- package/src/observe/readiness.ts +12 -6
- package/src/observe/system-trace-android.ts +133 -0
- package/src/observe/system-trace.ts +218 -0
- package/src/server/debugger-handlers.ts +29 -0
- package/src/server/debugger-schema.ts +37 -0
- package/src/server/journey-schema.ts +1 -0
- package/src/server/system-trace-schema.ts +17 -0
- package/src/server/tool-definitions.ts +6 -1
- package/src/server/tool-handlers.ts +92 -7
- package/src/server-core.ts +3 -3
- package/src/server.ts +24 -0
- package/src/system/index.ts +7 -5
- package/src/utils/exec.ts +2 -0
- package/src/utils/java.ts +13 -12
- package/src/utils/operation-budget.ts +2 -0
- package/src/utils/resolve-device.ts +2 -0
- package/test/device/automated/debugger/runtime.android.test.ts +203 -0
- package/test/device/automated/observe/system-trace.smoke.ts +104 -0
- package/test/fixtures/debugger-app/MainActivity.java +46 -0
- package/test/fixtures/debugger-app/NoLocals.java +7 -0
- package/test/fixtures/debugger-app/README.md +13 -0
- package/test/fixtures/debugger-app/build.ts +29 -0
- package/test/helpers/perfetto.ts +59 -0
- package/test/unit/debugger/guards.test.ts +46 -0
- package/test/unit/debugger/native.test.ts +33 -0
- package/test/unit/debugger/sessions.test.ts +83 -0
- package/test/unit/observe/readiness.test.ts +3 -1
- package/test/unit/observe/system-trace-android.test.ts +52 -0
- package/test/unit/observe/system-trace.test.ts +166 -0
- package/test/unit/server/system-trace.test.ts +64 -0
- package/worker/DebuggerWorker.java +160 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"status": "PASS",
|
|
3
|
+
"build_sha256": "f59ec5112751295517ce3fd6fafe78e06ca009f30ecfcc560c872bfbf1cf86ee",
|
|
4
|
+
"runtime": "v23.11.0",
|
|
5
|
+
"server": {
|
|
6
|
+
"name": "mobile-debug-mcp",
|
|
7
|
+
"version": "0.33.0"
|
|
8
|
+
},
|
|
9
|
+
"device": "emulator-5554",
|
|
10
|
+
"osVersion": "16",
|
|
11
|
+
"starting_state": "System Settings fixture",
|
|
12
|
+
"journey": "start Settings, assert baseline Settings-owned resource visible in UI tree; explicit trace association",
|
|
13
|
+
"trace_id": "7a0bdca9-f64f-4c4f-b204-5c9b7527c2c6",
|
|
14
|
+
"correlation_id": "6622a71c-e556-4e27-b228-1eb0328f0637",
|
|
15
|
+
"phases": {
|
|
16
|
+
"capture_started_at_ms": 1793359970395,
|
|
17
|
+
"capture_completed_at_ms": 1793359976096
|
|
18
|
+
},
|
|
19
|
+
"artifact_bytes": 870332,
|
|
20
|
+
"content": {
|
|
21
|
+
"packets": 227,
|
|
22
|
+
"ftrace_bundles": 210,
|
|
23
|
+
"events": 19833,
|
|
24
|
+
"compact_sched_bundles": 210,
|
|
25
|
+
"validation": "local protobuf structure, trace config duration and timestamped ftrace/compact scheduler content; not full Perfetto analysis"
|
|
26
|
+
},
|
|
27
|
+
"durationContent": {
|
|
28
|
+
"packets": 51,
|
|
29
|
+
"ftrace_bundles": 35,
|
|
30
|
+
"events": 4596,
|
|
31
|
+
"compact_sched_bundles": 35,
|
|
32
|
+
"validation": "local protobuf structure, trace config duration and timestamped ftrace/compact scheduler content; not full Perfetto analysis"
|
|
33
|
+
},
|
|
34
|
+
"cancel": "PASS",
|
|
35
|
+
"expired_journey": "PASS",
|
|
36
|
+
"active_shutdown": "PASS",
|
|
37
|
+
"cleanup": "Device capture files removed; test host artifacts removed in finally. No settings or app data changed. Settings remains foreground."
|
|
38
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"status": "PASS",
|
|
3
|
+
"build_sha256": "f59ec5112751295517ce3fd6fafe78e06ca009f30ecfcc560c872bfbf1cf86ee",
|
|
4
|
+
"runtime": "v23.11.0",
|
|
5
|
+
"server": {
|
|
6
|
+
"name": "mobile-debug-mcp",
|
|
7
|
+
"version": "0.33.0"
|
|
8
|
+
},
|
|
9
|
+
"device": "emulator-5554",
|
|
10
|
+
"osVersion": "16",
|
|
11
|
+
"starting_state": "System Settings fixture",
|
|
12
|
+
"journey": "start Settings, assert baseline Settings-owned resource visible in UI tree; explicit trace association",
|
|
13
|
+
"trace_id": "af7507e9-90ee-48e1-af43-f81bf3a66840",
|
|
14
|
+
"correlation_id": "dfe3e3ae-54f1-4c7a-afad-0c5ee76ede12",
|
|
15
|
+
"phases": {
|
|
16
|
+
"capture_started_at_ms": 1793360613568,
|
|
17
|
+
"capture_completed_at_ms": 1793360619070
|
|
18
|
+
},
|
|
19
|
+
"artifact_bytes": 996053,
|
|
20
|
+
"content": {
|
|
21
|
+
"packets": 230,
|
|
22
|
+
"ftrace_bundles": 213,
|
|
23
|
+
"events": 23054,
|
|
24
|
+
"compact_sched_bundles": 213,
|
|
25
|
+
"validation": "local protobuf structure, trace config duration and timestamped ftrace/compact scheduler content; not full Perfetto analysis"
|
|
26
|
+
},
|
|
27
|
+
"durationContent": {
|
|
28
|
+
"packets": 54,
|
|
29
|
+
"ftrace_bundles": 36,
|
|
30
|
+
"events": 3094,
|
|
31
|
+
"compact_sched_bundles": 36,
|
|
32
|
+
"validation": "local protobuf structure, trace config duration and timestamped ftrace/compact scheduler content; not full Perfetto analysis"
|
|
33
|
+
},
|
|
34
|
+
"cancel": "PASS",
|
|
35
|
+
"expired_journey": "PASS",
|
|
36
|
+
"active_shutdown": "PASS",
|
|
37
|
+
"cleanup": "Device capture files removed; test host artifacts removed in finally. No settings or app data changed. Settings remains foreground."
|
|
38
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Intent: Android system traces
|
|
2
|
+
|
|
3
|
+
Originator: repository maintainer, through GitHub roadmap issue #67.
|
|
4
|
+
Date: 2026-10-30. Status: approved.
|
|
5
|
+
Source: [issue #67](https://github.com/clivejefferies/mobile-debug-tools/issues/67), roadmap priority 4 of 9.
|
|
6
|
+
|
|
7
|
+
## Problem and outcome
|
|
8
|
+
|
|
9
|
+
MCP clients investigating slow or frozen Android interactions need system-level
|
|
10
|
+
performance evidence alongside existing journey and observation evidence.
|
|
11
|
+
The server currently has no system-trace capture capability.
|
|
12
|
+
|
|
13
|
+
Enable clients to start a bounded Android system trace, run an existing journey,
|
|
14
|
+
stop capture, and obtain a local Perfetto artifact with device, capture timing,
|
|
15
|
+
and correlation metadata. Detect available profiling capabilities explicitly and
|
|
16
|
+
report unsupported environments, failures, cancellation, and cleanup outcomes.
|
|
17
|
+
|
|
18
|
+
## Scope and success criteria
|
|
19
|
+
|
|
20
|
+
- Android capture around existing journeys, reusing established device targeting
|
|
21
|
+
and correlated-evidence conventions.
|
|
22
|
+
- Optional profiling tooling with explicit capability and prerequisite reporting.
|
|
23
|
+
- Local artifact handling and bounded capture/resource ownership.
|
|
24
|
+
- Successful start/stop and artifact retrieval on a supported Android fixture.
|
|
25
|
+
- Explicit failure/cancellation outcomes and cleanup of session-owned resources.
|
|
26
|
+
|
|
27
|
+
## Exclusions and open decisions
|
|
28
|
+
|
|
29
|
+
Exclude iOS tracing, runtime debugging, heap dumps, automatic performance diagnosis,
|
|
30
|
+
and changes to journey interaction semantics. Do not upload trace contents.
|
|
31
|
+
|
|
32
|
+
Specification must establish the supported backend/tooling, tool contracts,
|
|
33
|
+
capture limits/configuration, concurrent-session rules, cancellation/recovery,
|
|
34
|
+
artifact retention, privacy handling, and verification prerequisites. The issue's
|
|
35
|
+
Android CLI integration is provisional and requires investigation.
|
|
36
|
+
|
|
37
|
+
## Approval
|
|
38
|
+
|
|
39
|
+
The maintainer approved the complete captured intent with “yes” in this
|
|
40
|
+
conversation on 2026-10-30. Specification approval remains pending.
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Plan: Android system traces
|
|
2
|
+
|
|
3
|
+
Authorised by [intent](intent.md) (“yes”) and [specification](spec.md)
|
|
4
|
+
(“looks good”, followed by “great”), 2026-10-30 in this conversation.
|
|
5
|
+
|
|
6
|
+
## Implementation
|
|
7
|
+
|
|
8
|
+
- [x] Implement ADB capability/capture adapter with PID identity and bounded files.
|
|
9
|
+
- [x] Implement serialised sessions, deadlines, retries, retention and shutdown.
|
|
10
|
+
- [x] Register strict schemas/tools, link journeys and propagate trace evidence.
|
|
11
|
+
- [x] Add regression/device tests and align README/tool docs/changelog.
|
|
12
|
+
- [x] Review ownership/failure/concurrency/contracts; run verification below.
|
|
13
|
+
|
|
14
|
+
Use existing device resolver, ADB path helper, execution helper and async-local
|
|
15
|
+
evidence context. Node >=18; CI uses Node 18 and local runtime is recorded below.
|
|
16
|
+
No installation, publishing, commit or push is required. Android CLI absent;
|
|
17
|
+
ADB/Perfetto available on emulator-5554 API 36. Inspect trace content with a local
|
|
18
|
+
parser or Perfetto UI; missing viewer/parser blocks artifact-format proof, not
|
|
19
|
+
implementation. Avoid downloading tooling without need.
|
|
20
|
+
|
|
21
|
+
## Verification
|
|
22
|
+
|
|
23
|
+
| Criteria | Evidence |
|
|
24
|
+
| --- | --- |
|
|
25
|
+
| 1 capability/no side effects | Fake adapter/ADB tests, strict runtime/registration schemas, iOS rejection. |
|
|
26
|
+
| 2 artifact/correlation | Updated stdio server: emulator start, Settings journey, stop, nonempty bounded artifact and Perfetto content inspection. |
|
|
27
|
+
| 3 lifecycle/isolation | Deterministic injected adapter/clock tests: duration, cancel, repeated controls, contention, stale IDs, reused PID, concurrent devices. |
|
|
28
|
+
| 4 failures/cleanup | Tests: missing tool/service, start/stop/pull timeout, disconnect, partial transfer, shutdown and mismatch without journey dispatch; real cancel/expiry. |
|
|
29
|
+
| 5 compatibility | Existing unit/device suites and additive schema/serialization assertions. |
|
|
30
|
+
|
|
31
|
+
Commands: `node --import tsx test/unit/observe/system-trace.test.ts`,
|
|
32
|
+
`node --import tsx test/unit/server/system-trace.test.ts`, `npm run verify`,
|
|
33
|
+
`npm run test:device`. Local verify adds plugin checks beyond CI; CI device
|
|
34
|
+
workflow is manual and Android API 30, local suite additionally requires iOS.
|
|
35
|
+
|
|
36
|
+
Device smoke: fresh discovery, explicit Android emulator, rebuilt 0.33.0 stdio
|
|
37
|
+
server. Start in Settings; capture a start_app Settings journey; assert identifiers,
|
|
38
|
+
state, artifact size and cleanup. Repeat cancellation, duration expiry and invalid
|
|
39
|
+
journey reference. Inspect resulting Perfetto packets; save metadata only in this
|
|
40
|
+
directory. Remove test-owned host artifacts; no app data/settings changes. State
|
|
41
|
+
pass/fail/blocked/unrun, build hash, device and gaps. Physical-device capture and
|
|
42
|
+
installed/published package remain separate from emulator evidence.
|
|
43
|
+
|
|
44
|
+
## Results
|
|
45
|
+
|
|
46
|
+
Implementation and focused review completed on 2026-10-30 on
|
|
47
|
+
`codex/android-system-traces`, based on `a74238b`. Changes remain uncommitted;
|
|
48
|
+
no push, publication or installed-package update was requested.
|
|
49
|
+
|
|
50
|
+
- Local runtime: Node 23.11.0 / npm 10.9.2. CI's Node 18 runtime remains **unrun**
|
|
51
|
+
locally; the final CI workflow was not invoked. Existing CI uses Node 18 and
|
|
52
|
+
manual Android API 30 integration; local device evidence uses API 36.
|
|
53
|
+
- Focused session, Android adapter and tool/journey contract checks: **pass**.
|
|
54
|
+
Cover strict input/error flags, unsupported iOS/no dispatch, missing native
|
|
55
|
+
prerequisites, bounded capture, successful transfer permissions, cancellation,
|
|
56
|
+
automatic duration completion, failed/empty/oversized/partial transfers,
|
|
57
|
+
stop/start timeouts, unavailable devices, retry, PID reuse, naturally exiting
|
|
58
|
+
processes, simultaneous control calls, parallel devices, active shutdown,
|
|
59
|
+
shutdown racing start, metadata expiry/eviction and trace evidence isolation.
|
|
60
|
+
- `npm run verify`: **pass** on the final code (68 unit files, lint, TypeScript
|
|
61
|
+
build, plugin consistency). The tsx CLI requires local IPC
|
|
62
|
+
blocked by the sandbox, so the required command ran with approved escalation.
|
|
63
|
+
- `npm run test:device`: **pass** on the final runtime code, eight smoke files.
|
|
64
|
+
Existing Android/iOS screenshot, tree, log and correlation checks pass; correlation
|
|
65
|
+
pins emulator-5554 and iPhone 17 Pro simulator
|
|
66
|
+
F9243BAF-62A8-4990-8A99-17F527F56FDA (iOS 26.4). The six older platform smokes use
|
|
67
|
+
automatic targeting and do not all identify the selected device.
|
|
68
|
+
- Focused updated stdio-server trace journeys: **pass** on Android 16
|
|
69
|
+
emulator-5554, local package 0.33.0. Final combined runtime hash:
|
|
70
|
+
`f59ec5112751295517ce3fd6fafe78e06ca009f30ecfcc560c872bfbf1cf86ee`.
|
|
71
|
+
Fresh Settings baseline, traced launch and semantic assertion of a visible
|
|
72
|
+
Settings-owned resource, matching trace/journey/step IDs, local artifact,
|
|
73
|
+
idempotent stop, inactive reference rejection, cancellation, 1,001 ms duration
|
|
74
|
+
expiry, and closing another server during active capture all pass.
|
|
75
|
+
- Artifact format/content: **pass** using the local protobuf decoder: complete
|
|
76
|
+
Trace.packet boundaries, embedded requested duration, timestamped ftrace events
|
|
77
|
+
and compact scheduler bundles. Final full-suite artifact: 870,332 bytes,
|
|
78
|
+
227 packets, 19,833 timestamped events and 210 compact scheduler bundles.
|
|
79
|
+
This is structural/content evidence, not full Perfetto UI/SQL analysis.
|
|
80
|
+
- Device metadata is in [device-evidence.json](device-evidence.json), without
|
|
81
|
+
trace contents, UI text, screenshots or logs. Test-owned device/host capture
|
|
82
|
+
artifacts are removed. No device settings or app data changed; Settings remains
|
|
83
|
+
foreground. Final device-directory inspection confirms no test trace files
|
|
84
|
+
remain. The first shutdown regression test's bounded leftover file was
|
|
85
|
+
removed individually after confirming its process had exited.
|
|
86
|
+
- Review corrected stdin-end cleanup (the SDK does not emit transport close on
|
|
87
|
+
stdin EOF), process-exit races around identity reads/SIGTERM, error flags for
|
|
88
|
+
unsupported action-control fields, and conservative journey coverage when
|
|
89
|
+
capture state becomes unavailable. Unreadable/reused live identity still fails
|
|
90
|
+
closed. No outstanding findings in the implemented scope.
|
|
91
|
+
- The initial extra UI assertion expected a Settings title, but Settings resumed
|
|
92
|
+
Network & internet. The smoke now establishes a fresh Settings-owned resource
|
|
93
|
+
baseline and proves that element is visible during the journey. No assertion
|
|
94
|
+
was removed, and no fixture settings were changed.
|
|
95
|
+
- Physical Android capture, actual unplug/disconnect and hard-crash recovery:
|
|
96
|
+
**unrun**; deterministic adapter/session failure coverage passes. iOS tracing is
|
|
97
|
+
explicitly unsupported, with rejection tested. Installed/published-package and
|
|
98
|
+
full trace-analysis verification remain **unrun**.
|
|
99
|
+
|
|
100
|
+
Validation logs: `/tmp/mobile-debug-system-traces-verify.log`,
|
|
101
|
+
`/tmp/mobile-debug-system-traces-device.log`, and
|
|
102
|
+
`/tmp/mobile-debug-system-traces-focused-device.log`.
|
|
103
|
+
Changed documentation links, evidence JSON and whitespace checks pass.
|
|
104
|
+
|
|
105
|
+
## Emulator recheck — 2026-10-30
|
|
106
|
+
|
|
107
|
+
User requested a fresh emulator test. Rebuilt with `npm run build` (**pass**),
|
|
108
|
+
then ran `SYSTEM_TRACE_EVIDENCE_PATH=docs/specs/023-android-system-traces/emulator-recheck.json node --import tsx test/device/automated/observe/system-trace.smoke.ts`
|
|
109
|
+
on emulator-5554, Android 16, local stdio server 0.33.0, same runtime hash as above.
|
|
110
|
+
**Pass:** fresh Settings UI baseline, traced launch and semantic visibility
|
|
111
|
+
assertion, correlated IDs, nonempty Perfetto artifact with timestamped kernel and
|
|
112
|
+
scheduler content, repeated stop, inactive reference rejection, cancellation,
|
|
113
|
+
1,001 ms expiry, and active-capture server shutdown cleanup. Artifact: 996,053
|
|
114
|
+
bytes, 230 packets, 23,054 timestamped ftrace events. Test-owned host/device trace
|
|
115
|
+
files removed; no settings or app data changed. Settings remains foreground.
|
|
116
|
+
Metadata: [emulator-recheck.json](emulator-recheck.json). Full Perfetto analysis,
|
|
117
|
+
physical devices and failure-by-unplug were not part of this recheck.
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# Specification: Android system traces
|
|
2
|
+
|
|
3
|
+
Date: 2026-10-30. Status: approved.
|
|
4
|
+
Source: [issue #67](https://github.com/clivejefferies/mobile-debug-tools/issues/67).
|
|
5
|
+
[Intent](intent.md) approved by the maintainer’s “yes” in this conversation.
|
|
6
|
+
Specification approved by “looks good” followed by “great” on 2026-10-30.
|
|
7
|
+
|
|
8
|
+
## Backend and boundaries
|
|
9
|
+
|
|
10
|
+
Use the device’s Perfetto CLI through existing ADB discovery/execution helpers.
|
|
11
|
+
Require Android API 29+, authorised ADB, supported background-wait options,
|
|
12
|
+
tracing services, and writable trace storage. Probe capabilities without starting
|
|
13
|
+
capture. No SDK installation, root, external downloads, Android CLI dependency,
|
|
14
|
+
or fallback to legacy systrace. iOS returns unsupported before side effects.
|
|
15
|
+
Android CLI is absent locally; official Android documentation supports direct
|
|
16
|
+
ADB capture. Analysis skills/SQL and trace interpretation remain out of scope.
|
|
17
|
+
|
|
18
|
+
## Tools and schemas
|
|
19
|
+
|
|
20
|
+
All objects reject unknown fields. IDs are opaque server-generated UUIDs.
|
|
21
|
+
|
|
22
|
+
- `get_system_trace_capabilities({platform, deviceId?})`: resolve one device;
|
|
23
|
+
return supported/backend, resolved device, prerequisites, limitations, reasons.
|
|
24
|
+
- `start_system_trace({platform, deviceId?, durationMs?})`: integer duration
|
|
25
|
+
1,000–120,000, default 30,000. Return recording session only after Perfetto’s
|
|
26
|
+
data-source-start acknowledgement; otherwise return failure and cleanup result.
|
|
27
|
+
- `get_system_trace_status({traceId})`: reconcile owned process/deadline and return
|
|
28
|
+
current state; finalise automatically completed capture when queried.
|
|
29
|
+
- `stop_system_trace({traceId})`: gracefully stop, retrieve and finalise artifact.
|
|
30
|
+
- `cancel_system_trace({traceId})`: stop and discard owned device/partial local
|
|
31
|
+
files; return cancelled plus cleanup outcome. Completed artifacts are retained.
|
|
32
|
+
|
|
33
|
+
Trace ID determines the pinned device; control calls cannot redirect it. Unknown,
|
|
34
|
+
expired, or previous-server IDs return `TRACE_NOT_FOUND`. One recording per device,
|
|
35
|
+
maximum four server-wide; reject excess with `TRACE_BUSY`. Concurrent operations
|
|
36
|
+
on one session serialise; repeated terminal operations return the stored outcome.
|
|
37
|
+
Retain at most 100 terminal records for 10 minutes; expiry never deletes completed
|
|
38
|
+
artifacts. Starting/active records are not evicted.
|
|
39
|
+
|
|
40
|
+
Responses use JSON text with `trace_id`, `session_id`, `device`, `backend: perfetto`,
|
|
41
|
+
`state` (starting/recording/stopping/completed/cancelled/failed), `reason`,
|
|
42
|
+
`capture_started_at_ms`, `capture_completed_at_ms`, `completion_reason`
|
|
43
|
+
(requested/duration_limit/cancelled/error), `artifact`, `cleanup`, and
|
|
44
|
+
`correlation_ids`. Unreached values are null. Artifact is null or contains absolute
|
|
45
|
+
`path`, `format: perfetto`, and `size_bytes`. Cleanup reports pending/complete/failed
|
|
46
|
+
and remaining owned resources. Errors retain known session metadata, use MCP
|
|
47
|
+
`isError`, and distinguish INVALID_ARGUMENT, UNSUPPORTED_PLATFORM,
|
|
48
|
+
TRACE_UNSUPPORTED, TRACE_BUSY, TRACE_NOT_FOUND, TRACE_START_FAILED,
|
|
49
|
+
TRACE_STOP_FAILED, TRACE_ARTIFACT_FAILED, ACTION_TIMEOUT, and TRACE_CANCELLED.
|
|
50
|
+
Capability queries with unsupported prerequisites are normal supported:false results.
|
|
51
|
+
|
|
52
|
+
## Capture and lifecycle
|
|
53
|
+
|
|
54
|
+
Use a fixed scheduling/input/rendering preset (sched, freq, idle, am, wm, gfx,
|
|
55
|
+
view, input), 16 MiB ring buffer, and maximum output 32 MiB. Report enabled sources
|
|
56
|
+
and unavailable categories; unavailable required sched/input categories reject
|
|
57
|
+
start. No arbitrary config, package wildcard annotations, heap, screenshots, or
|
|
58
|
+
logcat data sources. This is device-wide evidence, not app-private capture.
|
|
59
|
+
|
|
60
|
+
Generate unique device paths under `/data/misc/perfetto-traces/`. Start with
|
|
61
|
+
background-wait and device-side duration limit. Record PID and process identity;
|
|
62
|
+
before SIGTERM validate both identity and unique output path. Never kill by process
|
|
63
|
+
name or signal a reused/unverified PID. Poll boundedly for termination before pull;
|
|
64
|
+
uncertain stop yields failure, never a successful artifact. Allow 35 seconds for
|
|
65
|
+
start acknowledgement, 10 for stop, and 30 for pull; subprocesses must terminate
|
|
66
|
+
on deadlines. Failed cleanup is explicit and retryable through control calls.
|
|
67
|
+
|
|
68
|
+
A server timer stops/finalises at duration; device duration also bounds capture
|
|
69
|
+
if the server dies. Normal shutdown attempts owned cleanup within 10 seconds;
|
|
70
|
+
crash recovery is not promised. A crash may leave its uniquely named device file
|
|
71
|
+
for manual removal; no restart-wide sweep. Host subprocess termination alone is
|
|
72
|
+
never reported as stopping device capture.
|
|
73
|
+
|
|
74
|
+
Pull into a unique server-created temporary directory with restrictive permissions;
|
|
75
|
+
rename only after successful transfer and nonempty size <=32 MiB. Return paths,
|
|
76
|
+
never binary/base64 contents. Remove owned device files after verified pull, retain
|
|
77
|
+
local artifacts for user-managed deletion. Pull failure retains bounded device
|
|
78
|
+
output for retry; cancelled partial files are removed. No upload or telemetry.
|
|
79
|
+
|
|
80
|
+
## Journey and evidence association
|
|
81
|
+
|
|
82
|
+
Add optional `systemTraceId` to `run_journey`. Validate active same-server,
|
|
83
|
+
same-device recording before any journey input; mismatch/inactive ID fails without
|
|
84
|
+
executing steps. Preserve existing journey semantics and correlation IDs. It is
|
|
85
|
+
explicit bracketing: start, run journey, stop; journeys do not own trace lifetime.
|
|
86
|
+
A failed journey leaves capture available for stop/cancel or duration expiry.
|
|
87
|
+
|
|
88
|
+
Extend evidence `trace_context` for explicitly linked journey/step observations:
|
|
89
|
+
`supported:true`, `trace_id`, `markers:[]`. Otherwise preserve the existing
|
|
90
|
+
unsupported/null context. Record linked journey correlation IDs in trace metadata;
|
|
91
|
+
report capture ending during a journey as partial coverage. No injected device
|
|
92
|
+
markers, clock synchronisation, causal claims, or inferred associations. Host UTC
|
|
93
|
+
intervals and monotonic duration do not claim alignment with device trace clocks.
|
|
94
|
+
|
|
95
|
+
## Acceptance and verification
|
|
96
|
+
|
|
97
|
+
1. Capability detection and invalid arguments cause no recording side effects.
|
|
98
|
+
2. Emulator start → existing Settings journey → stop produces a nonempty local
|
|
99
|
+
Perfetto artifact and matching trace/journey evidence IDs; inspect with an
|
|
100
|
+
available trace parser/viewer before claiming valid Perfetto content.
|
|
101
|
+
3. Duration completion, explicit cancel, repeated controls, same-device contention,
|
|
102
|
+
concurrent devices, stale IDs, PID reuse and cleanup failures have deterministic tests.
|
|
103
|
+
4. Test missing tools/services, start/stop/pull timeout, device disconnect, partial
|
|
104
|
+
transfer, shutdown, and journey mismatch; report real-device gaps explicitly.
|
|
105
|
+
5. Existing clients without tracing retain contracts. Run maintainer verification,
|
|
106
|
+
automated device suite, and focused updated-server trace journeys.
|
|
107
|
+
|
|
108
|
+
Affected: new observe/session adapter, tool registration/validation/handlers,
|
|
109
|
+
journey schema/execution, evidence context/types, lifecycle shutdown, tests,
|
|
110
|
+
README/tool docs/changelog. Main risks: platform source availability, process
|
|
111
|
+
ownership races, finalisation correctness, storage/privacy, and absent parser.
|
|
112
|
+
|
|
113
|
+
Baseline: local package 0.33.0; emulator-5554 Android API 36 exposes Perfetto
|
|
114
|
+
background-wait, bounded output, and graceful PID-stop options. Pixel 9 Pro is
|
|
115
|
+
also connected but untested. ADB inspection passed after sandbox escalation;
|
|
116
|
+
no capture or new behaviour has been verified. Physical-device and iOS tests
|
|
117
|
+
remain unrun. Approval of this complete specification authorises implementation.
|
|
118
|
+
|
|
119
|
+
Sources: [Android Perfetto CLI](https://developer.android.com/tools/perfetto),
|
|
120
|
+
[Perfetto background capture](https://perfetto.dev/docs/learning-more/tracing-in-background).
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Intent: Android heap dump capture
|
|
2
|
+
|
|
3
|
+
Originator: clivejefferies, through GitHub roadmap issue #69 and the current conversation.
|
|
4
|
+
Date: 2026-10-30. Status: parked; intent not approved.
|
|
5
|
+
Source: [issue #69](https://github.com/clivejefferies/mobile-debug-tools/issues/69), roadmap priority 6 of 9.
|
|
6
|
+
|
|
7
|
+
## Problem and outcome
|
|
8
|
+
|
|
9
|
+
MCP clients investigating Android memory growth and out-of-memory failures need
|
|
10
|
+
a heap dump they can inspect with external analysis tools. Provide capture of a
|
|
11
|
+
supported running Android app's heap and return a local artifact with device,
|
|
12
|
+
app, capture-time, and artifact-path metadata.
|
|
13
|
+
|
|
14
|
+
## Scope and success criteria
|
|
15
|
+
|
|
16
|
+
- Capture and retrieve an Android heap dump for an explicitly targeted app/process.
|
|
17
|
+
- Report device, app/process identity, capture timing, and the local artifact path.
|
|
18
|
+
- Detect unsupported configurations and report failed, cancelled, and timed-out
|
|
19
|
+
captures clearly.
|
|
20
|
+
- Bound capture work and clean up capture-owned temporary resources.
|
|
21
|
+
- Verify successful artifact retrieval on a supported Android fixture, alongside
|
|
22
|
+
meaningful failure and cleanup checks.
|
|
23
|
+
|
|
24
|
+
## Exclusions and open decisions
|
|
25
|
+
|
|
26
|
+
Exclude iOS capture, deep heap analysis, leak diagnosis, automatic uploads, and
|
|
27
|
+
changes to app behaviour or permissions to enable capture.
|
|
28
|
+
|
|
29
|
+
Specification must resolve supported app/device configurations, capture backend
|
|
30
|
+
(including whether optional Android CLI tooling is useful), process selection,
|
|
31
|
+
tool contracts, limits, cancellation, concurrency, artifact retention, privacy,
|
|
32
|
+
and device-verification prerequisites. Heap contents can include sensitive app
|
|
33
|
+
data; capture and artifact handling must make their ownership explicit.
|
|
34
|
+
|
|
35
|
+
## Approval
|
|
36
|
+
|
|
37
|
+
The user switched to Android runtime debugger work before approving this intent.
|
|
38
|
+
Heap capture remains parked pending explicit agreement on the complete intent. No specification or
|
|
39
|
+
implementation approval is recorded.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Intent: Android runtime debugger
|
|
2
|
+
|
|
3
|
+
Originator: clivejefferies, through GitHub roadmap issue #68 and the current conversation.
|
|
4
|
+
Date: 2026-10-30. Status: approved.
|
|
5
|
+
Source: [issue #68](https://github.com/clivejefferies/mobile-debug-tools/issues/68), roadmap priority 5 of 9.
|
|
6
|
+
|
|
7
|
+
## Problem and outcome
|
|
8
|
+
|
|
9
|
+
MCP clients investigating incorrect Android app behaviour need runtime evidence
|
|
10
|
+
to test hypotheses: where execution stopped, how it got there, and the values
|
|
11
|
+
available at that point. Enable a bounded debugging session against an explicitly
|
|
12
|
+
selected debuggable app process on a specific Android device.
|
|
13
|
+
|
|
14
|
+
## Scope and success criteria
|
|
15
|
+
|
|
16
|
+
- Attach and detach, set source breakpoints, and report stop events.
|
|
17
|
+
- Inspect stacks and locals while paused; step and resume execution.
|
|
18
|
+
- Bind sessions to device/process identity and invalidate inspection references
|
|
19
|
+
when execution resumes or the session ends.
|
|
20
|
+
- Coordinate UI actions and verification with known debugger pauses.
|
|
21
|
+
- Report unsupported configurations and setup/runtime failures explicitly.
|
|
22
|
+
- On detach or failure, clean up only session-owned resources and handle
|
|
23
|
+
debugger-owned suspension explicitly.
|
|
24
|
+
- Verify the complete journey on a debuggable Android fixture.
|
|
25
|
+
|
|
26
|
+
## Exclusions and open decisions
|
|
27
|
+
|
|
28
|
+
Defer arbitrary expression evaluation, value mutation, coroutine reconstruction,
|
|
29
|
+
native debugging, iOS debugging, heap capture, and production-app enablement.
|
|
30
|
+
|
|
31
|
+
The ticket proposes an independently developed JDI worker. Specification must
|
|
32
|
+
validate that backend and establish prerequisites, MCP contracts, source/line
|
|
33
|
+
mapping limits, suspension policy, event delivery, timeouts, cancellation,
|
|
34
|
+
concurrency, crash recovery, privacy, and runnable fixture coverage.
|
|
35
|
+
|
|
36
|
+
## Approval
|
|
37
|
+
|
|
38
|
+
The user selected Android runtime debugger work with “ok, lets pick that up” and
|
|
39
|
+
approved the complete captured intent with “yes” on 2026-10-30 in this
|
|
40
|
+
conversation. Specification approval remains pending.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Plan: Android runtime debugger
|
|
2
|
+
|
|
3
|
+
2026-10-30. [Intent](intent.md) and [spec](spec.md) explicitly approved by the
|
|
4
|
+
user's successive “yes” responses in this conversation. Implementation authorized.
|
|
5
|
+
|
|
6
|
+
## Implementation
|
|
7
|
+
|
|
8
|
+
- [x] Build optional JDK 17+ worker compilation/cache and bounded JSON-lines client.
|
|
9
|
+
- [x] Implement JDI attach, breakpoint events, bounded inspection, step/resume,
|
|
10
|
+
reference epochs, expiry and owned cleanup.
|
|
11
|
+
- [x] Implement explicit Android process identity/JDWP targeting and owned forwarding.
|
|
12
|
+
- [x] Register strict MCP contracts and serialize session transitions.
|
|
13
|
+
- [x] Integrate pause evidence, dispatch/wait/lifecycle guards and shutdown.
|
|
14
|
+
- [x] Add isolated debuggable fixture, regression tests and native journeys.
|
|
15
|
+
- [x] Align capabilities, packaging, tools, README and changelog; review consistency.
|
|
16
|
+
|
|
17
|
+
## Verification
|
|
18
|
+
|
|
19
|
+
| Criteria | Checks |
|
|
20
|
+
| --- | --- |
|
|
21
|
+
| Explicit targeting/unsupported/ambiguity | Native adapter tests; emulator fixture attach and capability calls |
|
|
22
|
+
| Breakpoints/stacks/locals/steps | Real Android fixture through built MCP stdio; no separate JVM debuggee required |
|
|
23
|
+
| Stale references/bounds/metadata | Unit contract checks plus Android stale inspection, bounded locals and source metadata checks |
|
|
24
|
+
| UI pause and races | Guard/readiness unit checks; paused fixture action, wait and journey; resumed UI assertion |
|
|
25
|
+
| Detach/failure/expiry/ownership | Unit worker/session tests, native disconnect and forward comparison |
|
|
26
|
+
| Packaging/compatibility | npm pack --dry-run; npm run verify; worker compile --release 17 |
|
|
27
|
+
| Existing runtime | npm run test:device; inspect actual platform coverage |
|
|
28
|
+
|
|
29
|
+
Prerequisites: Node >=18, JDK >=17 with javac/jdk.jdi; Android SDK platform/build-tools
|
|
30
|
+
36 for fixture, platform-tools. Host currently Java 23/ADB 37.0.1; emulator-5554
|
|
31
|
+
API 36 arm64 online outside sandbox. Existing CI: Node 18, manual Android JDK17/API30.
|
|
32
|
+
Use separate dev.mobiledebugmcp.debugfixture app with javac -g. Capture source-line
|
|
33
|
+
and known-local evidence; remove fixture, temporary outputs and owned forwards.
|
|
34
|
+
Physical device and iOS debugger verification are not required by this Android
|
|
35
|
+
scope; report them unrun/unsupported. Never treat readiness probes as debug proof.
|
|
36
|
+
|
|
37
|
+
## Results
|
|
38
|
+
|
|
39
|
+
Implemented and reviewed locally. No commit, push, release or hosted CI run performed.
|
|
40
|
+
|
|
41
|
+
- **PASS** `npm run verify`: lint, TypeScript build, all self-running unit tests,
|
|
42
|
+
agent-plugin consistency. Focused debugger tests cover schema strictness,
|
|
43
|
+
identity/PID reuse, exact-forward ownership, event wait concurrency/overflow,
|
|
44
|
+
stale stops, inspection versus mutation timeout policy, worker failure,
|
|
45
|
+
cleanup retry, no-read paused readiness and mid-journey preservation.
|
|
46
|
+
- **PASS** `npm run test:device`: existing Android/iOS screenshot, log, hierarchy
|
|
47
|
+
and correlated-evidence smoke checks; Android Perfetto journeys. The debugger
|
|
48
|
+
case reports **UNRUN** without its explicit device environment variable and is
|
|
49
|
+
independently verified below. Generic observations do not prove iOS debugging.
|
|
50
|
+
- **PASS** `MCP_DEBUGGER_DEVICE=emulator-5554 npx tsx test/device/automated/debugger/runtime.android.test.ts`:
|
|
51
|
+
built server 0.33.0 over actual MCP stdio; Node 23.11.0, worker JBR 25.0.3,
|
|
52
|
+
API 36/Android 16 arm64 emulator. Final full dist/worker fingerprint:
|
|
53
|
+
`5281d7127822e83355f6be1fcf81555827a078839364fb5115d4644d63d6048d`.
|
|
54
|
+
Isolated fixture starts at Ready; explicit attach, correct source breakpoint,
|
|
55
|
+
known local 42, 256-character string truncation and shallow object identity pass.
|
|
56
|
+
A separately compiled fixture with no local-variable tables establishes explicit
|
|
57
|
+
ART metadata uncertainty rather than an inferred empty scope. Removed pending
|
|
58
|
+
breakpoints remain removed when another request prepares the same class.
|
|
59
|
+
Into/over/out, stale frame rejection and resume pass; a fresh UI tree establishes
|
|
60
|
+
Result 43. Pending class resolves and stops; invalid line is rejected. Capability
|
|
61
|
+
deadline and missing app outcomes are explicit. Paused input/wait/lifecycle/journey
|
|
62
|
+
calls block; MCP event-wait cancellation leaves the stop intact. Reattach after
|
|
63
|
+
detach and process-exit cleanup pass. Closing MCP while actively paused removes
|
|
64
|
+
the owned forward; an independent fresh server observes Result 43 afterward.
|
|
65
|
+
Fixture package, temporary outputs and owned forwards are removed; pre-existing
|
|
66
|
+
forwards and device display settings are preserved.
|
|
67
|
+
- **PASS** extended stdio journey with `MCP_DEBUGGER_EXTENDED=1`: real 60-second
|
|
68
|
+
continuous-pause expiry despite repeated client polling, with complete owned
|
|
69
|
+
cleanup. Core-build fingerprint at that earlier checkpoint:
|
|
70
|
+
`76c0937b01aa296839783651bd9f445b0a1855f3e5416a4f3d41cf8a04a4757d`.
|
|
71
|
+
Later bounded-memory/heartbeat changes are covered by the final native journey;
|
|
72
|
+
pause-limit logic was unchanged. This earlier hash covers the named debugger
|
|
73
|
+
modules/worker, unlike the final complete dist/worker fingerprint.
|
|
74
|
+
- **PASS** standalone `javac --release 17 --add-modules jdk.jdi` compilation;
|
|
75
|
+
`npm pack --dry-run --json` includes worker source and built debugger/schema modules.
|
|
76
|
+
CI YAML parses; unit CI now compiles the worker on JDK 17 and checks packaging;
|
|
77
|
+
manual Android CI installs fixture SDK prerequisites and selects its emulator.
|
|
78
|
+
Hosted CI and JDK 17 runtime execution remain **UNRUN** locally.
|
|
79
|
+
|
|
80
|
+
Focused review corrected bounded JDWP subscription discovery, integer IPC,
|
|
81
|
+
terminal-state/cleanup races, import-order coupling, MCP stdout diagnostic leakage,
|
|
82
|
+
mutation cancellation/deadlines, device-specific guards, and event-poll activity
|
|
83
|
+
accounting, removed pending-breakpoint rebinding, per-location code-index identity,
|
|
84
|
+
and ART empty-table uncertainty. Test fixture content was moved below Android edge-to-edge system bars.
|
|
85
|
+
|
|
86
|
+
Remaining limits: physical-device debugging, API 30 CI execution, Windows/Linux
|
|
87
|
+
native runtime, Kotlin-specific metadata, and concurrent class-loader breakpoint
|
|
88
|
+
variants are **UNRUN**. ART empty/absent-variable metadata ambiguity is native-verified; the distinct JDI
|
|
89
|
+
AbsentInformationException path is code-inspected.
|
|
90
|
+
String truncation is native-verified; multi-device/race paths have unit coverage,
|
|
91
|
+
not exhaustive native coverage. Real
|
|
92
|
+
five-minute idle and 30-minute total expiry have not been wall-clock exercised;
|
|
93
|
+
all host expiry boundaries have deterministic unit checks;
|
|
94
|
+
the real pause expiry has. iOS/native/evaluation/mutation/coroutine debugging are
|
|
95
|
+
excluded. Abrupt host loss cannot guarantee confirmed device resumption.
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
Verification note: one late full run failed the unchanged conditional-action
|
|
99
|
+
150 ms action-budget assertion (`condition read does not consume the action
|
|
100
|
+
budget`). The focused test passed unchanged on both the current implementation
|
|
101
|
+
and an isolated HEAD archive; this does not prove the intermittent failure
|
|
102
|
+
predates this change. The final full `npm run verify` run passed in isolation, including the unchanged
|
|
103
|
+
conditional-action test. No timeout,
|
|
104
|
+
assertion, validation rule or test selection was weakened.
|