Skip to content

[kernel-1116] Add CDP Monitor#213

Open
archandatta wants to merge 53 commits intomainfrom
archand/kernel-1116/cdp-foundation
Open

[kernel-1116] Add CDP Monitor#213
archandatta wants to merge 53 commits intomainfrom
archand/kernel-1116/cdp-foundation

Conversation

@archandatta
Copy link
Copy Markdown
Contributor

@archandatta archandatta commented Apr 13, 2026

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
High risk because it introduces a new CDP WebSocket ingestion pipeline with complex concurrency/reconnect logic and begins capturing potentially sensitive browser data (network headers/bodies and interaction events). Failures could impact stability (goroutine/connection lifecycles) and data correctness in the event stream.

Overview
Adds a new cdpmonitor package that connects to Chrome DevTools over WebSocket, auto-attaches to targets, translates CDP notifications into structured events.Events (console, network, page lifecycle, layout shifts), and emits computed meta-events (network_idle, layout_settled, navigation_settled).

The monitor now includes reconnection on upstream DevTools URL changes with backoff, bounded cleanup of in-flight requests/commands, optional screenshot capture via ffmpeg (rate-limited + downscaling), and injected interaction.js for click/key/scroll events with basic suppression heuristics for sensitive inputs. API wiring is updated to pass a logger into cdpmonitor.New and to depend on a cdpMonitorController interface with test stubs; extensive new tests/fixtures validate protocol round-tripping and lifecycle behaviors.

Reviewed by Cursor Bugbot for commit fd4d4d3. Bugbot is set up for automated code reviews on this repo. Configure here.

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.
Comment thread server/lib/cdpmonitor/monitor.go
Comment thread server/lib/cdpmonitor/monitor.go
@archandatta archandatta force-pushed the archand/kernel-1116/cdp-foundation branch from 092a265 to 7550bc1 Compare April 22, 2026 14:35
Comment thread server/lib/cdpmonitor/interaction.js Outdated
Comment thread server/lib/cdpmonitor/monitor.go
Comment thread server/lib/cdpmonitor/interaction.js
Comment thread server/lib/cdpmonitor/screenshot.go
Comment thread server/lib/cdpmonitor/interaction.js
_ = m.injectScript(ctx, p.SessionID)
}
})
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Injected script never runs on already-loaded pages

Medium Severity

handleAttachedToTarget calls injectScript, which only uses Page.addScriptToEvaluateOnNewDocument. This registers interaction.js for future navigations but never evaluates it on the current document. Pages already loaded when the monitor attaches (via attachExistingTargets or after reconnect) won't have click, keydown, or scroll-settled tracking until their next navigation. A Runtime.evaluate call with the same script source is needed alongside the addScriptToEvaluateOnNewDocument registration to cover the current page.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit bf4b04c. Configure here.

Comment thread server/lib/cdpmonitor/interaction.js
Comment thread server/lib/cdpmonitor/monitor.go
Comment thread server/lib/cdpmonitor/interaction.js
Base automatically changed from archand/kernel-1116/cdp-pipeline to main April 22, 2026 17:41
@archandatta archandatta dismissed Sayan-’s stale review April 22, 2026 17:41

The base branch was changed.

@archandatta archandatta requested a review from Sayan- April 22, 2026 17:43
_, err := m.send(ctx, "Page.addScriptToEvaluateOnNewDocument", map[string]any{
"source": injectedJS,
}, sessionID)
return err
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interaction script not injected into current document

Medium Severity

injectScript only calls Page.addScriptToEvaluateOnNewDocument, which registers the interaction-tracking JS for future navigations. The already-loaded document in an attached target never receives the script. When the monitor attaches to existing pages (via attachExistingTargets at startup or after reconnect), clicks, keydowns, and scroll events on those pages won't be captured until the user navigates away. A companion Runtime.evaluate call is needed to inject into the current document.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 8e94162. Configure here.

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 6 total unresolved issues (including 5 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 5465e59. Configure here.

key: e.key,
selector: sel(t), tag: t.tagName || ''
}));
}, true);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sensitive input detection bypassed by shadow DOM retargeting

Medium Severity

The keydown handler uses e.target to check isSensitiveInput, but e.target is retargeted across shadow DOM boundaries. When a <input type="password"> lives inside a web component's shadow DOM (common with Material UI, Lit, Shoelace, etc.), e.target at the document level resolves to the shadow host custom element — not the inner password input. Since the shadow host typically isn't an INPUT/TEXTAREA, isEditable returns false and isSensitiveInput returns false, allowing the actual e.key character to be captured. Using e.composedPath()[0] instead of e.target would resolve this, as it returns the real originating element even across shadow boundaries.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 5465e59. Configure here.

Comment thread server/lib/cdpmonitor/monitor.go Outdated
Comment thread server/lib/cdpmonitor/monitor.go Outdated
Comment on lines +28 to +34
//
// Lock ordering (outer → inner):
//
// restartMu → lifeMu → pendReqMu → computed.mu → pendMu → sessionsMu
//
// Never acquire a lock that appears later in this order while holding an
// earlier one, to prevent deadlock.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is missing a lot of introductory context about what these locks control / what the Monitor struct is responsible for. This file is the entrypoint to the package and reading this I am very lost

maybe a lib/cdpmonitor/README.md would be helpful

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lmk if this is clear enough, or if there other details that would be worth adding! fd4d4d3

Comment thread server/lib/cdpmonitor/monitor.go Outdated
Comment thread server/lib/cdpmonitor/types.go Outdated
@archandatta archandatta requested a review from rgarcia April 23, 2026 19:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants