react-native-ai-debugger 1.6.11 → 1.6.13

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
@@ -11,6 +11,7 @@ import { API_BASE_URL } from "./core/config.js";
11
11
  import { getPostHogClient, identifyIfDevMode, shutdownPostHog } from "./core/posthog.js";
12
12
  import { getInstallationId, getServerVersion, getPackageName, 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
+ import { reduxDispatch, reduxGetState } from "./core/redux.js";
14
15
  import { tap } from "./pro/tap.js";
15
16
  import { getActivateLicenseConfig, handleActivateLicense, getDeleteAccountConfig, handleDeleteAccount, } from "./tools/accountTools.js";
16
17
  import { logBuffers, networkBuffers, getLogBuffer, getNetworkBuffer, getTotalLogCount, getConnectedAppByDevice, getConnectedAppBySimulatorUdid, getConnectedAppByAndroidDeviceId, LogBuffer, NetworkBuffer, bundleErrorBuffer, imageBuffer, connectedApps, getActiveOrBootedSimulatorUdid, scanMetroPorts, fetchDevices, filterDebuggableDevices, connectToDevice, getConnectedApps, executeInApp, listDebugGlobals, inspectGlobal, reloadApp,
@@ -2104,6 +2105,86 @@ registerToolWithTelemetry("inspect_global", {
2104
2105
  };
2105
2106
  });
2106
2107
  // ============================================================================
2108
+ // Redux Tools
2109
+ // ============================================================================
2110
+ registerToolWithTelemetry("redux_dispatch", {
2111
+ description: "Dispatch a Redux action to the store bound to the app's <Provider>, triggering useSelector subscribers and React re-renders. Resolves the live store by walking the React fiber tree on each call (no SDK setup needed; works even if no store was registered with init()).\n" +
2112
+ "PURPOSE: Drive state-controlled UI (loaders, modals, toasts, error overlays) without exercising the real flow (network, OTP, etc.).\n" +
2113
+ "WHY THIS EXISTS: __RN_AI_DEVTOOLS__.stores.redux often holds a different store reference than the one passed to <Provider>, so dispatching through it updates state but does NOT notify react-redux subscribers. This tool dispatches through the actual Provider store, so views re-render.\n" +
2114
+ "WHEN TO USE: Verify state-driven UI by seeding redux state directly. Example: dispatch app/setIsLoading: true, then ios_screenshot to confirm the loader rendered.\n" +
2115
+ "WORKFLOW: redux_dispatch({ action: { type: 'app/setIsLoading', payload: true } }) -> ios_screenshot -> redux_dispatch({ action: { type: 'app/setIsLoading', payload: false } }).\n" +
2116
+ "LIMITATIONS: Requires React DevTools hook (dev mode). Action must be plain JSON-serializable (no thunks/functions). If the app has multiple <Provider> roots, pass storeIndex (default 0).\n" +
2117
+ "GOOD: redux_dispatch({ action: { type: 'app/setIsLoading', payload: true } })\n" +
2118
+ "BAD: redux_dispatch({ action: () => ... }) — actions must be plain objects; for thunks use execute_in_app to call your action creator.",
2119
+ inputSchema: {
2120
+ action: z
2121
+ .record(z.unknown())
2122
+ .describe("Plain JSON-serializable Redux action object, e.g. { type: 'app/setIsLoading', payload: true }."),
2123
+ storeIndex: z
2124
+ .number()
2125
+ .int()
2126
+ .min(0)
2127
+ .optional()
2128
+ .describe("Index of the Provider store to dispatch to when the app has multiple <Provider> roots (default: 0)."),
2129
+ returnPath: z
2130
+ .string()
2131
+ .optional()
2132
+ .describe("Optional dotted path into the post-dispatch state to return for verification (e.g. 'app' or 'auth.user'). Omit to skip returning state — keeps the response small. Use redux_get_state for ad-hoc reads."),
2133
+ device: z
2134
+ .string()
2135
+ .optional()
2136
+ .describe("Target device name (substring match). Omit for default device. Run get_apps to see connected devices.")
2137
+ }
2138
+ }, async ({ action, storeIndex, returnPath, device }) => {
2139
+ const result = await reduxDispatch({ action: action, storeIndex, returnPath, device });
2140
+ if (!result.success) {
2141
+ return {
2142
+ content: [{ type: "text", text: `Error: ${result.error ?? "Unknown error"}` }],
2143
+ isError: true
2144
+ };
2145
+ }
2146
+ const ack = `Dispatched to store ${result.storeIndex} of ${result.storeCount}: ${JSON.stringify(result.previousAction)}`;
2147
+ const stateLine = returnPath
2148
+ ? `\n\nState at '${returnPath}':\n${JSON.stringify(result.state, null, 2)}`
2149
+ : "";
2150
+ return { content: [{ type: "text", text: ack + stateLine }] };
2151
+ });
2152
+ registerToolWithTelemetry("redux_get_state", {
2153
+ description: "Read state from the Redux store bound to the app's <Provider>, resolved live via the fiber tree (same store redux_dispatch targets).\n" +
2154
+ "PURPOSE: Inspect the current app state without relying on __RN_AI_DEVTOOLS__.stores.redux (which may point at a different store instance than the Provider).\n" +
2155
+ "WHEN TO USE: Verify state shape before/after redux_dispatch, or check what slice keys exist before crafting an action.\n" +
2156
+ "WORKFLOW: redux_get_state() -> craft action -> redux_dispatch -> redux_get_state({ path: 'app' }) to confirm.\n" +
2157
+ "LIMITATIONS: Requires React DevTools hook (dev mode). State must be JSON-serializable; non-serializable values are replaced with an error marker.\n" +
2158
+ "GOOD: redux_get_state({ path: 'app' })\n" +
2159
+ "BAD: redux_get_state({ path: 'app.isLoading.0' }) when isLoading is a boolean — path traversal returns undefined.",
2160
+ inputSchema: {
2161
+ storeIndex: z
2162
+ .number()
2163
+ .int()
2164
+ .min(0)
2165
+ .optional()
2166
+ .describe("Index of the Provider store to read from when the app has multiple <Provider> roots (default: 0)."),
2167
+ path: z
2168
+ .string()
2169
+ .optional()
2170
+ .describe("Optional dotted path into state (e.g. 'app' or 'auth.user'). Omit for the full state."),
2171
+ device: z
2172
+ .string()
2173
+ .optional()
2174
+ .describe("Target device name (substring match). Omit for default device.")
2175
+ }
2176
+ }, async ({ storeIndex, path, device }) => {
2177
+ const result = await reduxGetState({ storeIndex, path, device });
2178
+ if (!result.success) {
2179
+ return {
2180
+ content: [{ type: "text", text: `Error: ${result.error ?? "Unknown error"}` }],
2181
+ isError: true
2182
+ };
2183
+ }
2184
+ const header = `Store ${result.storeIndex} of ${result.storeCount}${path ? ` at path '${path}'` : ""}:`;
2185
+ return { content: [{ type: "text", text: `${header}\n\n${JSON.stringify(result.state, null, 2)}` }] };
2186
+ });
2187
+ // ============================================================================
2107
2188
  // React Component Inspection Tools
2108
2189
  // ============================================================================
2109
2190
  // Tool: Get the React component tree
@@ -4282,9 +4363,10 @@ async function main() {
4282
4363
  }
4283
4364
  }
4284
4365
  // Skip boot when loaded by unit tests — tests import this module purely to
4285
- // enumerate `toolRegistry`. Jest sets JEST_WORKER_ID; RN_AI_DEVTOOLS_TEST_MODE
4286
- // is a manual escape hatch. Production + dev:mcp leave both unset and boot.
4287
- if (!process.env.RN_AI_DEVTOOLS_TEST_MODE && !process.env.JEST_WORKER_ID) {
4366
+ // enumerate `toolRegistry`. Jest sets JEST_WORKER_ID; EXECBRO_TEST_MODE
4367
+ // (or legacy RN_AI_DEVTOOLS_TEST_MODE) is a manual escape hatch.
4368
+ // Production + dev:mcp leave all unset and boot.
4369
+ if (!process.env.EXECBRO_TEST_MODE && !process.env.RN_AI_DEVTOOLS_TEST_MODE && !process.env.JEST_WORKER_ID) {
4288
4370
  main().catch((error) => {
4289
4371
  console.error("[execbro] Fatal error:", error);
4290
4372
  process.exit(1);