aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorTianren Dong <tianrendong.dtr@gmail.com>2026-05-14 22:46:31 -0400
committerTianren Dong <tianrendong.dtr@gmail.com>2026-05-14 22:46:31 -0400
commit58e86b70a0c7f6bf8e44f8b658e8194444ade943 (patch)
treeb56f638493c4967544b39c465596dddac1d1b4a9 /docs
parent1ec189f8f7f137555e8ae90d6753ee226eefa457 (diff)
Audit pi-chrome docs
Diffstat (limited to 'docs')
-rw-r--r--docs/COMPARISON.md6
-rw-r--r--docs/EXAMPLES.md8
-rw-r--r--docs/FAQ.md21
3 files changed, 13 insertions, 22 deletions
diff --git a/docs/COMPARISON.md b/docs/COMPARISON.md
index d30cb6a..7dfe5ed 100644
--- a/docs/COMPARISON.md
+++ b/docs/COMPARISON.md
@@ -52,7 +52,7 @@ We benchmark in public — see [`../test-suite/`](../test-suite). Where exact sc
1. **Profile attach, not driver launch.** Every other driver fights cookie persistence, login walls, MFA, and extension state. pi-chrome inherits all of it because it *is* your Chrome.
2. **Chrome input against your real profile.** Interactive tools use CDP input for reliability while still controlling the Chrome profile you already use.
3. **Extension bridge transport.** No `--remote-debugging-port`, no throwaway Chromium. Survives Chrome auto-updates. Works alongside your normal Chrome usage.
-4. **Honest result envelopes.** Every action returns `pageMutated`, `defaultPrevented`, `elementVisible`, `occludedBy`, `valueMatches`. Competitors return `void` or generic acks; agents loop blindly on broken clicks.
+4. **Structured action results.** Input tools return target coordinates/tags and can include a fresh snapshot (`includeSnapshot`) so agents can verify state instead of blindly retrying.
5. **Multi-session shared bridge.** Planner + worker + audit Pi sessions all drive the same Chrome concurrently.
6. **Stable element uids.** `chrome_snapshot` returns deterministic uids you can pass to subsequent actions — similar to BrowserGym's `bid`, but built into the snapshot tool itself.
@@ -101,9 +101,9 @@ These wrap a driver with an LLM loop. They are **higher-level than pi-chrome** a
`pi-chrome` exposes tools that any Pi agent can call. If you want to use it from outside Pi:
-1. The local bridge speaks HTTP JSON-RPC at `127.0.0.1:17318` (default). The API is internal but stable across patch versions.
+1. The local bridge speaks HTTP JSON over `127.0.0.1:17318` (default). The API is internal; use the Pi tool surface unless you are building an adapter.
2. Tool surface mirrors Playwright closely (click/type/navigate/snapshot/screenshot/evaluate/wait_for) so adapter code is short.
-3. Honest envelopes (`pageMutated`, `valueMatches`, `occludedBy`) let agent harnesses skip retry/heal logic.
+3. `includeSnapshot` on input tools lets agent harnesses verify state after actions.
If you want a first-class pi-chrome adapter for Browser Use / Stagehand / LangGraph, file an issue with your use case.
diff --git a/docs/EXAMPLES.md b/docs/EXAMPLES.md
index a5cccf4..b3c6286 100644
--- a/docs/EXAMPLES.md
+++ b/docs/EXAMPLES.md
@@ -119,10 +119,8 @@ On my staging app:
### React controlled inputs
```text
-chrome_fill (not chrome_type) for React inputs — it uses the
-framework-aware native value setter so the form's state actually updates.
-After each fill, the result envelope's valueMatches=true confirms the
-component re-rendered with the new value.
+Use `chrome_fill` for React inputs when you want to replace the full value.
+Pass `includeSnapshot=true` to verify the component re-rendered with the new value.
```
### File upload without the native picker
@@ -160,7 +158,7 @@ Interactive tools use Chrome's real input layer by default: clicks, typing, fill
- sign-in flows
- guarded buttons
- audio/video controls
-- fullscreen / permission prompts
+- fullscreen and other user-activation checks
- pages with strict CSP or user-activation checks
Chrome may show its debugger banner while pi-chrome is attached.
diff --git a/docs/FAQ.md b/docs/FAQ.md
index 33902d3..f7f871f 100644
--- a/docs/FAQ.md
+++ b/docs/FAQ.md
@@ -32,9 +32,9 @@ Chrome control is also locked per Pi session until you run `/chrome authorize`;
Yes. The first session opens the local bridge; later sessions detect it and pipe their commands through the same bridge. Each Pi session must be authorized with `/chrome authorize` before its chrome_* tools work.
-## Why can't this be on the Chrome Web Store?
+## Why ship as an unpacked extension?
-Web Store extensions cannot communicate with a local process bridge controlled by another tool — Google's policy. pi-chrome must ship as an unpacked extension you load yourself. The upside: you can read the source. The downside: each Chrome update may prompt you to re-confirm.
+pi-chrome ships as an unpacked extension so the source and broad browser permissions are easy to inspect and update with the npm package. The downside: you load it manually from `chrome://extensions` and reload it after package updates.
## What happens when I update pi-chrome?
@@ -42,8 +42,8 @@ Web Store extensions cannot communicate with a local process bridge controlled b
## What's the install footprint?
-- Pi side: one extension that registers ~20 tools and a few slash commands.
-- Chrome side: one unpacked extension, ~5000 LOC of plain JavaScript, no dependencies.
+- Pi side: one extension that registers 19 tools and a few slash commands.
+- Chrome side: one unpacked extension, ~2000 LOC of plain JavaScript, no dependencies.
## Can I script it without Pi?
@@ -53,18 +53,11 @@ The Pi-facing tools are thin wrappers around an HTTP bridge at `127.0.0.1:17318`
Not always. `chrome_evaluate` and `chrome_snapshot` run in the page's MAIN world through the Function constructor, so pages whose CSP blocks `'unsafe-eval'` can reject them. `chrome_screenshot`, `chrome_navigate`, tab tools, and real Chrome input still work because they use extension/browser APIs rather than page JavaScript.
-## Why does my click return `pageMutated=false`?
+## How do I tell whether a click or type worked?
-Either:
-- The element was occluded (look for `occludedBy: <selector>` in the envelope).
-- The click handler called `event.preventDefault()` and the page intentionally ignored it.
-- The target changed after your snapshot; take a fresh snapshot or screenshot.
+Use `includeSnapshot=true` on `chrome_click`, `chrome_type`, `chrome_fill`, or `chrome_key`. The tool returns the Chrome-input result plus a fresh snapshot, so the agent can verify text, URL, visible elements, or form values before continuing.
-The result envelope tells you which one. **Don't blind-retry.**
-
-## Why does `chrome_type` return `valueMatches=false`?
-
-The field rejected or transformed the typed value. Common culprits: contenteditable rich-text editors, native date pickers, masked-input libraries, or masks. Try `chrome_fill`, then verify with `includeSnapshot=true`.
+If the page did not change, take a fresh snapshot or screenshot and check for overlays, disabled controls, stale element uids, or app-side validation.
## How do I attach a file to a React file input?