| Age | Commit message (Collapse) | Author |
|
The grant lives on globalThis so /reload keeps it, but nothing cleared it
when pi replaced the session in the same process. After /new, /resume or
/fork the next session started authorized and announced it in the footer.
Drop the saved grant on session_shutdown for new, resume and fork. Reload
keeps it. Quit leaves it alone, so a subagent quitting in the same process
does not take its parent's grant with it.
grant-scope.test.mjs loads the shipped module once per runtime in one
shared context, the way pi keeps globalThis across reloads and switches,
and checks the tools and the footer after each. It fails on 85b4988, and
its /chrome authorize cases fail with only the PI_CHROME_AUTHORIZE fix.
|
|
The env grant was saved to globalThis like a /chrome authorize grant. After
a /reload or a session switch (/resume, /fork, /new) the new runtime restored
it, skipped the env branch, and left envGranted false, so the footer
announced a grant the user never gave.
Read the variable again on each session_start instead of persisting it.
A restored grant now always comes from /chrome authorize. A timed env grant
restarts its countdown on each reload or switch.
|
|
A standing PI_CHROME_AUTHORIZE is not session state worth a line at the
bottom of every session that has it; announce only access the user granted
through /chrome authorize.
|
|
PI_CHROME_REMOTE=host:port sends every command to a broker/broker.mjs there,
with its bearer token, instead of binding a bridge on this machine. Unset, the
extension behaves as upstream. A remote session never binds or takes over a
port: when the broker is unreachable the tools fail rather than drive some
other browser.
A pi-chrome-remote prompt section says which browser chrome_* drives and how
files move to and from its host; chrome_upload_file wants absolute paths there.
PI_CHROME_AUTHORIZE grants every session up front.
|
|
|
|
0.15.54 opened Pi's automation target as a tab in the user's window while it
was full screen, assuming macOS would merge a new window into it as a hidden
window tab. Chrome disables automatic window tabbing (app_controller_mac.mm),
so that never happens; the hidden tabs came from the tab-group bug fixed in
0.15.56. Always prefer Pi's own window.
|
|
Chrome ignores clicks and typing in hidden pages. Doctor now asks the worker
whether this session's own tab is visible (automation.status includeVisibility,
which never creates or activates a tab) and reports the reason and fix when it
is hidden.
|
|
storage.session is wiped when the extension reloads, which it does on every
pi-chrome update, so Pi lost track of its automation window and session tabs
and left them behind. Mirror ownership to storage.local, restore it only when
the session copy is missing, re-check every restored tab (same window; adopted
tabs still in Pi's group), and drop the local copy on browser startup.
|
|
chrome.tabs.group without createProperties.windowId creates the group in the
current (user's) window and moves the tab there, so a session's automation tab
left its dedicated window and became a hidden inactive tab. Make the unit mock
match Chrome's behavior.
|
|
|
|
chrome_fill's triple-click selected one line of a multi-line textarea, so fill
replaced only that line. Select value fields with the selectAll editing command
before deleting. Early capture now waits for in-flight tab.new creations, so a
first page that commits before the tab is tracked is still captured.
|
|
|
|
- Contribute the primer as a structured prompt section instead of forcing systemPrompt.
- Log pi-chrome-tool-change as a rendered custom entry that is not sent to the model.
|
|
to Pi tabs
Fixes #9. Sites like BOSS Zhipin log an object with a getter/toString trap and
close the tab if it is read. Store captured console args raw and serialize them
on read without running page code (data properties only, accessors as [getter],
built-ins via native getters). Inject document-start capture only into Pi's
automation tab and session-tracked tabs.
|
|
screenshots; release 0.15.54
- 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.
|
|
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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.
|
|
* 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>
|
|
|
|
|
|
|
|
- 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
|
|
chrome_* tools on session_start)
|
|
chrome_type/chrome_key (US-layout keymap)
|
|
|
|
|
|
|
|
merge by title
|
|
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.
|
|
DOMRect serialization, stale-target errors, pageMutated wording
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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.
|