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