From 226e814d47a5e1acd4d308619921ca1012723b88 Mon Sep 17 00:00:00 2001 From: amankumarsingh77 Date: Tue, 28 Jul 2026 19:44:17 +0530 Subject: fix(cdp): route background-tab events to the tab they belong to MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The event loop dropped every event whose sessionId was not the active tab's, so the per-tab console and network buffers could only ever hold data captured while their tab was in the foreground. The filter now drops only sessions this instance never attached, and the dialog, frameNavigated and loadEventFired arms resolve their tab from the event's sessionId instead of assuming the active tab — without that, a background tab's dialog would have been recorded against the foreground one. Tabs are also registered before the domain-enable round trips, so events arriving during attach are no longer dropped as unknown. Report: docs/superpowers/reports/2026-07-26-bug-audit.md#f4 Co-Authored-By: Claude Opus 5 (1M context) --- src/cdp/session.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/cdp/session.ts b/src/cdp/session.ts index 39cd87e..2e0e71f 100644 --- a/src/cdp/session.ts +++ b/src/cdp/session.ts @@ -90,11 +90,11 @@ export const createCdpSession = ( // Filter: skip events from sessions we're not currently tracking. // Target.targetDestroyed is browser-level (no sessionId) — always process. if (ev.method !== "Target.targetDestroyed") { - if (ev.sessionId && ev.sessionId !== sessionId) continue; + if (ev.sessionId && !sessionIdToTargetId.has(ev.sessionId)) continue; } switch (ev.method) { case "Page.javascriptDialogOpening": { - const tab = targetId ? tabs.get(targetId) : undefined; + const tab = resolveTab(ev.sessionId); if (!tab) break; const decoded = decodeEvent(ev.method, ev.params); tab.dialog = decoded.success @@ -114,7 +114,7 @@ export const createCdpSession = ( // was about to read. (Fix for spec §7 predictability bug #2.) case "Page.frameNavigated": case "Page.loadEventFired": { - const tab = targetId ? tabs.get(targetId) : undefined; + const tab = resolveTab(ev.sessionId); if (tab) tab.pageInfoDirty = true; break; } @@ -333,7 +333,6 @@ export const createCdpSession = ( const attachedSessionId = attached.data; sessionId = attachedSessionId; targetId = pickTargetId; - await enableDomains(attachedSessionId); tabs.set(pickTargetId, { sessionId: attachedSessionId, targetId: pickTargetId, @@ -345,6 +344,7 @@ export const createCdpSession = ( refSig: new Map(), }); sessionIdToTargetId.set(attachedSessionId, pickTargetId); + await enableDomains(attachedSessionId); return ok({ targetId: pickTargetId, sessionId: attachedSessionId }); }, async switchTo(tid) { -- cgit v1.2.3