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 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: don't steal focus
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
- - Run-in-background optional; tab/window focus is observable by default (the user can see Pi acting).
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
 
@@ -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 only calling session's own target, never user tabs/windows or other sessions' targets.
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
- By default, chrome calls run in background so Chrome does not steal focus.
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 # background mode
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
- Per-call `background: false` brings Chrome forward for that action. Per-call `background: true` forces background.
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
 
@@ -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 **42 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.
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
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "manifest_version": 3,
3
3
  "name": "Pi Chrome Connector",
4
- "version": "0.15.46",
4
+ "version": "0.15.48",
5
5
  "description": "Lets Pi control tabs in Chrome via a local connector at 127.0.0.1.",
6
6
  "permissions": [
7
7
  "tabs",