react-native-ai-devtools 1.4.22 → 1.4.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/index.js CHANGED
@@ -9,7 +9,7 @@ import { getGuideOverview, getGuideByTopic, getAvailableTopics } from "./core/gu
9
9
  import { getLicenseStatus, getDashboardUrl, getUsageInfo } from "./core/license.js";
10
10
  import { API_BASE_URL } from "./core/config.js";
11
11
  import { getPostHogClient, identifyIfDevMode, shutdownPostHog } from "./core/posthog.js";
12
- import { getInstallationId, getServerVersion, isDevMode, TELEMETRY_JSONL_PATH } from "./core/telemetry.js";
12
+ import { getInstallationId, getServerVersion, isDevMode, TELEMETRY_JSONL_PATH, categorizeError } from "./core/telemetry.js";
13
13
  import { isSDKInstalled, querySDKNetwork, getSDKNetworkEntry, getSDKNetworkStats, clearSDKNetwork, querySDKConsole, getSDKConsoleStats, clearSDKConsole } from "./core/sdkBridge.js";
14
14
  import { tap } from "./pro/tap.js";
15
15
  import { getActivateLicenseConfig, handleActivateLicense, getDeleteAccountConfig, handleDeleteAccount, } from "./tools/accountTools.js";
@@ -38,8 +38,8 @@ androidDescribeAll, androidDescribePoint,
38
38
  androidFindElement, androidWaitForElement,
39
39
  // iOS
40
40
  listIOSSimulators, iosScreenshot, iosInstallApp, iosLaunchApp, iosOpenUrl, iosTerminateApp, iosBootSimulator,
41
- // iOS IDB-based UI tools
42
- iosTap, iosSwipe, iosInputText, iosButton, iosKeyEvent, iosKeySequence, iosDescribeAll, iosDescribePoint, IOS_BUTTON_TYPES,
41
+ // iOS UI driver tools
42
+ isUiDriverAvailable, iosTap, iosSwipe, iosInputText, iosButton, iosKeyEvent, iosKeySequence, iosDescribeAll, iosDescribePoint, IOS_BUTTON_TYPES,
43
43
  // iOS Element Finding (no screenshots)
44
44
  iosFindElement, iosWaitForElement,
45
45
  // Telemetry
@@ -290,7 +290,14 @@ function registerToolWithTelemetry(toolName, config, handler, emptyResultDetecto
290
290
  duration,
291
291
  server_version: getServerVersion(),
292
292
  ...(errorMessage && { error: errorMessage.substring(0, 200) }),
293
+ ...(errorMessage && { error_category: categorizeError(errorMessage) }),
293
294
  ...(getTargetPlatform() && { platform: getTargetPlatform() }),
295
+ ...(tapStrategy && { tap_strategy: tapStrategy }),
296
+ ...(meaningful !== undefined && { meaningful }),
297
+ ...(changeRate !== undefined && { change_rate: changeRate }),
298
+ ...(iosDriver && { ios_driver: iosDriver }),
299
+ ...(emptyResult !== undefined && { empty_result: emptyResult }),
300
+ ...(emptyReason && { empty_reason: emptyReason }),
294
301
  },
295
302
  });
296
303
  }
@@ -435,6 +442,21 @@ registerToolWithTelemetry("scan_metro", {
435
442
  // Build events connection is optional
436
443
  }
437
444
  }
445
+ // Proactive check: warn if iOS UI driver is missing
446
+ const hasIosDevice = Array.from(allDeviceNames.values()).some(({ device }) => {
447
+ const title = (device.title || "").toLowerCase();
448
+ return title.includes("iphone") || title.includes("ipad") || title.includes("ios");
449
+ });
450
+ if (hasIosDevice) {
451
+ const uiDriverOk = await isUiDriverAvailable();
452
+ if (!uiDriverOk) {
453
+ results.push("");
454
+ results.push("⚠️ WARNING: iOS UI driver is NOT installed. Tools like tap, ios_swipe, ios_input_text, ios_describe_all, and ios_find_element will fail.");
455
+ results.push(" Install the recommended driver: brew install cameroncooke/axe/axe");
456
+ results.push(" Then set IOS_DRIVER=axe in your MCP server environment.");
457
+ results.push(" Alternative: brew install idb-companion (used by default)");
458
+ }
459
+ }
438
460
  return {
439
461
  content: [
440
462
  {
@@ -1540,6 +1562,7 @@ registerToolWithTelemetry("find_components", {
1540
1562
  registerToolWithTelemetry("tap", {
1541
1563
  description: "Tap a UI element. Automatically tries multiple strategies: fiber tree (React), accessibility tree (native), and OCR (visual). " +
1542
1564
  "Auto-detects platform (iOS/Android). For coordinates, pass raw pixel values from screenshot — tap handles all coordinate conversion internally (iOS pixel-to-point, scale factor adjustments).\n\n" +
1565
+ "PREREQUISITE: For iOS, an iOS UI driver must be installed — AXe (recommended: brew install cameroncooke/axe/axe) or IDB (brew install idb-companion). Without it, accessibility and coordinate strategies will fail.\n\n" +
1543
1566
  "IMPORTANT: When both iOS and Android devices are connected, specify platform explicitly to avoid tapping on the wrong device.\n\n" +
1544
1567
  "Examples:\n" +
1545
1568
  "- tap(text=\"Submit\") — finds and taps element with matching text\n" +
@@ -3659,12 +3682,13 @@ registerToolWithTelemetry("ios_boot_simulator", {
3659
3682
  };
3660
3683
  });
3661
3684
  // ============================================================================
3662
- // iOS IDB-Based UI Tools (require Facebook IDB)
3663
- // Install with: brew install idb-companion
3685
+ // iOS UI Interaction Tools (require an iOS UI driver)
3686
+ // Recommended: AXe — brew install cameroncooke/axe/axe (set IOS_DRIVER=axe)
3687
+ // Alternative: IDB — brew install idb-companion (default)
3664
3688
  // ============================================================================
3665
3689
  // Tool: iOS swipe
3666
3690
  server.registerTool("ios_swipe", {
3667
- description: "Swipe gesture on an iOS simulator screen. Requires IDB to be installed (brew install idb-companion).",
3691
+ description: "Swipe gesture on an iOS simulator screen. Requires an iOS UI driver: AXe (recommended: brew install cameroncooke/axe/axe) or IDB (brew install idb-companion).",
3668
3692
  inputSchema: {
3669
3693
  startX: z.coerce.number().describe("Starting X coordinate in pixels"),
3670
3694
  startY: z.coerce.number().describe("Starting Y coordinate in pixels"),
@@ -3688,7 +3712,7 @@ server.registerTool("ios_swipe", {
3688
3712
  });
3689
3713
  // Tool: iOS input text
3690
3714
  server.registerTool("ios_input_text", {
3691
- description: "Type text into the active input field on an iOS simulator. Requires IDB to be installed (brew install idb-companion).",
3715
+ description: "Type text into the active input field on an iOS simulator. Requires an iOS UI driver: AXe (recommended: brew install cameroncooke/axe/axe) or IDB (brew install idb-companion).",
3692
3716
  inputSchema: {
3693
3717
  text: z.string().describe("Text to type into the active input field"),
3694
3718
  udid: z.string().optional().describe("Optional simulator UDID. Uses booted simulator if not specified.")
@@ -3707,7 +3731,7 @@ server.registerTool("ios_input_text", {
3707
3731
  });
3708
3732
  // Tool: iOS button
3709
3733
  server.registerTool("ios_button", {
3710
- description: "Press a hardware button on an iOS simulator. Requires IDB to be installed (brew install idb-companion).",
3734
+ description: "Press a hardware button on an iOS simulator. Requires an iOS UI driver: AXe (recommended: brew install cameroncooke/axe/axe) or IDB (brew install idb-companion).",
3711
3735
  inputSchema: {
3712
3736
  button: z
3713
3737
  .enum(IOS_BUTTON_TYPES)
@@ -3729,7 +3753,7 @@ server.registerTool("ios_button", {
3729
3753
  });
3730
3754
  // Tool: iOS key event
3731
3755
  server.registerTool("ios_key_event", {
3732
- description: "Send a key event to an iOS simulator by keycode. Requires IDB to be installed (brew install idb-companion).",
3756
+ description: "Send a key event to an iOS simulator by keycode. Requires an iOS UI driver: AXe (recommended: brew install cameroncooke/axe/axe) or IDB (brew install idb-companion).",
3733
3757
  inputSchema: {
3734
3758
  keycode: z.coerce.number().describe("iOS keycode to send"),
3735
3759
  duration: z.coerce.number().optional().describe("Optional key press duration in seconds"),
@@ -3749,7 +3773,7 @@ server.registerTool("ios_key_event", {
3749
3773
  });
3750
3774
  // Tool: iOS key sequence
3751
3775
  server.registerTool("ios_key_sequence", {
3752
- description: "Send a sequence of key events to an iOS simulator. Requires IDB to be installed (brew install idb-companion).",
3776
+ description: "Send a sequence of key events to an iOS simulator. Requires an iOS UI driver: AXe (recommended: brew install cameroncooke/axe/axe) or IDB (brew install idb-companion).",
3753
3777
  inputSchema: {
3754
3778
  keycodes: z.array(z.coerce.number()).describe("Array of iOS keycodes to send in sequence"),
3755
3779
  udid: z.string().optional().describe("Optional simulator UDID. Uses booted simulator if not specified.")
@@ -3768,7 +3792,7 @@ server.registerTool("ios_key_sequence", {
3768
3792
  });
3769
3793
  // Tool: iOS describe all (accessibility tree)
3770
3794
  server.registerTool("ios_describe_all", {
3771
- description: "Get accessibility information for the entire iOS simulator screen. Returns a nested tree of UI elements with labels, values, and frames. Requires IDB to be installed (brew install idb-companion).",
3795
+ description: "Get accessibility information for the entire iOS simulator screen. Returns a nested tree of UI elements with labels, values, and frames. Requires an iOS UI driver: AXe (recommended: brew install cameroncooke/axe/axe) or IDB (brew install idb-companion).",
3772
3796
  inputSchema: {
3773
3797
  udid: z.string().optional().describe("Optional simulator UDID. Uses booted simulator if not specified.")
3774
3798
  }
@@ -3799,7 +3823,7 @@ server.registerTool("ios_describe_all", {
3799
3823
  });
3800
3824
  // Tool: iOS describe point
3801
3825
  server.registerTool("ios_describe_point", {
3802
- description: "Get accessibility information for the UI element at a specific point on the iOS simulator screen. Requires IDB to be installed (brew install idb-companion).",
3826
+ description: "Get accessibility information for the UI element at a specific point on the iOS simulator screen. Requires an iOS UI driver: AXe (recommended: brew install cameroncooke/axe/axe) or IDB (brew install idb-companion).",
3803
3827
  inputSchema: {
3804
3828
  x: z.coerce.number().describe("X coordinate in pixels"),
3805
3829
  y: z.coerce.number().describe("Y coordinate in pixels"),
@@ -3819,7 +3843,7 @@ server.registerTool("ios_describe_point", {
3819
3843
  });
3820
3844
  // Tool: iOS find element (no screenshot needed)
3821
3845
  server.registerTool("ios_find_element", {
3822
- description: "Find a UI element on iOS simulator by accessibility label or value. Returns element details including tap coordinates. Requires IDB (brew install idb-companion). Workflow: 1) wait_for_element, 2) find_element, 3) tap with returned coordinates. Prefer this over screenshots for button taps.",
3846
+ description: "Find a UI element on iOS simulator by accessibility label or value. Returns element details including tap coordinates. Requires an iOS UI driver: AXe (recommended: brew install cameroncooke/axe/axe) or IDB (brew install idb-companion). Workflow: 1) wait_for_element, 2) find_element, 3) tap with returned coordinates. Prefer this over screenshots for button taps.",
3823
3847
  inputSchema: {
3824
3848
  label: z.string().optional().describe("Exact accessibility label match"),
3825
3849
  labelContains: z.string().optional().describe("Partial label match (case-insensitive)"),
@@ -3866,7 +3890,7 @@ server.registerTool("ios_find_element", {
3866
3890
  });
3867
3891
  // Tool: iOS wait for element
3868
3892
  server.registerTool("ios_wait_for_element", {
3869
- description: "Wait for a UI element to appear on iOS simulator. Polls until found or timeout. Requires IDB (brew install idb-companion). Use this FIRST after navigation to ensure screen is ready, then use find_element + tap.",
3893
+ description: "Wait for a UI element to appear on iOS simulator. Polls until found or timeout. Requires an iOS UI driver: AXe (recommended: brew install cameroncooke/axe/axe) or IDB (brew install idb-companion). Use this FIRST after navigation to ensure screen is ready, then use find_element + tap.",
3870
3894
  inputSchema: {
3871
3895
  label: z.string().optional().describe("Exact accessibility label match"),
3872
3896
  labelContains: z.string().optional().describe("Partial label match (case-insensitive)"),