<feed xmlns='http://www.w3.org/2005/Atom'>
<title>sz-chrome-remote-extension.git/docs, branch master</title>
<subtitle>pi-chrome, patched to drive a signed-in browser on another host through a broker, with an MCP server
</subtitle>
<id>https://git.soarez.net/sz/sz-chrome-remote-extension.git/atom?h=master</id>
<link rel='self' href='https://git.soarez.net/sz/sz-chrome-remote-extension.git/atom?h=master'/>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/sz-chrome-remote-extension.git/'/>
<updated>2026-09-26T23:07:56+00:00</updated>
<entry>
<title>Report hidden-tab input, append targeted typing, smarter uploads, prune screenshots; release 0.15.54</title>
<updated>2026-09-26T23:07:56+00:00</updated>
<author>
<name>Tianren Dong</name>
<email>tianrendong.dtr@gmail.com</email>
</author>
<published>2026-09-26T23:07:56+00:00</published>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/sz-chrome-remote-extension.git/commit/?id=238f347a03b2cefb21198bb78a90699e931d8504'/>
<id>urn:sha1:238f347a03b2cefb21198bb78a90699e931d8504</id>
<content type='text'>
- Check page visibility before trusted input: Chrome drops input to hidden pages (inactive tabs,
  covered/minimized windows, macOS window tabs behind full screen). Type/key/hover/scroll/tap/drag
  fail fast with the reason; click/fill use their DOM fallback immediately (or reject with
  domFallback:false).
- Use an inactive tab instead of a new window for the automation target while the user's window is
  full screen.
- chrome_type with uid/selector moves the caret to the end (moveToEndOfDocument) after its focus click.
- chrome_upload_file: labels/wrappers resolve to their file input, same-origin iframe search, and
  intercepted file chooser for upload buttons (trusted click when visible, user-gesture click when
  hidden); reject multiple paths for single-file inputs; no duplicate change event.
- Prune default-folder chrome_screenshot captures (7 days, newest 20 kept, retentionDays override).
- input.debug without a target no longer calls tabs.get(-1).
- New hidden-input unit suite.
</content>
</entry>
<entry>
<title>Absorb fork fixes and features; release 0.15.53</title>
<updated>2026-09-26T20:37:25+00:00</updated>
<author>
<name>Tianren Dong</name>
<email>tianrendong.dtr@gmail.com</email>
</author>
<published>2026-09-26T20:37:25+00:00</published>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/sz-chrome-remote-extension.git/commit/?id=c49dc15fa5c33d5b1d210b0185677ce29640e2d5'/>
<id>urn:sha1:c49dc15fa5c33d5b1d210b0185677ce29640e2d5</id>
<content type='text'>
Adapted from community forks (ardhiqii, kkunkunya, nihar-oracle, steimerbyte):

- Abort stalled /next long polls after 45s; time out, retry, and single-post results.
- Fall back to CDP Runtime.evaluate when chrome.scripting is refused (about:blank automation tabs).
- Load pi-chrome in same-process subagent sessions as a bridge client; client chrome_launch reports owner status.
- Add chrome_cdp (validated raw CDP passthrough, background-guarded, payload summarization) and chrome_cdp_targets.
- chrome_type reports before/after values, insertedAt, splice/unchanged warnings; add replace=true.
- includeSnapshot waits for navigations started by the action; tab.new reports the settled tab.
- CDP timeouts surface as timeouts and are not re-sent after the cleanup detach.
- Activate/deactivate chrome_find and chrome_inspect with the rest of the chrome_* tools.
- New unit suites: bridge-resilience, cdp-passthrough, type-evidence.
</content>
</entry>
<entry>
<title>Enforce hard background and release 0.15.48</title>
<updated>2026-09-10T03:48:50+00:00</updated>
<author>
<name>Tianren Dong</name>
<email>tianrendong.dtr@gmail.com</email>
</author>
<published>2026-09-10T03:37:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/sz-chrome-remote-extension.git/commit/?id=c1f230eeb76aaa50e98d3fe7d838573612b6e36f'/>
<id>urn:sha1:c1f230eeb76aaa50e98d3fe7d838573612b6e36f</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Fix session cleanup and release 0.15.47</title>
<updated>2026-09-10T03:14:15+00:00</updated>
<author>
<name>Tianren Dong</name>
<email>tianrendong.dtr@gmail.com</email>
</author>
<published>2026-09-10T02:54:22+00:00</published>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/sz-chrome-remote-extension.git/commit/?id=1ec29fc90b84517322bf5994245368f0e59eff61'/>
<id>urn:sha1:1ec29fc90b84517322bf5994245368f0e59eff61</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Shorten README and move architecture docs</title>
<updated>2026-06-26T01:06:39+00:00</updated>
<author>
<name>Tianren Dong</name>
<email>tianrendong.dtr@gmail.com</email>
</author>
<published>2026-06-26T01:06:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/sz-chrome-remote-extension.git/commit/?id=d5d5bcd4909b08d3bae02b74b7ce2ff260676ffb'/>
<id>urn:sha1:d5d5bcd4909b08d3bae02b74b7ce2ff260676ffb</id>
<content type='text'>
</content>
</entry>
<entry>
<title>0.15.39: dedicated pi-chrome automation tab/window isolation (#6)</title>
<updated>2026-06-22T23:55:20+00:00</updated>
<author>
<name>TJ Dong</name>
<email>122852285+tj-dong@users.noreply.github.com</email>
</author>
<published>2026-06-22T23:55:20+00:00</published>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/sz-chrome-remote-extension.git/commit/?id=b8165967408be47e93b6a566270988177f8f6866'/>
<id>urn:sha1:b8165967408be47e93b6a566270988177f8f6866</id>
<content type='text'>
Stop pi-chrome from hijacking the user's active tab. Page/navigation actions
with no explicit target now route to a dedicated automation window owned by the
calling Pi session (falling back to a dedicated tab if a window can't be made),
instead of overwriting whatever the user has open.

- Session-scoped ownership: Map&lt;sessionKey, target&gt; in the service worker, keyed
  by a sessionKey forwarded from index.ts, so concurrent sessions (one shared
  extension) never fight over a window or close each other's tabs.
- Persistence: ownership mirrored to chrome.storage.session so a service-worker
  restart re-hydrates and reuses the window instead of orphaning it. Cleared on
  full browser restart; restored windows are then left alone (never reclaimed).
- getTabByParams default branch resolves the owned target; tab.activate/close/
  group/ungroup pass createOwnedTarget:false so management never auto-creates a
  throwaway tab or falls back to the user's active tab.
- Session-group integration: the dedicated-window tab still joins this session's
  tab group, in its own window; grouping stays best-effort.
- Lifecycle: cleanup on /chrome revoke and real session end (not /reload);
  fire-and-forget so it never blocks /quit, /reload, or shutdown.
- Tests: new test-suite/unit/automation-target.test.mjs (isolation, reuse,
  concurrency, restart/reconnect re-hydration, guarded tab.*, group integration,
  window-&gt;tab fallback, robust cleanup). Docs + CHANGELOG updated.</content>
</entry>
<entry>
<title>0.15.29: CSP bypass via CDP Runtime.evaluate for evaluate/snapshot/waitFor/initScript</title>
<updated>2026-05-31T18:19:04+00:00</updated>
<author>
<name>Tianren Dong</name>
<email>tianrendong.dtr@gmail.com</email>
</author>
<published>2026-05-31T18:19:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/sz-chrome-remote-extension.git/commit/?id=d21ebf7b96c90943ab48ffcd6d5b02c6f7438c04'/>
<id>urn:sha1:d21ebf7b96c90943ab48ffcd6d5b02c6f7438c04</id>
<content type='text'>
- evaluateInTab/executeInTab now run through CDP Runtime.evaluate instead of
  new Function() in MAIN world, so chrome_evaluate/chrome_snapshot work on pages
  that block unsafe-eval (github.com, many bank/SaaS apps). Preserves value
  markers (undefined/function/symbol/bigint/Error), DOMRect expansion, and the
  expression/statement fallback; keeps {ok,value} error envelope.
- page.waitFor polls via service-worker-side CDP evaluation.
- chrome_navigate initScript uses Page.addScriptToEvaluateOnNewDocument.
- Add npm test (test-suite/unit/csp-eval.test.mjs) and in-browser regression
  challenge 42 strict-csp-evaluate; update challenge 39 notes + docs/primer.
</content>
</entry>
<entry>
<title>0.15.26: update docs for benchmark gates</title>
<updated>2026-05-16T18:12:13+00:00</updated>
<author>
<name>Tianren Dong</name>
<email>tianrendong.dtr@gmail.com</email>
</author>
<published>2026-05-16T18:12:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/sz-chrome-remote-extension.git/commit/?id=0c3613891604d10e332d31762c9c3345c357a3bb'/>
<id>urn:sha1:0c3613891604d10e332d31762c9c3345c357a3bb</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Revert 0.16.x and 0.17.x: restore tree to v0.15.20 state</title>
<updated>2026-05-16T17:13:48+00:00</updated>
<author>
<name>Tianren Dong</name>
<email>tianrendong.dtr@gmail.com</email>
</author>
<published>2026-05-16T17:13:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/sz-chrome-remote-extension.git/commit/?id=b2ca8f8c343281c0263bda4c043cbe7f0d7d442e'/>
<id>urn:sha1:b2ca8f8c343281c0263bda4c043cbe7f0d7d442e</id>
<content type='text'>
Reverts the pairing + signed-envelopes work (0.16.0-0.16.1), the
standalone daemon refactor (0.17.0-0.17.3), and assorted patches.
These were unpublished from npm; this commit restores the working
tree to match the v0.15.20 release so the branch tip and the npm
'latest' dist-tag are consistent again.

Tags v0.16.0 through v0.17.3 are preserved as recovery anchors;
the work is reachable via 'git checkout v0.17.3' if ever needed.

Tree-equivalent to v0.15.20.
</content>
</entry>
<entry>
<title>0.17.0: standalone daemon, no more owner-vs-client topology</title>
<updated>2026-05-16T16:46:57+00:00</updated>
<author>
<name>Tianren Dong</name>
<email>tianrendong.dtr@gmail.com</email>
</author>
<published>2026-05-16T16:46:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/sz-chrome-remote-extension.git/commit/?id=2ac665ec31fe156b372540e8ac38aa42765b3001'/>
<id>urn:sha1:2ac665ec31fe156b372540e8ac38aa42765b3001</id>
<content type='text'>
The Chrome bridge is now a separate detached daemon at
~/.cache/pi-chrome/&lt;version&gt;/daemon.cjs. Every Pi session is a uniform client;
daemon lifecycle is decoupled from any Pi session. Killing a Pi never breaks
Chrome control, and pi update followed by any new Pi session auto-replaces
an incompatible daemon.

Architecture:
- New extensions/chrome-profile-bridge/daemon.cjs: ~700 LOC, zero deps, runs
  detached. Owns the HTTP listener, BridgeAuth state, command queue, /pair
  handshake. Idle-shuts-down after 10 min of no activity.
- ChromeProfileBridge on Pi side becomes a pure client: start() probes /status,
  spawns daemon if missing/incompatible, kills+respawns if version mismatch.
  send() always uses signed /command. No more server-mode branch.
- New signed /admin RPC for pair-window/reset/status state mutations the
  daemon owns. Pi clients sign with broker key (same contract as /command).
- New /heartbeat for daemon idle-timer keepalive.
- daemon.log at ~/.cache/pi-chrome/&lt;version&gt;/daemon.log.

/chrome pair, /chrome unpair, /chrome onboard now go through /admin RPCs
instead of mutating in-process bridge state.

Removed the foreign-owner takeover dance from /chrome onboard (auto-handled
at session_start now).

Wire protocol is byte-identical to 0.16.x; existing paired extensions don't
need to re-pair. See docs/DESIGN-0.17-daemon.md for the full write-up.
</content>
</entry>
</feed>
