<feed xmlns='http://www.w3.org/2005/Atom'>
<title>sz-chrome-remote-cdp.git/src/cdp/session.ts, branch master</title>
<subtitle>pi-browser-harness, patched to drive a Chrome on another host over CDP, with castle_cdp_search web search
</subtitle>
<id>https://git.soarez.net/sz/sz-chrome-remote-cdp.git/atom?h=master</id>
<link rel='self' href='https://git.soarez.net/sz/sz-chrome-remote-cdp.git/atom?h=master'/>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/sz-chrome-remote-cdp.git/'/>
<updated>2026-08-02T13:42:46+00:00</updated>
<entry>
<title>refactor: merge nine files whose reason to exist was gone</title>
<updated>2026-08-02T13:42:46+00:00</updated>
<author>
<name>amankumarsingh77</name>
<email>amankumarsingh7702@gmail.com</email>
</author>
<published>2026-07-28T17:11:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/sz-chrome-remote-cdp.git/commit/?id=dcb79fc62bdd4d9ec0cbdb2c97d3eb2b2dacdf22'/>
<id>urn:sha1:dcb79fc62bdd4d9ec0cbdb2c97d3eb2b2dacdf22</id>
<content type='text'>
src/ goes from 84 files to 75 at the same line count — every merge below
had exactly one consumer.

cdp/event-queue.ts and cdp/pending-requests.ts become daemon/queue.ts.
I split these in the daemon-internals commit on the grounds that they
held two unrelated concerns, but the transport commit had already deleted
the second transport, so both halves had one consumer and the split
bought nothing. They also sat in cdp/ while only daemon/ used them.

cdp/transport.ts held only the CdpTransport interface after the second
transport went; five of its six consumers import it type-only, so it
moves to cdp/types.ts. cdp/evaluate.ts moves into cdp/session.ts rather
than into its lone consumer isolated-tab.ts — it reaches session.call
directly, so under src/domains/ it would trip the raw-cdp-call rule.

util/keycodes.ts and util/time.ts fold into their only callers
(keyboard.ts, page.ts); util/bytes.ts into util/truncate.ts, which
already owns output-size formatting; readpage/capture.ts and
search/extract.ts into the tools beside them; profile/picker.ts into
profile/command.ts.

Kept deliberately: mutex.ts and domains/target.ts each have their own
test suite, and folding target.ts into click.ts would make a tool file
export a helper. sharp-shim.ts is an isolation boundary carrying two
allowlisted casts. result.ts, guards.ts, js-template.ts and paths.ts are
small but have 44, 12, 8 and 3 consumers.

Co-Authored-By: Claude Opus 5 (1M context) &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>refactor: attach and windowId become session methods</title>
<updated>2026-08-02T13:42:46+00:00</updated>
<author>
<name>amankumarsingh77</name>
<email>amankumarsingh7702@gmail.com</email>
</author>
<published>2026-07-28T16:31:47+00:00</published>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/sz-chrome-remote-cdp.git/commit/?id=c88082515dcd9c0df1328b85420e97d7286ad428'/>
<id>urn:sha1:c88082515dcd9c0df1328b85420e97d7286ad428</id>
<content type='text'>
cdp/attach.ts and cdp/window.ts were a module each for a single
`map(await session.callBrowser(...))` one-liner that took the session as
its first argument — two files, two imports and two names for what the
session can expose itself. They are now session.attach(targetId) and
session.windowId(targetId).

session.ts also repeated `targetId ? tabs.get(targetId) : undefined`
eight times; that is now currentTab().

Co-Authored-By: Claude Opus 5 (1M context) &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>refactor(cdp): strip comment noise</title>
<updated>2026-08-02T13:42:46+00:00</updated>
<author>
<name>amankumarsingh77</name>
<email>amankumarsingh7702@gmail.com</email>
</author>
<published>2026-07-28T14:55:38+00:00</published>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/sz-chrome-remote-cdp.git/commit/?id=330767d862458386e804bde240a1f0d7835b9b8e'/>
<id>urn:sha1:330767d862458386e804bde240a1f0d7835b9b8e</id>
<content type='text'>
Removes module banners, section dividers, and comments restating the code.
Keeps one-line notes for the window.open/browserContextId constraint, the
seed-tab claim, the unverifiable-pin reuse rule, the SeedTargetProvider
rationale, the deliberate dialog retention, the discovery-time browser
quirks, and the guarded CDP decoder assertion.

Co-Authored-By: Claude Opus 5 (1M context) &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>fix(domains): keep element refs stable across a mutation</title>
<updated>2026-08-02T13:42:46+00:00</updated>
<author>
<name>amankumarsingh77</name>
<email>amankumarsingh7702@gmail.com</email>
</author>
<published>2026-07-28T14:20:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/sz-chrome-remote-cdp.git/commit/?id=254de089ee468795bac175d99e09ddaec4ac1469'/>
<id>urn:sha1:254de089ee468795bac175d99e09ddaec4ac1469</id>
<content type='text'>
interactiveDiff re-assigned refs by tree position after every fill, click and
select, so any element appearing or disappearing shifted the numbering and a ref
the agent was still holding silently resolved to a different element — while the
tools kept promising that refs survive re-renders. Refs are now carried over by
backendNodeId and only genuinely new elements draw a new number.

Report: docs/superpowers/reports/2026-07-26-bug-audit.md#f6

Co-Authored-By: Claude Opus 5 (1M context) &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>fix(cdp): route background-tab events to the tab they belong to</title>
<updated>2026-08-02T13:42:46+00:00</updated>
<author>
<name>amankumarsingh77</name>
<email>amankumarsingh7702@gmail.com</email>
</author>
<published>2026-07-28T14:14:17+00:00</published>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/sz-chrome-remote-cdp.git/commit/?id=226e814d47a5e1acd4d308619921ca1012723b88'/>
<id>urn:sha1:226e814d47a5e1acd4d308619921ca1012723b88</id>
<content type='text'>
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) &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>fix(cdp): re-enable domains when re-attaching to a known tab</title>
<updated>2026-08-02T13:42:46+00:00</updated>
<author>
<name>amankumarsingh77</name>
<email>amankumarsingh7702@gmail.com</email>
</author>
<published>2026-07-28T14:12:25+00:00</published>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/sz-chrome-remote-cdp.git/commit/?id=ce30547af39f692bef777591bdb329a7fa00e86e'/>
<id>urn:sha1:ce30547af39f692bef777591bdb329a7fa00e86e</id>
<content type='text'>
Every Target.attachToTarget mints a new sessionId and CDP domain enablement is
per-session, but switchTo only enabled domains on a tab's first visit. Switching
away and back left the refreshed session with Page, Network, Runtime and Log
disabled, so that tab silently stopped collecting console and network records and
stopped reporting dialogs and load events for the rest of the session.

Report: docs/superpowers/reports/2026-07-26-bug-audit.md#f3

Co-Authored-By: Claude Opus 5 (1M context) &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>refactor: close the remaining unguarded type assertions</title>
<updated>2026-08-02T13:42:46+00:00</updated>
<author>
<name>amankumarsingh77</name>
<email>amankumarsingh7702@gmail.com</email>
</author>
<published>2026-07-27T19:49:58+00:00</published>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/sz-chrome-remote-cdp.git/commit/?id=f9dcdf7f6dcdf2979693a9f179eda2b9995d57ae'/>
<id>urn:sha1:f9dcdf7f6dcdf2979693a9f179eda2b9995d57ae</id>
<content type='text'>
Types the event-queue iterator's TReturn as undefined so the terminal
result needs no cast; declares the isError field the pi runtime reads by
duck-typing; binds socket to a local const in the daemon transport;
replaces the @ts-ignore on the optional sharp import with a non-literal
specifier so src/ still typechecks where sharp was not installed.

Adds src/util/guards.ts as the single home for narrowing over unknown —
isRecord plus scalar/array readers — and converts the two private
isObject copies in cdp/types.ts and daemon/protocol.ts along with every
inline `as Record&lt;string, unknown&gt;` in domains/js.ts and domains/render.ts.

Gives Accessibility.getFullAXTree a real result schema, closing the last
unvalidated CDP boundary: only nodeId is required, every object carries
additionalProperties, and each AX value stays Unknown, so the tree
decodes as a whole or fails as a whole rather than being filtered.

Guards the five tool-result `details` readers, the daemon attach
response, the persisted session state, the browser-namespace flag, and
the fs errno narrowing, each feeding an already-present failure path.

The daemon-transport socket binding is not a bug fix: send() runs
synchronously inside sendWithTimeout's promise executor, so socket cannot
be reassigned between the check and the write. It removes the assertion
and makes the write immune to a later refactor that adds an await.

Two assertions survive by design and are documented in the task report:
the never-&gt;unknown re-widening in util/tool.ts, which the type-erased
tool registry makes unavoidable, and the AsyncFunction constructor lookup
in domains/js.ts, which JavaScript exposes no typed binding for.

Co-Authored-By: Claude Opus 5 (1M context) &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>refactor(cdp): validate event params against a typed table</title>
<updated>2026-08-02T13:42:46+00:00</updated>
<author>
<name>amankumarsingh77</name>
<email>amankumarsingh7702@gmail.com</email>
</author>
<published>2026-07-27T18:16:25+00:00</published>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/sz-chrome-remote-cdp.git/commit/?id=753c2ad615fa9827e168be256e1a7c7384605855'/>
<id>urn:sha1:753c2ad615fa9827e168be256e1a7c7384605855</id>
<content type='text'>
Malformed or unknown events are now dropped rather than hand-narrowed;
consumers get typed params. Unknown methods are ignored, since the
transport delivers every event Chrome emits.

Co-Authored-By: Claude Opus 5 (1M context) &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>refactor(cdp): extract attachTo, getWindowId, evaluateJson helpers</title>
<updated>2026-08-02T13:42:46+00:00</updated>
<author>
<name>amankumarsingh77</name>
<email>amankumarsingh7702@gmail.com</email>
</author>
<published>2026-07-26T19:47:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/sz-chrome-remote-cdp.git/commit/?id=9e9bf2a3badb59d0ce5bdb47c4e9d09ffb259e69'/>
<id>urn:sha1:9e9bf2a3badb59d0ce5bdb47c4e9d09ffb259e69</id>
<content type='text'>
Target.attachToTarget was decoded at 5 sites, Browser.getWindowForTarget
at 5, and Runtime.evaluate unwrapped at another. Each is now one typed
helper. Deletes the dead cdp/window-binding.ts.

Co-Authored-By: Claude Opus 5 (1M context) &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>test(cdp): cover call/callOnTarget/callBrowser through a stub transport; collapse decode into one path</title>
<updated>2026-08-02T13:42:46+00:00</updated>
<author>
<name>amankumarsingh77</name>
<email>amankumarsingh7702@gmail.com</email>
</author>
<published>2026-07-26T19:37:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/sz-chrome-remote-cdp.git/commit/?id=d1b57558ff40ef6d6b19ee7eff0a44f7f4a585f6'/>
<id>urn:sha1:d1b57558ff40ef6d6b19ee7eff0a44f7f4a585f6</id>
<content type='text'>
session-call-test.ts previously only exercised decodeResult (Task 3's
surface, and mostly duplicating commands-test.ts) — call, callOnTarget,
callBrowser, and the session's internal req helper had zero coverage.
Add a stub CdpTransport (no socket, no browser) and test: a valid payload
decodes to typed data, a garbage payload becomes invalid_response without
throwing, a transport-level error passes through with its original kind
(not relabeled), call/callOnTarget/callBrowser route the session id
correctly, and opts.timeoutMs reaches the transport only when provided.

Also collapse the four near-identical transport-then-decode bodies (req,
call, callOnTarget, callBrowser) into one: the three public methods now
delegate to req, which is the sole place unknown ends for every CDP call
the session makes, internal or public. Public signatures are unchanged.

Co-Authored-By: Claude Opus 5 (1M context) &lt;noreply@anthropic.com&gt;
</content>
</entry>
</feed>
