mobile-debug-mcp 0.32.4 → 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.
Files changed (170) hide show
  1. package/.agents/plugins/marketplace.json +20 -0
  2. package/.claude-plugin/marketplace.json +14 -0
  3. package/.cursor-plugin/marketplace.json +16 -0
  4. package/.github/copilot-instructions.md +7 -0
  5. package/.github/workflows/ci.yml +21 -0
  6. package/AGENTS.md +21 -10
  7. package/README.md +69 -4
  8. package/agent-plugin/.claude-plugin/plugin.json +20 -0
  9. package/agent-plugin/.codex-plugin/plugin.json +34 -0
  10. package/agent-plugin/.cursor-plugin/plugin.json +23 -0
  11. package/agent-plugin/.mcp.json +14 -0
  12. package/agent-plugin/README.md +9 -3
  13. package/agent-plugin/assets/mobile-debug-tools.svg +28 -0
  14. package/agent-plugin/mcp.json +1 -1
  15. package/agent-plugin/plugin.json +1 -1
  16. package/agent-plugin/skills/mobile-debug-mcp/SKILL.md +113 -1
  17. package/dist/debugger/android.js +78 -0
  18. package/dist/debugger/guard.js +30 -0
  19. package/dist/debugger/sessions.js +262 -0
  20. package/dist/debugger/worker.js +165 -0
  21. package/dist/interact/android.js +10 -4
  22. package/dist/interact/conditional-action.js +68 -0
  23. package/dist/interact/index.js +70 -14
  24. package/dist/interact/ios.js +14 -8
  25. package/dist/manage/android.js +4 -3
  26. package/dist/manage/ios.js +3 -2
  27. package/dist/observe/android.js +25 -4
  28. package/dist/observe/evidence.js +280 -0
  29. package/dist/observe/index.js +33 -6
  30. package/dist/observe/ios.js +25 -6
  31. package/dist/observe/readiness-service.js +124 -0
  32. package/dist/observe/readiness.js +88 -0
  33. package/dist/observe/recording.js +165 -0
  34. package/dist/observe/snapshot-metadata.js +10 -2
  35. package/dist/observe/system-trace-android.js +135 -0
  36. package/dist/observe/system-trace.js +285 -0
  37. package/dist/server/common.js +9 -0
  38. package/dist/server/condition-schema.js +32 -0
  39. package/dist/server/debugger-handlers.js +38 -0
  40. package/dist/server/debugger-schema.js +42 -0
  41. package/dist/server/journey-schema.js +4 -2
  42. package/dist/server/readiness-schema.js +12 -0
  43. package/dist/server/system-trace-schema.js +17 -0
  44. package/dist/server/tool-definitions.js +51 -0
  45. package/dist/server/tool-handlers.js +294 -105
  46. package/dist/server-core.js +3 -3
  47. package/dist/server.js +34 -0
  48. package/dist/system/index.js +5 -4
  49. package/dist/utils/exec.js +2 -0
  50. package/dist/utils/ios/utils.js +4 -4
  51. package/dist/utils/java.js +14 -12
  52. package/dist/utils/operation-budget.js +26 -2
  53. package/dist/utils/resolve-device.js +9 -0
  54. package/docs/CHANGELOG.md +15 -0
  55. package/docs/specs/020-conditional-actions/intent.md +62 -0
  56. package/docs/specs/020-conditional-actions/plan.md +214 -0
  57. package/docs/specs/020-conditional-actions/spec.md +301 -0
  58. package/docs/specs/021-app-readiness-signals/intent.md +40 -0
  59. package/docs/specs/021-app-readiness-signals/plan.md +102 -0
  60. package/docs/specs/021-app-readiness-signals/spec.md +144 -0
  61. package/docs/specs/022-correlated-evidence/device-evidence.json +60 -0
  62. package/docs/specs/022-correlated-evidence/intent.md +37 -0
  63. package/docs/specs/022-correlated-evidence/modul8-evidence.json +1062 -0
  64. package/docs/specs/022-correlated-evidence/modul8-selector-fix-evidence.json +336 -0
  65. package/docs/specs/022-correlated-evidence/plan.md +171 -0
  66. package/docs/specs/022-correlated-evidence/spec.md +123 -0
  67. package/docs/specs/023-android-system-traces/device-evidence.json +38 -0
  68. package/docs/specs/023-android-system-traces/emulator-recheck.json +38 -0
  69. package/docs/specs/023-android-system-traces/intent.md +40 -0
  70. package/docs/specs/023-android-system-traces/plan.md +117 -0
  71. package/docs/specs/023-android-system-traces/spec.md +120 -0
  72. package/docs/specs/024-android-heap-dump-capture/intent.md +39 -0
  73. package/docs/specs/025-android-runtime-debugger/intent.md +40 -0
  74. package/docs/specs/025-android-runtime-debugger/plan.md +104 -0
  75. package/docs/specs/025-android-runtime-debugger/spec.md +182 -0
  76. package/docs/specs/process.md +213 -0
  77. package/docs/tools/TOOLS.md +5 -0
  78. package/docs/tools/debugger.md +104 -0
  79. package/docs/tools/evidence.md +82 -0
  80. package/docs/tools/interact.md +125 -2
  81. package/docs/tools/observe.md +70 -0
  82. package/docs/tools/system-traces.md +126 -0
  83. package/package.json +1 -1
  84. package/scripts/agent-plugin.mjs +68 -8
  85. package/src/debugger/android.ts +65 -0
  86. package/src/debugger/guard.ts +26 -0
  87. package/src/debugger/sessions.ts +168 -0
  88. package/src/debugger/worker.ts +122 -0
  89. package/src/interact/android.ts +10 -4
  90. package/src/interact/conditional-action.ts +75 -0
  91. package/src/interact/index.ts +57 -28
  92. package/src/interact/ios.ts +14 -8
  93. package/src/manage/android.ts +4 -3
  94. package/src/manage/ios.ts +3 -2
  95. package/src/observe/android.ts +33 -6
  96. package/src/observe/evidence.ts +262 -0
  97. package/src/observe/index.ts +32 -8
  98. package/src/observe/ios.ts +32 -8
  99. package/src/observe/readiness-service.ts +94 -0
  100. package/src/observe/readiness.ts +84 -0
  101. package/src/observe/snapshot-metadata.ts +12 -1
  102. package/src/observe/system-trace-android.ts +133 -0
  103. package/src/observe/system-trace.ts +218 -0
  104. package/src/server/common.ts +7 -0
  105. package/src/server/condition-schema.ts +32 -0
  106. package/src/server/debugger-handlers.ts +29 -0
  107. package/src/server/debugger-schema.ts +37 -0
  108. package/src/server/journey-schema.ts +4 -2
  109. package/src/server/readiness-schema.ts +12 -0
  110. package/src/server/system-trace-schema.ts +17 -0
  111. package/src/server/tool-definitions.ts +49 -0
  112. package/src/server/tool-handlers.ts +182 -21
  113. package/src/server-core.ts +3 -3
  114. package/src/server.ts +24 -0
  115. package/src/system/index.ts +7 -5
  116. package/src/types.ts +30 -1
  117. package/src/utils/exec.ts +2 -0
  118. package/src/utils/ios/utils.ts +4 -4
  119. package/src/utils/java.ts +13 -12
  120. package/src/utils/operation-budget.ts +24 -2
  121. package/src/utils/resolve-device.ts +10 -0
  122. package/test/device/automated/debugger/runtime.android.test.ts +203 -0
  123. package/test/device/automated/observe/correlated-evidence.smoke.ts +70 -0
  124. package/test/device/automated/observe/system-trace.smoke.ts +104 -0
  125. package/test/device/manual/interact/conditional_actions.manual.ts +95 -0
  126. package/test/device/manual/interact/modul8_selector_tap.manual.ts +63 -0
  127. package/test/device/manual/interact/readiness.manual.ts +99 -0
  128. package/test/fixtures/debugger-app/MainActivity.java +46 -0
  129. package/test/fixtures/debugger-app/NoLocals.java +7 -0
  130. package/test/fixtures/debugger-app/README.md +13 -0
  131. package/test/fixtures/debugger-app/build.ts +29 -0
  132. package/test/fixtures/readiness-app/MainActivity.java +23 -0
  133. package/test/fixtures/readiness-app/README.md +12 -0
  134. package/test/fixtures/readiness-app/build.ts +37 -0
  135. package/test/fixtures/readiness-app/main.m +27 -0
  136. package/test/helpers/perfetto.ts +59 -0
  137. package/test/unit/debugger/guards.test.ts +46 -0
  138. package/test/unit/debugger/native.test.ts +33 -0
  139. package/test/unit/debugger/sessions.test.ts +83 -0
  140. package/test/unit/observe/android_tree_acquisition.test.ts +2 -0
  141. package/test/unit/observe/capture_debug_snapshot.test.ts +42 -32
  142. package/test/unit/observe/compact_tree_error.test.ts +24 -0
  143. package/test/unit/observe/conditional_snapshots.test.ts +33 -0
  144. package/test/unit/observe/correlated-evidence.test.ts +128 -0
  145. package/test/unit/observe/ios_tree_acquisition.test.ts +2 -0
  146. package/test/unit/observe/readiness.test.ts +41 -0
  147. package/test/unit/observe/readiness_native.test.ts +68 -0
  148. package/test/unit/observe/system-trace-android.test.ts +52 -0
  149. package/test/unit/observe/system-trace.test.ts +166 -0
  150. package/test/unit/server/conditional_actions.test.ts +299 -0
  151. package/test/unit/server/conditional_schema.test.ts +59 -0
  152. package/test/unit/server/correlated-evidence.test.ts +194 -0
  153. package/test/unit/server/readiness.test.ts +170 -0
  154. package/test/unit/server/selector_tap_target.test.ts +79 -0
  155. package/test/unit/server/system-trace.test.ts +64 -0
  156. package/test/unit/server/tap_selector.test.ts +2 -0
  157. package/worker/DebuggerWorker.java +160 -0
  158. package/skills/mobile-debug-tools-usage/SKILL.md +0 -96
  159. /package/{skills → .agents/skills}/README.md +0 -0
  160. /package/{skills → .agents/skills}/mcp-builder/SKILL.md +0 -0
  161. /package/{skills → .agents/skills}/mcp-builder/references/build-flags.md +0 -0
  162. /package/{skills → .agents/skills}/mcp-builder/references/diagnostics-schema.md +0 -0
  163. /package/{skills → .agents/skills}/mcp-builder/references/toolchain-details.md +0 -0
  164. /package/{skills → .agents/skills}/spec-review/SKILL.md +0 -0
  165. /package/{skills → .agents/skills}/spec-review/references/spec-review-checklist.md +0 -0
  166. /package/{skills → .agents/skills}/spec-review/references/spec-review-template.md +0 -0
  167. /package/{skills → .agents/skills}/test-authoring/SKILL.md +0 -0
  168. /package/{skills → .agents/skills}/test-authoring/references/repo-test-layout.md +0 -0
  169. /package/{skills → .agents/skills}/test-authoring/references/test-authoring-workflow.md +0 -0
  170. /package/{skills → .agents/skills}/test-authoring/references/test-quality-checklist.md +0 -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": "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.