aboutsummaryrefslogtreecommitdiff
path: root/docs/ARCHITECTURE.md
blob: 2e21499921ca608b9531a16216f17cd025f795f7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# pi-chrome architecture

`pi-chrome` connects Pi to your existing Chrome profile through a local-only bridge and an unpacked Chrome extension.

```text
  +----------------------+                       +--------------------------+
  |  Pi agent (terminal) |  -- 127.0.0.1:17318 ->|  Chrome extension        |
  |  chrome_* tools      |                       |  (your real profile)     |
  +-----------+----------+                       +-------------+------------+
              |  same machine                                  |
              v                                                v
   Other Pi sessions                          Tabs you already have open
   share same bridge                          (GitHub, Linear, Stripe, etc.)
```

## Components

- **Pi extension** — exposes `chrome_*` tools and `/chrome` commands inside Pi.
- **Loopback bridge** — listens on `127.0.0.1:17318`; no external network bind by default.
- **Chrome companion extension** — loaded unpacked into your real Chrome profile.
- **Chrome debugger / CDP** — drives input, screenshots, network/console observation, and evaluation.

## Session model

Multiple Pi sessions can use same Chrome companion extension. First session opens local bridge; later sessions detect it and pipe commands through.

Each Pi session owns its own automation target:

- First chrome action without explicit target opens dedicated automation window.
- If separate window cannot be created, pi-chrome falls back to dedicated tab.
- Target survives `/reload` and Chrome service-worker restarts.
- Ownership is tracked by id and mirrored to `chrome.storage.session`.
- Cleanup closes calling session's automation target and every tab it created through `tab.new`.
- Existing user tabs adopted into a session group are preserved, and ungrouped only if still in that group.
- 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.
- 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.

To point pi-chrome at an existing tab, pass `targetId`, `urlIncludes`, or `titleIncludes`.

## Tab management guards

`chrome_tab` management actions are guarded:

- `activate`, `close`, `group`, and `ungroup` without explicit target act on session automation tab if it exists.
- If no automation tab exists, operation errors instead of touching your active tab.

## Background mode

By default, chrome calls run in background so Chrome does not steal focus.

```text
/chrome background on       # background mode
/chrome background off      # foreground/watch mode
```

Per-call `background: false` brings Chrome forward for that action. Per-call `background: true` forces background.

## Authorization

Bridge connection alone is not enough. Chrome control stays locked until current Pi session runs:

```text
/chrome authorize
```

Authorization expires after configured duration, on `/chrome revoke`, or when Pi exits.

## Unpacked extension choice

`pi-chrome` ships browser extension source as an unpacked folder on purpose:

- easy to inspect before loading
- no Web Store release delay
- MIT-licensed source in repo
- `/chrome doctor` can compare loaded extension version against installed package

Loaded extension has broad tab/scripting permissions inside profile where it is installed. Install only from trusted package source.