[kernel-1116] Add CDP Monitor#213
Conversation
…ies and fix delimiter in CategoryFor
… and category validation
…alloc in filewriter, fix session doc
This binary is tracked on main and was incidentally deleted earlier on this branch. Restoring it keeps the 13.4MB binary out of this PR's diff. Removing the tracked binary from main should be done in a separate PR.
|
I did a manual pass against this branch with the review harness, doing a single navigation to A few observations/suggestions from that run: The event stream needs richer CDP identity metadata before this is reviewable as a browser logging foundation. The monitor already receives enough data to tie network events to a target/frame/navigation, but the published event drops most of it. Could we include at least:
Relatedly, the computed events ( Without this, consumers can’t reliably answer “which tab/page/navigation produced this event?”, which seems core to the usefulness of the CDP monitor. One note from the log: the first three document |
|
@rgarcia feedback addressed! the fields like |
16d37eb to
83a164b
Compare
| for _, ev := range evs { | ||
| s.publish(ev) | ||
| } | ||
| } |
There was a problem hiding this comment.
Missing dead check in onDOMContentLoaded
Low Severity
onDOMContentLoaded unconditionally sets s.navDOMLoaded = true without checking s.dead first. Every other state-mutating method (onRequest, onLoadingFinished, onPageLoad, onLayoutShift) guards with if s.dead { return } before modifying state. While pendingNavigationSettled independently checks dead preventing event emission, this inconsistency mutates a stopped state machine, which could mask bugs if future code reads navDOMLoaded without also checking dead.
Reviewed by Cursor Bugbot for commit 83a164b. Configure here.
|
I ran another manual pass with the review harness, this time navigating to Hacker News, then opening a new tab and navigating to kernel.sh. Event data: https://gist.github.com/rgarcia/0a60c17ece22e9394bdd9118475a0f5c Observations:
Overall the new loader/frame/request/target additions are a big improvement. I think the remaining work is mostly making the schema consistent and documented enough for downstream consumers. |
|
Couple of other things:
|
d64437e to
916f275
Compare
|
new test run where I navigated to hacker news, then opened a new tab and did some kernel.sh things, then went back to the HN tab and clicked into an openai blog post: https://gist.github.com/rgarcia/a0c7670d3c3850a7fdab7daeb6460611 The final navigation took five mins to produce Maybe we define The other thing I noticed is that SPA/client-side route changes did not trigger events (on kernel.sh i clicked into the pricing page to simulate this). I think it's fine to treat inferring these as a follow-up because correctly distinguishing real route changes from prefetch/background fetches is harder. |
|
Here is the latest run -> https://gist.github.com/archandatta/b7a841c0837afa27780177680228c878. Updated to not wait |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 5 total unresolved issues (including 4 from previous reviews).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit bbc3c91. Configure here.


Introduces the foundational layer of the CDP monitor as a standalone reviewablechunk. No Monitor struct wiring, just the primitives that everything else builds on.
types.go: CDP wire format (cdpMessage), all event type constants, internal state structs (networkReqState, targetInfo, CDP param shapes).
util.go: Console arg extraction, MIME allow-list (isCapturedMIME), resource type filter (isTextualResource), per-MIME body size caps (bodyCapFor), UTF-8-safe body truncation (truncateBody).
computed.go: State machine for the three derived events: network_idle (500ms debounce after all requests finish), layout_settled (1s after page_load with no layout shifts), navigation_settled (fires once all three flags converge). Timer invalidation via navSeq prevents stale AfterFunc callbacks from publishing for a previous navigation.
domains.go: isPageLikeTarget predicate (pages and iframes get Page.* / PerformanceTimeline.*; workers don't), bindingName constant, interaction.js embed.
interaction.js: Injected script tracking clicks, keydowns, and scroll-settled events via the __kernelEvent CDP binding.
Note
High Risk
Large new CDP capture subsystem that streams network/console data (including headers/bodies) and manages reconnect/timers across goroutines, which is complex and can impact stability, performance, and sensitive-data exposure if misconfigured.
Overview
Adds a full
cdpmonitorimplementation that connects to Chrome’s DevTools WebSocket, auto-attaches to targets, translates CDP notifications into typedevents.Events (console, network, page, interaction), and publishes monitor lifecycle events (disconnect/reconnect/init-failed) with capped-exponential reconnect backoff.Introduces per-session computed state machines (
network_idle,page_layout_settled,page_navigation_settled), interaction tracking via embeddedinteraction.jswith rate-limiting and sensitive-input suppression, and screenshot capture viaffmpegwith size downscaling and 2s rate limiting.Updates API wiring to pass a
sloglogger intocdpmonitor.New, abstractsApiService.cdpMonitorbehind an interface for easier stubbing in tests, and adds extensive fixtures/tests to validate CDP wire-type roundtrips and monitor behavior (events, redirects, detach handling, TTL sweeps, and reconnects).Reviewed by Cursor Bugbot for commit 7cc19d8. Bugbot is set up for automated code reviews on this repo. Configure here.