pi-chrome 0.3.1 → 0.4.0
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/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# pi-chrome
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/pi-chrome)
|
|
4
|
+
|
|
3
5
|
Control the Chrome profile you already use from Pi.
|
|
4
6
|
|
|
5
7
|
`pi-chrome` gives Pi agents browser tools for your **real Chrome windows, tabs, and authenticated sessions**. It uses a companion Chrome extension instead of the Chrome DevTools Protocol (CDP), so it does not launch a throwaway debug browser profile and does not require re-signing into the apps you already have open.
|
|
@@ -9,8 +11,8 @@ Multiple Pi sessions can use Chrome at the same time. The first Pi session start
|
|
|
9
11
|
## Why try it?
|
|
10
12
|
|
|
11
13
|
- **Uses your existing Chrome profile** — works with the Chrome windows/tabs you are already using, including logged-in GitHub, admin dashboards, local apps, and internal tools.
|
|
14
|
+
- **Background by default** — agents can inspect, navigate, click, type, and snapshot without bringing Chrome to the foreground or interrupting whatever you are doing. Toggle for the whole session with `/chrome-foreground`, or pass `foreground: true` on a single tool call.
|
|
12
15
|
- **Full browser automation toolkit for Pi** — list/create/activate/close tabs, snapshot pages with usable CSS selectors, navigate, evaluate JavaScript, click, type, press keys, wait for page state, and capture screenshots.
|
|
13
|
-
- **Background by default** — agents can inspect, navigate, click, type, and snapshot without bringing Chrome to the foreground or interrupting whatever you are doing. Toggle for the whole session with `/chrome-foreground` (useful for demos, pair-driving, debugging) or pass `foreground: true` on a single tool call.
|
|
14
16
|
- **Built-in setup and agent guidance** — `/chrome-onboard` walks users through installing the companion extension, `/chrome-status` checks connectivity, screenshots save to disk, and the prompt primer tells agents to inspect with `chrome_snapshot` before acting and avoid destructive actions unless explicitly requested.
|
|
15
17
|
|
|
16
18
|
## Install
|
|
@@ -25,6 +27,10 @@ For local development from a checkout:
|
|
|
25
27
|
pi install ./pi-chrome
|
|
26
28
|
```
|
|
27
29
|
|
|
30
|
+
### Why an unpacked Chrome extension?
|
|
31
|
+
|
|
32
|
+
The Chrome Web Store does not allow extensions that talk to a local bridge controlled by another tool, so `pi-chrome` ships its companion as an unpacked extension you load yourself. The source is small, MIT-licensed, and lives in `extensions/chrome-profile-bridge/browser-extension/` next to this README — read it before loading.
|
|
33
|
+
|
|
28
34
|
## First-time setup
|
|
29
35
|
|
|
30
36
|
In Pi, run:
|
|
@@ -57,20 +63,68 @@ Performing Chrome bridge health check
|
|
|
57
63
|
Chrome profile bridge connected (ID: <chrome-extension-id>)
|
|
58
64
|
```
|
|
59
65
|
|
|
60
|
-
##
|
|
66
|
+
## Foreground control
|
|
67
|
+
|
|
68
|
+
By default, `chrome_*` tools act silently in the background — your editor or terminal keeps focus and Chrome does not pop up. This lets agents work alongside you without interrupting whatever you are doing.
|
|
61
69
|
|
|
62
|
-
|
|
70
|
+
When you want to watch the agent (demos, pair-driving, debugging), turn foreground on for the whole Pi session:
|
|
71
|
+
|
|
72
|
+
```text
|
|
73
|
+
/chrome-foreground # toggle
|
|
74
|
+
/chrome-foreground on # explicit
|
|
75
|
+
/chrome-foreground off # explicit
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
For a single tool call, the agent can pass `foreground: true` directly. The per-call value always wins over the session toggle.
|
|
79
|
+
|
|
80
|
+
## Quick demo prompts
|
|
81
|
+
|
|
82
|
+
After setup, try one of these in Pi:
|
|
83
|
+
|
|
84
|
+
Background inspection (no Chrome interruption):
|
|
85
|
+
|
|
86
|
+
```text
|
|
87
|
+
Inspect my active GitHub tab in the background with chrome_snapshot and summarize the PR state without focusing Chrome.
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Existing authenticated tab:
|
|
63
91
|
|
|
64
92
|
```text
|
|
65
93
|
Use chrome_tab list to find my existing GitHub tab, chrome_snapshot it, then summarize the visible PR state. Do not click anything yet.
|
|
66
94
|
```
|
|
67
95
|
|
|
68
|
-
|
|
96
|
+
Local web app repro with screenshot:
|
|
69
97
|
|
|
70
98
|
```text
|
|
71
99
|
Use chrome_tab list to find my localhost app, inspect it with chrome_snapshot, navigate through the bug repro flow, and save a screenshot when you reach the broken state.
|
|
72
100
|
```
|
|
73
101
|
|
|
102
|
+
## Recipes
|
|
103
|
+
|
|
104
|
+
Copy-paste these into Pi after setup. Each one uses tabs you already have open and accounts you are already signed into.
|
|
105
|
+
|
|
106
|
+
- **PR triage:** "Use chrome_tab list to find my GitHub notifications tab, snapshot it, and summarize PRs needing my review."
|
|
107
|
+
- **Linear standup:** "Open my Linear current cycle in the active tab, snapshot it, and write me a 5-bullet standup."
|
|
108
|
+
- **Bug repro with evidence:** "Open the staging app I'm already signed into, reproduce <bug>, and save a screenshot of each step under ./repro/."
|
|
109
|
+
- **Form auto-fill (no submit):** "Open <vendor> portal, fill the new-vendor form from this JSON, but stop before submit."
|
|
110
|
+
- **Admin cross-check:** "Across my Stripe / Postmark / our admin tabs, find any user where state disagrees."
|
|
111
|
+
- **Local dev visual diff:** "Snapshot localhost:3000 and the staging URL of the same page; tell me what's visually different."
|
|
112
|
+
- **Auth-only data pull:** "Open my analytics dashboard tab and chrome_evaluate to extract today's KPIs from the page state."
|
|
113
|
+
|
|
114
|
+
Screenshots save under `.pi/chrome-screenshots/` by default, which composes nicely with PR demo workflows.
|
|
115
|
+
|
|
116
|
+
## Diagnostics
|
|
117
|
+
|
|
118
|
+
- `/chrome-status` — quick health check; reports the connected Chrome extension ID and version.
|
|
119
|
+
- `/chrome-doctor` — deeper diagnosis with one-line fixes for common setup failures (extension not loaded, bridge owner stale after `pi update`, version mismatch between pi-chrome and the loaded Chrome extension).
|
|
120
|
+
|
|
121
|
+
If the Chrome extension you have loaded is older than `pi-chrome` on disk, `/chrome-doctor` will tell you to reload it from `chrome://extensions`.
|
|
122
|
+
|
|
123
|
+
## Compose with
|
|
124
|
+
|
|
125
|
+
- **pi-qq** — ask side questions about what the agent saw in Chrome without polluting the main transcript: `/qq summarize what the active GitHub tab shows`.
|
|
126
|
+
- **PR demo skills** (such as `ios-pr-agent` / `ios-demo-record` workflows) — `chrome_screenshot` writes to `.pi/chrome-screenshots/` so you can attach images to PR descriptions or demo bundles.
|
|
127
|
+
|
|
74
128
|
## Tools
|
|
75
129
|
|
|
76
130
|
The package registers these Pi tools:
|
|
@@ -88,7 +142,8 @@ The package registers these Pi tools:
|
|
|
88
142
|
|
|
89
143
|
These tools are especially useful for authenticated web app debugging, repro flows, admin workflows, visual checks, and inspecting local development pages without rebuilding login state.
|
|
90
144
|
|
|
91
|
-
|
|
145
|
+
<details>
|
|
146
|
+
<summary><strong>How it works (technical details)</strong></summary>
|
|
92
147
|
|
|
93
148
|
Pi starts a local bridge on `127.0.0.1:17318`. The companion Chrome extension, installed in your normal Chrome profile, polls that local bridge for commands and executes them using Chrome extension APIs.
|
|
94
149
|
|
|
@@ -96,6 +151,8 @@ If another Pi session is already running the bridge, additional Pi sessions auto
|
|
|
96
151
|
|
|
97
152
|
This is intentionally different from CDP-based tools: the browser extension lives inside the profile you already use, so Pi can interact with existing tabs and authenticated page state.
|
|
98
153
|
|
|
154
|
+
</details>
|
|
155
|
+
|
|
99
156
|
## Security model
|
|
100
157
|
|
|
101
158
|
The companion Chrome extension runs in the Chrome profile where you install it and has broad tab/scripting permissions. Only install it from a package source you trust.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"manifest_version": 3,
|
|
3
3
|
"name": "Pi Existing Chrome Profile Bridge",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.4.0",
|
|
5
5
|
"description": "Lets Pi control tabs in this existing Chrome profile via a local bridge at 127.0.0.1.",
|
|
6
6
|
"permissions": ["tabs", "scripting", "storage", "activeTab", "alarms"],
|
|
7
7
|
"host_permissions": ["<all_urls>", "http://127.0.0.1:17318/*"],
|
|
@@ -80,7 +80,12 @@ function sleep(ms) {
|
|
|
80
80
|
async function dispatch(action, params) {
|
|
81
81
|
switch (action) {
|
|
82
82
|
case "tab.version":
|
|
83
|
-
return {
|
|
83
|
+
return {
|
|
84
|
+
extensionId: chrome.runtime.id,
|
|
85
|
+
extensionVersion: chrome.runtime.getManifest().version,
|
|
86
|
+
bridgeUrl: BRIDGE_URL,
|
|
87
|
+
userAgent: navigator.userAgent,
|
|
88
|
+
};
|
|
84
89
|
case "tab.list":
|
|
85
90
|
return (await chrome.tabs.query({})).map(formatTab);
|
|
86
91
|
case "tab.new": {
|
|
@@ -46,6 +46,7 @@ type BridgeResult = {
|
|
|
46
46
|
error?: string;
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
+
const PI_CHROME_VERSION = "0.4.0";
|
|
49
50
|
const DEFAULT_HOST = process.env.PI_CHROME_BRIDGE_HOST ?? "127.0.0.1";
|
|
50
51
|
const DEFAULT_PORT = Number(process.env.PI_CHROME_BRIDGE_PORT ?? "17318");
|
|
51
52
|
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
@@ -351,19 +352,50 @@ If chrome_* tools time out, ask the user to run /chrome-onboard, then load the b
|
|
|
351
352
|
handler: async (_args, ctx) => {
|
|
352
353
|
ctx.ui.notify("Performing Chrome bridge health check", "info");
|
|
353
354
|
try {
|
|
354
|
-
const version = (await bridge.send("tab.version", {}, 35_000)) as { extensionId?: string };
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
"info",
|
|
360
|
-
);
|
|
355
|
+
const version = (await bridge.send("tab.version", {}, 35_000)) as { extensionId?: string; extensionVersion?: string };
|
|
356
|
+
const suffix = [version.extensionId ? `ID: ${version.extensionId}` : null, version.extensionVersion ? `ext v${version.extensionVersion}` : null]
|
|
357
|
+
.filter(Boolean)
|
|
358
|
+
.join(", ");
|
|
359
|
+
ctx.ui.notify(suffix ? `Chrome profile bridge connected (${suffix})` : "Chrome profile bridge connected", "info");
|
|
361
360
|
} catch (error) {
|
|
362
361
|
ctx.ui.notify(`Chrome bridge health check failed: ${(error as Error).message}`, "warning");
|
|
363
362
|
}
|
|
364
363
|
},
|
|
365
364
|
});
|
|
366
365
|
|
|
366
|
+
pi.registerCommand("chrome-doctor", {
|
|
367
|
+
description:
|
|
368
|
+
"Diagnose Chrome bridge setup. Checks the local bridge, the companion Chrome extension, and reports a one-line fix for common failures.",
|
|
369
|
+
handler: async (_args, ctx) => {
|
|
370
|
+
const lines: string[] = [`pi-chrome v${PI_CHROME_VERSION}`];
|
|
371
|
+
const status = bridge.status();
|
|
372
|
+
lines.push(`• Local bridge: mode=${status.mode}, url=${status.url}`);
|
|
373
|
+
try {
|
|
374
|
+
const version = (await bridge.send("tab.version", {}, 8_000)) as {
|
|
375
|
+
extensionId?: string;
|
|
376
|
+
extensionVersion?: string;
|
|
377
|
+
};
|
|
378
|
+
if (version.extensionId)
|
|
379
|
+
lines.push(`✓ Companion Chrome extension responding (ID: ${version.extensionId}, ext v${version.extensionVersion ?? "unknown"})`);
|
|
380
|
+
else lines.push("✓ Companion Chrome extension responding (no extension ID reported)");
|
|
381
|
+
if (version.extensionVersion && version.extensionVersion !== PI_CHROME_VERSION) {
|
|
382
|
+
lines.push(
|
|
383
|
+
`⚠ Extension version (${version.extensionVersion}) differs from pi-chrome (${PI_CHROME_VERSION}). Reload "Pi Existing Chrome Profile Bridge" in chrome://extensions to pick up the latest service worker.`,
|
|
384
|
+
);
|
|
385
|
+
}
|
|
386
|
+
} catch (error) {
|
|
387
|
+
const message = (error as Error).message;
|
|
388
|
+
lines.push(`✗ Companion Chrome extension not responding: ${message}`);
|
|
389
|
+
if (message.includes("older pi-chrome without multi-session")) {
|
|
390
|
+
lines.push(" Fix: restart the Pi session that owns the bridge (it was started on an older pi-chrome).");
|
|
391
|
+
} else {
|
|
392
|
+
lines.push(" Fix: run /chrome-onboard, then load the bundled browser-extension folder in chrome://extensions and keep that Chrome window open.");
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
ctx.ui.notify(lines.join("\n"), "info");
|
|
396
|
+
},
|
|
397
|
+
});
|
|
398
|
+
|
|
367
399
|
pi.registerCommand("chrome-foreground", {
|
|
368
400
|
description:
|
|
369
401
|
"Toggle whether chrome_* tools bring Chrome to the foreground. Foreground ON: you can watch the agent work in your browser, useful for demos, pair-driving, and debugging — tradeoff: Chrome pops up and steals focus, interrupting whatever app you were using. Foreground OFF (default): chrome_* tools act silently in the background, so your editor/terminal keeps focus and your workflow is not interrupted. Pass `on` / `off` to set explicitly, or no argument to toggle.",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-chrome",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Control your existing authenticated Chrome profile from
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "Control your existing authenticated Chrome profile from Pi with tabs, snapshots, clicks, typing, JS evaluation, waits, and screenshots \u2014 background by default.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|
|
7
7
|
"pi-extension",
|