mobile-debug-mcp 0.34.0 → 0.35.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 (432) hide show
  1. package/.agents/skills/mcp-builder/SKILL.md +44 -64
  2. package/.agents/skills/mcp-builder/references/build-flags.md +44 -43
  3. package/.agents/skills/mcp-builder/references/diagnostics-schema.md +4 -1
  4. package/.agents/skills/mcp-builder/references/toolchain-details.md +49 -62
  5. package/.agents/skills/spec-review/references/spec-review-checklist.md +7 -0
  6. package/.agents/skills/test-authoring/SKILL.md +7 -6
  7. package/.agents/skills/test-authoring/references/repo-test-layout.md +3 -1
  8. package/.agents/skills/test-authoring/references/test-authoring-workflow.md +16 -7
  9. package/.agents/skills/test-authoring/references/test-quality-checklist.md +2 -1
  10. package/.github/copilot-instructions.md +14 -36
  11. package/.github/workflows/ci.yml +4 -4
  12. package/AGENTS.md +12 -3
  13. package/CONTRIBUTING.md +79 -0
  14. package/README.md +156 -129
  15. package/agent-plugin/.claude-plugin/plugin.json +2 -2
  16. package/agent-plugin/.codex-plugin/plugin.json +1 -1
  17. package/agent-plugin/.cursor-plugin/plugin.json +2 -2
  18. package/agent-plugin/.mcp.json +1 -1
  19. package/agent-plugin/README.md +16 -6
  20. package/agent-plugin/mcp.json +1 -1
  21. package/agent-plugin/plugin.json +1 -1
  22. package/agent-plugin/skills/mobile-debug-mcp/SKILL.md +27 -2
  23. package/dist/contracts/execution-controls.js +24 -0
  24. package/dist/contracts/selector.js +8 -0
  25. package/dist/contracts/target.js +15 -0
  26. package/dist/contracts/ui.js +1 -0
  27. package/dist/debugger/android.js +2 -1
  28. package/dist/debugger/diagnostics.js +54 -0
  29. package/dist/debugger/protocol.js +33 -0
  30. package/dist/debugger/sessions.js +104 -62
  31. package/dist/debugger/worker.js +53 -42
  32. package/dist/interact/adjustment/adjustment-context.js +41 -0
  33. package/dist/interact/adjustment/adjustment-gestures.js +55 -0
  34. package/dist/interact/adjustment/adjustment-plan.js +18 -0
  35. package/dist/interact/adjustment/adjustment-resolution.js +127 -0
  36. package/dist/interact/adjustment/adjustment-result.js +19 -0
  37. package/dist/interact/adjustment/adjustment-semantic.js +64 -0
  38. package/dist/interact/adjustment/adjustment-verification.js +35 -0
  39. package/dist/interact/adjustment/adjustment.js +52 -0
  40. package/dist/interact/adjustment/control-geometry.js +87 -0
  41. package/dist/interact/adjustment/control-values.js +136 -0
  42. package/dist/interact/adjustment/slider-labels.js +84 -0
  43. package/dist/interact/assertions/screen-assertion.js +37 -0
  44. package/dist/interact/assertions/state-assertion-context.js +35 -0
  45. package/dist/interact/assertions/state-assertion.js +76 -0
  46. package/dist/interact/assertions/state-comparison.js +141 -0
  47. package/dist/interact/assertions/visibility-assertion.js +34 -0
  48. package/dist/interact/conditional-action.js +12 -7
  49. package/dist/interact/index.js +65 -3090
  50. package/dist/interact/input-service.js +1 -0
  51. package/dist/interact/interaction-trace.js +21 -0
  52. package/dist/interact/model.js +1 -0
  53. package/dist/interact/observation.js +1 -0
  54. package/dist/interact/targeting/candidate-ancestor.js +58 -0
  55. package/dist/interact/targeting/candidate-result.js +23 -0
  56. package/dist/interact/targeting/candidate-scoring.js +50 -0
  57. package/dist/interact/targeting/element-helpers.js +216 -0
  58. package/dist/interact/targeting/find-element.js +65 -0
  59. package/dist/interact/targeting/nearby-control.js +56 -0
  60. package/dist/interact/targeting/resolved-elements.js +21 -0
  61. package/dist/interact/targeting/tap-target.js +17 -0
  62. package/dist/interact/targeting/target-scope.js +104 -0
  63. package/dist/interact/waits/legacy-log-wait.js +38 -0
  64. package/dist/interact/waits/legacy-wait-observations.js +103 -0
  65. package/dist/interact/waits/legacy-wait-state.js +34 -0
  66. package/dist/interact/waits/legacy-wait.js +48 -0
  67. package/dist/interact/waits/screen-wait.js +49 -0
  68. package/dist/interact/waits/ui-change-helpers.js +157 -0
  69. package/dist/interact/waits/ui-change-state.js +18 -0
  70. package/dist/interact/waits/ui-change-wait.js +77 -0
  71. package/dist/interact/waits/ui-wait-condition.js +56 -0
  72. package/dist/interact/waits/ui-wait-state.js +38 -0
  73. package/dist/interact/waits/ui-wait.js +106 -0
  74. package/dist/manage/android.js +55 -51
  75. package/dist/manage/index.js +38 -75
  76. package/dist/manage/ios/build-types.js +1 -0
  77. package/dist/manage/ios/build.js +210 -0
  78. package/dist/manage/ios/project-discovery.js +29 -0
  79. package/dist/manage/ios/scheme.js +18 -0
  80. package/dist/manage/ios.js +42 -256
  81. package/dist/observe/android/context.js +1 -0
  82. package/dist/observe/android/current-screen.js +55 -0
  83. package/dist/observe/android/fingerprint.js +13 -0
  84. package/dist/observe/android/log-stream.js +132 -0
  85. package/dist/observe/android/logs.js +107 -0
  86. package/dist/observe/android/screenshot.js +70 -0
  87. package/dist/observe/android/ui-tree.js +107 -0
  88. package/dist/observe/android.js +16 -520
  89. package/dist/observe/evidence.js +114 -75
  90. package/dist/observe/index.js +16 -263
  91. package/dist/observe/ios/context.js +16 -0
  92. package/dist/observe/ios/fingerprint.js +12 -0
  93. package/dist/observe/ios/log-stream.js +105 -0
  94. package/dist/observe/ios/logs.js +168 -0
  95. package/dist/observe/ios/screenshot.js +22 -0
  96. package/dist/observe/ios/ui-elements.js +241 -0
  97. package/dist/observe/ios/ui-tree.js +137 -0
  98. package/dist/observe/ios.js +17 -715
  99. package/dist/observe/logs/model.js +1 -0
  100. package/dist/{network → observe/network}/index.js +2 -2
  101. package/dist/observe/readiness-service.js +4 -2
  102. package/dist/observe/readiness.js +29 -10
  103. package/dist/observe/screenshot-encoding.js +41 -0
  104. package/dist/observe/snapshot-collection.js +79 -0
  105. package/dist/observe/snapshot-logs.js +30 -0
  106. package/dist/observe/snapshot-metadata.js +43 -31
  107. package/dist/observe/snapshot-semantic.js +115 -0
  108. package/dist/observe/system-trace.js +22 -13
  109. package/dist/runtime/action-results.js +270 -0
  110. package/dist/runtime/clock.js +4 -0
  111. package/dist/server/common.js +1 -256
  112. package/dist/server/definitions/assert.js +162 -0
  113. package/dist/server/definitions/diagnostic.js +118 -0
  114. package/dist/server/definitions/input.js +274 -0
  115. package/dist/server/definitions/manage.js +194 -0
  116. package/dist/server/definitions/observe.js +149 -0
  117. package/dist/server/definitions/target.js +138 -0
  118. package/dist/server/definitions/wait.js +105 -0
  119. package/dist/server/handlers/action-execution.js +163 -0
  120. package/dist/server/handlers/correlation.js +23 -0
  121. package/dist/server/{debugger-handlers.js → handlers/debugger-handlers.js} +22 -12
  122. package/dist/server/handlers/debugger-response.js +9 -0
  123. package/dist/server/handlers/diagnostic.js +69 -0
  124. package/dist/server/handlers/handler-types.js +1 -0
  125. package/dist/server/handlers/input.js +154 -0
  126. package/dist/server/handlers/interact.js +113 -0
  127. package/dist/server/handlers/journey-assertions.js +35 -0
  128. package/dist/server/handlers/journey.js +147 -0
  129. package/dist/server/handlers/manage.js +119 -0
  130. package/dist/server/handlers/observe.js +95 -0
  131. package/dist/server/handlers/payload.js +4 -0
  132. package/dist/server/handlers/tool-handlers.js +160 -0
  133. package/dist/server/schemas/condition-schema.js +2 -0
  134. package/dist/server/{debugger-schema.js → schemas/debugger-schema.js} +11 -6
  135. package/dist/server/{journey-schema.js → schemas/journey-schema.js} +7 -22
  136. package/dist/server/tool-definitions.js +58 -1135
  137. package/dist/server-core.js +2 -2
  138. package/dist/system/android-status.js +101 -0
  139. package/dist/system/android.js +37 -27
  140. package/dist/system/index.js +13 -439
  141. package/dist/system/ios-status.js +132 -0
  142. package/dist/system/ios.js +11 -8
  143. package/dist/system/model.js +1 -0
  144. package/dist/system/probes.js +105 -0
  145. package/dist/system/status-summary.js +43 -0
  146. package/dist/system/unsupported-status.js +52 -0
  147. package/dist/utils/android/commands.js +89 -0
  148. package/dist/utils/android/gradle.js +139 -0
  149. package/dist/utils/android/logs.js +103 -0
  150. package/dist/utils/android/ui-tree.js +233 -0
  151. package/dist/utils/android/utils.js +6 -564
  152. package/dist/utils/cli/idb/idb-helper.js +4 -6
  153. package/dist/utils/cli/idb/install-idb.js +13 -9
  154. package/dist/utils/cli/ios/preflight-ios.js +42 -38
  155. package/dist/utils/ios/utils.js +45 -46
  156. package/dist/utils/java.js +65 -49
  157. package/dist/utils/resolve-device.js +4 -2
  158. package/dist/utils/ui/index.js +26 -26
  159. package/docs/CHANGELOG.md +44 -0
  160. package/docs/README.md +38 -0
  161. package/docs/benchmarks/README.md +18 -0
  162. package/docs/benchmarks/interaction-latency/README.md +14 -0
  163. package/docs/benchmarks/interaction-latency/final.md +4 -1
  164. package/docs/benchmarks/interaction-latency/ios-validation.md +2 -0
  165. package/docs/benchmarks/ui-tree-performance/README.md +24 -16
  166. package/docs/benchmarks/ui-tree-performance/comparison.md +11 -10
  167. package/docs/code-structure.md +118 -0
  168. package/docs/specs/001-state-verification/spec.md +16 -14
  169. package/docs/specs/002-richer-element-identity/spec.md +12 -10
  170. package/docs/specs/003-wait-and-synchronization-reliability/spec.md +12 -10
  171. package/docs/specs/004-action-verification-routing/spec.md +3 -3
  172. package/docs/specs/005-unified-action-execution-and-verification-model/spec.md +2 -0
  173. package/docs/specs/006-runtime-action-instrumentation-and-binding-layer/spec.md +2 -0
  174. package/docs/specs/007-actionability-resolution-and-executable-target-selection/spec.md +3 -1
  175. package/docs/specs/008-adjustable-control-support-and-semantic-value-manipulation/spec.md +3 -4
  176. package/docs/specs/009-semantic-control-modeling-for-custom-and-composite-controls/spec.md +2 -0
  177. package/docs/specs/010-verification-stabilization-and-temporal-convergence/spec.md +2 -2
  178. package/docs/specs/011-recovery-and-replanning-for-failed-or-ambiguous-interaction-flows/spec.md +2 -2
  179. package/docs/specs/011.1-recovery-contract-types-and-runtime-wiring-spec/spec.md +2 -0
  180. package/docs/specs/012-action-trace-and-xecution-observability/spec.md +2 -3
  181. package/docs/specs/013-wait-and-synchronization-reliability/spec.md +19 -19
  182. package/docs/specs/014-actionability-resolution/spec.md +20 -18
  183. package/docs/specs/015-adjustable-control-support/spec.md +17 -15
  184. package/docs/specs/016-environment-tools/spec.md +20 -20
  185. package/docs/specs/018-interaction-latency-and-batched-journeys/spec.md +2 -0
  186. package/docs/specs/019-ui-tree-observation-performance/spec.md +3 -1
  187. package/docs/specs/020-conditional-actions/intent.md +5 -3
  188. package/docs/specs/020-conditional-actions/plan.md +8 -9
  189. package/docs/specs/020-conditional-actions/spec.md +4 -2
  190. package/docs/specs/021-app-readiness-signals/intent.md +4 -2
  191. package/docs/specs/021-app-readiness-signals/plan.md +7 -6
  192. package/docs/specs/021-app-readiness-signals/spec.md +3 -1
  193. package/docs/specs/022-correlated-evidence/intent.md +4 -4
  194. package/docs/specs/022-correlated-evidence/plan.md +10 -11
  195. package/docs/specs/022-correlated-evidence/spec.md +3 -1
  196. package/docs/specs/023-android-system-traces/intent.md +3 -2
  197. package/docs/specs/023-android-system-traces/plan.md +5 -7
  198. package/docs/specs/023-android-system-traces/spec.md +3 -1
  199. package/docs/specs/024-android-heap-dump-capture/intent.md +3 -1
  200. package/docs/specs/025-android-runtime-debugger/intent.md +4 -3
  201. package/docs/specs/025-android-runtime-debugger/plan.md +3 -1
  202. package/docs/specs/025-android-runtime-debugger/spec.md +4 -3
  203. package/docs/specs/026-code-structure-and-quality-gates/health-plan.md +88 -0
  204. package/docs/specs/026-code-structure-and-quality-gates/intent.md +47 -0
  205. package/docs/specs/026-code-structure-and-quality-gates/plan.md +191 -0
  206. package/docs/specs/026-code-structure-and-quality-gates/spec.md +138 -0
  207. package/docs/specs/026-code-structure-and-quality-gates/verification-final.json +200 -0
  208. package/docs/specs/026-code-structure-and-quality-gates/verification-thin-facade.json +154 -0
  209. package/docs/specs/026-code-structure-and-quality-gates/verification.json +136 -0
  210. package/docs/specs/027-debugger-failure-diagnostics/intent.md +43 -0
  211. package/docs/specs/027-debugger-failure-diagnostics/plan.md +86 -0
  212. package/docs/specs/027-debugger-failure-diagnostics/spec.md +133 -0
  213. package/docs/specs/028-compact-debugger-responses/intent.md +41 -0
  214. package/docs/specs/028-compact-debugger-responses/plan.md +112 -0
  215. package/docs/specs/028-compact-debugger-responses/spec.md +108 -0
  216. package/docs/specs/029-kotlin-locals-validation/report.md +119 -0
  217. package/docs/specs/030-android-coroutine-validation/evidence.json +475 -0
  218. package/docs/specs/030-android-coroutine-validation/intent.md +47 -0
  219. package/docs/specs/030-android-coroutine-validation/plan.md +147 -0
  220. package/docs/specs/030-android-coroutine-validation/report.md +240 -0
  221. package/docs/specs/030-android-coroutine-validation/spec.md +107 -0
  222. package/docs/tools/TOOLS.md +31 -18
  223. package/docs/tools/{evidence.md → correlated-evidence.md} +9 -1
  224. package/docs/tools/debugger.md +76 -0
  225. package/docs/tools/interact.md +42 -20
  226. package/docs/tools/manage.md +25 -44
  227. package/docs/tools/observe.md +55 -23
  228. package/docs/tools/system-traces.md +9 -1
  229. package/docs/tools/system.md +12 -5
  230. package/package.json +11 -8
  231. package/scripts/architecture-graph.mjs +69 -0
  232. package/scripts/check-architecture.mjs +47 -0
  233. package/scripts/code-quality-baseline.json +1 -0
  234. package/scripts/code-quality.mjs +161 -0
  235. package/src/contracts/execution-controls.ts +26 -0
  236. package/src/contracts/selector.ts +17 -0
  237. package/src/contracts/target.ts +19 -0
  238. package/src/contracts/ui.ts +94 -0
  239. package/src/debugger/android.ts +2 -1
  240. package/src/debugger/diagnostics.ts +43 -0
  241. package/src/debugger/guard.ts +6 -1
  242. package/{worker → src/debugger/java}/DebuggerWorker.java +9 -3
  243. package/src/debugger/protocol.ts +37 -0
  244. package/src/debugger/sessions.ts +314 -155
  245. package/src/debugger/worker.ts +51 -38
  246. package/src/interact/adjustment/adjustment-context.ts +83 -0
  247. package/src/interact/adjustment/adjustment-gestures.ts +48 -0
  248. package/src/interact/adjustment/adjustment-plan.ts +23 -0
  249. package/src/interact/adjustment/adjustment-resolution.ts +104 -0
  250. package/src/interact/adjustment/adjustment-result.ts +34 -0
  251. package/src/interact/adjustment/adjustment-semantic.ts +53 -0
  252. package/src/interact/adjustment/adjustment-verification.ts +60 -0
  253. package/src/interact/adjustment/adjustment.ts +49 -0
  254. package/src/interact/adjustment/control-geometry.ts +120 -0
  255. package/src/interact/adjustment/control-values.ts +141 -0
  256. package/src/interact/adjustment/slider-labels.ts +84 -0
  257. package/src/interact/assertions/screen-assertion.ts +39 -0
  258. package/src/interact/assertions/state-assertion-context.ts +48 -0
  259. package/src/interact/assertions/state-assertion.ts +64 -0
  260. package/src/interact/assertions/state-comparison.ts +168 -0
  261. package/src/interact/assertions/visibility-assertion.ts +41 -0
  262. package/src/interact/conditional-action.ts +18 -12
  263. package/src/interact/index.ts +76 -3492
  264. package/src/interact/input-service.ts +11 -0
  265. package/src/interact/interaction-trace.ts +36 -0
  266. package/src/interact/model.ts +109 -0
  267. package/src/interact/observation.ts +7 -0
  268. package/src/interact/targeting/candidate-ancestor.ts +49 -0
  269. package/src/interact/targeting/candidate-result.ts +24 -0
  270. package/src/interact/targeting/candidate-scoring.ts +42 -0
  271. package/src/interact/targeting/element-helpers.ts +243 -0
  272. package/src/interact/targeting/find-element.ts +47 -0
  273. package/src/interact/targeting/nearby-control.ts +46 -0
  274. package/src/interact/targeting/resolved-elements.ts +20 -0
  275. package/src/interact/targeting/tap-target.ts +22 -0
  276. package/src/interact/targeting/target-scope.ts +121 -0
  277. package/src/interact/waits/legacy-log-wait.ts +30 -0
  278. package/src/interact/waits/legacy-wait-observations.ts +55 -0
  279. package/src/interact/waits/legacy-wait-state.ts +48 -0
  280. package/src/interact/waits/legacy-wait.ts +34 -0
  281. package/src/interact/waits/screen-wait.ts +37 -0
  282. package/src/interact/waits/ui-change-helpers.ts +184 -0
  283. package/src/interact/waits/ui-change-state.ts +26 -0
  284. package/src/interact/waits/ui-change-wait.ts +59 -0
  285. package/src/interact/waits/ui-wait-condition.ts +52 -0
  286. package/src/interact/waits/ui-wait-state.ts +55 -0
  287. package/src/interact/waits/ui-wait.ts +84 -0
  288. package/src/manage/android.ts +56 -50
  289. package/src/manage/index.ts +63 -93
  290. package/src/manage/ios/build-types.ts +14 -0
  291. package/src/manage/ios/build.ts +230 -0
  292. package/src/manage/ios/project-discovery.ts +26 -0
  293. package/src/manage/ios/scheme.ts +16 -0
  294. package/src/manage/ios.ts +65 -298
  295. package/src/observe/android/context.ts +1 -0
  296. package/src/observe/android/current-screen.ts +63 -0
  297. package/src/observe/android/fingerprint.ts +13 -0
  298. package/src/observe/android/log-stream.ts +127 -0
  299. package/src/observe/android/logs.ts +110 -0
  300. package/src/observe/android/screenshot.ts +79 -0
  301. package/src/observe/android/ui-tree.ts +113 -0
  302. package/src/observe/android.ts +17 -531
  303. package/src/observe/evidence.ts +122 -70
  304. package/src/observe/index.ts +24 -286
  305. package/src/observe/ios/context.ts +22 -0
  306. package/src/observe/ios/fingerprint.ts +12 -0
  307. package/src/observe/ios/log-stream.ts +103 -0
  308. package/src/observe/ios/logs.ts +179 -0
  309. package/src/observe/ios/screenshot.ts +26 -0
  310. package/src/observe/ios/ui-elements.ts +266 -0
  311. package/src/observe/ios/ui-tree.ts +143 -0
  312. package/src/observe/ios.ts +18 -749
  313. package/src/observe/logs/model.ts +11 -0
  314. package/src/{network → observe/network}/index.ts +2 -2
  315. package/src/observe/readiness-service.ts +5 -3
  316. package/src/observe/readiness.ts +39 -18
  317. package/src/observe/screenshot-encoding.ts +32 -0
  318. package/src/observe/snapshot-collection.ts +69 -0
  319. package/src/observe/snapshot-logs.ts +26 -0
  320. package/src/observe/snapshot-metadata.ts +51 -31
  321. package/src/observe/snapshot-semantic.ts +153 -0
  322. package/src/observe/system-trace.ts +24 -15
  323. package/src/runtime/action-results.ts +376 -0
  324. package/src/runtime/clock.ts +9 -0
  325. package/src/server/common.ts +9 -359
  326. package/src/server/definitions/assert.ts +164 -0
  327. package/src/server/definitions/diagnostic.ts +120 -0
  328. package/src/server/definitions/input.ts +276 -0
  329. package/src/server/definitions/manage.ts +196 -0
  330. package/src/server/definitions/observe.ts +151 -0
  331. package/src/server/definitions/target.ts +140 -0
  332. package/src/server/definitions/wait.ts +107 -0
  333. package/src/server/handlers/action-execution.ts +164 -0
  334. package/src/server/handlers/correlation.ts +20 -0
  335. package/src/server/handlers/debugger-handlers.ts +39 -0
  336. package/src/server/handlers/debugger-response.ts +7 -0
  337. package/src/server/handlers/diagnostic.ts +79 -0
  338. package/src/server/handlers/handler-types.ts +7 -0
  339. package/src/server/handlers/input.ts +173 -0
  340. package/src/server/handlers/interact.ts +135 -0
  341. package/src/server/handlers/journey-assertions.ts +39 -0
  342. package/src/server/handlers/journey.ts +132 -0
  343. package/src/server/handlers/manage.ts +141 -0
  344. package/src/server/handlers/observe.ts +116 -0
  345. package/src/server/handlers/payload.ts +36 -0
  346. package/src/server/handlers/tool-handlers.ts +159 -0
  347. package/src/server/schemas/condition-schema.ts +2 -0
  348. package/src/server/{debugger-schema.ts → schemas/debugger-schema.ts} +13 -7
  349. package/src/server/{journey-schema.ts → schemas/journey-schema.ts} +7 -22
  350. package/src/server/{system-trace-schema.ts → schemas/system-trace-schema.ts} +3 -3
  351. package/src/server/tool-definitions.ts +67 -1143
  352. package/src/server-core.ts +2 -2
  353. package/src/server.ts +1 -1
  354. package/src/system/android-status.ts +124 -0
  355. package/src/system/android.ts +33 -21
  356. package/src/system/index.ts +21 -525
  357. package/src/system/ios-status.ts +147 -0
  358. package/src/system/ios.ts +14 -10
  359. package/src/system/model.ts +41 -0
  360. package/src/system/probes.ts +114 -0
  361. package/src/system/status-summary.ts +47 -0
  362. package/src/system/unsupported-status.ts +55 -0
  363. package/src/types.ts +16 -106
  364. package/src/utils/android/commands.ts +81 -0
  365. package/src/utils/android/gradle.ts +132 -0
  366. package/src/utils/android/logs.ts +103 -0
  367. package/src/utils/android/ui-tree.ts +239 -0
  368. package/src/utils/android/utils.ts +16 -556
  369. package/src/utils/cli/idb/check-idb.ts +4 -4
  370. package/src/utils/cli/idb/idb-helper.ts +6 -8
  371. package/src/utils/cli/idb/install-idb.ts +15 -9
  372. package/src/utils/cli/ios/preflight-ios.ts +39 -31
  373. package/src/utils/cli/ios/run-ios-ui-tree-tap.ts +4 -4
  374. package/src/utils/ios/utils.ts +57 -61
  375. package/src/utils/java.ts +62 -43
  376. package/src/utils/resolve-device.ts +9 -6
  377. package/src/utils/ui/index.ts +28 -28
  378. package/test/device/automated/debugger/coroutine-lifecycle.ts +27 -0
  379. package/test/device/automated/debugger/coroutine-support.ts +140 -0
  380. package/test/device/automated/debugger/coroutine.android.test.ts +169 -0
  381. package/test/device/automated/debugger/kotlin.android.test.ts +127 -0
  382. package/test/device/automated/debugger/runtime.android.test.ts +19 -3
  383. package/test/device/automated/interact/interaction.android.test.ts +56 -0
  384. package/test/device/automated/observe/system-trace.smoke.ts +1 -1
  385. package/test/device/manual/interact/modul8_selector_tap.manual.ts +1 -1
  386. package/test/fixtures/contracts/tool-definitions.json +3536 -0
  387. package/test/fixtures/coroutine-app/MainActivity.kt +100 -0
  388. package/test/fixtures/coroutine-app/README.md +48 -0
  389. package/test/fixtures/coroutine-app/build.ts +35 -0
  390. package/test/fixtures/debugger-app/MainActivity.java +21 -0
  391. package/test/fixtures/debugger-app/MainActivity.kt +32 -0
  392. package/test/fixtures/debugger-app/README.md +52 -0
  393. package/test/fixtures/debugger-app/build.ts +25 -15
  394. package/test/fixtures/latency-journey-app/README.md +2 -0
  395. package/test/fixtures/readiness-app/README.md +2 -0
  396. package/test/unit/debugger/coroutine-lifecycle.test.ts +43 -0
  397. package/test/unit/debugger/diagnostic-sessions.test.ts +67 -0
  398. package/test/unit/debugger/diagnostics.test.ts +80 -0
  399. package/test/unit/debugger/guards.test.ts +4 -0
  400. package/test/unit/debugger/preparation.test.ts +32 -0
  401. package/test/unit/debugger/protocol.test.ts +15 -0
  402. package/test/unit/debugger/sessions.test.ts +1 -1
  403. package/test/unit/interact/adjustment_service.test.ts +42 -0
  404. package/test/unit/interact/adjustment_verification.test.ts +35 -0
  405. package/test/unit/interact/clock_dependencies.test.ts +63 -0
  406. package/test/unit/interact/element_helpers.test.ts +19 -0
  407. package/test/unit/interact/legacy_wait_service.test.ts +17 -0
  408. package/test/unit/interact/state_comparison.test.ts +20 -0
  409. package/test/unit/interact/target_scope.test.ts +35 -0
  410. package/test/unit/network/get_network_activity.test.ts +1 -1
  411. package/test/unit/observe/screenshot-encoding.test.ts +30 -0
  412. package/test/unit/observe/snapshot-logs.test.ts +14 -0
  413. package/test/unit/quality/architecture.test.ts +60 -0
  414. package/test/unit/quality/code-quality.test.ts +58 -0
  415. package/test/unit/quality/interaction_boundaries.test.ts +24 -0
  416. package/test/unit/server/conditional_actions.test.ts +1 -1
  417. package/test/unit/server/conditional_schema.test.ts +2 -2
  418. package/test/unit/server/debugger-response.test.ts +63 -0
  419. package/test/unit/server/tool_definitions_parity.test.ts +8 -0
  420. package/dist/server/tool-handlers.js +0 -1000
  421. package/docs/ROADMAP.md +0 -646
  422. package/docs/benchmarks/ui-tree-performance/bridge-probe.json +0 -29
  423. package/docs/benchmarks/ui-tree-performance/initial-baseline.json +0 -59560
  424. package/docs/specs/baseline-spec-v0.md +0 -312
  425. package/docs/specs/mcp-tooling-spec-v1.md +0 -446
  426. package/src/server/debugger-handlers.ts +0 -29
  427. package/src/server/tool-handlers.ts +0 -1008
  428. /package/dist/{server/condition-schema.js → contracts/condition.js} +0 -0
  429. /package/dist/server/{readiness-schema.js → schemas/readiness-schema.js} +0 -0
  430. /package/dist/server/{system-trace-schema.js → schemas/system-trace-schema.js} +0 -0
  431. /package/src/{server/condition-schema.ts → contracts/condition.ts} +0 -0
  432. /package/src/server/{readiness-schema.ts → schemas/readiness-schema.ts} +0 -0
@@ -1,523 +1,13 @@
1
- import { spawnSync } from 'child_process'
2
- import path from 'path'
3
-
1
+ import type { HostOs } from './model.js'
4
2
  import { checkAndroid } from './android.js'
5
3
  import { checkGradle } from './gradle.js'
6
4
  import { checkIOS } from './ios.js'
7
- import { resolveAdbCmd } from '../utils/android/utils.js'
8
- import { getIdbCmd, getXcrunCmd } from '../utils/ios/utils.js'
9
- import { probeIdb } from '../utils/cli/idb/idb-helper.js'
10
5
  import { detectJavaHome } from '../utils/java.js'
11
-
12
- type HostOs = 'macos' | 'linux' | 'windows' | 'freebsd' | 'openbsd' | 'netbsd' | 'sunos' | 'unknown'
13
- type PlatformStatus = 'ready' | 'partially_ready' | 'unavailable' | 'unsupported'
14
- type ValidationStatus = 'valid' | 'invalid' | 'missing' | 'unsupported' | 'unknown'
15
-
16
- interface DiagnosticFailure {
17
- code: string
18
- platform: 'android' | 'ios'
19
- tool: string | null
20
- message: string
21
- searchedLocations: string[]
22
- selectedProvider: string | null
23
- rawVersion: string | null
24
- remediation: string[]
25
- }
26
-
27
- interface ToolEntry {
28
- resolvedPath: string | null
29
- discoverySource: string | null
30
- parsedVersion: string | null
31
- rawVersionOutput: string | null
32
- validationStatus: ValidationStatus
33
- }
34
-
35
- interface CapabilityEntry {
36
- probeRequired?: string
37
- availability: boolean
38
- selectedProvider: string | null
39
- blockingFailure: DiagnosticFailure | null
40
- }
41
-
42
- interface PlatformEntry {
43
- status: PlatformStatus
44
- tools: Record<string, ToolEntry>
45
- providers: Record<string, { available: boolean; selected: boolean; tool: string | null; probeRequired?: string }>
46
- capabilities: Record<string, CapabilityEntry>
47
- devices: Array<Record<string, unknown>>
48
- failures: DiagnosticFailure[]
49
- }
50
-
51
- function normalizeHostOs(platform: NodeJS.Platform): HostOs {
52
- switch (platform) {
53
- case 'darwin':
54
- return 'macos'
55
- case 'linux':
56
- return 'linux'
57
- case 'win32':
58
- return 'windows'
59
- case 'freebsd':
60
- case 'openbsd':
61
- case 'netbsd':
62
- case 'sunos':
63
- return platform
64
- default:
65
- return 'unknown'
66
- }
67
- }
68
-
69
- function isSupportedHost(hostOs: HostOs): boolean {
70
- return hostOs === 'macos' || hostOs === 'linux' || hostOs === 'windows'
71
- }
72
-
73
- function firstVersionToken(raw: string | null | undefined): string | null {
74
- if (!raw) return null
75
- const match = String(raw).match(/(\d+(?:\.\d+)+|\d+)/)
76
- return match?.[1] ?? null
77
- }
78
-
79
- function probeCommand(command: string, args: string[], timeoutMs = 2000): { ok: boolean, raw: string | null, parsedVersion: string | null } {
80
- try {
81
- const result = spawnSync(command, args, { encoding: 'utf8', timeout: timeoutMs, stdio: ['ignore', 'pipe', 'pipe'] })
82
- const raw = `${result.stdout || ''}${result.stderr || ''}`.trim() || null
83
- return {
84
- ok: result.status === 0,
85
- raw,
86
- parsedVersion: firstVersionToken(raw)
87
- }
88
- } catch {
89
- return { ok: false, raw: null, parsedVersion: null }
90
- }
91
- }
92
-
93
- function makeFailure(
94
- code: string,
95
- platform: 'android' | 'ios',
96
- message: string,
97
- opts: Partial<DiagnosticFailure> = {}
98
- ): DiagnosticFailure {
99
- return {
100
- code,
101
- platform,
102
- tool: opts.tool ?? null,
103
- message,
104
- searchedLocations: opts.searchedLocations ?? [],
105
- selectedProvider: opts.selectedProvider ?? null,
106
- rawVersion: opts.rawVersion ?? null,
107
- remediation: opts.remediation ?? []
108
- }
109
- }
110
-
111
- function makeToolEntry(
112
- resolvedPath: string | null,
113
- discoverySource: string | null,
114
- rawVersionOutput: string | null,
115
- validationStatus: ValidationStatus
116
- ): ToolEntry {
117
- return {
118
- resolvedPath,
119
- discoverySource,
120
- parsedVersion: firstVersionToken(rawVersionOutput),
121
- rawVersionOutput,
122
- validationStatus
123
- }
124
- }
125
-
126
- function describeAdbDiscovery(adbCmd: string): { discoverySource: string | null, searchedLocations: string[] } {
127
- const searchedLocations: string[] = ['ADB_PATH', 'ANDROID_SDK_ROOT/platform-tools/adb', 'ANDROID_HOME/platform-tools/adb', '~/Library/Android/sdk/platform-tools/adb', 'PATH']
128
- if (process.env.ADB_PATH && process.env.ADB_PATH.trim()) return { discoverySource: 'ADB_PATH', searchedLocations }
129
- if (process.env.ANDROID_SDK_ROOT) return { discoverySource: 'ANDROID_SDK_ROOT', searchedLocations }
130
- if (process.env.ANDROID_HOME) return { discoverySource: 'ANDROID_HOME', searchedLocations }
131
- if (adbCmd.includes('Library/Android/sdk')) return { discoverySource: 'HOME_SDK', searchedLocations }
132
- if (adbCmd === 'adb') return { discoverySource: 'PATH_OR_FALLBACK', searchedLocations }
133
- return { discoverySource: 'PATH', searchedLocations }
134
- }
135
-
136
- function describeXcrunDiscovery(xcrunCmd: string): { discoverySource: string | null, searchedLocations: string[] } {
137
- const searchedLocations: string[] = ['XCRUN_PATH', 'PATH']
138
- if (process.env.XCRUN_PATH && process.env.XCRUN_PATH.trim()) return { discoverySource: 'XCRUN_PATH', searchedLocations }
139
- return { discoverySource: xcrunCmd === 'xcrun' ? 'PATH' : 'PATH', searchedLocations }
140
- }
141
-
142
- function describeIdbDiscovery(idbCmd: string): { discoverySource: string | null, searchedLocations: string[] } {
143
- const searchedLocations: string[] = ['MCP_IDB_PATH', 'IDB_PATH', 'mcp.config.json', '~/.mcp/config.json', 'PATH', '/opt/homebrew/bin/idb', '/usr/local/bin/idb']
144
- if (process.env.MCP_IDB_PATH && process.env.MCP_IDB_PATH.trim()) return { discoverySource: 'MCP_IDB_PATH', searchedLocations }
145
- if (process.env.IDB_PATH && process.env.IDB_PATH.trim()) return { discoverySource: 'IDB_PATH', searchedLocations }
146
- return { discoverySource: idbCmd === 'idb' ? 'PATH_OR_FALLBACK' : 'PATH', searchedLocations }
147
- }
148
-
149
- function describeJavaDiscovery(javaHome: string | null): { discoverySource: string | null, searchedLocations: string[] } {
150
- const searchedLocations: string[] = ['GRADLE_JAVA_HOME', 'JAVA_HOME', 'GRADLE_HOME', 'detectJavaHome']
151
- if (process.env.GRADLE_JAVA_HOME && process.env.GRADLE_JAVA_HOME.trim()) return { discoverySource: 'GRADLE_JAVA_HOME', searchedLocations }
152
- if (process.env.JAVA_HOME && process.env.JAVA_HOME.trim()) return { discoverySource: 'JAVA_HOME', searchedLocations }
153
- if (process.env.GRADLE_HOME && process.env.GRADLE_HOME.trim()) return { discoverySource: 'GRADLE_HOME', searchedLocations }
154
- return { discoverySource: javaHome ? 'detected' : null, searchedLocations }
155
- }
156
-
157
- function resolveJavaBinaryPath(javaHome: string, hostOs: HostOs): string {
158
- const javaBinary = hostOs === 'windows' ? 'java.exe' : 'java'
159
- return path.join(javaHome, 'bin', javaBinary)
160
- }
161
-
162
- function buildUnsupportedHostStatus(hostOs: HostOs) {
163
- const failureMessage = `Host operating system '${hostOs}' is not supported.`
164
- const remediation = ['Run Mobile Debug MCP on macOS, Linux, or Windows.']
165
- const failureAndroid = makeFailure('HOST_OS_UNSUPPORTED', 'android', failureMessage, {
166
- remediation
167
- })
168
- const failureIos = makeFailure('HOST_OS_UNSUPPORTED', 'ios', failureMessage, {
169
- remediation
170
- })
171
-
172
- return {
173
- success: false,
174
- status: 'blocked',
175
- adbAvailable: false,
176
- adbVersion: '',
177
- devices: 0,
178
- deviceStates: '',
179
- logsAvailable: false,
180
- envValid: false,
181
- issues: [failureMessage],
182
- appInstalled: undefined,
183
- iosAvailable: false,
184
- iosDevices: 0,
185
- gradleJavaHome: undefined,
186
- gradleValid: false,
187
- gradleFilesChecked: [],
188
- gradleSuggestedFixes: [],
189
- host: { os: hostOs, supported: false },
190
- android: {
191
- status: 'unsupported',
192
- tools: {},
193
- providers: {},
194
- capabilities: {},
195
- devices: [],
196
- failures: [failureAndroid]
197
- },
198
- ios: {
199
- status: 'unsupported',
200
- tools: {},
201
- providers: {},
202
- capabilities: {},
203
- devices: [],
204
- failures: [failureIos]
205
- },
206
- summary: {
207
- overall: 'blocked',
208
- android: { ready: false, summary: `Host operating system '${hostOs}' is not supported.`, blockers: [failureMessage] },
209
- ios: { ready: false, summary: `Host operating system '${hostOs}' is not supported.`, blockers: [failureMessage] },
210
- gradle: { ready: false, summary: 'Gradle status unavailable on unsupported host', blockers: [], suggestedFixes: [] }
211
- }
212
- }
213
- }
214
-
215
- function buildAndroidPlatform(android: Awaited<ReturnType<typeof checkAndroid>>, hostSupported: boolean): PlatformEntry {
216
- const resolvedAdbCmd = resolveAdbCmd()
217
- const adbDiscovery = describeAdbDiscovery(resolvedAdbCmd)
218
- const adbTool = makeToolEntry(
219
- resolvedAdbCmd,
220
- adbDiscovery.discoverySource,
221
- android.adbVersion || null,
222
- android.adbAvailable ? 'valid' : 'invalid'
223
- )
224
-
225
- const adbAvailable = !!android.adbAvailable
226
- const deviceIssues = android.issues.filter((issue) => /unauthorized|offline|No Android devices connected/i.test(issue))
227
- const envFailure = !android.envValid
228
- ? makeFailure('TOOL_VALIDATION_FAILED', 'android', 'Android environment prerequisites are incomplete.', {
229
- tool: 'adb',
230
- searchedLocations: ['ANDROID_SDK_ROOT', 'ANDROID_HOME', 'PATH'],
231
- selectedProvider: 'adb',
232
- rawVersion: android.adbVersion || null,
233
- remediation: ['Set ANDROID_SDK_ROOT or ANDROID_HOME, or ensure adb is on PATH.']
234
- })
235
- : null
236
-
237
- const adbFailure = !adbAvailable
238
- ? makeFailure(
239
- process.env.ADB_PATH && process.env.ADB_PATH.trim() ? 'TOOL_NOT_EXECUTABLE' : 'TOOL_NOT_FOUND',
240
- 'android',
241
- 'Android adb could not be resolved or executed.',
242
- {
243
- tool: 'adb',
244
- searchedLocations: adbDiscovery.searchedLocations,
245
- selectedProvider: null,
246
- rawVersion: android.adbVersion || null,
247
- remediation: [
248
- 'Install Android platform-tools.',
249
- 'Set ADB_PATH or ANDROID_SDK_ROOT/ANDROID_HOME if adb is installed in a non-standard location.'
250
- ]
251
- }
252
- )
253
- : null
254
-
255
- const deviceFailure = adbAvailable && android.devices === 0
256
- ? makeFailure('DEVICE_NOT_FOUND', 'android', 'No Android devices or emulators are connected.', {
257
- tool: 'adb',
258
- searchedLocations: ['adb devices -l'],
259
- selectedProvider: 'adb',
260
- rawVersion: android.adbVersion || null,
261
- remediation: ['Start an emulator or connect a device, then re-run adb devices.']
262
- })
263
- : null
264
-
265
- const diagnosticFailures = [adbFailure, envFailure, deviceFailure].filter((value): value is DiagnosticFailure => value !== null)
266
-
267
- const status: PlatformStatus = !hostSupported
268
- ? 'unsupported'
269
- : !adbAvailable
270
- ? 'unavailable'
271
- : (android.devices === 0 || deviceIssues.length > 0 || !android.logsAvailable || !android.envValid)
272
- ? 'partially_ready'
273
- : 'ready'
274
-
275
- const deviceEntries = android.devices > 0
276
- ? Array.from({ length: android.devices }, (_, index) => ({
277
- id: `android-device-${index + 1}`,
278
- state: deviceIssues.length > 0 ? 'degraded' : 'connected'
279
- }))
280
- : []
281
-
282
- const deviceDiscoveryAvailable = adbAvailable
283
- const installAvailable = adbAvailable && android.devices > 0 && deviceIssues.length === 0
284
- const logAvailable = adbAvailable && android.logsAvailable
285
-
286
- return {
287
- status,
288
- tools: {
289
- adb: adbTool
290
- },
291
- providers: {
292
- adb: { available: adbAvailable, selected: true, tool: 'adb' },
293
- jdwp: { available: false, selected: false, tool: 'adb', probeRequired: 'get_debugger_capabilities' }
294
- },
295
- capabilities: {
296
- device_discovery: {
297
- availability: deviceDiscoveryAvailable,
298
- selectedProvider: deviceDiscoveryAvailable ? 'adb' : null,
299
- blockingFailure: deviceDiscoveryAvailable ? null : diagnosticFailures[0] ?? null
300
- },
301
- install_app: {
302
- availability: installAvailable,
303
- selectedProvider: installAvailable ? 'adb' : null,
304
- blockingFailure: installAvailable ? null : deviceFailure ?? adbFailure ?? envFailure
305
- },
306
- launch_app: {
307
- availability: installAvailable,
308
- selectedProvider: installAvailable ? 'adb' : null,
309
- blockingFailure: installAvailable ? null : deviceFailure ?? adbFailure ?? envFailure
310
- },
311
- ui_interaction: {
312
- availability: installAvailable,
313
- selectedProvider: installAvailable ? 'adb' : null,
314
- blockingFailure: installAvailable ? null : deviceFailure ?? adbFailure ?? envFailure
315
- },
316
- screenshot: {
317
- availability: installAvailable,
318
- selectedProvider: installAvailable ? 'adb' : null,
319
- blockingFailure: installAvailable ? null : deviceFailure ?? adbFailure ?? envFailure
320
- },
321
- log_capture: {
322
- availability: logAvailable,
323
- selectedProvider: logAvailable ? 'adb' : null,
324
- blockingFailure: logAvailable ? null : adbFailure ?? envFailure
325
- },
326
- debug: {
327
- probeRequired: 'get_debugger_capabilities',
328
- availability: false,
329
- selectedProvider: null,
330
- blockingFailure: deviceFailure ?? adbFailure ?? envFailure
331
- }
332
- },
333
- devices: deviceEntries,
334
- failures: diagnosticFailures
335
- }
336
- }
337
-
338
- function buildIOSPlatform(ios: Awaited<ReturnType<typeof checkIOS>>, hostSupported: boolean, hostOs: HostOs): PlatformEntry {
339
- const platformUnsupported = !hostSupported || hostOs === 'linux' || hostOs === 'windows'
340
- if (platformUnsupported) {
341
- return {
342
- status: 'unsupported',
343
- tools: {},
344
- providers: {},
345
- capabilities: {},
346
- devices: [],
347
- failures: [
348
- makeFailure('PLATFORM_UNAVAILABLE', 'ios', 'iOS tooling is only supported on macOS.', {
349
- tool: null,
350
- searchedLocations: [],
351
- selectedProvider: null,
352
- rawVersion: null,
353
- remediation: ['Run Mobile Debug MCP on macOS for iOS toolchain discovery.']
354
- })
355
- ]
356
- }
357
- }
358
-
359
- const xcrunCmd = getXcrunCmd()
360
- const xcrunProbe = ios.iosAvailable ? probeCommand(xcrunCmd, ['--version']) : { ok: false, raw: null, parsedVersion: null }
361
- const idbCmd = getIdbCmd()
362
- const idbProbe = hostSupported && hostOs === 'macos' ? probeIdb(idbCmd) : { ok: false, raw: null, parsedVersion: null }
363
- const idbCompanionProbe = hostSupported && hostOs === 'macos' ? probeCommand('idb_companion', ['--version']) : { ok: false, raw: null, parsedVersion: null }
364
- const xcrunTool = makeToolEntry(xcrunCmd, describeXcrunDiscovery(xcrunCmd).discoverySource, xcrunProbe.raw, xcrunProbe.ok ? 'valid' : 'invalid')
365
- const idbTool = makeToolEntry(idbCmd, describeIdbDiscovery(idbCmd).discoverySource, idbProbe.raw, idbProbe.ok ? 'valid' : 'invalid')
366
- const idbCompanionTool = makeToolEntry('idb_companion', 'PATH', idbCompanionProbe.raw, idbCompanionProbe.ok ? 'valid' : 'invalid')
367
- const lldbTool = makeToolEntry('xcrun lldb', 'xcrun', xcrunProbe.raw, xcrunProbe.ok ? 'valid' : 'invalid')
368
-
369
- const simctlAvailable = !!ios.iosAvailable
370
- const idbAvailable = !!idbProbe.ok
371
- const bootedDevices = ios.iosDevices > 0
372
- ? Array.from({ length: ios.iosDevices }, (_, index) => ({
373
- id: `ios-simulator-${index + 1}`,
374
- state: 'booted'
375
- }))
376
- : []
377
-
378
- const platformUnavailableFailure = !platformUnsupported && !simctlAvailable
379
- ? makeFailure('PLATFORM_UNAVAILABLE', 'ios', 'iOS tooling is unavailable on this host.', {
380
- tool: 'xcrun',
381
- searchedLocations: describeXcrunDiscovery(xcrunCmd).searchedLocations,
382
- selectedProvider: null,
383
- rawVersion: xcrunProbe.raw,
384
- remediation: ['Install Xcode Command Line Tools and ensure xcrun is on PATH.']
385
- })
386
- : null
387
-
388
- const deviceFailure = simctlAvailable && !bootedDevices.length
389
- ? makeFailure('DEVICE_NOT_FOUND', 'ios', 'No iOS simulators are booted.', {
390
- tool: 'simctl',
391
- searchedLocations: ['xcrun simctl list devices booted --json'],
392
- selectedProvider: 'simctl',
393
- rawVersion: xcrunProbe.raw,
394
- remediation: ['Boot a simulator in Xcode or via xcrun simctl boot.']
395
- })
396
- : null
397
-
398
- const selectedInstallProvider = idbAvailable ? 'idb' : simctlAvailable ? 'simctl' : null
399
- const selectedDebugProvider = simctlAvailable ? 'LLDB' : null
400
- const selectedDiscoveryProvider = idbAvailable ? 'idb' : simctlAvailable ? 'simctl' : null
401
-
402
- const status: PlatformStatus = platformUnsupported
403
- ? 'unsupported'
404
- : !simctlAvailable
405
- ? 'unavailable'
406
- : !bootedDevices.length
407
- ? 'partially_ready'
408
- : 'ready'
409
-
410
- const iosFailure = platformUnsupported
411
- ? makeFailure('PLATFORM_UNAVAILABLE', 'ios', 'iOS tooling is only supported on macOS.', {
412
- tool: null,
413
- searchedLocations: [],
414
- selectedProvider: null,
415
- rawVersion: null,
416
- remediation: ['Run Mobile Debug MCP on macOS for iOS toolchain discovery.']
417
- })
418
- : platformUnavailableFailure ?? deviceFailure ?? null
419
-
420
- const failureList = [iosFailure].filter((value): value is DiagnosticFailure => value !== null)
421
-
422
- return {
423
- status,
424
- tools: {
425
- xcrun: xcrunTool,
426
- idb: idbTool,
427
- idb_companion: idbCompanionTool,
428
- lldb: lldbTool
429
- },
430
- providers: {
431
- idb: { available: idbAvailable, selected: selectedInstallProvider === 'idb', tool: 'idb' },
432
- simctl: { available: simctlAvailable, selected: selectedInstallProvider === 'simctl', tool: 'xcrun' },
433
- lldb: { available: simctlAvailable, selected: selectedDebugProvider === 'LLDB', tool: 'xcrun' }
434
- },
435
- capabilities: {
436
- device_discovery: {
437
- availability: !!selectedDiscoveryProvider,
438
- selectedProvider: selectedDiscoveryProvider,
439
- blockingFailure: selectedDiscoveryProvider ? null : iosFailure
440
- },
441
- install_app: {
442
- availability: !!selectedInstallProvider && bootedDevices.length > 0,
443
- selectedProvider: selectedInstallProvider,
444
- blockingFailure: selectedInstallProvider && bootedDevices.length > 0 ? null : deviceFailure ?? iosFailure
445
- },
446
- launch_app: {
447
- availability: !!selectedInstallProvider && bootedDevices.length > 0,
448
- selectedProvider: selectedInstallProvider,
449
- blockingFailure: selectedInstallProvider && bootedDevices.length > 0 ? null : deviceFailure ?? iosFailure
450
- },
451
- ui_interaction: {
452
- availability: !!selectedInstallProvider && bootedDevices.length > 0,
453
- selectedProvider: selectedInstallProvider,
454
- blockingFailure: selectedInstallProvider && bootedDevices.length > 0 ? null : deviceFailure ?? iosFailure
455
- },
456
- screenshot: {
457
- availability: !!selectedInstallProvider && bootedDevices.length > 0,
458
- selectedProvider: selectedInstallProvider,
459
- blockingFailure: selectedInstallProvider && bootedDevices.length > 0 ? null : deviceFailure ?? iosFailure
460
- },
461
- log_capture: {
462
- availability: simctlAvailable && bootedDevices.length > 0,
463
- selectedProvider: simctlAvailable ? 'simctl' : null,
464
- blockingFailure: simctlAvailable && bootedDevices.length > 0 ? null : deviceFailure ?? iosFailure
465
- },
466
- debug: {
467
- availability: !!selectedDebugProvider,
468
- selectedProvider: selectedDebugProvider,
469
- blockingFailure: selectedDebugProvider ? null : iosFailure
470
- }
471
- },
472
- devices: bootedDevices,
473
- failures: failureList
474
- }
475
- }
476
-
477
- function buildLegacySummary(androidStatus: PlatformEntry, iosStatus: PlatformEntry, gradle: Awaited<ReturnType<typeof checkGradle>>) {
478
- const androidReady = androidStatus.status === 'ready'
479
- const iosReady = iosStatus.status === 'ready'
480
- const gradleReady = (gradle.issues || []).length === 0
481
- const overallStatus = (androidReady || iosReady || gradleReady)
482
- ? ((androidReady && iosReady && gradleReady) ? 'ready' : 'degraded')
483
- : 'blocked'
484
-
485
- return {
486
- overall: overallStatus,
487
- android: {
488
- ready: androidReady,
489
- summary: androidStatus.status === 'ready'
490
- ? `${androidStatus.devices.length} Android device(s) connected; log access available`
491
- : androidStatus.status === 'partially_ready'
492
- ? 'Android toolchain available but device-dependent capabilities are limited'
493
- : androidStatus.status === 'unsupported'
494
- ? 'Android unsupported on this host'
495
- : 'ADB unavailable',
496
- blockers: androidStatus.failures.map((failure) => failure.message)
497
- },
498
- ios: {
499
- ready: iosReady,
500
- summary: iosStatus.status === 'ready'
501
- ? `${iosStatus.devices.length} iOS simulator(s) booted`
502
- : iosStatus.status === 'partially_ready'
503
- ? 'iOS toolchain available but device-dependent capabilities are limited'
504
- : iosStatus.status === 'unsupported'
505
- ? 'iOS unsupported on this host'
506
- : 'xcrun unavailable',
507
- blockers: iosStatus.failures.map((failure) => failure.message)
508
- },
509
- gradle: {
510
- ready: gradleReady,
511
- summary: !gradle.gradleJavaHome
512
- ? 'No explicit Gradle JDK override detected'
513
- : gradleReady
514
- ? `Gradle JDK configured at ${gradle.gradleJavaHome}`
515
- : `Gradle JDK override invalid: ${gradle.gradleJavaHome}`,
516
- blockers: gradle.issues || [],
517
- suggestedFixes: gradle.suggestedFixes || []
518
- }
519
- }
520
- }
6
+ import { buildAndroidPlatform } from './android-status.js'
7
+ import { buildIOSPlatform } from './ios-status.js'
8
+ import { buildLegacySummary } from './status-summary.js'
9
+ import { buildUnsupportedHostStatus } from './unsupported-status.js'
10
+ import { normalizeHostOs, isSupportedHost, probeCommand, makeToolEntry, describeJavaDiscovery, resolveJavaBinaryPath } from './probes.js'
521
11
 
522
12
  export async function getSystemStatus() {
523
13
  const hostOs = normalizeHostOs((process.env.MOBILE_DEBUG_MCP_HOST_OS || process.platform) as NodeJS.Platform)
@@ -545,15 +35,7 @@ export async function getSystemStatus() {
545
35
  const iosReady = hostOs === 'macos' ? (iosRaw.iosAvailable && iosRaw.iosDevices > 0) : false
546
36
  const overallStatus = success ? 'ready' : (androidReady || iosReady ? 'degraded' : 'blocked')
547
37
 
548
- const javaHome = gradle.gradleJavaHome || (await detectJavaHome().catch(() => undefined))
549
- const javaBin = javaHome ? resolveJavaBinaryPath(javaHome, hostOs) : null
550
- const javaProbe = javaBin ? probeCommand(javaBin, ['-version']) : { ok: false, raw: null, parsedVersion: null }
551
- const javaTool = makeToolEntry(
552
- javaBin,
553
- describeJavaDiscovery(javaHome ?? null).discoverySource,
554
- javaProbe.raw,
555
- javaProbe.ok ? 'valid' : (javaHome ? 'invalid' : 'missing')
556
- )
38
+ const javaTool = await javaStatus(gradle, hostOs)
557
39
 
558
40
  return {
559
41
  success,
@@ -610,3 +92,17 @@ export async function getSystemStatus() {
610
92
  }
611
93
  }
612
94
  }
95
+
96
+ async function javaStatus(gradle: Awaited<ReturnType<typeof checkGradle>>, hostOs: HostOs) {
97
+ const javaHome = gradle.gradleJavaHome || (await detectJavaHome().catch(() => undefined))
98
+ const javaBin = javaHome ? resolveJavaBinaryPath(javaHome, hostOs) : null
99
+ const javaProbe = javaBin ? probeCommand(javaBin, ['-version']) : { ok: false, raw: null, parsedVersion: null }
100
+ const javaTool = makeToolEntry(
101
+ javaBin,
102
+ describeJavaDiscovery(javaHome ?? null).discoverySource,
103
+ javaProbe.raw,
104
+ javaProbe.ok ? 'valid' : (javaHome ? 'invalid' : 'missing')
105
+ )
106
+
107
+ return javaTool
108
+ }