iframer-toolkit 0.9.0 → 0.10.1

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.
@@ -0,0 +1,134 @@
1
+ # iframer browser extension (extension mode)
2
+
3
+ Let iframer drive **a tab you already have open in your real Chrome** — no
4
+ relaunch, no remote-debugging port, on your real logged-in session. While a run
5
+ is in progress Chrome shows its yellow "iframer started debugging this browser"
6
+ bar; it disappears when the run finishes.
7
+
8
+ ## How it works
9
+
10
+ ```
11
+ Claude (agent) ──MCP──▶ iframer server ──connectOverCDP──▶ CDP relay ──WS──▶ this extension ──chrome.debugger──▶ your tab
12
+ ```
13
+
14
+ - The extension **dials out** to iframer's local server (extensions can't listen
15
+ on a port). It authenticates with a first `{type:"auth"}` message — the token
16
+ never appears in a URL.
17
+ - For discovery (`tabs`), the extension uses `chrome.tabs`.
18
+ - To **drive** a tab, the extension attaches `chrome.debugger` to it and **relays
19
+ the CDP protocol** to iframer's server, which connects with
20
+ `connectOverCDP` and runs the **exact same pipeline** (find/click/snapshot/
21
+ navigate/obstacle-handling/API-capture) it uses in every other mode. Nothing is
22
+ reimplemented — your live tab is driven by the real, proven engine, with real
23
+ trusted input.
24
+
25
+ Once paired, iframer can see and drive **any** of your open tabs — the agent lists
26
+ them (`tabs` tool), finds the one you meant, and drives it. One pipeline drives a
27
+ given tab at a time; different tabs can run concurrently.
28
+
29
+ ## Multiple profiles / browsers
30
+
31
+ You can run the extension in as many Chrome profiles (or browsers) as you want at
32
+ once. Each install identifies itself with a stable random **profile id** and a
33
+ **profile name** (the signed-in account's email, or set one in the popup —
34
+ "Work", "Personal", …). The server keeps every connection separate, aggregates
35
+ tabs across all of them (each tab tagged with its profile), and routes every
36
+ `execute`/`reverse-engineer` to the profile that owns the target tab. If two
37
+ browsers happen to report the same numeric tab id, iframer refuses to guess and
38
+ asks for the tab's `clientId`. A service-worker restart replaces that profile's
39
+ own connection instead of piling up. The server stays alive while any profile is
40
+ connected and idle-exits once none are.
41
+
42
+ The extension is an **optional** add-on (Chrome/Chromium today; Firefox and
43
+ others later). You opt in explicitly — nothing installs it for you.
44
+
45
+ ## Install (opt-in, Chrome)
46
+
47
+ ```sh
48
+ iframer install extension chrome
49
+ ```
50
+
51
+ That installs the pairing (native-messaging) host and prints the folder to load.
52
+ Then finish the one manual step it tells you:
53
+
54
+ 1. Open `chrome://extensions`.
55
+ 2. Turn on **Developer mode** (top right).
56
+ 3. **Load unpacked** → select the printed folder — the `extension/` dir **inside
57
+ the installed package** (get it again with `iframer extension path`).
58
+
59
+ Loading from that path is what lets `iframer update` refresh it in place. The
60
+ pinned `key` keeps the extension ID — and pairing — stable across updates.
61
+
62
+ ## Updating (npm is the update channel)
63
+
64
+ The extension ships inside the `iframer-toolkit` npm package, so npm *is* the
65
+ update channel — no Chrome Web Store. When a newer version is published, the
66
+ extension notices (the running extension is older than the files on disk) and
67
+ shows a **↑ Update available** badge + a popup notice. To apply it:
68
+
69
+ ```sh
70
+ iframer update # npm-updates, reloads the extension, restarts the server
71
+ iframer update --check # just report whether a newer version exists
72
+ ```
73
+
74
+ `iframer update` runs `npm install -g iframer-toolkit@latest` (which overwrites
75
+ the extension files in place at the path above), tells the running extension to
76
+ `chrome.runtime.reload()` so it re-reads the new files, and retires the old
77
+ server. The only manual step is ever the *first* **Load unpacked** — after that,
78
+ updates are one command. (Dev/linked checkouts update via `git pull && bun run
79
+ build` instead; `iframer update` detects that and says so.)
80
+
81
+ ## Pair it (one time, zero copying)
82
+
83
+ ```sh
84
+ iframer install extension
85
+ ```
86
+
87
+ then restart the browser. That installs a Chrome **native-messaging host**
88
+ (locked to this extension's pinned ID) that hands the extension the pairing
89
+ token straight from `~/.iframer/secret` — every profile and every Chromium-family
90
+ browser (Chrome, Brave, Edge, …) pairs itself, and re-pairs automatically after
91
+ a reinstall or a rotated secret. No copying, ever.
92
+
93
+ Manual fallback (host not installed): click the iframer toolbar icon → paste the
94
+ token from `cat ~/.iframer/secret` → **Save & connect**.
95
+
96
+ Either way the dot turns green when it finds the running iframer server (it
97
+ scans ports 3022–3042 on `127.0.0.1`; the server allocates its port from the
98
+ same window). The token is the same machine-local secret the iframer CLI/MCP
99
+ already use. It is only ever sent to `127.0.0.1`.
100
+
101
+ ## Use it
102
+
103
+ Just tell your agent, e.g. *"use my Gmail tab and archive everything from X."*
104
+ The agent calls the `tabs` tool to list your open tabs, finds the one you meant,
105
+ then `execute`s with `mode: "extension"` and that tab's id. No per-tab step —
106
+ once the extension is connected, every open tab is reachable.
107
+
108
+ Because runs go through iframer's real engine, **every pipeline step works
109
+ exactly as in the other modes** — same selectors, same `@e` refs, same
110
+ screenshots, same knowledge cache.
111
+
112
+ ## Reverse-engineering
113
+
114
+ Extension mode captures the API too. Run `reverse-engineer` (or `execute` with
115
+ `options.captureApi: true`) with `mode: "extension"` + `tabId`. Capture happens
116
+ in the server's normal network layer over the CDP relay, so you get everything
117
+ the other modes get — parameterized paths, protocol/verb classification,
118
+ `functionName`, ready-to-run `curl`, extracted auth, **including response
119
+ bodies**. Captured endpoints also feed the knowledge cache automatically.
120
+
121
+ ## Limitations
122
+
123
+ - **The debug bar.** `chrome.debugger` is what makes trusted input and the full
124
+ engine possible; Chrome always shows the yellow bar while it's attached.
125
+ - **The tab becomes active in its window while driven.** An inactive tab
126
+ doesn't render, so the extension activates it — but it does NOT steal your OS
127
+ focus: the window stays in the background and the page is driven with CDP
128
+ focus emulation, so you can keep working. A minimized window is auto-restored
129
+ (without focus — it stays behind your other windows), and screenshots fall
130
+ back to renderer capture if the compositor produces no frame. If a site still
131
+ ignores background input, pass `options.focus: true` to restore the old
132
+ raise-the-window behavior.
133
+ - **No session inject/extract.** Your real profile owns its cookies; iframer
134
+ doesn't copy sessions in or out of extension mode.