react-native-ai-devtools 1.3.4 → 1.3.6

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
@@ -6,8 +6,9 @@ import { createServer as createHttpServer } from "node:http";
6
6
  import { z } from "zod";
7
7
  import { getGuideOverview, getGuideByTopic, getAvailableTopics } from "./core/guides.js";
8
8
  import { getLicenseStatus, getDashboardUrl } from "./core/license.js";
9
- import { isSDKInstalled, readSDKNetworkRequests, readSDKNetworkRequest, readSDKNetworkStats, clearSDKNetwork } from "./core/sdkBridge.js";
9
+ import { isSDKInstalled, querySDKNetwork, getSDKNetworkEntry, getSDKNetworkStats, clearSDKNetwork, querySDKConsole, getSDKConsoleStats, clearSDKConsole } from "./core/sdkBridge.js";
10
10
  import { tap } from "./pro/tap.js";
11
+ import { getActivateLicenseConfig, handleActivateLicense, getDeleteAccountConfig, handleDeleteAccount, } from "./tools/accountTools.js";
11
12
  import { logBuffers, networkBuffers, getLogBuffer, getNetworkBuffer, getTotalLogCount, getConnectedAppByDevice, LogBuffer, NetworkBuffer, bundleErrorBuffer, connectedApps, scanMetroPorts, fetchDevices, selectMainDevice, filterBridgelessDevices, connectToDevice, getConnectedApps, executeInApp, listDebugGlobals, inspectGlobal, reloadApp,
12
13
  // React Component Inspection
13
14
  getComponentTree, getScreenLayout, inspectComponent, findComponents, inspectAtPoint, toggleElementInspector, isInspectorActive, getInspectorSelection, getFirstConnectedApp, getLogs, searchLogs, getLogSummary, getNetworkRequests, searchNetworkRequests, getNetworkStats, formatRequestDetails,
@@ -477,18 +478,17 @@ registerToolWithTelemetry("get_license_status", {
477
478
  const status = getLicenseStatus();
478
479
  const lines = [];
479
480
  lines.push(`Installation ID: ${status.installationId}`);
480
- lines.push(`License: ${status.status.charAt(0).toUpperCase() + status.status.slice(1)}`);
481
+ lines.push(`License: ${status.tier.charAt(0).toUpperCase() + status.tier.slice(1)}`);
481
482
  if (status.plan) {
482
483
  lines.push(`Plan expires: ${status.plan.expiresAt}`);
483
484
  }
484
485
  lines.push(`Cache valid until: ${status.cacheExpiresAt}`);
485
- if (status.status === "free") {
486
+ if (status.tier === "free") {
486
487
  const dashboardUrl = getDashboardUrl();
487
488
  lines.push("");
488
489
  if (dashboardUrl) {
489
- lines.push(`Activate Pro at: ${dashboardUrl}`);
490
+ lines.push(`Link your account: ${dashboardUrl}/link?id=${status.installationId}`);
490
491
  }
491
- lines.push("Enter your Installation ID in the dashboard to unlock Pro features.");
492
492
  }
493
493
  return {
494
494
  content: [{ type: "text", text: lines.join("\n") }],
@@ -583,6 +583,51 @@ registerToolWithTelemetry("get_logs", {
583
583
  device: z.string().optional().describe("Target device name (substring match). Omit for all devices. Run get_apps to see connected devices.")
584
584
  }
585
585
  }, async ({ maxLogs, level, startFromText, maxMessageLength, verbose, format, summary, device }) => {
586
+ // Check if SDK is installed — prefer SDK data for richer logs
587
+ const sdkAvailable = await isSDKInstalled();
588
+ if (sdkAvailable) {
589
+ if (summary) {
590
+ const sdkStats = await getSDKConsoleStats();
591
+ if (sdkStats.success) {
592
+ const s = sdkStats.data;
593
+ const lines = [];
594
+ lines.push(`Total logs: ${s.total}`);
595
+ if (s.byLevel && Object.keys(s.byLevel).length > 0) {
596
+ lines.push("\nBy Level:");
597
+ for (const [lvl, cnt] of Object.entries(s.byLevel))
598
+ lines.push(` ${lvl}: ${cnt}`);
599
+ }
600
+ return { content: [{ type: "text", text: `Log Summary (SDK):\n\n${lines.join("\n")}` }] };
601
+ }
602
+ }
603
+ const sdkResult = await querySDKConsole({ count: maxLogs, level, text: startFromText });
604
+ if (sdkResult.success) {
605
+ const entries = sdkResult.data;
606
+ if (entries.length === 0) {
607
+ return { content: [{ type: "text", text: "No console logs captured yet." }] };
608
+ }
609
+ if (format === "tonl") {
610
+ const tonlLines = entries.map((e) => {
611
+ const time = new Date(e.timestamp).toLocaleTimeString();
612
+ let msg = e.message;
613
+ if (!verbose && maxMessageLength > 0 && msg.length > maxMessageLength) {
614
+ msg = msg.slice(0, maxMessageLength) + "...";
615
+ }
616
+ return `${time} [${e.level}] ${msg}`;
617
+ });
618
+ return { content: [{ type: "text", text: `Console Logs (${entries.length} entries, SDK):\n\n${tonlLines.join("\n")}` }] };
619
+ }
620
+ const lines = entries.map((e) => {
621
+ const time = new Date(e.timestamp).toLocaleTimeString();
622
+ let msg = e.message;
623
+ if (!verbose && maxMessageLength > 0 && msg.length > maxMessageLength) {
624
+ msg = msg.slice(0, maxMessageLength) + "...";
625
+ }
626
+ return `[${time}] [${e.level.toUpperCase()}] ${msg}`;
627
+ });
628
+ return { content: [{ type: "text", text: `Console Logs (${entries.length} entries, SDK):\n\n${lines.join("\n")}` }] };
629
+ }
630
+ }
586
631
  // Return summary if requested
587
632
  if (summary) {
588
633
  const summaryText = getLogSummary(resolveLogBuffer(device), { lastN: 5, maxMessageLength: 100 });
@@ -682,6 +727,37 @@ registerToolWithTelemetry("search_logs", {
682
727
  device: z.string().optional().describe("Target device name (substring match). Omit for all devices. Run get_apps to see connected devices.")
683
728
  }
684
729
  }, async ({ text, maxResults, maxMessageLength, verbose, format, device }) => {
730
+ // Check if SDK is installed — prefer SDK data
731
+ const sdkAvailable = await isSDKInstalled();
732
+ if (sdkAvailable) {
733
+ const sdkResult = await querySDKConsole({ count: maxResults, text });
734
+ if (sdkResult.success) {
735
+ const entries = sdkResult.data;
736
+ if (entries.length === 0) {
737
+ return { content: [{ type: "text", text: `No logs matching "${text}" found.` }] };
738
+ }
739
+ if (format === "tonl") {
740
+ const tonlLines = entries.map((e) => {
741
+ const time = new Date(e.timestamp).toLocaleTimeString();
742
+ let msg = e.message;
743
+ if (!verbose && maxMessageLength > 0 && msg.length > maxMessageLength) {
744
+ msg = msg.slice(0, maxMessageLength) + "...";
745
+ }
746
+ return `${time} [${e.level}] ${msg}`;
747
+ });
748
+ return { content: [{ type: "text", text: `Search results for "${text}" (${entries.length} matches, SDK):\n\n${tonlLines.join("\n")}` }] };
749
+ }
750
+ const lines = entries.map((e) => {
751
+ const time = new Date(e.timestamp).toLocaleTimeString();
752
+ let msg = e.message;
753
+ if (!verbose && maxMessageLength > 0 && msg.length > maxMessageLength) {
754
+ msg = msg.slice(0, maxMessageLength) + "...";
755
+ }
756
+ return `[${time}] [${e.level.toUpperCase()}] ${msg}`;
757
+ });
758
+ return { content: [{ type: "text", text: `Search results for "${text}" (${entries.length} matches, SDK):\n\n${lines.join("\n")}` }] };
759
+ }
760
+ }
685
761
  const { logs, count, formatted } = searchLogs(resolveLogBuffer(device), text, { maxResults, maxMessageLength, verbose });
686
762
  // Check connection health
687
763
  let connectionWarning = "";
@@ -736,6 +812,14 @@ registerToolWithTelemetry("clear_logs", {
736
812
  for (const buffer of logBuffers.values()) {
737
813
  total += buffer.clear();
738
814
  }
815
+ // Also clear SDK buffer if available
816
+ const sdkAvailable = await isSDKInstalled();
817
+ if (sdkAvailable) {
818
+ const sdkResult = await clearSDKConsole();
819
+ if (sdkResult.success && sdkResult.count) {
820
+ total += sdkResult.count;
821
+ }
822
+ }
739
823
  return { content: [{ type: "text", text: `Cleared ${total} log entries from all devices.` }] };
740
824
  });
741
825
  // Tool: Connect to specific Metro port
@@ -1572,7 +1656,7 @@ registerToolWithTelemetry("get_network_requests", {
1572
1656
  const sdkAvailable = await isSDKInstalled();
1573
1657
  if (sdkAvailable) {
1574
1658
  if (summary) {
1575
- const sdkStats = await readSDKNetworkStats();
1659
+ const sdkStats = await getSDKNetworkStats();
1576
1660
  if (sdkStats.success) {
1577
1661
  const s = sdkStats.data;
1578
1662
  const lines = [];
@@ -1599,8 +1683,8 @@ registerToolWithTelemetry("get_network_requests", {
1599
1683
  return { content: [{ type: "text", text: `Network Summary (SDK):\n\n${lines.join("\n")}` }] };
1600
1684
  }
1601
1685
  }
1602
- const sdkResult = await readSDKNetworkRequests({ count: maxRequests, method, urlPattern, status });
1603
- if (sdkResult.success && sdkResult.data) {
1686
+ const sdkResult = await querySDKNetwork({ count: maxRequests, method, urlPattern, status });
1687
+ if (sdkResult.success) {
1604
1688
  const entries = sdkResult.data;
1605
1689
  if (entries.length === 0) {
1606
1690
  return { content: [{ type: "text", text: "No network requests captured yet." }] };
@@ -1709,6 +1793,27 @@ registerToolWithTelemetry("search_network", {
1709
1793
  device: z.string().optional().describe("Target device name (substring match). Omit for all devices. Run get_apps to see connected devices.")
1710
1794
  }
1711
1795
  }, async ({ urlPattern, maxResults, format, device }) => {
1796
+ // Check if SDK is installed — prefer SDK data
1797
+ const sdkAvailable = await isSDKInstalled();
1798
+ if (sdkAvailable) {
1799
+ const sdkResult = await querySDKNetwork({ count: maxResults, urlPattern });
1800
+ if (sdkResult.success) {
1801
+ const entries = sdkResult.data;
1802
+ if (entries.length === 0) {
1803
+ return { content: [{ type: "text", text: `No network requests matching "${urlPattern}" found.` }] };
1804
+ }
1805
+ const lines = entries.map((r) => {
1806
+ const time = new Date(r.timestamp).toLocaleTimeString();
1807
+ const st = r.status ?? "pending";
1808
+ const dur = r.duration != null ? `${r.duration}ms` : "-";
1809
+ return `[${r.id}] ${time} ${r.method} ${st} ${dur} ${r.url}`;
1810
+ });
1811
+ if (format === "tonl") {
1812
+ return { content: [{ type: "text", text: `Network search results for "${urlPattern}" (${entries.length} matches, SDK):\n\n${lines.join("\n")}` }] };
1813
+ }
1814
+ return { content: [{ type: "text", text: `Network search results for "${urlPattern}" (${entries.length} matches, SDK):\n\n${lines.join("\n")}` }] };
1815
+ }
1816
+ }
1712
1817
  const { requests, count, formatted } = searchNetworkRequests(resolveNetworkBuffer(device), urlPattern, maxResults);
1713
1818
  // Check connection health
1714
1819
  let connectionWarning = "";
@@ -1764,7 +1869,7 @@ registerToolWithTelemetry("get_request_details", {
1764
1869
  // Check SDK first — it has full headers and body
1765
1870
  const sdkAvailable = await isSDKInstalled();
1766
1871
  if (sdkAvailable) {
1767
- const sdkResult = await readSDKNetworkRequest(requestId);
1872
+ const sdkResult = await getSDKNetworkEntry(requestId);
1768
1873
  if (sdkResult.success && sdkResult.data) {
1769
1874
  const r = sdkResult.data;
1770
1875
  const lines = [];
@@ -1838,6 +1943,36 @@ registerToolWithTelemetry("get_network_stats", {
1838
1943
  device: z.string().optional().describe("Target device name (substring match). Omit for all devices. Run get_apps to see connected devices.")
1839
1944
  }
1840
1945
  }, async ({ device }) => {
1946
+ // Check if SDK is installed — prefer SDK data
1947
+ const sdkAvailable = await isSDKInstalled();
1948
+ if (sdkAvailable) {
1949
+ const sdkStats = await getSDKNetworkStats();
1950
+ if (sdkStats.success) {
1951
+ const s = sdkStats.data;
1952
+ const lines = [];
1953
+ lines.push(`Total requests: ${s.total}`);
1954
+ lines.push(`Completed: ${s.completed}`);
1955
+ lines.push(`Errors: ${s.errors}`);
1956
+ if (s.avgDuration != null)
1957
+ lines.push(`Avg duration: ${s.avgDuration}ms`);
1958
+ if (s.byMethod && Object.keys(s.byMethod).length > 0) {
1959
+ lines.push("\nBy Method:");
1960
+ for (const [m, c] of Object.entries(s.byMethod))
1961
+ lines.push(` ${m}: ${c}`);
1962
+ }
1963
+ if (s.byStatus && Object.keys(s.byStatus).length > 0) {
1964
+ lines.push("\nBy Status:");
1965
+ for (const [st, c] of Object.entries(s.byStatus))
1966
+ lines.push(` ${st}: ${c}`);
1967
+ }
1968
+ if (s.byDomain && Object.keys(s.byDomain).length > 0) {
1969
+ lines.push("\nBy Domain:");
1970
+ for (const [d, c] of Object.entries(s.byDomain).sort((a, b) => b[1] - a[1]).slice(0, 10))
1971
+ lines.push(` ${d}: ${c}`);
1972
+ }
1973
+ return { content: [{ type: "text", text: `Network Statistics (SDK):\n\n${lines.join("\n")}` }] };
1974
+ }
1975
+ }
1841
1976
  const stats = getNetworkStats(resolveNetworkBuffer(device));
1842
1977
  // Check connection health
1843
1978
  let connectionWarning = "";
@@ -3227,6 +3362,10 @@ registerToolWithTelemetry("restart_http_server", {
3227
3362
  ]
3228
3363
  };
3229
3364
  });
3365
+ // Tool: Activate Pro license
3366
+ registerToolWithTelemetry("activate_license", getActivateLicenseConfig(), handleActivateLicense);
3367
+ // Tool: Delete account
3368
+ registerToolWithTelemetry("delete_account", getDeleteAccountConfig(), handleDeleteAccount);
3230
3369
  /**
3231
3370
  * Auto-connect to Metro bundler on startup
3232
3371
  * Scans common ports and connects to any running Metro servers