react-native-debug-toolkit 3.3.8 → 3.5.1

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 (223) hide show
  1. package/README.md +40 -26
  2. package/README.zh-CN.md +52 -38
  3. package/android/src/main/java/com/reactnativedebugtoolkit/DebugToolkitNativeLogsModule.java +146 -0
  4. package/android/src/main/java/com/reactnativedebugtoolkit/ReactNativeDebugToolkitPackage.java +5 -3
  5. package/ios/DebugToolkitNativeLogs.mm +92 -0
  6. package/lib/commonjs/constants/logLevels.js +19 -0
  7. package/lib/commonjs/constants/logLevels.js.map +1 -0
  8. package/lib/commonjs/core/initialize.js +32 -19
  9. package/lib/commonjs/core/initialize.js.map +1 -1
  10. package/lib/commonjs/features/console/ConsoleLogTab.js +4 -15
  11. package/lib/commonjs/features/console/ConsoleLogTab.js.map +1 -1
  12. package/lib/commonjs/features/console/index.js +15 -8
  13. package/lib/commonjs/features/console/index.js.map +1 -1
  14. package/lib/commonjs/features/nativeLogs/NativeLogTab.js +156 -0
  15. package/lib/commonjs/features/nativeLogs/NativeLogTab.js.map +1 -0
  16. package/lib/commonjs/features/nativeLogs/index.js +97 -0
  17. package/lib/commonjs/features/nativeLogs/index.js.map +1 -0
  18. package/lib/commonjs/features/nativeLogs/nativeLogsBridge.js +71 -0
  19. package/lib/commonjs/features/nativeLogs/nativeLogsBridge.js.map +1 -0
  20. package/lib/commonjs/features/network/NetworkLogTab.js +90 -95
  21. package/lib/commonjs/features/network/NetworkLogTab.js.map +1 -1
  22. package/lib/commonjs/features/network/index.js +7 -4
  23. package/lib/commonjs/features/network/index.js.map +1 -1
  24. package/lib/commonjs/features/sessionHistory/SessionHistoryTab.js +1046 -0
  25. package/lib/commonjs/features/sessionHistory/SessionHistoryTab.js.map +1 -0
  26. package/lib/commonjs/features/sessionHistory/index.js +104 -0
  27. package/lib/commonjs/features/sessionHistory/index.js.map +1 -0
  28. package/lib/commonjs/features/track/index.js +4 -3
  29. package/lib/commonjs/features/track/index.js.map +1 -1
  30. package/lib/commonjs/index.js +27 -0
  31. package/lib/commonjs/index.js.map +1 -1
  32. package/lib/commonjs/ui/DebugView.js +2 -0
  33. package/lib/commonjs/ui/DebugView.js.map +1 -1
  34. package/lib/commonjs/ui/panel/DebugPanel.js +67 -34
  35. package/lib/commonjs/ui/panel/DebugPanel.js.map +1 -1
  36. package/lib/commonjs/ui/panel/FeatureIntroCard.js +151 -0
  37. package/lib/commonjs/ui/panel/FeatureIntroCard.js.map +1 -0
  38. package/lib/commonjs/ui/panel/FeatureRail.js +163 -0
  39. package/lib/commonjs/ui/panel/FeatureRail.js.map +1 -0
  40. package/lib/commonjs/ui/panel/FloatPanelView.js +119 -22
  41. package/lib/commonjs/ui/panel/FloatPanelView.js.map +1 -1
  42. package/lib/commonjs/ui/panel/buildFeatureSummary.js +207 -0
  43. package/lib/commonjs/ui/panel/buildFeatureSummary.js.map +1 -0
  44. package/lib/commonjs/ui/panel/filterFeatureSnapshot.js +43 -0
  45. package/lib/commonjs/ui/panel/filterFeatureSnapshot.js.map +1 -0
  46. package/lib/commonjs/ui/theme/colors.js +6 -0
  47. package/lib/commonjs/ui/theme/colors.js.map +1 -1
  48. package/lib/commonjs/utils/DaemonClient.js +30 -8
  49. package/lib/commonjs/utils/DaemonClient.js.map +1 -1
  50. package/lib/commonjs/utils/SessionManager.js +132 -0
  51. package/lib/commonjs/utils/SessionManager.js.map +1 -0
  52. package/lib/commonjs/utils/StorageAdapter.js +104 -0
  53. package/lib/commonjs/utils/StorageAdapter.js.map +1 -0
  54. package/lib/commonjs/utils/createChannelFeature.js +22 -5
  55. package/lib/commonjs/utils/createChannelFeature.js.map +1 -1
  56. package/lib/commonjs/utils/createPersistedObservableStore.js +14 -8
  57. package/lib/commonjs/utils/createPersistedObservableStore.js.map +1 -1
  58. package/lib/commonjs/utils/debugPreferences.js +28 -5
  59. package/lib/commonjs/utils/debugPreferences.js.map +1 -1
  60. package/lib/commonjs/utils/deviceReport.js +5 -1
  61. package/lib/commonjs/utils/deviceReport.js.map +1 -1
  62. package/lib/commonjs/utils/logRuntime.js +32 -0
  63. package/lib/commonjs/utils/logRuntime.js.map +1 -0
  64. package/lib/module/constants/logLevels.js +15 -0
  65. package/lib/module/constants/logLevels.js.map +1 -0
  66. package/lib/module/core/initialize.js +32 -19
  67. package/lib/module/core/initialize.js.map +1 -1
  68. package/lib/module/features/console/ConsoleLogTab.js +1 -12
  69. package/lib/module/features/console/ConsoleLogTab.js.map +1 -1
  70. package/lib/module/features/console/index.js +15 -8
  71. package/lib/module/features/console/index.js.map +1 -1
  72. package/lib/module/features/nativeLogs/NativeLogTab.js +151 -0
  73. package/lib/module/features/nativeLogs/NativeLogTab.js.map +1 -0
  74. package/lib/module/features/nativeLogs/index.js +91 -0
  75. package/lib/module/features/nativeLogs/index.js.map +1 -0
  76. package/lib/module/features/nativeLogs/nativeLogsBridge.js +63 -0
  77. package/lib/module/features/nativeLogs/nativeLogsBridge.js.map +1 -0
  78. package/lib/module/features/network/NetworkLogTab.js +90 -95
  79. package/lib/module/features/network/NetworkLogTab.js.map +1 -1
  80. package/lib/module/features/network/index.js +7 -4
  81. package/lib/module/features/network/index.js.map +1 -1
  82. package/lib/module/features/sessionHistory/SessionHistoryTab.js +1041 -0
  83. package/lib/module/features/sessionHistory/SessionHistoryTab.js.map +1 -0
  84. package/lib/module/features/sessionHistory/index.js +100 -0
  85. package/lib/module/features/sessionHistory/index.js.map +1 -0
  86. package/lib/module/features/track/index.js +4 -3
  87. package/lib/module/features/track/index.js.map +1 -1
  88. package/lib/module/index.js +3 -0
  89. package/lib/module/index.js.map +1 -1
  90. package/lib/module/ui/DebugView.js +2 -0
  91. package/lib/module/ui/DebugView.js.map +1 -1
  92. package/lib/module/ui/panel/DebugPanel.js +67 -34
  93. package/lib/module/ui/panel/DebugPanel.js.map +1 -1
  94. package/lib/module/ui/panel/FeatureIntroCard.js +146 -0
  95. package/lib/module/ui/panel/FeatureIntroCard.js.map +1 -0
  96. package/lib/module/ui/panel/FeatureRail.js +158 -0
  97. package/lib/module/ui/panel/FeatureRail.js.map +1 -0
  98. package/lib/module/ui/panel/FloatPanelView.js +119 -22
  99. package/lib/module/ui/panel/FloatPanelView.js.map +1 -1
  100. package/lib/module/ui/panel/buildFeatureSummary.js +203 -0
  101. package/lib/module/ui/panel/buildFeatureSummary.js.map +1 -0
  102. package/lib/module/ui/panel/filterFeatureSnapshot.js +39 -0
  103. package/lib/module/ui/panel/filterFeatureSnapshot.js.map +1 -0
  104. package/lib/module/ui/theme/colors.js +6 -0
  105. package/lib/module/ui/theme/colors.js.map +1 -1
  106. package/lib/module/utils/DaemonClient.js +30 -8
  107. package/lib/module/utils/DaemonClient.js.map +1 -1
  108. package/lib/module/utils/SessionManager.js +127 -0
  109. package/lib/module/utils/SessionManager.js.map +1 -0
  110. package/lib/module/utils/StorageAdapter.js +96 -0
  111. package/lib/module/utils/StorageAdapter.js.map +1 -0
  112. package/lib/module/utils/createChannelFeature.js +22 -5
  113. package/lib/module/utils/createChannelFeature.js.map +1 -1
  114. package/lib/module/utils/createPersistedObservableStore.js +14 -8
  115. package/lib/module/utils/createPersistedObservableStore.js.map +1 -1
  116. package/lib/module/utils/debugPreferences.js +27 -5
  117. package/lib/module/utils/debugPreferences.js.map +1 -1
  118. package/lib/module/utils/deviceReport.js +4 -1
  119. package/lib/module/utils/deviceReport.js.map +1 -1
  120. package/lib/module/utils/logRuntime.js +26 -0
  121. package/lib/module/utils/logRuntime.js.map +1 -0
  122. package/lib/typescript/src/constants/logLevels.d.ts +3 -0
  123. package/lib/typescript/src/constants/logLevels.d.ts.map +1 -0
  124. package/lib/typescript/src/core/initialize.d.ts +6 -0
  125. package/lib/typescript/src/core/initialize.d.ts.map +1 -1
  126. package/lib/typescript/src/features/console/ConsoleLogTab.d.ts.map +1 -1
  127. package/lib/typescript/src/features/console/index.d.ts +2 -1
  128. package/lib/typescript/src/features/console/index.d.ts.map +1 -1
  129. package/lib/typescript/src/features/nativeLogs/NativeLogTab.d.ts +4 -0
  130. package/lib/typescript/src/features/nativeLogs/NativeLogTab.d.ts.map +1 -0
  131. package/lib/typescript/src/features/nativeLogs/index.d.ts +12 -0
  132. package/lib/typescript/src/features/nativeLogs/index.d.ts.map +1 -0
  133. package/lib/typescript/src/features/nativeLogs/nativeLogsBridge.d.ts +11 -0
  134. package/lib/typescript/src/features/nativeLogs/nativeLogsBridge.d.ts.map +1 -0
  135. package/lib/typescript/src/features/network/NetworkLogTab.d.ts.map +1 -1
  136. package/lib/typescript/src/features/network/index.d.ts +2 -1
  137. package/lib/typescript/src/features/network/index.d.ts.map +1 -1
  138. package/lib/typescript/src/features/sessionHistory/SessionHistoryTab.d.ts +20 -0
  139. package/lib/typescript/src/features/sessionHistory/SessionHistoryTab.d.ts.map +1 -0
  140. package/lib/typescript/src/features/sessionHistory/index.d.ts +4 -0
  141. package/lib/typescript/src/features/sessionHistory/index.d.ts.map +1 -0
  142. package/lib/typescript/src/features/track/index.d.ts +2 -1
  143. package/lib/typescript/src/features/track/index.d.ts.map +1 -1
  144. package/lib/typescript/src/index.d.ts +7 -1
  145. package/lib/typescript/src/index.d.ts.map +1 -1
  146. package/lib/typescript/src/types/feature.d.ts +1 -1
  147. package/lib/typescript/src/types/feature.d.ts.map +1 -1
  148. package/lib/typescript/src/types/index.d.ts +3 -1
  149. package/lib/typescript/src/types/index.d.ts.map +1 -1
  150. package/lib/typescript/src/types/logs.d.ts +15 -0
  151. package/lib/typescript/src/types/logs.d.ts.map +1 -1
  152. package/lib/typescript/src/ui/DebugView.d.ts.map +1 -1
  153. package/lib/typescript/src/ui/panel/DebugPanel.d.ts +3 -1
  154. package/lib/typescript/src/ui/panel/DebugPanel.d.ts.map +1 -1
  155. package/lib/typescript/src/ui/panel/FeatureIntroCard.d.ts +14 -0
  156. package/lib/typescript/src/ui/panel/FeatureIntroCard.d.ts.map +1 -0
  157. package/lib/typescript/src/ui/panel/FeatureRail.d.ts +16 -0
  158. package/lib/typescript/src/ui/panel/FeatureRail.d.ts.map +1 -0
  159. package/lib/typescript/src/ui/panel/FloatPanelView.d.ts.map +1 -1
  160. package/lib/typescript/src/ui/panel/buildFeatureSummary.d.ts +13 -0
  161. package/lib/typescript/src/ui/panel/buildFeatureSummary.d.ts.map +1 -0
  162. package/lib/typescript/src/ui/panel/filterFeatureSnapshot.d.ts +3 -0
  163. package/lib/typescript/src/ui/panel/filterFeatureSnapshot.d.ts.map +1 -0
  164. package/lib/typescript/src/ui/theme/colors.d.ts +5 -0
  165. package/lib/typescript/src/ui/theme/colors.d.ts.map +1 -1
  166. package/lib/typescript/src/utils/DaemonClient.d.ts +7 -1
  167. package/lib/typescript/src/utils/DaemonClient.d.ts.map +1 -1
  168. package/lib/typescript/src/utils/SessionManager.d.ts +30 -0
  169. package/lib/typescript/src/utils/SessionManager.d.ts.map +1 -0
  170. package/lib/typescript/src/utils/StorageAdapter.d.ts +38 -0
  171. package/lib/typescript/src/utils/StorageAdapter.d.ts.map +1 -0
  172. package/lib/typescript/src/utils/createChannelFeature.d.ts +2 -0
  173. package/lib/typescript/src/utils/createChannelFeature.d.ts.map +1 -1
  174. package/lib/typescript/src/utils/createPersistedObservableStore.d.ts +4 -1
  175. package/lib/typescript/src/utils/createPersistedObservableStore.d.ts.map +1 -1
  176. package/lib/typescript/src/utils/debugPreferences.d.ts +1 -3
  177. package/lib/typescript/src/utils/debugPreferences.d.ts.map +1 -1
  178. package/lib/typescript/src/utils/deviceReport.d.ts +1 -0
  179. package/lib/typescript/src/utils/deviceReport.d.ts.map +1 -1
  180. package/lib/typescript/src/utils/logRuntime.d.ts +13 -0
  181. package/lib/typescript/src/utils/logRuntime.d.ts.map +1 -0
  182. package/node/daemon/src/console/console.html +18 -0
  183. package/node/mcp/src/logs.js +1 -1
  184. package/package.json +9 -1
  185. package/src/constants/logLevels.ts +13 -0
  186. package/src/core/initialize.ts +54 -25
  187. package/src/features/console/ConsoleLogTab.tsx +1 -14
  188. package/src/features/console/index.ts +18 -8
  189. package/src/features/nativeLogs/NativeLogTab.tsx +66 -0
  190. package/src/features/nativeLogs/index.ts +94 -0
  191. package/src/features/nativeLogs/nativeLogsBridge.ts +51 -0
  192. package/src/features/network/NetworkLogTab.tsx +60 -71
  193. package/src/features/network/index.ts +12 -3
  194. package/src/features/sessionHistory/SessionHistoryTab.tsx +693 -0
  195. package/src/features/sessionHistory/index.ts +102 -0
  196. package/src/features/track/index.ts +10 -3
  197. package/src/index.ts +16 -0
  198. package/src/types/feature.ts +3 -1
  199. package/src/types/index.ts +13 -0
  200. package/src/types/logs.ts +17 -0
  201. package/src/ui/DebugView.tsx +2 -0
  202. package/src/ui/panel/DebugPanel.tsx +60 -30
  203. package/src/ui/panel/FeatureIntroCard.tsx +147 -0
  204. package/src/ui/panel/FeatureRail.tsx +165 -0
  205. package/src/ui/panel/FloatPanelView.tsx +123 -15
  206. package/src/ui/panel/buildFeatureSummary.ts +288 -0
  207. package/src/ui/panel/filterFeatureSnapshot.ts +51 -0
  208. package/src/ui/theme/colors.ts +7 -0
  209. package/src/utils/DaemonClient.ts +33 -5
  210. package/src/utils/SessionManager.ts +174 -0
  211. package/src/utils/StorageAdapter.ts +135 -0
  212. package/src/utils/createChannelFeature.ts +28 -6
  213. package/src/utils/createPersistedObservableStore.ts +18 -10
  214. package/src/utils/debugPreferences.ts +38 -7
  215. package/src/utils/deviceReport.ts +5 -1
  216. package/src/utils/logRuntime.ts +39 -0
  217. package/lib/commonjs/ui/panel/FeatureTabBar.js +0 -182
  218. package/lib/commonjs/ui/panel/FeatureTabBar.js.map +0 -1
  219. package/lib/module/ui/panel/FeatureTabBar.js +0 -177
  220. package/lib/module/ui/panel/FeatureTabBar.js.map +0 -1
  221. package/lib/typescript/src/ui/panel/FeatureTabBar.d.ts +0 -13
  222. package/lib/typescript/src/ui/panel/FeatureTabBar.d.ts.map +0 -1
  223. package/src/ui/panel/FeatureTabBar.tsx +0 -204
package/README.md CHANGED
@@ -4,21 +4,19 @@
4
4
 
5
5
  [中文](README.zh-CN.md)
6
6
 
7
- React Native Debug Toolkit is a dev-only local debugging toolkit for React Native apps.
8
-
9
- Use it to inspect app logs on device, stream logs to a desktop Web Console, and let AI coding agents read real runtime evidence through HTTP or MCP.
7
+ A local debugging toolkit for React Native apps. It provides an in-app debug panel, a desktop Web Console, an HTTP API, and an MCP server — all running locally with no cloud dependency.
10
8
 
11
9
  ```text
12
10
  RN App -> Debug Panel -> local daemon -> Web Console / HTTP API / MCP
13
11
  ```
14
12
 
15
- ## What You Get
13
+ ## Features
16
14
 
17
- - In-app debug panel with Network, Console, Navigation, Track, Zustand, Environment, and Clipboard logs.
18
- - Desktop Web Console for simulator and real-device logs.
19
- - Local HTTP API for curl, scripts, Codex, Claude Code, and other AI agents with shell access.
20
- - Optional MCP server with `list_app_devices` and `get_app_logs`.
21
- - Local-first workflow. No cloud service. No AI API call inside the package.
15
+ - In-app debug panel: Network, Console, Native, Navigation, Track, Zustand, Environment, Clipboard, and custom tabs.
16
+ - Desktop Web Console for viewing simulator and real-device logs in a browser.
17
+ - Local HTTP API for reading logs with `curl`, scripts, or AI agents (Codex, Claude Code, etc.).
18
+ - Optional MCP server exposing `list_app_devices` and `get_app_logs`.
19
+ - Local-first: no cloud service, no signup, no AI API calls inside the package.
22
20
 
23
21
  ## Install
24
22
 
@@ -26,7 +24,7 @@ RN App -> Debug Panel -> local daemon -> Web Console / HTTP API / MCP
26
24
  npm install react-native-debug-toolkit
27
25
  ```
28
26
 
29
- Install the native part and rebuild the app:
27
+ Install the native part and rebuild:
30
28
 
31
29
  ```bash
32
30
  cd ios && pod install
@@ -73,13 +71,13 @@ Open the Web Console:
73
71
  http://127.0.0.1:3799/console
74
72
  ```
75
73
 
76
- In the app, open Debug Panel -> `DevConnect` -> `Send Once` or `Start Live Sync` for desktop logs.
74
+ In the app, go to Debug Panel `DevConnect` `Send Once` or `Start Live Sync` to sync logs to the desktop.
77
75
 
78
- DevConnect auto-detects simulator/emulator and uses local host settings automatically. On real devices, enter your computer IP to connect.
76
+ DevConnect auto-detects simulator/emulator and configures host settings. On real devices, enter your computer IP manually.
79
77
 
80
- The IP and ports are persisted through AsyncStorage when installed, or through the native module after rebuild.
78
+ IP and ports are persisted via AsyncStorage (when installed) or through the native module after rebuild.
81
79
 
82
- QR scan is optional. Install `react-native-camera-kit` or `expo-camera` in the app to enable the scan button. The app must request camera permission before scanning.
80
+ QR scan is optional. Install `react-native-camera-kit` or `expo-camera` to enable the scan button. The app must request camera permission before scanning.
83
81
 
84
82
  ## Device Setup
85
83
 
@@ -89,7 +87,7 @@ QR scan is optional. Install `react-native-camera-kit` or `expo-camera` in the a
89
87
  | Android emulator | `http://10.0.2.2:3799` |
90
88
  | Real device | `http://<mac-ip>:3799` |
91
89
 
92
- For a real device, first open this URL in the phone browser:
90
+ For real devices, first open this URL in the phone browser:
93
91
 
94
92
  ```text
95
93
  http://<mac-ip>:3799/health
@@ -97,7 +95,7 @@ http://<mac-ip>:3799/health
97
95
 
98
96
  If it does not open, check Mac firewall, Wi-Fi isolation, VPN, local network permission, and cleartext HTTP settings.
99
97
 
100
- The daemon stores logs at:
98
+ Daemon log store:
101
99
 
102
100
  ```text
103
101
  ~/.react-native-debug-toolkit/daemon-devices.json
@@ -113,7 +111,7 @@ DEBUG_TOOLKIT_DAEMON_STORE=/path/to/devices.json npm exec -- debug-toolkit --dae
113
111
 
114
112
  ## Read Logs With HTTP
115
113
 
116
- HTTP is the best path when your AI agent or script has shell access.
114
+ HTTP is the recommended path when your AI agent or script has shell access.
117
115
 
118
116
  ```bash
119
117
  BASE=http://127.0.0.1:3799
@@ -132,7 +130,7 @@ curl "$BASE/devices/$DEVICE_ID/logs?limit=100&includeBodies=true"
132
130
  curl -X DELETE "$BASE/devices"
133
131
  ```
134
132
 
135
- Main endpoints:
133
+ Endpoints:
136
134
 
137
135
  ```text
138
136
  GET /health
@@ -156,14 +154,30 @@ claude mcp add debug-toolkit -- npm exec -- debug-toolkit
156
154
 
157
155
  Tools:
158
156
 
159
- - `list_app_devices`
160
- - `get_app_logs`
157
+ - `list_app_devices` — list connected devices
158
+ - `get_app_logs` — fetch device logs
159
+
160
+ `get_app_logs` excludes bodies by default to reduce token usage. Set `includeBodies=true` or pass `entryId` to fetch a single full entry.
161
+
162
+ ## Native Logs
163
+
164
+ Native Logs collects native app-process logs and displays them in the `Native` tab.
165
+
166
+ - Android: captures current app-process `logcat` entries visible to the app.
167
+ - iOS: captures React Native native logs emitted through `RCTLog*`.
168
+ - DevConnect sends Native logs to the desktop daemon with the rest of the current session.
169
+
170
+ Release builds stay disabled by default. To enable for internal release, TestFlight, QA, or gray rollout builds:
171
+
172
+ ```tsx
173
+ <DebugView enabled={true} />
174
+ ```
161
175
 
162
- `get_app_logs` excludes bodies by default to reduce tokens. Set `includeBodies=true` or pass `entryId` to fetch one full log entry.
176
+ Native logs may contain user data, tokens, URLs, or device state. Do not enable by default in public production builds.
163
177
 
164
178
  ## App Options
165
179
 
166
- Disable features:
180
+ ### Disable features
167
181
 
168
182
  ```tsx
169
183
  <DebugView features={{ clipboard: false, zustand: false }}>
@@ -171,7 +185,7 @@ Disable features:
171
185
  </DebugView>
172
186
  ```
173
187
 
174
- Custom tabs:
188
+ ### Custom tabs
175
189
 
176
190
  ```tsx
177
191
  import {
@@ -211,7 +225,7 @@ const userDebugTab = createDebugTab<UserSnapshot>({
211
225
 
212
226
  Each custom feature becomes a panel tab. `name` is the stable tab id, `label` is shown in the tab bar, `getSnapshot` provides tab data, and `render` controls the UI. Add `subscribe` when the tab should refresh after external state changes.
213
227
 
214
- Navigation tracking:
228
+ ### Navigation tracking
215
229
 
216
230
  ```tsx
217
231
  <DebugView navigationRef={navigationRef}>
@@ -221,13 +235,13 @@ Navigation tracking:
221
235
  </DebugView>
222
236
  ```
223
237
 
224
- Zustand:
238
+ ### Zustand
225
239
 
226
240
  ```tsx
227
241
  import { zustandLogMiddleware } from 'react-native-debug-toolkit';
228
242
  ```
229
243
 
230
- Track:
244
+ ### Track events
231
245
 
232
246
  ```tsx
233
247
  import { addTrackLog } from 'react-native-debug-toolkit';
package/README.zh-CN.md CHANGED
@@ -4,21 +4,19 @@
4
4
 
5
5
  [English](README.md)
6
6
 
7
- React Native Debug Toolkit React Native 开发期本地调试工具。
8
-
9
- 它可以在 App 内查看日志,把模拟器或真机日志同步到桌面 Web Console,也可以让 AI 编程工具通过 HTTP 或 MCP 直接读取真实运行日志。
7
+ React Native 开发期本地调试工具。提供 App 内调试面板、桌面 Web Console、本地 HTTP API 和 MCP server,全部在本地运行,不依赖云服务。
10
8
 
11
9
  ```text
12
- RN App -> Debug Panel -> local daemon -> Web Console / HTTP API / MCP
10
+ RN App -> Debug Panel -> 本地 daemon -> Web Console / HTTP API / MCP
13
11
  ```
14
12
 
15
- ## 能做什么
13
+ ## 功能
16
14
 
17
- - App 内调试面板:Network、Console、Navigation、Track、Zustand、Environment、Clipboard。
18
- - 桌面 Web Console:查看模拟器和真机日志。
19
- - 本地 HTTP API:给 curl、脚本、Codex、Claude Code、其他有 shell 的 AI 读取。
20
- - 可选 MCP:提供 `list_app_devices` 和 `get_app_logs`。
21
- - 本地优先:不接云服务,包内不调用 AI API。
15
+ - App 内调试面板:Network、Console、原生日志(Native)、Navigation、Track、Zustand、Environment、Clipboard,支持自定义 Tab
16
+ - 桌面 Web Console:在浏览器中查看模拟器和真机日志。
17
+ - 本地 HTTP API:供 `curl`、脚本、AI Agent(Codex、Claude Code 等)读取日志。
18
+ - 可选 MCP server:提供 `list_app_devices` 和 `get_app_logs`。
19
+ - 本地优先:不接云服务,不注册,包内不调用 AI API。
22
20
 
23
21
  ## 安装
24
22
 
@@ -26,14 +24,14 @@ RN App -> Debug Panel -> local daemon -> Web Console / HTTP API / MCP
26
24
  npm install react-native-debug-toolkit
27
25
  ```
28
26
 
29
- 安装原生部分并重新构建 App:
27
+ 安装原生部分并重新构建:
30
28
 
31
29
  ```bash
32
30
  cd ios && pod install
33
31
  # Android:下次构建时 Gradle autolinking 生效
34
32
  ```
35
33
 
36
- Expo Go 不能加载这个原生模块。Expo 项目需用 development build、prebuild,或 bare React Native。
34
+ Expo Go 无法加载此原生模块。Expo 项目需用 development build、prebuild bare React Native。
37
35
 
38
36
  可选依赖:
39
37
 
@@ -44,7 +42,7 @@ npm install @react-native-async-storage/async-storage
44
42
 
45
43
  ## 快速开始
46
44
 
47
- 包住你的 App:
45
+ `DebugView` 包裹 App:
48
46
 
49
47
  ```tsx
50
48
  import { DebugView } from 'react-native-debug-toolkit';
@@ -58,7 +56,7 @@ export function App() {
58
56
  }
59
57
  ```
60
58
 
61
- 开发模式打开 App,点击 `DBG`。
59
+ 开发模式启动 App,点击 `DBG` 打开调试面板。
62
60
 
63
61
  启动桌面 daemon:
64
62
 
@@ -73,31 +71,31 @@ npm exec -- debug-toolkit --daemon-only
73
71
  http://127.0.0.1:3799/console
74
72
  ```
75
73
 
76
- App 内打开 Debug Panel -> `DevConnect` -> `Send Once` 或 `Start Live Sync` 同步桌面日志。
74
+ App 内打开 Debug Panel `DevConnect` `Send Once` 或 `Start Live Sync` 同步日志到桌面。
77
75
 
78
- DevConnect 自动识别模拟器/真机,模拟器下自动使用本机 Metro/daemon 地址。真机需输入电脑 IP 地址。
76
+ DevConnect 自动识别模拟器/真机并配置主机地址。真机需手动输入电脑 IP
79
77
 
80
- IP 和端口会通过 AsyncStorage 持久化;如果没装 AsyncStorage,则在重建后通过本库原生模块持久化。
78
+ IP 和端口通过 AsyncStorage(如果装了)或原生模块持久化。
81
79
 
82
- 扫码是可选能力。App 安装 `react-native-camera-kit` 或 `expo-camera` 后,DevConnect 才显示扫码按钮。App 仍需自己配置相机权限文案,并在使用扫码前申请相机权限。
80
+ 扫码是可选功能。安装 `react-native-camera-kit` 或 `expo-camera` DevConnect 会显示扫码按钮。App 需在使用前自行申请相机权限。
83
81
 
84
82
  ## 设备连接
85
83
 
86
84
  | 运行时 | App endpoint |
87
85
  | --- | --- |
88
- | iOS simulator | `http://localhost:3799` |
89
- | Android emulator | `http://10.0.2.2:3799` |
90
- | 真机 | `http://<mac-ip>:3799` |
86
+ | iOS 模拟器 | `http://localhost:3799` |
87
+ | Android 模拟器 | `http://10.0.2.2:3799` |
88
+ | 真机 | `http://<电脑IP>:3799` |
91
89
 
92
90
  真机先用手机浏览器打开:
93
91
 
94
92
  ```text
95
- http://<mac-ip>:3799/health
93
+ http://<电脑IP>:3799/health
96
94
  ```
97
95
 
98
- 打不开就检查 Mac 防火墙、Wi-Fi 隔离、VPN、本地网络权限、明文 HTTP 配置。
96
+ 打不开则检查 Mac 防火墙、Wi-Fi 隔离、VPN、本地网络权限、明文 HTTP 配置。
99
97
 
100
- daemon 默认日志文件:
98
+ Daemon 日志存储位置:
101
99
 
102
100
  ```text
103
101
  ~/.react-native-debug-toolkit/daemon-devices.json
@@ -113,7 +111,7 @@ DEBUG_TOOLKIT_DAEMON_STORE=/path/to/devices.json npm exec -- debug-toolkit --dae
113
111
 
114
112
  ## 用 HTTP 读取日志
115
113
 
116
- AI 或脚本有 shell 时,优先用 HTTP。
114
+ AI 或脚本有 shell 访问时,推荐用 HTTP。
117
115
 
118
116
  ```bash
119
117
  BASE=http://127.0.0.1:3799
@@ -132,7 +130,7 @@ curl "$BASE/devices/$DEVICE_ID/logs?limit=100&includeBodies=true"
132
130
  curl -X DELETE "$BASE/devices"
133
131
  ```
134
132
 
135
- 主要端点:
133
+ 端点:
136
134
 
137
135
  ```text
138
136
  GET /health
@@ -156,14 +154,30 @@ claude mcp add debug-toolkit -- npm exec -- debug-toolkit
156
154
 
157
155
  工具:
158
156
 
159
- - `list_app_devices`
160
- - `get_app_logs`
157
+ - `list_app_devices` — 列出已连接设备
158
+ - `get_app_logs` — 拉取设备日志
159
+
160
+ `get_app_logs` 默认不含 body 以节省 token。设 `includeBodies=true` 或传 `entryId` 获取单条完整日志。
161
+
162
+ ## 原生日志
163
+
164
+ Native Logs 收集当前 App 进程的原生日志,显示在 `Native` Tab。
165
+
166
+ - Android:收集当前 App 进程可见的 `logcat` 条目。
167
+ - iOS:收集 React Native 通过 `RCTLog*` 输出的原生日志。
168
+ - DevConnect 会把 Native 日志和当前 session 其他日志一起同步到桌面 daemon。
169
+
170
+ Release 包默认关闭。内部 release、TestFlight、QA 或灰度构建需要开启时:
171
+
172
+ ```tsx
173
+ <DebugView enabled={true} />
174
+ ```
161
175
 
162
- `get_app_logs` 默认不返回 body,减少 token。设置 `includeBodies=true` 或传 `entryId` 可读取单条完整日志。
176
+ 原生日志可能包含用户数据、token、URL 或设备状态,不要在公开生产包中默认开启。
163
177
 
164
178
  ## App 配置
165
179
 
166
- 禁用功能:
180
+ ### 禁用功能
167
181
 
168
182
  ```tsx
169
183
  <DebugView features={{ clipboard: false, zustand: false }}>
@@ -171,7 +185,7 @@ claude mcp add debug-toolkit -- npm exec -- debug-toolkit
171
185
  </DebugView>
172
186
  ```
173
187
 
174
- 自定义 Tab
188
+ ### 自定义 Tab
175
189
 
176
190
  ```tsx
177
191
  import {
@@ -209,9 +223,9 @@ const userDebugTab = createDebugTab<UserSnapshot>({
209
223
  </DebugView>;
210
224
  ```
211
225
 
212
- 每个自定义 feature 都会变成一个面板 Tab。`name` 是稳定 Tab id,`label` 显示在 Tab 栏,`getSnapshot` 提供展示数据,`render` 控制展示 UI。外部状态变化后需要自动刷新时,给它加 `subscribe`。
226
+ 每个自定义 feature 会变成面板 Tab。`name` 是稳定 Tab id,`label` 显示在 Tab 栏,`getSnapshot` 提供数据,`render` 控制展示 UI。需要自动刷新时加 `subscribe`。
213
227
 
214
- 导航追踪:
228
+ ### 导航追踪
215
229
 
216
230
  ```tsx
217
231
  <DebugView navigationRef={navigationRef}>
@@ -221,13 +235,13 @@ const userDebugTab = createDebugTab<UserSnapshot>({
221
235
  </DebugView>
222
236
  ```
223
237
 
224
- Zustand
238
+ ### Zustand
225
239
 
226
240
  ```tsx
227
241
  import { zustandLogMiddleware } from 'react-native-debug-toolkit';
228
242
  ```
229
243
 
230
- Track
244
+ ### Track 事件
231
245
 
232
246
  ```tsx
233
247
  import { addTrackLog } from 'react-native-debug-toolkit';
@@ -248,13 +262,13 @@ addTrackLog({ eventName: 'button_click' });
248
262
  - `stopStreaming`
249
263
  - `isStreaming`
250
264
  - `autoDetectDaemonIp`
251
- - feature factories and types
265
+ - feature factories 和类型
252
266
 
253
267
  ## 边界
254
268
 
255
269
  - 开发工具,不是生产监控。
256
- - 本地 daemon,不是云 replay。
257
- - Network 只观察流量,不自动分析 auth、token、业务错误。
270
+ - 本地 daemon,不是云回放。
271
+ - Network 只观察流量,不分析 auth、token、业务错误。
258
272
  - 不默认脱敏。
259
273
  - 不替代 React Native DevTools。
260
274
 
@@ -0,0 +1,146 @@
1
+ package com.reactnativedebugtoolkit;
2
+
3
+ import android.os.Process;
4
+ import androidx.annotation.NonNull;
5
+ import com.facebook.react.bridge.Arguments;
6
+ import com.facebook.react.bridge.Promise;
7
+ import com.facebook.react.bridge.ReactApplicationContext;
8
+ import com.facebook.react.bridge.ReactContextBaseJavaModule;
9
+ import com.facebook.react.bridge.ReactMethod;
10
+ import com.facebook.react.bridge.ReadableMap;
11
+ import com.facebook.react.bridge.WritableArray;
12
+ import com.facebook.react.bridge.WritableMap;
13
+
14
+ import java.io.BufferedReader;
15
+ import java.io.InputStreamReader;
16
+ import java.util.ArrayDeque;
17
+ import java.util.Locale;
18
+ import java.util.regex.Matcher;
19
+ import java.util.regex.Pattern;
20
+
21
+ public class DebugToolkitNativeLogsModule extends ReactContextBaseJavaModule {
22
+ private static final String MODULE_NAME = "DebugToolkitNativeLogs";
23
+ private static final int MAX_BUFFER = 500;
24
+ private static final Pattern THREADTIME = Pattern.compile(
25
+ "^\\s*(\\d+-\\d+)\\s+(\\d+:\\d+:\\d+\\.\\d+)\\s+(\\d+)\\s+(\\d+)\\s+([VDIWEF])\\s+([^:]+):\\s?(.*)$");
26
+
27
+ private final Object lock = new Object();
28
+ private final ArrayDeque<WritableMap> buffer = new ArrayDeque<>();
29
+ private java.lang.Process logcatProcess;
30
+ private Thread readerThread;
31
+ private boolean capturing = false;
32
+ private String lastError = null;
33
+
34
+ public DebugToolkitNativeLogsModule(ReactApplicationContext reactContext) {
35
+ super(reactContext);
36
+ }
37
+
38
+ @NonNull
39
+ @Override
40
+ public String getName() { return MODULE_NAME; }
41
+
42
+ @ReactMethod
43
+ public void startCapture(ReadableMap options, Promise promise) {
44
+ synchronized (lock) {
45
+ if (capturing) { promise.resolve(statusMap(true)); return; }
46
+ capturing = true;
47
+ lastError = null;
48
+ }
49
+ readerThread = new Thread(() -> readLogcat(), "DebugToolkitNativeLogs");
50
+ readerThread.setDaemon(true);
51
+ readerThread.start();
52
+ promise.resolve(statusMap(true));
53
+ }
54
+
55
+ @ReactMethod
56
+ public void stopCapture(Promise promise) {
57
+ synchronized (lock) {
58
+ capturing = false;
59
+ if (logcatProcess != null) { logcatProcess.destroy(); logcatProcess = null; }
60
+ }
61
+ promise.resolve(statusMap(false));
62
+ }
63
+
64
+ @ReactMethod
65
+ public void drainLogs(double max, Promise promise) {
66
+ int limit = Math.max(1, (int) Math.floor(max));
67
+ WritableArray drained = Arguments.createArray();
68
+ synchronized (lock) {
69
+ while (!buffer.isEmpty() && limit > 0) { drained.pushMap(buffer.removeFirst()); limit--; }
70
+ }
71
+ promise.resolve(drained);
72
+ }
73
+
74
+ @ReactMethod
75
+ public void getStatus(Promise promise) {
76
+ synchronized (lock) {
77
+ WritableMap status = statusMap(capturing);
78
+ if (lastError != null) status.putString("error", lastError);
79
+ promise.resolve(status);
80
+ }
81
+ }
82
+
83
+ private WritableMap statusMap(boolean isCapturing) {
84
+ WritableMap map = Arguments.createMap();
85
+ map.putBoolean("ok", true);
86
+ map.putBoolean("available", true);
87
+ map.putBoolean("capturing", isCapturing);
88
+ return map;
89
+ }
90
+
91
+ private void readLogcat() {
92
+ int pid = Process.myPid();
93
+ try {
94
+ ProcessBuilder builder = new ProcessBuilder("logcat", "-v", "threadtime", "--pid", String.valueOf(pid));
95
+ logcatProcess = builder.redirectErrorStream(true).start();
96
+ BufferedReader reader = new BufferedReader(new InputStreamReader(logcatProcess.getInputStream()));
97
+ String line;
98
+ while (isCapturing() && (line = reader.readLine()) != null) {
99
+ WritableMap entry = parseLine(line, pid);
100
+ if (entry != null) push(entry);
101
+ }
102
+ } catch (Exception error) {
103
+ synchronized (lock) { lastError = error.getMessage(); }
104
+ } finally {
105
+ synchronized (lock) { capturing = false; logcatProcess = null; }
106
+ }
107
+ }
108
+
109
+ private boolean isCapturing() { synchronized (lock) { return capturing; } }
110
+
111
+ private void push(WritableMap entry) {
112
+ synchronized (lock) {
113
+ while (buffer.size() >= MAX_BUFFER) buffer.removeFirst();
114
+ buffer.addLast(entry);
115
+ }
116
+ }
117
+
118
+ private WritableMap parseLine(String line, int pid) {
119
+ Matcher m = THREADTIME.matcher(line);
120
+ if (!m.matches()) return null;
121
+ if (Integer.parseInt(m.group(3)) != pid) return null;
122
+ WritableMap entry = Arguments.createMap();
123
+ entry.putDouble("timestamp", System.currentTimeMillis());
124
+ entry.putString("platform", "android");
125
+ entry.putString("source", "logcat");
126
+ entry.putString("level", levelFromPriority(m.group(5)));
127
+ entry.putString("thread", m.group(4));
128
+ entry.putString("tag", m.group(6).trim());
129
+ entry.putString("message", m.group(7));
130
+ entry.putString("raw", line);
131
+ return entry;
132
+ }
133
+
134
+ private String levelFromPriority(String priority) {
135
+ String p = priority == null ? "" : priority.toUpperCase(Locale.US);
136
+ switch (p) {
137
+ case "V": return "trace";
138
+ case "D": return "debug";
139
+ case "I": return "info";
140
+ case "W": return "warn";
141
+ case "E": return "error";
142
+ case "F": return "fatal";
143
+ default: return "unknown";
144
+ }
145
+ }
146
+ }
@@ -7,19 +7,21 @@ import com.facebook.react.bridge.NativeModule;
7
7
  import com.facebook.react.bridge.ReactApplicationContext;
8
8
  import com.facebook.react.uimanager.ViewManager;
9
9
 
10
- import java.util.Collections;
10
+ import java.util.Arrays;
11
11
  import java.util.List;
12
12
 
13
13
  public class ReactNativeDebugToolkitPackage implements ReactPackage {
14
14
  @NonNull
15
15
  @Override
16
16
  public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
17
- return Collections.<NativeModule>singletonList(new DebugToolkitDevConnectModule(reactContext));
17
+ return Arrays.<NativeModule>asList(
18
+ new DebugToolkitDevConnectModule(reactContext),
19
+ new DebugToolkitNativeLogsModule(reactContext));
18
20
  }
19
21
 
20
22
  @NonNull
21
23
  @Override
22
24
  public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
23
- return Collections.emptyList();
25
+ return java.util.Collections.emptyList();
24
26
  }
25
27
  }
@@ -0,0 +1,92 @@
1
+ #import <Foundation/Foundation.h>
2
+ #import <React/RCTBridgeModule.h>
3
+ #import <React/RCTLog.h>
4
+
5
+ @interface DebugToolkitNativeLogs : NSObject <RCTBridgeModule>
6
+ @end
7
+
8
+ @implementation DebugToolkitNativeLogs
9
+
10
+ RCT_EXPORT_MODULE(DebugToolkitNativeLogs)
11
+
12
+ static const NSUInteger DebugToolkitNativeLogsMaxBuffer = 500;
13
+ static NSMutableArray<NSDictionary *> *buffer;
14
+ static dispatch_queue_t bufferQueue;
15
+ static BOOL captureEnabled = NO;
16
+ static BOOL logFunctionInstalled = NO;
17
+
18
+ + (BOOL)requiresMainQueueSetup { return NO; }
19
+
20
+ + (void)initialize {
21
+ if (self == [DebugToolkitNativeLogs class]) {
22
+ buffer = [NSMutableArray new];
23
+ bufferQueue = dispatch_queue_create("com.reactnativedebugtoolkit.nativeLogs", DISPATCH_QUEUE_SERIAL);
24
+ }
25
+ }
26
+
27
+ RCT_EXPORT_METHOD(startCapture:(NSDictionary *)options
28
+ resolver:(RCTPromiseResolveBlock)resolve
29
+ rejecter:(__unused RCTPromiseRejectBlock)reject) {
30
+ dispatch_sync(bufferQueue, ^{
31
+ captureEnabled = YES;
32
+ if (!logFunctionInstalled) {
33
+ logFunctionInstalled = YES;
34
+ RCTAddLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
35
+ if (!captureEnabled || !message) return;
36
+ NSDictionary *entry = @{
37
+ @"timestamp": @([[NSDate date] timeIntervalSince1970] * 1000),
38
+ @"platform": @"ios",
39
+ @"source": @"rctLog",
40
+ @"level": DebugToolkitNativeLogsLevel(level),
41
+ @"message": message,
42
+ @"file": fileName ?: @"",
43
+ @"line": lineNumber ?: @0,
44
+ @"raw": RCTFormatLog([NSDate date], level, fileName, lineNumber, message) ?: message
45
+ };
46
+ dispatch_async(bufferQueue, ^{
47
+ if (buffer.count >= DebugToolkitNativeLogsMaxBuffer) [buffer removeObjectAtIndex:0];
48
+ [buffer addObject:entry];
49
+ });
50
+ });
51
+ }
52
+ });
53
+ resolve(@{@"ok": @YES, @"available": @YES, @"capturing": @YES});
54
+ }
55
+
56
+ RCT_EXPORT_METHOD(stopCapture:(RCTPromiseResolveBlock)resolve
57
+ rejecter:(__unused RCTPromiseRejectBlock)reject) {
58
+ dispatch_sync(bufferQueue, ^{ captureEnabled = NO; });
59
+ resolve(@{@"ok": @YES, @"available": @YES, @"capturing": @NO});
60
+ }
61
+
62
+ RCT_EXPORT_METHOD(drainLogs:(nonnull NSNumber *)max
63
+ resolver:(RCTPromiseResolveBlock)resolve
64
+ rejecter:(__unused RCTPromiseRejectBlock)reject) {
65
+ __block NSArray<NSDictionary *> *drained = @[];
66
+ NSUInteger limit = MAX((NSUInteger)1, max.unsignedIntegerValue);
67
+ dispatch_sync(bufferQueue, ^{
68
+ NSUInteger count = MIN(limit, buffer.count);
69
+ drained = [buffer subarrayWithRange:NSMakeRange(0, count)];
70
+ if (count > 0) [buffer removeObjectsInRange:NSMakeRange(0, count)];
71
+ });
72
+ resolve(drained);
73
+ }
74
+
75
+ RCT_EXPORT_METHOD(getStatus:(RCTPromiseResolveBlock)resolve
76
+ rejecter:(__unused RCTPromiseRejectBlock)reject) {
77
+ __block BOOL current = NO;
78
+ dispatch_sync(bufferQueue, ^{ current = captureEnabled; });
79
+ resolve(@{@"available": @YES, @"capturing": @(current)});
80
+ }
81
+
82
+ static NSString *DebugToolkitNativeLogsLevel(RCTLogLevel level) {
83
+ switch (level) {
84
+ case RCTLogLevelTrace: return @"trace";
85
+ case RCTLogLevelInfo: return @"info";
86
+ case RCTLogLevelWarning: return @"warn";
87
+ case RCTLogLevelError: return @"error";
88
+ case RCTLogLevelFatal: return @"fatal";
89
+ }
90
+ }
91
+
92
+ @end
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.LEVEL_ICONS = exports.LEVEL_COLORS = void 0;
7
+ const LEVEL_COLORS = exports.LEVEL_COLORS = {
8
+ log: '#8E8E93',
9
+ info: '#007AFF',
10
+ warn: '#FF9500',
11
+ error: '#FF3B30'
12
+ };
13
+ const LEVEL_ICONS = exports.LEVEL_ICONS = {
14
+ log: '●',
15
+ info: 'ℹ',
16
+ warn: '⚠',
17
+ error: '✕'
18
+ };
19
+ //# sourceMappingURL=logLevels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["LEVEL_COLORS","exports","log","info","warn","error","LEVEL_ICONS"],"sourceRoot":"../../../src","sources":["constants/logLevels.ts"],"mappings":";;;;;;AAAO,MAAMA,YAAoC,GAAAC,OAAA,CAAAD,YAAA,GAAG;EAClDE,GAAG,EAAE,SAAS;EACdC,IAAI,EAAE,SAAS;EACfC,IAAI,EAAE,SAAS;EACfC,KAAK,EAAE;AACT,CAAC;AAEM,MAAMC,WAAmC,GAAAL,OAAA,CAAAK,WAAA,GAAG;EACjDJ,GAAG,EAAE,GAAG;EACRC,IAAI,EAAE,GAAG;EACTC,IAAI,EAAE,GAAG;EACTC,KAAK,EAAE;AACT,CAAC","ignoreList":[]}