Repository navigation
Conversation
|
Size Report
Startup median (7 runs, lower is better):
|
There was a problem hiding this comment.
All reported issues were addressed across 25 files
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
|
At f87e64a, the Metro-inspector transport and injected runtime look like real new capability, but two problems need fixing before merge.
Help and docs say "a development build on React Native 0.74 or newer" for every platform (https://github.com/callstack/agent-device/blob/f87e64a/src/commands/schema/cli-help.ts#L308), but the PR body says iOS was not verified. The remote-bridge branch at Is about 1,970 production lines (3,536 gross) the right shape for one PR, given the 700 net-production and 1,000-line gross budgets in Not blocking, and you can take or leave these: the The Lint & Format failure is the PR's own. The di-seams gate fails on Before merge, the lint failure and the two findings above need fixing. Of the open inline threads, the P2 threads on #3613 (comment) (context renders), #3613 (comment) (inferred effect chain), #3613 (comment) (start-reset test), #3613 (comment) (duplicate instance counts), #3613 (comment) (emoji fixture length), #3613 (comment) (help "effect sets state"), #3613 (comment) (help "unrelated context"), #3613 (comment) (unused disconnect handle), #3613 (comment) (lastId only), #3613 (comment) (prop candidate cap), #3613 (comment) (timing-only effect claim), #3613 (comment) (top mounts only) and #3613 (comment) (stale react-native topic) still stand. Also, 10 lower-priority P3 threads still apply. No thread is outdated, so none need resolving. |
f87e64a to
f25394b
Compare
|
At Device ambiguity: iOS: shown through the CLI on a bare RN 0.83 iOS simulator. Each scenario ran as Remote bridge: not run. Help now says remote bridge sessions are not verified yet, matching the docs. Lint: removed the Shape: restacked as you suggested. This PR keeps the transport, runtime, analysis and Non-blocking items:
All 25 inline threads are answered and resolved. Re-validated on the final top-of-stack build: Android RN 0.88-rc, 7/7. |
There was a problem hiding this comment.
All reported issues were addressed across 16 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
|
I reviewed f25394b again. The code looks good, and the seams that failed Lint & Format (di-seams) at f87e64a are gone from Not blocking: when one app runs on several devices, every session sharing that Metro gets INVALID_ARGS until Several inline threads from cubic-dev-ai still stand. #3613 (comment) (duplicate-name hint) is the one to fix first: when two devices share a Before merge, fix the duplicate-name hint above, then wait for CI to finish, including |
b7eb909 to
f1f454b
Compare
|
At
|
There was a problem hiding this comment.
All reported issues were addressed
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
|
At
The All 41 review threads have a reply and are resolved. |
There was a problem hiding this comment.
All reported issues were addressed across 18 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
|
The PR is ready at 639d73d. The issues from the earlier review (f25394b) are fixed: the device key now uses the target-id prefix, the 16 ms frame budget wording is correct, and the render analysis fixes landed. CI is green with 22 checks and none failing, and there are no conflicts. Not blocking, and you can take or leave these: the waiver reason in scripts/fuzz/validation-arbitraries-cli.ts#L37 and the predicate name On the open inline threads from the other reviewer: all of them are fixed at this head except one, #3613 (comment) (passing I ran no device for this review. The Android RN 0.74-0.88, iOS 0.83 and drill-down runs come from the PR body, with no commit named for each. No run with two devices on one Metro was reported, so the target-id-prefix device key rests on unit tests over a synthetic |
There was a problem hiding this comment.
All reported issues were addressed across 15 files (changes from recent commits).
Tip: Get a Slack DM when cubic finishes reviewing your PRs. Connect Slack
View guided diff | Turn on auto-fix | Re-trigger cubic
|
The fixes since the earlier review (639d73d) look good at a127024, and I found no new problems in the code. Smoke Tests is still running, not failed, and this change touches nothing on the daemon or device smoke route, so I see no overlap. There are no conflicts. The live evidence in the PR body is from the earlier head. Before merge, please address or dismiss the four open Cubic P2 threads, which all still apply: the report component wording, the started-interface failure count, the quadratic finding filter, and the double-counted subtree time. Then let Smoke Tests finish. Not blocking, and you can take or leave it: |
There was a problem hiding this comment.
All reported issues were addressed across 38 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
There was a problem hiding this comment.
All reported issues were addressed across 38 files (changes from recent commits).
Requires human review: Auto-approval blocked because this review re-detected 2 unresolved issues already reported by Cubic.
View guided diff | Turn on auto-fix | Re-trigger cubic
|
The four profiler threads from the earlier review are still open at 77e9159, and the delta adds a second feature on top: component inspection (tree, find, inspect, errors). I found no new correctness problem in that code, but the profiler fixes are not done. The earlier review asked you to address or dismiss the four open profiler threads: #3613 (comment), #3613 (comment), #3613 (comment) and #3613 (comment). None has a reply or a fix yet. Two more open P2 threads still apply and are worth fixing in this PR: #3613 (comment) (shared port parsing) and #3613 (comment) (host-only fallback). Nine more P2 threads and two P3 threads from the same reviewer still apply, and the sanitizer and inspect-error threads should be fixed through one shared helper. One thread does not apply and you can resolve it: #3613 (comment) (state data of null means a function component has no state, so printing nothing is correct). Would it be simpler to ship the profiler alone with those fixes, then land component inspection as a stacked PR on the already extracted react-devtools-connection.ts? Each PR would then sit nearer the 700-line threshold, and the new surface would get its own review round. The split point is bc041b3: the profiler commits up to a127024 plus the connection-module extraction, then inspection on top. Either way, please export one control-character sanitizer from capture-kit instead of adding a third local copy. The transport ownership itself is well placed, and I found no smaller owner for it. Not blocking, and you can take or leave these: the delta is roughly 720 new production lines, so if inspection stays here, a line in the PR body on why the two must ship together would help. Also, the Connection paragraph in cli-help.ts and the matching text in commands.md say every react-devtools command is verified on Android emulators and iOS simulators with RN 0.74+. The PR body says inspection was verified only on Android with RN 0.88-rc, so please scope that sentence to profiling, or run tree, inspect @ref and errors once on an iOS simulator and once on RN 0.74 and paste the output. I did not run the live device commands, so the Android validation at 77e9159 is your report. No conflicts are known. The eager-closure-budgets Coverage failure looks unrelated: it lists rows that #3625 added on main and #3623 (8c01a37) later removed, and this PR touches neither the budget file nor those packages. Rebasing on 8c01a37 should clear it. The iOS Smoke failure in testRegularSnapshotStillRepairsBackgroundAndDisclosesPriorState also looks unrelated, since the diff changes no Swift, runner or daemon snapshot code. Before merge, please fix the four profiler threads, decide on the split, and rebase on main. |
|
Addressed at 2acde20. All 17 Cubic threads have a reply and are resolved: 16 fixed and 1 dismissed (state data of null means no class state, as you noted).
Gates: On splitting: the maintainer asked to keep profiling and inspection in this one PR, so inspection stays here rather than in a stacked PR. |
There was a problem hiding this comment.
All reported issues were addressed across 21 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
There was a problem hiding this comment.
All reported issues were addressed across 15 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
|
Thanks for the update. At 4178ccd the code looks good: the issues from the earlier review (#3613 (comment)) are fixed, and no blocking findings remain in the code. Not blocking, and you can take or leave it: src/cli/react-devtools/react-devtools-text.ts:5 adds a new local control-character regex in printable(). The earlier review asked for one shared sanitizer from capture-kit (collapseControlCharacters in packages/capture-kit/src/snapshot/snapshot-lines.ts:124, currently private). It is not a copy, since capture-kit folds whitespace, removes controls and trims, while this one maps each control to a space. Either export one helper and call it from react-devtools, or note in the PR why the two must differ. Three Cubic threads still apply: #3613 (comment) (sanitize at output), #3613 (comment) (sanitize at output), and #3613 (comment) (docs Metro qualifier). The rule for the first two is to sanitize only where text leaves for output, and to keep raw text for identity and lookup. The third needs debugging-profiling.md:88 to say that bridge sessions fall back to metroPublicBaseUrl when no binding is recorded, as cli-help.ts:313 and commands.md:660 already do. The other threads are fixed at this head and can be resolved: #3613 (comment), #3613 (comment), #3613 (comment), #3613 (comment), #3613 (comment), #3613 (comment), #3613 (comment), #3613 (comment), #3613 (comment), #3613 (comment), #3613 (comment), #3613 (comment), #3613 (comment), #3613 (comment), #3613 (comment) and #3613 (comment). The thread at #3613 (comment) was dismissed on purpose: a null state.data means a function component has no class state, so printing nothing is correct. The PR now has a merge conflict with main (35c21b6) in src/metro/client-metro-companion.test.ts. Main moved that test, and this PR edits it to drop the react-devtools companion cases. Only the CodeQL jobs are queued and the rest of CI has not started, so no check has failed yet. I did not run any device, proxy or remote-bridge command, and I did not run the test suite. The live-validation rows in the PR body, including the RN 0.74/0.76 errors note and the bridge run through metroPublicBaseUrl, are your reports without pasted output. I also could not confirm that a bridged session's recorded binding always points at the host-local Metro, because recordMetroSessionHintsAfterOpen can record device-facing hints when no metro prepare ran. Reload already shares that path, so it is not new here. The logsTracked heuristic was checked only against the fake runtime, not real React DevTools 5 or 6 backends. Before merge, please rebase on main to clear the conflict so CI can run. Then fix or resolve the three open Cubic threads above. |
4178ccd to
dc23e5a
Compare
… word findings as heuristics
…up by its own render, refuse unread options
… cost repeated eager mounts, and count changed props - Elements the profile cannot name stay out of components and findings instead of folding into one Unknown. - Animated(...) wrappers keep their name so they stay framework components; Memo(Row) and Row are separate components. - A prop whose inspected instances disagree on its kind claims no new identity. - memo-defeated evidence counts each changed prop; eager-mount costs every qualifying commit of a component. - Devices without a logical id are keyed by target id before display name. - Docs name --bundle-url; perf guidance and ADR 0029 no longer point at a daemon command react-devtools does not send.
…ow report and commit arguments in usage
… identity through analysis, and fold the views into report and commit - profile stop saves the raw recording with prop kinds and notes; report and commit analyze it again, so a commit lists every component that rendered in it - findings carry the component kind, so a finding about memo Row no longer explains a slow commit spent in plain Row - a renderer whose profiling data cannot be read fails stop (collect-failed) or, when others were read, adds a note instead of saving an empty profile - profile surface is start, stop, report [Component], commit [N]: report without a name replaces slow and rerenders, commit without an index replaces timeline; status and --sort are gone
…nnection - react-devtools tree [@ref|Name], find <Name> [--exact], inspect <@ref|Name>, and errors read the component tree, props, state, hooks, owners, and errors and warnings logged while rendering through the same in-app runtime and Metro connection as profiling - the runtime keeps keys, child order, and per-component error and warning counts from the operations stream; inspect calls the backend's inspectElement - tree collapses wrapper chains onto one line and runs of same-shape siblings into one counted line; a name several components share fails closed with their refs - the profiler moves to src/cli/react-devtools with one shared connection module
…g, tree runs, output safety, and Metro flags - stop reads back only the renderers that started profiling - slow-commit accounting indexes findings once and counts a subtree inside an accounted subtree only once (profiles now carry each rendered element's ancestors) - tree collapses only siblings whose whole subtrees match, logged problems included - app-provided names, keys, values, and messages print without control characters - errors says when messages could not be read; an empty result keeps total - --metro-port must be a whole number; a host or port flag alone keeps the rest of the session binding
…refer the session's Metro on bridges, and flag untracked logs - the CDP socket opens on the server that listed the target: behind a tunnel Metro advertises its own loopback address, which a client elsewhere cannot reach - a remote bridge session uses its recorded Metro server next to the agent before the public URL - errors notes that its list can be incomplete when the backend does not attribute every log to a component (React DevTools 5, seen on React Native 0.74 and 0.76) - help and docs: verified through agent-device proxy and on remote bridge sessions
…the local Metro on bridges Profile analysis keys components and prop keys by their raw text; control characters are replaced only in the printed lines, so names that differ only by them no longer merge. Metro accepts the debugger socket only from its own machine (local socket and loopback Origin), so a device-facing URL such as metroPublicBaseUrl or the remote bridge can never carry it. Drop that fallback: resolve explicit flags, then the session's Metro binding, then localhost:8081.
…nd later DevTools 7 added a name-prop field to each non-root ADD and Suspense tree and Activity slice ops (8-13). The runtime stopped decoding at the first of them, so tree, find, and errors failed as if another frontend owned the tree, and profiles fell back to name lookups. Renderer interfaces gained supportsTogglingSuspense in the same release; the runtime reads the ADD length from it and skips the new ops by their encoded lengths. Verified on an RN 0.83.1 iOS simulator with react-devtools-core 8.0.0 swapped in, and again on its shipped 6.1.5.
dc23e5a to
af282ef
Compare
|
This PR is ready at af282ef. The fixes from the earlier review (#3613 (comment)) are in, and I found no new problems in the code. Not blocking: in The three automated review threads (#3613 (comment), #3613 (comment) and #3613 (comment)) are fixed at this commit, so please resolve them. The key sanitizing now happens at output, render identity uses raw display names, and the docs and help describe the flags, binding, then localhost:8081 order. Smoke Tests is still running and has no failure. This change does not touch what Smoke drives. It only changes I could not check the op lengths in As noted before, Smoke Tests must finish green at af282ef before merge. Nothing in the code holds it back. |
Summary
agent-device react-devtoolsis now built-in React Native component inspection and render profiling. Every command attaches to the app's JavaScript runtime through its Metro dev server (CDPRuntime.evaluate) and drives the React DevTools backend that development builds already ship. The app, Metro config and Babel config need no changes, and there is no helper to start or wait for.Components
tree [@ref|Name] [--depth] [--limit]prints the mounted tree with@crefs. Wrapper chains such as providers collapse onto one line, and runs of three or more same-shape siblings (list rows) into one counted line, so the 1,510-component Expo Router test app fits in about 25 lines.find <Name> [--exact]lists matches with the components that rendered them.inspect <@ref|Name>prints owners, props, state, hooks and logged problems. A name that several components share fails closed and lists their refs.errorslists components that logged console errors or warnings while rendering, with the messages.The tree comes from the backend's
operationsstream (names, keys, child order, error and warning counts). Props, state and hooks come from itsinspectElement. When another DevTools frontend owns that stream, the tree commands fail withtree-unavailableinstead of returning a partial tree.Render profiling
stopprints ranked findings and saves the raw recording.reportandcommitre-analyze the saved recording, so no view loses detail another trimmed.reportwith no name lists components by self time with why they rendered;report <Component>shows each variant (Rowand memoRowstay separate) with its findings.commitwith no index lists commits in order (the slowest ones when capped);commit <N>lists every component that rendered in it.Findings carry the component kind, so a finding about memo
Rownever explains a slow commit spent in plainRow. A renderer whose profiling data cannot be read failsstopwithcollect-failed, or adds a note when other renderers were read.Each subcommand rejects options it does not read. If one app is connected from several devices, every command fails closed until
--metro-devicenames one.Removed: the
npm exec agent-react-devtoolspassthrough, its 8097 remote tunnel and port reverse, and the injected-dispatch seam only that port reverse used.Validation
At
4178ccd7b1,check:affected --run(4,589 tests),check:production-exportsandcheck:di-seamspass.tree,find,inspectby ref and name,errors, ambiguous names, inspect during a profile, allprofileviewsprofile start/stop/report/commitreact-devtools-core8.0.0 swapped in (no RN release ships DevTools 7+ yet; 0.88 and the 0.89 nightly pin^6.1.5)tree,find,inspect,errors,profilewith mounts while recordingtreehere; 6.1.5 rechecked after the changetree,inspect(hooks),errors,profileerrorsnotes that the list can be incompletetree,find,inspect,errors,profile(memo-defeated)errorsnoteagent-device proxy, client with its own state dirprofile start/stop, drill-downsconnect --remote-config,open, inspection and profiling from the containerFound and fixed while verifying:
webSocketDebuggerUrl. The CDP socket now opens on the server that listed the target.metroPublicBaseUrlor the bridge).errorson older backends. React DevTools 5 (RN 0.74 and 0.76) does not attribute every console call to a component, soerrorsnow says its list can be incomplete instead of claiming nothing was logged.By design, not changed: Metro accepts the debugger socket only from its own machine (local socket and loopback
Origin). The companion bridge opens upstream WebSockets without anOrigin, so Metro refuses debugger sockets sent through the bridge. That keeps the bridge from exposing JavaScript execution in the app, so the companion stays as it is. The removed 8097 tunnel did something else: it carried the app's DevTools backend to a frontend on the host.