pi-chrome 0.15.46 → 0.15.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/CONTRIBUTING.md +4 -0
- package/README.md +9 -1
- package/SECURITY.md +1 -1
- package/docs/ARCHITECTURE.md +20 -5
- package/docs/COMPARISON.md +1 -1
- package/extensions/chrome-profile-bridge/browser-extension/manifest.json +1 -1
- package/extensions/chrome-profile-bridge/browser-extension/service_worker.js +202 -102
- package/extensions/chrome-profile-bridge/index.ts +115 -119
- package/package.json +2 -2
- package/test-suite/README.md +9 -0
- package/test-suite/challenges/43-hard-background.html +42 -0
- package/test-suite/manifest.json +75 -0
- package/test-suite/unit/automation-target.test.mjs +109 -2
- package/test-suite/unit/background-policy.test.mjs +469 -0
- package/test-suite/unit/session-cleanup.test.mjs +93 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
All notable user-facing changes to `pi-chrome`.
|
|
4
4
|
|
|
5
|
+
## 0.15.48 — 2026-09-09
|
|
6
|
+
|
|
7
|
+
- **Existing background mode is now hard background.** `/chrome background on` (still the default) overrides per-call foreground requests, keeps new tabs inactive, and blocks `chrome_tab activate`. Use the existing `/chrome background off` for foreground/watch mode; no new command or lock state.
|
|
8
|
+
- **Screenshots without tab activation.** PNG/JPEG and full-page tiles use CDP instead of `captureVisibleTab`. Debugger/capture failures never fall back to switching tabs. Old companions reject background creation/capture with a reload instruction. Screenshot tools now require debugger access.
|
|
9
|
+
- **Trusted input preserved.** Background policy does not replace Chrome input with synthetic events. It blocks explicit focus/activation, not page/native/Chrome/OS side effects; inactive-page rendering and focus-gated workflows can still vary by environment.
|
|
10
|
+
- **Regression coverage.** Added policy/worker/screenshot unit tests and challenge 43 for inactive-tab visibility plus trusted input. Full-page capture restores both scroll axes best-effort after success or failure.
|
|
11
|
+
- **Live validation and unresolved limitation.** Chrome 152/macOS checks passed for inactive tab creation, blocked activation, background PNG/JPEG/full-page capture, and scroll restoration. The trusted-click check encountered debugger detachment, then a visibility failure on retry; the cause remains unresolved and human interference was not ruled out. This release does not promise zero focus changes during trusted input. Chrome-behind-another-app and macOS Spaces behavior remain unverified.
|
|
12
|
+
|
|
13
|
+
## 0.15.47 — 2026-09-09
|
|
14
|
+
|
|
15
|
+
- **Bounded session cleanup.** On exit, Pi waits up to two seconds for cleanup before stopping the bridge. Reload preserves browser resources; revoke remains non-blocking.
|
|
16
|
+
- **Track every created tab.** Cleanup closes session-created tabs and ungroups adopted user tabs only if they remain in the group Pi assigned. Ownership survives service-worker restarts; failed removals remain tracked for retry.
|
|
17
|
+
- **Mixed-window safety.** Cleanup removes individual owned tabs, never whole windows. User tabs moved into a Pi window, and other sessions' tabs sharing that window, remain open.
|
|
18
|
+
|
|
5
19
|
## 0.15.40 — 2026-06-22
|
|
6
20
|
|
|
7
21
|
- **Automation targets reuse the session tab group.** When `chrome_navigate` / implicit page actions create a new pi-chrome automation tab, it is now created in this session's existing tab-group window when possible and joins that same group, avoiding duplicate same-title `Pi Session: ...` groups.
|
package/CONTRIBUTING.md
CHANGED
|
@@ -15,6 +15,10 @@ Thanks for considering a contribution. pi-chrome aims to be the **de-facto brows
|
|
|
15
15
|
# Link from a checkout
|
|
16
16
|
pi install ./pi-chrome
|
|
17
17
|
|
|
18
|
+
# Run unit regressions (Node.js 22.13+; no live Chrome required)
|
|
19
|
+
# Lifecycle tests use Node's built-in TypeScript stripping.
|
|
20
|
+
npm test
|
|
21
|
+
|
|
18
22
|
# Run the benchmark dashboard
|
|
19
23
|
cd test-suite
|
|
20
24
|
python3 -m http.server 8765
|
package/README.md
CHANGED
|
@@ -108,13 +108,21 @@ Security details: [`SECURITY.md`](./SECURITY.md). Architecture details: [`docs/A
|
|
|
108
108
|
/chrome status # connection + auth + background state
|
|
109
109
|
/chrome authorize [duration]
|
|
110
110
|
/chrome revoke
|
|
111
|
-
/chrome background on # default:
|
|
111
|
+
/chrome background on # default: hard background policy
|
|
112
112
|
/chrome background off # foreground/watch mode
|
|
113
113
|
/chrome background status
|
|
114
114
|
```
|
|
115
115
|
|
|
116
116
|
If loaded extension is older than installed `pi-chrome`, `/chrome doctor` tells you to reload it from `chrome://extensions`.
|
|
117
117
|
|
|
118
|
+
### Background policy
|
|
119
|
+
|
|
120
|
+
`/chrome background on` is enforced, not an overridable default. Per-call `background:false` cannot bring Chrome forward, new tabs stay inactive, and `chrome_tab activate` is blocked. Use the existing `/chrome background off` for foreground/watch mode; per-call `background:true` still works when that mode is off.
|
|
121
|
+
|
|
122
|
+
Screenshots use CDP without activating background tabs. Debugger/capture failures return errors, never an activation fallback. Reload both Pi and the Chrome companion after upgrading; old companions reject background tab creation/screenshots rather than silently switching tabs.
|
|
123
|
+
|
|
124
|
+
This prevents explicit pi-chrome focus/activation, not every Chrome/OS side effect. Trusted input, page popups, native prompts, debugger banners, and macOS Spaces can still affect focus. Inactive pages may throttle rendering or reject focus-gated actions. See [scope and risks](./docs/ARCHITECTURE.md#scope-and-risks).
|
|
125
|
+
|
|
118
126
|
---
|
|
119
127
|
|
|
120
128
|
## Limits
|
package/SECURITY.md
CHANGED
|
@@ -27,7 +27,7 @@ The Chrome extension under `extensions/chrome-profile-bridge/browser-extension/`
|
|
|
27
27
|
- Loopback bridge only. No remote port. No telemetry.
|
|
28
28
|
- Chrome real input layer for interactive controls.
|
|
29
29
|
- Chrome control locked by default; `/chrome authorize` unlocks current Pi session after terminal confirmation, `/chrome revoke` locks it again.
|
|
30
|
-
-
|
|
30
|
+
- Hard background mode is on by default: tools cannot override it to explicitly focus windows or activate tabs. `/chrome background off` allows foreground/watch mode. This is not a security sandbox: trusted input, page scripts, native prompts, and Chrome/OS behavior can still affect focus.
|
|
31
31
|
|
|
32
32
|
## Custom ports
|
|
33
33
|
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -30,7 +30,10 @@ Each Pi session owns its own automation target:
|
|
|
30
30
|
- If separate window cannot be created, pi-chrome falls back to dedicated tab.
|
|
31
31
|
- Target survives `/reload` and Chrome service-worker restarts.
|
|
32
32
|
- Ownership is tracked by id and mirrored to `chrome.storage.session`.
|
|
33
|
-
- Cleanup closes
|
|
33
|
+
- Cleanup closes calling session's automation target and every tab it created through `tab.new`.
|
|
34
|
+
- Existing user tabs adopted into a session group are preserved, and ungrouped only if still in that group.
|
|
35
|
+
- Cleanup removes individual owned tabs, never whole windows. User/other-session tabs moved into a Pi window remain open; Chrome closes a window automatically when its final tab is removed.
|
|
36
|
+
- Shutdown waits at most two seconds for cleanup before stopping the bridge. `/reload` preserves resources; revoke starts cleanup without blocking. Hard process termination or unavailable Chrome can still leave owned tabs open.
|
|
34
37
|
|
|
35
38
|
To point pi-chrome at an existing tab, pass `targetId`, `urlIncludes`, or `titleIncludes`.
|
|
36
39
|
|
|
@@ -43,14 +46,26 @@ To point pi-chrome at an existing tab, pass `targetId`, `urlIncludes`, or `title
|
|
|
43
46
|
|
|
44
47
|
## Background mode
|
|
45
48
|
|
|
46
|
-
|
|
49
|
+
The existing background setting is a hard session policy, enabled by default. No separate lock/unlock command is needed.
|
|
47
50
|
|
|
48
51
|
```text
|
|
49
|
-
/chrome background on #
|
|
50
|
-
/chrome background off # foreground/watch mode
|
|
52
|
+
/chrome background on # enforce no explicit window focus/tab activation
|
|
53
|
+
/chrome background off # allow foreground/watch mode
|
|
51
54
|
```
|
|
52
55
|
|
|
53
|
-
|
|
56
|
+
- With background on, per-call `background:false` and legacy `foreground:true` cannot override the policy. `chrome_tab activate` errors with instructions to ask the user to turn background off.
|
|
57
|
+
- With background off, calls may focus Chrome; per-call `background:true` still avoids explicit focus/tab activation.
|
|
58
|
+
- Policy is applied in `authorizedBridgeSend` for every tool, including `chrome_launch(url)`, tab creation, and tools without a background parameter. Each session sends its own effective `background`/`foreground` flags through the shared bridge.
|
|
59
|
+
- All worker window-focus/tab-activation writes go through a guarded helper. Background tab creation uses `active:false`; implicit automation windows remain `focused:false`.
|
|
60
|
+
- Screenshots use CDP `Page.captureScreenshot` with `fromSurface:true` and `captureBeyondViewport:false`. They target a tab, not whichever tab happens to be visible. There is no `captureVisibleTab`/activation fallback on debugger or capture failure. PNG/JPEG output is unchanged; full-page capture retains tiles plus a JSON manifest and restores scroll position best-effort, including on failure.
|
|
61
|
+
- Background tab creation and screenshots use internal `tab.new.background` / `page.screenshot.background` wire actions. Old companions reject them before changing tabs; Pi reports a reload instruction instead of retrying an unsafe legacy action. No capability-probe race or extra round trip is needed.
|
|
62
|
+
- Real CDP input and existing explicit DOM-fallback controls are unchanged. Background mode never silently substitutes synthetic input to avoid focus.
|
|
63
|
+
|
|
64
|
+
### Scope and risks
|
|
65
|
+
|
|
66
|
+
This is a policy against **explicit pi-chrome focus/activation**, not an OS focus sandbox. Page scripts (`window.open`, `window.focus`), trusted input, native dialogs, debugger banners, Chrome window/Spaces behavior, and closing an active tab can still change focus or selection. Other sessions and human actions remain independent. Requests already dispatched before a mode change keep their earlier policy.
|
|
67
|
+
|
|
68
|
+
Inactive/minimized tabs can throttle timers or rendering, and clipboard/fullscreen/other focus-gated workflows may fail. Screenshots now require debugger attachment, which can conflict with DevTools or other extensions; hidden-tab rendering can differ or be unavailable. No automatic foreground retry is allowed. Full-page capture temporarily scrolls the target page. Reload both Pi and the Chrome companion after upgrading, and live-test tab selection, OS focus, and screenshot fidelity on supported Chrome/OS versions.
|
|
54
69
|
|
|
55
70
|
## Authorization
|
|
56
71
|
|
package/docs/COMPARISON.md
CHANGED
|
@@ -134,7 +134,7 @@ If your threat model excludes extensions with broad permissions, neither approac
|
|
|
134
134
|
|
|
135
135
|
## Public benchmarks worth knowing (for axis 2 / axis 3 comparison)
|
|
136
136
|
|
|
137
|
-
Pi-chrome itself ships a benchmark suite ([`../test-suite/`](../test-suite)) of **
|
|
137
|
+
Pi-chrome itself ships a benchmark suite ([`../test-suite/`](../test-suite)) of **43 primitive challenges** plus **4 hermetic BrowserGym-style long-horizon tasks** covering trusted input, pointer humanization, keyboard fidelity, drag/drop, Shadow DOM, iframes, file uploads, strict-CSP screenshot fallback and CDP eval/snapshot bypass, dynamic waits, tab lifecycle, network observability, fingerprint leaks, and agent-safety honeypots. Scoring tracks expected outcomes per challenge instead of raw PASS count, with `core`, `conditional`, and `quality` gate buckets. That's **driver-level** grading.
|
|
138
138
|
|
|
139
139
|
For **agent-level** comparison (axis 2), the public benchmarks worth citing:
|
|
140
140
|
|