aboutsummaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2026-06-22Keep Pi-created tabs in one session groupTianren Dong
2026-06-220.15.39: dedicated pi-chrome automation tab/window isolation (#6)TJ Dong
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<sessionKey, target> 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->tab fallback, robust cleanup). Docs + CHANGELOG updated.
2026-06-08feat: show remaining auth time in Chrome Bridge status bar (#5)TJ Dong
* 0.15.36: richer chrome_snapshot + chrome_find/chrome_inspect (ported from foxfirecodes fork) - chrome_snapshot returns a concise observation (layout, hints, actions, forms, page map, query matches, diff) with mode/query/maxTextChars params - new chrome_find (query -> ranked uids) and chrome_inspect (deep element context, with page.inspect fallback) - includeSnapshot on click/type/fill/key now embeds the formatted snapshot - snapshot/inspect logic shipped as eval-free packaged snapshot_injected.js, sharing window.__PI_CHROME_STATE__ (el- uid scheme) with existing input helpers * feat: show remaining auth time in Chrome Bridge status bar Before: ● Chrome Bridge After: ● Chrome Bridge (14m) ● Chrome Bridge (indefinite) Changes: - authCountdownLabel() computes remaining minutes from chromeAuthorizedUntil - updateChromeStatus appends the label to the status line - startCountdownTicker() runs setInterval every 60s to refresh the display while a timed authorization is active; no-ops for indefinite auth - clearCountdownInterval() called in lockChromeControl and session_shutdown so no interval leaks on revoke or reload - scheduleAuthExpiry calls startCountdownTicker so the ticker starts whenever authorization is granted or restored after /reload --------- Co-authored-by: Tianren Dong <tianrendong.dtr@gmail.com>
2026-06-070.15.38: harden chrome input overlay handlingTianren Dong
2026-06-070.15.37: harden Chrome input targetingTianren Dong
2026-06-070.15.37: clarify README installation instructions (#4)Tianren Dong
2026-06-07Clarify README installation instructions (#4)TJ Dong
2026-06-060.15.36: richer chrome_snapshot + chrome_find/chrome_inspectTianren Dong
- chrome_snapshot returns a concise observation (layout, hints, actions, forms, page map, query matches, diff) with mode/query/maxTextChars params - new chrome_find (query -> ranked uids) and chrome_inspect (deep element context, with page.inspect fallback) - includeSnapshot on click/type/fill/key now embeds the formatted snapshot - snapshot/inspect logic shipped as eval-free packaged snapshot_injected.js, sharing window.__PI_CHROME_STATE__ (el- uid scheme) with existing input helpers
2026-06-010.15.35: persist /chrome authorize grant across /reload (re-register ↵Tianren Dong
chrome_* tools on session_start)
2026-06-010.15.34: tabs Pi uses join session group; fix punctuation dropped by ↵Tianren Dong
chrome_type/chrome_key (US-layout keymap)
2026-05-310.15.33: default background mode on (chrome_* run without focusing Chrome)Tianren Dong
2026-05-310.15.32: session tab-group title uses 'Pi Session: <name-or-id>' (colon)Tianren Dong
2026-05-310.15.31: per-session tab groups named 'Pi Session <name-or-id>'Tianren Dong
2026-05-310.15.30: chrome_tab grouping — auto-group Pi tabs, group/ungroup actions, ↵Tianren Dong
merge by title
2026-05-310.15.29: CSP bypass via CDP Runtime.evaluate for ↵Tianren Dong
evaluate/snapshot/waitFor/initScript - 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.
2026-05-310.15.28: bridge self-heal, timeout diagnostics, pressKeyInPage helper, ↵Tianren Dong
DOMRect serialization, stale-target errors, pageMutated wording
2026-05-17chore: release v0.15.27Tianren Dong
2026-05-17chore: standardize gitignoreTianren Dong
2026-05-160.15.26: update docs for benchmark gatesTianren Dong
2026-05-160.15.25: fix reload after stale singletonTianren Dong
2026-05-160.15.24: unload Chrome tools when lockedTianren Dong
2026-05-160.15.23: attribute fork featuresTianren Dong
2026-05-160.15.22: pull fork improvementsTianren Dong
2026-05-16feat: lazy-register chrome tools until /chrome authorizeDani Bednarski
Defer all pi.registerTool() calls until /chrome authorize fires. Previously, 18 chrome_* tool definitions + chrome-profile-bridge primer consumed ~5K tokens/turn even when Chrome control locked. Changes: - Add chromeToolsRegistered flag (default false) - Wrap all pi.registerTool() calls in registerChromeTools(pi) - Only register tools when authorizeFor() runs - Make before_agent_start conditional: primer injected only when tools registered AND authorized - No tools exist in context until user explicitly allows it Saves ~5,000 tokens/turn when Chrome control is locked.
2026-05-16silence startup notify + dynamic status barDani Bednarski
- Remove startup notification about companion extension - Remove static 'Chrome bridge :17318' status bar entry - Add updateChromeStatus() helper: shows green dot + 'Chrome Bridge' only when authorized, clears otherwise - Call from session_start, authorizeFor, revokeHandler
2026-05-16fix: capture early console/network messages at document_startDani Bednarski
Adds an early-capture script injected at document_start on every navigation via webNavigation.onCommitted + injectImmediately:true. Wraps console.*, fetch, and XMLHttpRequest before page JS runs, so console messages, errors, unhandled rejections, and network requests during page load are captured in window.__PI_CHROME_STATE__. Sets __piChromeWrapped flags so the existing post-hoc installPiChromeInstrumentation() is idempotent (checks instrumentationInstalled). Fixes chrome_list_console_messages returning empty for errors that fire during React render / initial API calls.
2026-05-160.15.21: version bumpTianren Dong
Tree-equivalent to v0.15.20 (preceded by the revert commit). Bumping to 0.15.21 sets the package up for normal patch releases on the 0.15.x line going forward — no version-number collisions with the unpublished 0.16/0.17 work.
2026-05-16Revert 0.16.x and 0.17.x: restore tree to v0.15.20 stateTianren Dong
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.
2026-05-160.17.3: daemon self-heal on missing-daemon fetch failureTianren Dong
In 0.17.x the daemon is a separate process that can idle-shut-down (10 min idle) or be killed externally while Pi sessions are running. Without self-heal, the next /chrome onboard or chrome_* call surfaces 'fetch failed' instead of recovering. bridge.admin() now catches the failed fetch, re-runs ensureDaemonRunning (probe -> spawn if missing), and retries once. bridge.sendViaOwner() pre-probes /status and spawns the daemon if missing before issuing the signed /command. Net effect: a missing daemon transparently respawns instead of bubbling fetch failed up to the user.
2026-05-160.17.2: fix /next lastSeenAt + strict daemon version matchTianren Dong
Bugs surfaced in real-world 0.17.0/0.17.1 testing: 1. Daemon /next only recorded lastSeenAt AFTER the auth/pair checks. Pre-pair the daemon returns needsPairing early without recording the poll, so connected stayed false even though the extension was polling. /chrome onboard's wait-for-poll loop spun forever on a healthy extension. Fix: record lastSeenAt at the top of /next for any chrome-extension origin, before auth checks. Onboard now correctly detects 'extension alive but unpaired' which is the precise state during pair step. 2. Daemon compatibility was checked at major.minor match. Result: a patch release fixing a daemon bug (like #1) couldn't replace the running daemon — new Pi client joins old buggy daemon as client. Fix: exact version match. Patch releases auto-kill+respawn the daemon.
2026-05-160.17.1: fix /chrome onboard stuck on 'Waiting for the extension to wake up'Tianren Dong
0.17.0 made the daemon own the HTTP listener, but the Pi client's bridge.status().connected still reflected the local Pi's lastSeenAt (which is never updated in the daemon model). Onboard's connect-wait loop spun forever even when the extension was polling the daemon. Fix: new ChromeProfileBridge.daemonStatus() async helper that fetches the daemon's /status. onboard, doctor, and status now query that for the 'connected' flag instead of reading stale Pi-side state.
2026-05-160.17.0: standalone daemon, no more owner-vs-client topologyTianren Dong
The Chrome bridge is now a separate detached daemon at ~/.cache/pi-chrome/<version>/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/<version>/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.
2026-05-160.16.1: idempotent /chrome onboard + automatic stale-owner takeoverTianren Dong
User pain: machines stuck in broken state after pi-chrome upgrades because an old pi-chrome process kept holding :17318 and /chrome onboard trusted confirm() clicks without verifying anything. Both fixed. Idempotent /chrome onboard recovery flow: - Always resets Pi-side pairing state first (kills half-paired ghosts). - Step 1 covers both first-install AND v0.15->v0.16 reload (extension service worker must reload to gain the /pair logic). - Actively verifies progress at each step rather than trusting clicks: - polls bridge.status().connected (15s window) to confirm the extension polls /next, - polls bridge.bridgeAuth.paired to confirm the /pair handshake completed, - round-trips a real tab.version command to confirm the signed-envelope path works. - /chrome install is now an alias of /chrome onboard. Automatic stale-owner takeover at bridge.start(): - /status now includes bridgeVersion. - On EADDRINUSE, probe /status with 1s timeout. If unresponsive OR major.minor mismatches, locate the owner PID via lsof and kill it (SIGTERM -> SIGKILL), then re-bind. Same-version owners are joined as clients (multi-Pi sharing). - Eliminates the 'stale Pi session holding bridge' class of bugs that broke upgrades from 0.15.x. /chrome status / doctor / onboard no longer hang: - New probeExtension() short-circuits before bridge.send when the bridge can't round-trip (unpaired, or extension hasn't polled recently). Returns immediately with an actionable message instead of waiting 5-35s.
2026-05-160.16.0: mandatory pairing + signed envelopes + cross-process state coherenceTianren Dong
Major security hardening of the Chrome bridge driven by red-team findings. - Mandatory pairing via /chrome onboard (one-time per machine). Bridge pins exact chrome-extension:// origin and derives HMAC keys via HKDF. Until paired, the bridge returns idle responses and refuses to deliver commands. - Signed envelopes on /next, /result, /command. HMAC-SHA256 over protocol version, direction, method, path, extension ID, bridge ID, timestamp, fresh nonce, and SHA-256 of the body. +/-30s clock window; 5-min LRU nonce replay defense on both request and response directions; constant-time MAC compare. - Peer Pi sessions sharing the bridge sign each /command with a broker HKDF key (no bearer token transmitted) and verify the owner's signed response. - Global loopback enforcement. PI_CHROME_BRIDGE_HOST=0.0.0.0 ignored unless PI_CHROME_BRIDGE_DANGEROUS_REMOTE=1; loopback check still applies per-endpoint. - Cross-process state coherence: fs.watch + per-request mtime check on ~/.config/pi/chrome-bridge.json. A peer Pi's unpair (or any external rm/edit) propagates to the owner's in-memory state before the next privileged verify; replay caches reset on key rotation. - Body cap 1 MiB -> 413. Queue/pending/waiter caps. Malformed JSON -> 400. Non-object JSON bodies -> 400 instead of being trusted. - page.navigate initScript: try/finally around tabs.update, per-call onCommitted listener with bounded commit-wait window, one-shot delete in global onCommitted. No more stale init scripts firing on later unrelated navigations. - crypto.randomUUID() command IDs. - Manifest diet (dropped activeTab); added popup.html/popup.js for the pair UI. UX: - /chrome onboard runs install + pair in one interactive flow. - /chrome help reorganized into First-time / Day-to-day / Maintenance. - Status bar lights up as green dot only when authorized. - Early console/network capture at document_start so boot-time React errors and initial API calls aren't dropped (ported from DaniBedz/pi-chrome fork). Docs: - SECURITY.md threat model rewritten with in-scope / out-of-scope sections. - README rewritten with the install-then-pair flow front and center. - CHANGELOG 0.16.0 entry with full patch list.
2026-05-16Make chrome_* tools interruptible via AbortSignal (#1)Tianren Dong
Thread the harness AbortSignal through authorizedBridgeSend, the ChromeProfileBridge send/sendLocal/sendViaOwner paths, and every chrome_* tool's execute(). Pressing Esc now rejects the in-flight bridge call immediately (most visibly fixing chrome_wait_for, which would otherwise block for the full timeoutMs).
2026-05-15Clear pi-chrome singleton on shutdownTianren Dong
2026-05-14Simplify package descriptionTianren Dong
2026-05-14Refine package descriptionTianren Dong
2026-05-14Audit pi-chrome docsTianren Dong
2026-05-14Show Chrome connection check stateTianren Dong
2026-05-14Remove maintainer notesTianren Dong
2026-05-14Restore terminal Chrome authorizationTianren Dong
2026-05-13pi-chrome 0.15.2: recipe prompts in user-language (no tool names)Tianren Dong
2026-05-13pi-chrome 0.15.1: ASCII architecture diagram + author object formTianren Dong
2026-05-13pi-chrome 0.15.0: README rewrite — top-3 recipes, sharper comparison ↵Tianren Dong
table, section reorder
2026-05-13pi-chrome 0.14.9: trusted-mode primer + auto-sync manifest versionTianren Dong
- Primer teaches agents the trusted:true escape hatch for CSP-locked pages (github.com, banks, many SaaS) where chrome_evaluate/chrome_snapshot throw EvalError due to missing 'unsafe-eval'. Agents now self-escalate instead of giving up and asking the user. - Corrects stale primer claim that chrome_evaluate works without 'unsafe-eval'. - scripts/sync-manifest-version.js wired to npm version + prepublishOnly lifecycle hooks; kills the recurring browser-extension manifest version drift (cf. 0.14.4, 0.14.8).
2026-05-13pi-chrome 0.14.8: bump version + CHANGELOG for standalone repo moveTianren Dong
2026-05-13Migrate to standalone repo: update URLstianrendong
2026-05-13pi-chrome: snapshot pre-migration stateTianren Dong
2026-05-13pi-chrome: remove obsolete REBUILD-NOTES.mdTianren Dong
Internal scratch notes from an earlier rebuild; no external references. docs/, CHANGELOG.md, CONTRIBUTING.md, and README.md cover the same ground for the current shape of the package.