mobile-debug-mcp 0.30.1 → 0.31.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 (60) hide show
  1. package/README.md +50 -5
  2. package/dist/interact/index.js +546 -133
  3. package/dist/manage/ios.js +1 -1
  4. package/dist/server/tool-definitions.js +13 -9
  5. package/dist/server/tool-handlers.js +4 -4
  6. package/dist/server-core.js +1 -1
  7. package/dist/system/index.js +485 -48
  8. package/dist/system/ios.js +15 -7
  9. package/dist/utils/android/utils.js +4 -4
  10. package/dist/utils/cli/idb/check-idb.js +10 -3
  11. package/dist/utils/cli/idb/idb-helper.js +47 -13
  12. package/dist/utils/ios/utils.js +5 -9
  13. package/docs/CHANGELOG.md +6 -0
  14. package/docs/ROADMAP.md +88 -212
  15. package/docs/specs/baseline-spec-v0.md +1 -1
  16. package/docs/specs-deltas/015-adjustable-control-support.md +541 -0
  17. package/docs/specs-deltas/016-environment-tools.md +533 -0
  18. package/docs/tools/TOOLS.md +2 -0
  19. package/docs/tools/manage.md +4 -2
  20. package/docs/tools/system.md +9 -2
  21. package/package.json +1 -1
  22. package/skills/spec-review/SKILL.md +52 -0
  23. package/skills/spec-review/references/spec-review-checklist.md +13 -0
  24. package/skills/spec-review/references/spec-review-template.md +28 -0
  25. package/src/interact/index.ts +581 -138
  26. package/src/manage/ios.ts +1 -1
  27. package/src/server/tool-definitions.ts +13 -9
  28. package/src/server/tool-handlers.ts +4 -4
  29. package/src/server-core.ts +1 -1
  30. package/src/system/index.ts +572 -50
  31. package/src/system/ios.ts +14 -7
  32. package/src/types.ts +2 -0
  33. package/src/utils/android/utils.ts +3 -3
  34. package/src/utils/cli/idb/check-idb.ts +11 -2
  35. package/src/utils/cli/idb/idb-helper.ts +49 -12
  36. package/src/utils/ios/utils.ts +4 -8
  37. package/test/unit/interact/adjust_control.test.ts +586 -33
  38. package/test/unit/interact/tap_element.test.ts +1 -1
  39. package/test/unit/server/contract.test.ts +4 -0
  40. package/test/unit/system/get_system_status.test.ts +3 -0
  41. package/test/unit/system/system_status.test.ts +40 -0
  42. package/test/unit/utils/idb_health.test.ts +74 -0
  43. package/skills/rfc-review/SKILL.md +0 -52
  44. package/skills/rfc-review/references/rfc-review-checklist.md +0 -12
  45. package/skills/rfc-review/references/rfc-review-template.md +0 -28
  46. /package/docs/{rfcs → specs-deltas}/001-state-verification.md +0 -0
  47. /package/docs/{rfcs → specs-deltas}/002-richer-element-identity +0 -0
  48. /package/docs/{rfcs → specs-deltas}/003-wait-and-synchronization-reliability.md +0 -0
  49. /package/docs/{rfcs → specs-deltas}/004-action-verification-routing.md +0 -0
  50. /package/docs/{rfcs → specs-deltas}/005-unified-action-execution-and-verification-model.md +0 -0
  51. /package/docs/{rfcs → specs-deltas}/006-runtime-action-instrumentation-and-binding-layer.md +0 -0
  52. /package/docs/{rfcs → specs-deltas}/007-actionability-resolution-and-executable-target-selection.md +0 -0
  53. /package/docs/{rfcs → specs-deltas}/008-adjustable-control-support-and-semantic-value-manipulation.md +0 -0
  54. /package/docs/{rfcs → specs-deltas}/009-semantic-control-modeling-for-custom-and-composite-controls.md +0 -0
  55. /package/docs/{rfcs → specs-deltas}/010-verification-stabilization-and-temporal-convergence.md +0 -0
  56. /package/docs/{rfcs → specs-deltas}/011-recovery-and-replanning-for-failed-or-ambiguous-interaction-flows.md +0 -0
  57. /package/docs/{rfcs → specs-deltas}/011.1-recovery-contract-types-and-runtime-wiring-spec.md +0 -0
  58. /package/docs/{rfcs → specs-deltas}/012-action-trace-and-xecution-observability.md +0 -0
  59. /package/docs/{rfcs → specs-deltas}/013-wait-and-synchronization-reliability.md +0 -0
  60. /package/docs/{rfcs → specs-deltas}/014-actionability-resolution.md +0 -0
@@ -20,8 +20,10 @@ function findInPath(cmd: string): string | null {
20
20
  }
21
21
 
22
22
  export function resolveAdbCmd(): string {
23
- // Priority: explicit env ADB_PATH -> ANDROID_SDK_ROOT/platform-tools/adb -> ANDROID_HOME/platform-tools/adb -> ~/Library/Android/sdk/platform-tools/adb -> PATH discovery -> 'adb'
23
+ // Priority: explicit env ADB_PATH -> PATH -> known SDK locations -> fallback to 'adb'
24
24
  if (process.env.ADB_PATH && process.env.ADB_PATH.trim()) return process.env.ADB_PATH
25
+ const found = findInPath('adb')
26
+ if (found) return found
25
27
  const sdkRoot = process.env.ANDROID_SDK_ROOT || process.env.ANDROID_HOME
26
28
  if (sdkRoot) {
27
29
  const candidate = path.join(sdkRoot, 'platform-tools', process.platform === 'win32' ? 'adb.exe' : 'adb')
@@ -30,8 +32,6 @@ export function resolveAdbCmd(): string {
30
32
  // common macOS user SDK path
31
33
  const homeSdk = path.join(process.env.HOME || '', 'Library', 'Android', 'sdk', 'platform-tools', process.platform === 'win32' ? 'adb.exe' : 'adb')
32
34
  if (existsSync(homeSdk)) return homeSdk
33
- const found = findInPath('adb')
34
- if (found) return found
35
35
  return 'adb'
36
36
  }
37
37
 
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { execSync, spawnSync } from 'child_process'
3
3
  import { main as installMain } from './install-idb.js'
4
- import { getIdbCmd, isIDBInstalled } from './idb-helper.js'
4
+ import { getIdbCmd, getIdbPackageVersion, isIDBInstalled } from './idb-helper.js'
5
5
 
6
6
  function which(cmd: string): string | null {
7
7
  try {
@@ -48,7 +48,16 @@ try {
48
48
  const idb = process.env.IDB_PATH || getIdbCmd()
49
49
  print('idb:', idb)
50
50
  if (idb && isIDBInstalled()) {
51
- try { print('idb --version:', execSync(`${idb} --version`, { stdio: ['ignore','pipe','ignore'] }).toString().trim()) } catch (e) { print('idb --version: (failed)', e instanceof Error ? e.message : String(e)) }
51
+ const version = getIdbPackageVersion()
52
+ if (version) print('fb-idb version:', version)
53
+ try {
54
+ const output = execSync(`${idb} list-targets --json`, { stdio: ['ignore', 'pipe', 'pipe'], timeout: 5000 }).toString().trim()
55
+ print('idb list-targets --json: ok')
56
+ if (output) print(output)
57
+ } catch (e) {
58
+ print('idb list-targets --json: (failed)', e instanceof Error ? e.message : String(e))
59
+ process.exit(2)
60
+ }
52
61
  const companion = which('idb_companion')
53
62
  print('which idb_companion:', companion)
54
63
  if (companion) try { print('idb_companion --version:', execSync('idb_companion --version', { stdio: ['ignore','pipe','ignore'] }).toString().trim()) } catch (e) { print('idb_companion --version: (failed)', e instanceof Error ? e.message : String(e)) }
@@ -59,17 +59,54 @@ export function getIdbCmd(): string | null {
59
59
  return null
60
60
  }
61
61
 
62
- export function isIDBInstalled(): boolean {
63
- const cmd = getIdbCmd()
64
- if (!cmd) return false
65
- try {
66
- // command -v <cmd>
67
- const r = spawnSync('command', ['-v', cmd], { stdio: ['ignore', 'pipe', 'ignore'] })
68
- if (r && r.status === 0) return true
69
- } catch {}
62
+ export function getIdbPackageVersion(): string | null {
63
+ const runners = ['python3', 'python']
64
+ for (const runner of runners) {
65
+ try {
66
+ const result = spawnSync(runner, ['-m', 'pip', 'show', 'fb-idb'], {
67
+ encoding: 'utf8',
68
+ stdio: ['ignore', 'pipe', 'pipe']
69
+ })
70
+ if (result.status !== 0) continue
71
+ const output = `${result.stdout || ''}\n${result.stderr || ''}`
72
+ const match = output.match(/^Version:\s*(.+)$/mi)
73
+ if (match?.[1]) return match[1].trim()
74
+ } catch {
75
+ continue
76
+ }
77
+ }
78
+ return null
79
+ }
80
+
81
+ export function probeIdb(cmd = getIdbCmd()): { ok: boolean; raw: string | null; parsedVersion: string | null } {
82
+ if (!cmd) return { ok: false, raw: null, parsedVersion: null }
83
+
70
84
  try {
71
- execSync(`${cmd} list-targets --json`, { stdio: ['ignore', 'pipe', 'ignore'], timeout: 2000 })
72
- return true
73
- } catch {}
74
- return false
85
+ const result = spawnSync(cmd, ['list-targets', '--json'], {
86
+ encoding: 'utf8',
87
+ stdio: ['ignore', 'pipe', 'pipe'],
88
+ timeout: 5000
89
+ })
90
+ if (result.status !== 0) {
91
+ return {
92
+ ok: false,
93
+ raw: `${result.stdout || ''}${result.stderr || ''}`.trim() || null,
94
+ parsedVersion: null
95
+ }
96
+ }
97
+
98
+ const version = getIdbPackageVersion()
99
+ const raw = version ? `fb-idb ${version}` : `${result.stdout || ''}${result.stderr || ''}`.trim() || null
100
+ return {
101
+ ok: true,
102
+ raw,
103
+ parsedVersion: version
104
+ }
105
+ } catch {
106
+ return { ok: false, raw: null, parsedVersion: null }
107
+ }
108
+ }
109
+
110
+ export function isIDBInstalled(): boolean {
111
+ return probeIdb().ok
75
112
  }
@@ -59,17 +59,13 @@ export function getIdbCmd() {
59
59
 
60
60
  export async function isIDBInstalled(): Promise<boolean> {
61
61
  const cmd = getIdbCmd()
62
+ if (!cmd) return false
62
63
  try {
63
- execSync(`command -v ${cmd}`, { stdio: ['ignore','pipe','ignore'] })
64
+ execSync(`${cmd} list-targets --json`, { stdio: ['ignore','pipe','pipe'], timeout: 5000 })
64
65
  return true
65
66
  } catch (e: unknown) {
66
- try {
67
- execSync(`${cmd} list-targets --json`, { stdio: ['ignore','pipe','ignore'], timeout: 2000 })
68
- return true
69
- } catch (e2: unknown) {
70
- console.debug(`[isIDBInstalled] idb presence check failed for '${cmd}': ${e instanceof Error ? e.message : String(e2)}`)
71
- return false
72
- }
67
+ console.debug(`[isIDBInstalled] idb probe failed for '${cmd}': ${e instanceof Error ? e.message : String(e)}`)
68
+ return false
73
69
  }
74
70
  }
75
71