@empir3/empir3-bridge 0.3.21

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.
Files changed (62) hide show
  1. package/CHANGELOG.md +1531 -0
  2. package/CODE_OF_CONDUCT.md +9 -0
  3. package/CONTRIBUTING.md +75 -0
  4. package/LICENSE +21 -0
  5. package/README.md +464 -0
  6. package/SECURITY.md +130 -0
  7. package/assets/accuracy-lab.html +2639 -0
  8. package/assets/api-clis-real.jpg +0 -0
  9. package/assets/bridge-console-hero.jpg +0 -0
  10. package/assets/browser-privacy.svg +151 -0
  11. package/assets/demo-orchestration.svg +74 -0
  12. package/assets/desktop-select-region.jpg +0 -0
  13. package/assets/in-page-chat.gif +0 -0
  14. package/assets/orchestration-hero.svg +126 -0
  15. package/assets/social-preview.png +0 -0
  16. package/assets/zara-accent.png +0 -0
  17. package/build/bootstrap.js +548 -0
  18. package/build/build.js +680 -0
  19. package/build/payload-entry.js +649 -0
  20. package/build/payload-signing-pub.json +7 -0
  21. package/docs/AGENT_GUIDE.md +259 -0
  22. package/docs/RELEASE.md +106 -0
  23. package/docs/SAFETY.md +112 -0
  24. package/docs/TESTING.md +181 -0
  25. package/installer/server.js +231 -0
  26. package/installer/ui/app.js +278 -0
  27. package/installer/ui/index.html +24 -0
  28. package/installer/ui/styles.css +146 -0
  29. package/package.json +95 -0
  30. package/scripts/bootstrap-e2e.mjs +650 -0
  31. package/scripts/certify-bridge.mjs +636 -0
  32. package/scripts/check-companion-surface.mjs +118 -0
  33. package/scripts/extract-welcome.mjs +64 -0
  34. package/scripts/gh-route-handler-check.mjs +57 -0
  35. package/scripts/gh-wire-test.mjs +107 -0
  36. package/scripts/publish-downloads.mjs +180 -0
  37. package/scripts/smoke-all-tools.mjs +509 -0
  38. package/scripts/smoke-live-bridge.mjs +696 -0
  39. package/scripts/splice-welcome.mjs +63 -0
  40. package/scripts/welcome-body.txt +2733 -0
  41. package/src/anthropic-client.ts +192 -0
  42. package/src/bootstrap-exe.ts +69 -0
  43. package/src/bridge.ts +2444 -0
  44. package/src/chat.ts +345 -0
  45. package/src/cli-runner.ts +239 -0
  46. package/src/cli.ts +649 -0
  47. package/src/config.ts +199 -0
  48. package/src/desktop-overlay.ps1 +121 -0
  49. package/src/executable-resolver.ts +330 -0
  50. package/src/handlers/agy-imagegen.ts +179 -0
  51. package/src/handlers/github-cli.ts +399 -0
  52. package/src/handlers/higgsfield-cli.ts +783 -0
  53. package/src/launch.js +337 -0
  54. package/src/mcp-server.ts +1265 -0
  55. package/src/pair-claim.ts +218 -0
  56. package/src/payload-daemon.ts +168 -0
  57. package/src/server.ts +21036 -0
  58. package/src/tool-defaults.ts +230 -0
  59. package/src/update-check.js +136 -0
  60. package/tray/build.py +76 -0
  61. package/tray/requirements.txt +2 -0
  62. package/tray/tray.py +1843 -0
@@ -0,0 +1,259 @@
1
+ # Bridge agent guide — decision tree for picking the right tool
2
+
3
+ > Audience: AI agents driving the bridge (Claude in the overlay, Vincent on
4
+ > app.empir3.com, MCP clients in Claude Code / Codex / Cursor). Not the
5
+ > human user.
6
+
7
+ The bridge currently exposes **57 tools** across browser, desktop, overlay
8
+ + recording, reliability + safety, and API & CLIs (`custom_llm` +
9
+ `higgsfield_*`). Most tasks need 2-3 of them; the rest are specialised
10
+ fallbacks. Read this guide top-to-bottom once per session and you'll skip
11
+ the trial-and-error.
12
+
13
+ When asked to "test the bridge", use the standard smoke plan at
14
+ `/api/bridge-smoke-test-plan` and open `/desktop-test` first. That page is the
15
+ shared harness for browser actions, desktop actions, recording/playback,
16
+ overlay reinjection, and calibration checks; do not substitute a random page
17
+ unless the user asked for a site-specific test.
18
+
19
+ ---
20
+
21
+ ## The five things you can do
22
+
23
+ Every bridge action falls into one of these:
24
+
25
+ 1. **See** what's on screen — text, structure, or pixels
26
+ 2. **Find** a specific element (button, icon, field)
27
+ 3. **Act** on it (click, type, scroll)
28
+ 4. **Point** at it for the user (without taking control)
29
+ 5. **Manage state** (focus region, calibration, permissions)
30
+
31
+ Pick the lane first, then the tool.
32
+
33
+ ---
34
+
35
+ ## 1 · See what's on screen
36
+
37
+ | You want… | Tool | Why |
38
+ |---|---|---|
39
+ | Page text | `browser_text` | Cheapest. Always try first if content is web. |
40
+ | Page structure as JSON refs | `browser_snapshot` | Get clickable refs (e0, e1, …) with bounds + names. Use for any web target. |
41
+ | Visual confirmation of web page | `browser_screenshot` | After a write, to verify it landed. |
42
+ | Desktop pixels | `desktop_screenshot` | Native desktop apps, games, anything outside the bridge browser. |
43
+ | Tight zoom around a pixel | `desktop_screenshot_zoom` | Pixel-accurate inspection of a small area. |
44
+ | Which monitors exist | `desktop_monitors` | DPI-aware bounds, including negative coords. |
45
+
46
+ **Rule:** if the target is in the bridge tab, `browser_snapshot` beats every
47
+ desktop tool. Web work should never touch desktop_* unless you need pixels
48
+ outside the page.
49
+
50
+ ---
51
+
52
+ ## 2 · Find a specific element
53
+
54
+ The most common failure mode for agents is "I need to click X but I don't
55
+ know where it is." Pick the right finder for the surface:
56
+
57
+ | Surface | Tool | Returns |
58
+ |---|---|---|
59
+ | Web page in bridge tab | `browser_snapshot` | `e0`, `e1`, … refs with `role`, `name`, `bounds`. |
60
+ | Native Win32 / UWP app | `desktop_snapshot` | `d0`, `d1`, … refs with `role`, `name`, `bounds`. |
61
+ | **Any visible region, agent reads numbers off image** | `desktop_snapshot_som` | Numbered boxes drawn on a screenshot. You read "click 14" — no pixel math. |
62
+ | Pixel-only (no UIA, no DOM) — e.g. games, Photoshop, CEF | _Phase 2 (OmniParser)_ | Not shipped. Today: ask user to select region + use grid (see §5). |
63
+
64
+ **`desktop_snapshot_som` is the killer tool** when the user has selected
65
+ a focus region. It returns an annotated screenshot AND the element list —
66
+ you pick the number and call `desktop_click_ref` with the matching `ref`.
67
+ Zero pixel arithmetic.
68
+
69
+ ### When `_snapshot_som` returns `empty: true`
70
+ That means UIA found no elements. Reasons:
71
+ - App is CEF/Electron (Discord, Spotify, Steam, VS Code content area)
72
+ - App is a game or custom GPU surface (Photoshop, Illustrator)
73
+ - App is web content but in the bridge browser — use `browser_snapshot` instead
74
+
75
+ Fallback: ask the user to point (`desktop_pick_point`) or use the focus
76
+ chess-board grid (`desktop_click_cell`).
77
+
78
+ ---
79
+
80
+ ## 3 · Act on it (click / type / scroll)
81
+
82
+ ### Web
83
+ | Intent | Tool |
84
+ |---|---|
85
+ | Click a ref from `browser_snapshot` | `browser_click_ref` |
86
+ | Click by CSS selector | `browser_click` |
87
+ | Click at known viewport coords | `browser_click_xy` |
88
+ | Type into a ref | `browser_type_ref` |
89
+ | Type by selector | `browser_type` |
90
+ | Press a key globally | `browser_press` |
91
+ | Scroll | `browser_scroll` |
92
+ | Visual cue for the user | `browser_highlight` |
93
+
94
+ ### Desktop
95
+ | Intent | Tool |
96
+ |---|---|
97
+ | Click a ref from `desktop_snapshot` / `_som` | `desktop_click_ref` |
98
+ | Click at known screen coords | `desktop_click` |
99
+ | Hover (no click) | `desktop_hover` / `desktop_hover_ref` |
100
+ | Drag | `desktop_drag` |
101
+ | Click cell N,M in the focus grid | `desktop_click_cell` |
102
+
103
+ **Always prefer `_ref` over `_xy` / `_click`.** Refs survive screen movement
104
+ and DPI changes. Coords don't.
105
+
106
+ ### Browser eval
107
+ | Intent | Tool |
108
+ |---|---|
109
+ | Run arbitrary JS | `browser_evaluate` |
110
+
111
+ Default-off because it's effectively root on the page. Use only when no
112
+ other tool can get the data (e.g. inspecting `window.someAppState`).
113
+
114
+ ---
115
+
116
+ ## 4 · Point at it (don't take control)
117
+
118
+ Use these when the user is doing the work and you're guiding them. The
119
+ ghost cursor doesn't touch the real mouse.
120
+
121
+ | Intent | Tool |
122
+ |---|---|
123
+ | Show a labeled arrow at coords | `desktop_pointer_show` |
124
+ | Move the arrow | `desktop_pointer_move` |
125
+ | Pulse animation for emphasis | `desktop_pointer_pulse` |
126
+ | Hide it | `desktop_pointer_hide` |
127
+ | Show pointer at a focus-grid cell | `desktop_pointer_cell` |
128
+ | Check whether arrow is up | `desktop_pointer_status` |
129
+
130
+ **Tutorial pattern:**
131
+ ```
132
+ desktop_snapshot_som → "the brush tool is number 14"
133
+ desktop_pointer_show at element 14 bounds, label "click here"
134
+ … user clicks …
135
+ desktop_pointer_hide
136
+ desktop_snapshot_som → confirm next state
137
+ ```
138
+
139
+ ---
140
+
141
+ ## 5 · Manage focus, grid, and calibration
142
+
143
+ These are scaffolding — agents rarely call them directly, but should know
144
+ they exist.
145
+
146
+ | Intent | Tool |
147
+ |---|---|
148
+ | Ask user to select an area to work in | `desktop_select_region` (user-interactive) |
149
+ | Check whether a region is active | `desktop_focus_status` |
150
+ | Clear the region | `desktop_release_focus` |
151
+ | Show on-screen grid matching the agent's view | `desktop_focus_grid` |
152
+ | User clicks → bridge reports cell coords | `desktop_pick_point` (user-interactive) |
153
+ | Click a cell of the focus grid | `desktop_click_cell` |
154
+ | Calibrate clicks (first-time or after monitor change) | `desktop_calibrate_pointer` (user-interactive) |
155
+ | Read saved calibration | `desktop_calibration_status` |
156
+
157
+ **Focus region** is the agent's working area inside an arbitrary monitor
158
+ layout. When active, `desktop_screenshot` and `desktop_snapshot_som`
159
+ auto-scope to it. Pixel coords in the screenshot are then focus-relative,
160
+ which simplifies the agent's mental model.
161
+
162
+ ---
163
+
164
+ ## Recordings
165
+
166
+ | Intent | Tool |
167
+ |---|---|
168
+ | Start recording user actions | `browser_record_start` |
169
+ | Stop and save | `browser_record_stop` |
170
+ | List saved recordings | `browser_recordings` |
171
+ | Replay one | `browser_play` |
172
+ | Push a message into the overlay chat | `browser_chat` |
173
+ | Read overlay chat history | `browser_read_chat` |
174
+
175
+ ---
176
+
177
+ ## Common recipes
178
+
179
+ ### Recipe: click a button on a website
180
+ ```
181
+ browser_snapshot → find { role:"button", name:"Continue" } → click_ref
182
+ ```
183
+
184
+ ### Recipe: click a small icon in a native app the user selected
185
+ ```
186
+ desktop_snapshot_som → read numbered boxes → desktop_click_ref by id
187
+ ```
188
+
189
+ ### Recipe: guide user through Photoshop tutorial
190
+ ```
191
+ desktop_select_region (one-time)
192
+ desktop_calibrate_pointer (one-time)
193
+ for each step:
194
+ desktop_pointer_show at the target, with label
195
+ wait for user click
196
+ desktop_pointer_hide
197
+ ```
198
+
199
+ ### Recipe: confirm an action worked
200
+ ```
201
+ … action …
202
+ browser_screenshot OR desktop_screenshot
203
+ ```
204
+
205
+ ### Recipe: agent doesn't know what app is open
206
+ ```
207
+ desktop_snapshot scope:"all-windows" → returns each window's title + pid
208
+ ```
209
+
210
+ ---
211
+
212
+ ## Anti-patterns
213
+
214
+ - ❌ Eyeballing pixel coords from a chat-resized screenshot. Use refs.
215
+ - ❌ Calling `desktop_click x:… y:…` when `_snapshot_som` would work.
216
+ - ❌ Taking a `desktop_screenshot` to "see" a web page you could `browser_snapshot`.
217
+ - ❌ Repeating screenshots after every click — only re-capture when state changes meaningfully.
218
+ - ❌ Calling `desktop_calibrate_pointer` without warning the user — it's interactive.
219
+
220
+ ---
221
+
222
+ ## Permissions (won't fire without these)
223
+
224
+ Tools that *write* (anything in the Act / Point lanes, plus recordings)
225
+ need `globalSafety.write` true AND per-tool `enabledTools[name]` true.
226
+ Tools that *read* need `globalSafety.read`. The bridge returns
227
+ `Permission denied` if either is off.
228
+
229
+ Surface tools to the user via the bridge control center; never disable
230
+ permissions silently from agent code.
231
+
232
+ ---
233
+
234
+ ## Discoverability — when in doubt
235
+
236
+ Call `bridge_tool_advisor(intent: "I want to …")` — returns the relevant
237
+ slice of this guide plus the tool names that fit.
238
+
239
+ ---
240
+
241
+ ## 6 · API & CLIs (talk to other models)
242
+
243
+ The bridge can dispatch to other model endpoints you've already set up.
244
+ Configure them in the welcome console (**API & CLIs** pane) once, then
245
+ call from any MCP client.
246
+
247
+ | Intent | Tool |
248
+ |---|---|
249
+ | Call any custom LLM (OpenAI-compatible protocol) | `custom_llm` (route by `provider` slug — Ollama, LM Studio, OpenRouter, vLLM, etc.) |
250
+ | Check Higgsfield CLI status / auth | `higgsfield_status` |
251
+ | List Higgsfield models / generations | `higgsfield_list` |
252
+ | Generate an image with Higgsfield | `higgsfield_generate` (writes to `~/.empir3-bridge/artifacts/higgsfield/`) |
253
+
254
+ **Family gates:**
255
+ - `higgsfield_*` is gated by the `higgsfield-cli` handler toggle in bridge settings.
256
+ - `custom_llm` is gated by `customProviders.length` — it isn't registered (and doesn't appear in the permissions list) until the user adds at least one custom provider. Adding the first provider auto-enables the tool; removing the last provider auto-disables it.
257
+
258
+ Toggling any family after the MCP client is already connected requires
259
+ reconnecting that client for the tool list to refresh.
@@ -0,0 +1,106 @@
1
+ # Release And Download Pipeline
2
+
3
+ This repo is the canonical source for the open-source bridge and the Windows download.
4
+
5
+ Normal users install from:
6
+
7
+ ```text
8
+ https://empir3.com/download
9
+ ```
10
+
11
+ The direct artifact path is:
12
+
13
+ ```text
14
+ https://app.empir3.com/downloads/Empir3Setup.exe
15
+ ```
16
+
17
+ ## Version Source
18
+
19
+ `package.json` is the bridge payload version source of truth.
20
+
21
+ The tray menu displays the active payload version read from the downloaded payload. The public update manifest is:
22
+
23
+ ```text
24
+ https://app.empir3.com/downloads/bridge-version.json
25
+ ```
26
+
27
+ Do not guess the next version from this document. Before release, check both:
28
+
29
+ ```bash
30
+ node -p "require('./package.json').version"
31
+ curl -fsS https://app.empir3.com/downloads/bridge-version.json
32
+ ```
33
+
34
+ If runtime behavior changes, bump `package.json`, build, dry-run publish, publish, then verify the live manifest reports the new version.
35
+
36
+ ## Build
37
+
38
+ ```bash
39
+ npm install
40
+ npm run build:windows
41
+ ```
42
+
43
+ Build output lands in `build/dist/`:
44
+
45
+ - `Empir3Setup.exe`
46
+ - `bridge-payload-vX.Y.Z.tar.gz`
47
+ - `bridge-payload-vX.Y.Z.sig`
48
+ - `bridge-version.json`
49
+ - `empir3-bridge.crx`
50
+ - `empir3-bridge-update.xml`
51
+
52
+ `Empir3Setup.exe` is the stable bootstrapper. The payload tarball contains the actual bridge runtime, installer UI, extension, and tray wrapper.
53
+
54
+ ## Publish
55
+
56
+ Dry run:
57
+
58
+ ```bash
59
+ npm run publish:downloads -- --dry-run
60
+ ```
61
+
62
+ Publish (the deploy target comes from the environment — it is not hardcoded in the repo):
63
+
64
+ ```bash
65
+ export EMPIR3_DOWNLOAD_HOST=user@your-host
66
+ export EMPIR3_DOWNLOAD_DIR=/var/www/your-app/downloads
67
+ npm run publish:downloads
68
+ ```
69
+
70
+ The helper uploads the release artifacts to `$EMPIR3_DOWNLOAD_HOST:$EMPIR3_DOWNLOAD_DIR`, then verifies they are live:
71
+
72
+ ```text
73
+ https://app.empir3.com/downloads/Empir3Setup.exe
74
+ https://app.empir3.com/downloads/bridge-version.json
75
+ ```
76
+
77
+ ## Release Rule
78
+
79
+ Do not ship bridge source changes without also checking whether they affect the Windows installer path. If the change affects runtime behavior, bump `package.json`, build the Windows payload, publish `bridge-version.json`, and smoke the tray version line after install/update.
80
+
81
+ This release process is self-contained — it publishes the bridge payload + installer and is separate from any Empir3 app deploy. Do not use app deploy scripts (`deploy.ps1` / `deploy.sh`) for bridge releases.
82
+
83
+ ## Two Distribution Channels — Keep Them In Sync
84
+
85
+ This private staging repo (`empir3labs/empir3-bridge-staging`) is the single source of truth. Two **independent, manual** pipelines fan out from it, and they drift if you update one and forget the other:
86
+
87
+ | Channel | Tool | Target | What it is |
88
+ |---|---|---|---|
89
+ | **Public source** | `scripts/export-public.mjs` | `empir3hq/empir3-bridge` | A scrubbed, zero-history snapshot users clone / read (install-from-source path). |
90
+ | **Runtime payload** | `build:windows` + `publish:downloads` | `app.empir3.com/downloads` | The signed payload installed daemons auto-update from. |
91
+
92
+ `git push` to staging updates **neither** channel.
93
+
94
+ ### The coupling rule
95
+
96
+ **Any change to runtime behavior ships to BOTH channels in the same pass**, or the public source and the running binary diverge. Doc-only changes (README, this file) don't need a payload publish — they can ride the next HQ export.
97
+
98
+ One ordered checklist per runtime release:
99
+
100
+ 1. **Verify** the change live (alt-port `tsx` instance — never disturb the installed daemon).
101
+ 2. **Bump** `package.json` (the payload + HQ snapshot both carry it; it's how daemons detect updates — never publish two builds under the same version).
102
+ 3. **Build + publish payload**: `build:windows` → `publish:downloads -- --dry-run` → `publish:downloads`.
103
+ 4. **Export + push HQ from the same commit**: `export-public.mjs` → eyeball any new images (the scanner can't read them) → in `build/public-export/`, `git init` → commit **as "Empir3 Labs"** (never the maintainer's personal git identity — the export scanner hard-fails on it) → push to `empir3hq/empir3-bridge`.
104
+ 5. **Verify parity**: tray version == live `bridge-version.json` == HQ `package.json`.
105
+
106
+ The `Empir3Setup.exe` distribution stays gated on Authenticode signing; publishing the payload updates already-installed daemons regardless.
package/docs/SAFETY.md ADDED
@@ -0,0 +1,112 @@
1
+ # Safety Model
2
+
3
+ Empir3 Bridge can read browser state and, when explicitly enabled, operate pages and the desktop. This document explains the safety boundary.
4
+
5
+ ## Defaults
6
+
7
+ The first-run default is read-heavy and write-light:
8
+
9
+ - Read tools: enabled
10
+ - Navigation tools: enabled
11
+ - Browser click/type tools: disabled
12
+ - Desktop mouse tools: disabled
13
+ - JavaScript eval: disabled
14
+ - Recording and replay tools: disabled
15
+
16
+ Disabled tools are not sent to the chat model as available tools. The dispatcher also rejects disabled tool calls as a second layer of protection.
17
+
18
+ ## Visible Control State
19
+
20
+ The dashboard at `http://localhost:3006` shows a `Control Safety` card:
21
+
22
+ - `Read Only`: no write-capable tools are enabled.
23
+ - `Write Enabled`: one or more click, type, desktop, eval, or recording tools are enabled.
24
+
25
+ The current state is also available through:
26
+
27
+ ```bash
28
+ npx tsx src/cli.ts safety-status
29
+ ```
30
+
31
+ and through MCP:
32
+
33
+ ```text
34
+ bridge_safety_status
35
+ ```
36
+
37
+ ## Revoke Control
38
+
39
+ To disable all write-capable tools immediately:
40
+
41
+ ```bash
42
+ npx tsx src/cli.ts revoke-control
43
+ ```
44
+
45
+ or call the MCP tool:
46
+
47
+ ```text
48
+ bridge_revoke_control
49
+ ```
50
+
51
+ or press `Revoke Write Control` on the dashboard.
52
+
53
+ This turns off:
54
+
55
+ - browser clicks
56
+ - browser typing
57
+ - browser keypresses
58
+ - desktop click, hover, and drag
59
+ - JavaScript eval
60
+ - recording and replay tools
61
+ - overlay chat programmatic read/write tools
62
+
63
+ Read tools and browser navigation remain enabled.
64
+
65
+ ## Local Network Boundary
66
+
67
+ By default, the wrapper and CDP bridge bind to `127.0.0.1`.
68
+
69
+ Chrome is launched with:
70
+
71
+ ```text
72
+ --remote-debugging-address=127.0.0.1
73
+ ```
74
+
75
+ The bridge is intended for local tools on your own machine. Do not expose it to the LAN or internet.
76
+
77
+ ## Data Boundary
78
+
79
+ The bridge uses a dedicated Chrome profile:
80
+
81
+ ```text
82
+ ~/.empir3-bridge/profile/
83
+ ```
84
+
85
+ It does not use your normal Chrome profile. Site logins inside the bridge profile are separate from your daily browser.
86
+
87
+ Local data paths:
88
+
89
+ - `~/.empir3-bridge/config.json`: settings
90
+ - `~/.empir3-bridge/conversations/`: chat transcripts
91
+ - `./feedback/`: screenshots and action feedback
92
+ - `./recordings/`: saved replay flows
93
+
94
+ These paths can contain sensitive page state if you use the bridge on private sites. Treat them accordingly.
95
+
96
+ ## When To Enable Desktop Tools
97
+
98
+ Enable desktop tools only when you want an agent to operate the host desktop, not just Chrome.
99
+
100
+ Useful cases:
101
+
102
+ - desktop app smoke tests
103
+ - multi-monitor screenshots
104
+ - browser UI that cannot be reached through the DOM
105
+ - canvas or game interactions
106
+ - drag/drop testing
107
+
108
+ Use `http://localhost:3006/desktop-test` before trying desktop click/drag on real windows.
109
+
110
+ ## Reporting Security Issues
111
+
112
+ Do not open a public issue for security bugs. See [../SECURITY.md](../SECURITY.md).
@@ -0,0 +1,181 @@
1
+ # Testing The Bridge
2
+
3
+ This guide is for maintainers, contributors, and agents making bridge changes.
4
+
5
+ ## Static Checks
6
+
7
+ Run these before committing:
8
+
9
+ ```bash
10
+ npx tsc --noEmit
11
+ npm run build:mcp
12
+ npm test
13
+ git diff --check
14
+ ```
15
+
16
+ Before a release or package change:
17
+
18
+ ```bash
19
+ npm pack --dry-run
20
+ ```
21
+
22
+ ## Standard Smoke Test Plan
23
+
24
+ Agents and maintainers should use the same quick smoke every time someone says
25
+ "test the bridge." Do not skip `/desktop-test`; it is the shared harness for
26
+ browser tools, desktop tools, calibration checks, recording, and playback.
27
+
28
+ Open the live plan:
29
+
30
+ ```text
31
+ http://localhost:3006/api/bridge-smoke-test-plan
32
+ ```
33
+
34
+ Or print it from the CLI:
35
+
36
+ ```bash
37
+ npx tsx src/cli.ts smoke-plan
38
+ ```
39
+
40
+ Or open the visual harness:
41
+
42
+ ```text
43
+ http://localhost:3006/desktop-test
44
+ ```
45
+
46
+ Run the smoke in this order and stop after the first reproducible failure:
47
+
48
+ 1. Health: `status`, `reliability_status`, and `safety_status`.
49
+ 2. Overlay: navigate to `/desktop-test`, then run `bridge_overlay_reinject`.
50
+ Verify the chat bubble, cursor hook, and overlay transport are present.
51
+ 3. Browser tools: use `text`, `snapshot`, `screenshot`, `click #clickTarget`,
52
+ `type #nameInput`, `press Tab`, and scroll to `#scrollTarget`.
53
+ 4. Recording loop: `record_start`, click `#clickTarget`, `record_stop`,
54
+ list recordings, then play the saved recording once.
55
+ 5. Desktop tools: run `desktop_monitors`, `desktop_calibration_status`,
56
+ `desktop_cursor_position`, `desktop_screenshot_zoom`,
57
+ `desktop_focus_status`, and `desktop_release_focus`.
58
+ 6. Tray toolbar: run `desktop_toolbar status`, then `desktop_toolbar show`.
59
+
60
+ Required selectors on the harness:
61
+
62
+ ```text
63
+ #clickTarget
64
+ #dragSource
65
+ #dropTarget
66
+ #nameInput
67
+ #emailInput
68
+ #notesInput
69
+ #modeKeyboard
70
+ #modeMouse
71
+ #agreeBox
72
+ #prioritySelect
73
+ #submitForm
74
+ #scrollTarget
75
+ ```
76
+
77
+ ## Basic Smoke
78
+
79
+ Start the bridge:
80
+
81
+ ```bash
82
+ npm start
83
+ ```
84
+
85
+ In another shell:
86
+
87
+ ```bash
88
+ npx tsx src/cli.ts status
89
+ npx tsx src/cli.ts reliability-smoke
90
+ npx tsx src/cli.ts safety-status
91
+ ```
92
+
93
+ Expected:
94
+
95
+ - status reports the bridge is running
96
+ - reliability smoke passes
97
+ - safety status reports either `read_only` or lists enabled write tools
98
+
99
+ ## Browser Smoke
100
+
101
+ ```bash
102
+ npx tsx src/cli.ts desktop-test
103
+ npx tsx src/cli.ts snapshot
104
+ npx tsx src/cli.ts screenshot
105
+ npx tsx src/cli.ts text
106
+ ```
107
+
108
+ For write-capable browser tests, enable the relevant tool in settings first:
109
+
110
+ ```text
111
+ http://localhost:3006/settings
112
+ ```
113
+
114
+ Then use a harmless page before trying a real app.
115
+
116
+ ## Desktop Smoke
117
+
118
+ Open the safe desktop test harness:
119
+
120
+ ```bash
121
+ npx tsx src/cli.ts desktop-test
122
+ ```
123
+
124
+ Or visit:
125
+
126
+ ```text
127
+ http://localhost:3006/desktop-test
128
+ ```
129
+
130
+ Useful checks:
131
+
132
+ ```bash
133
+ npx tsx src/cli.ts desktop-monitors
134
+ npx tsx src/cli.ts desktop-screenshot all
135
+ npx tsx src/cli.ts desktop-hover 960 540 DISPLAY1
136
+ ```
137
+
138
+ Only run `desktop-click` or `desktop-drag` when the test harness window is visible and positioned where the target coordinates are known. Blind drag tests can move windows or select real UI.
139
+
140
+ ## Parallel Bridge Smoke
141
+
142
+ Use a separate profile and ports so you do not disturb the normal bridge:
143
+
144
+ ```bash
145
+ EMPIR3_PW_PORT=3106 \
146
+ EMPIR3_BRIDGE_HTTP_PORT=9967 \
147
+ EMPIR3_CDP_PORT=9322 \
148
+ EMPIR3_BRIDGE_PROFILE=$HOME/.empir3-bridge/profile-smoke \
149
+ EMPIR3_BRIDGE_LABEL=SMOKE \
150
+ npm start -- --fresh
151
+ ```
152
+
153
+ Drive it:
154
+
155
+ ```bash
156
+ BRIDGE_URL=http://localhost:3106 npx tsx src/cli.ts reliability-smoke
157
+ BRIDGE_URL=http://localhost:3106 npx tsx src/cli.ts desktop-test
158
+ ```
159
+
160
+ Stop it:
161
+
162
+ ```bash
163
+ EMPIR3_PW_PORT=3106 \
164
+ EMPIR3_BRIDGE_HTTP_PORT=9967 \
165
+ EMPIR3_CDP_PORT=9322 \
166
+ EMPIR3_BRIDGE_PROFILE=$HOME/.empir3-bridge/profile-smoke \
167
+ EMPIR3_BRIDGE_LABEL=SMOKE \
168
+ npm run kill
169
+ ```
170
+
171
+ ## What To Include In Bug Reports
172
+
173
+ - OS and version
174
+ - `node -v`
175
+ - Chrome version
176
+ - exact command run
177
+ - `npm run status` output
178
+ - `npx tsx src/cli.ts reliability-status` output
179
+ - relevant screenshots or `feedback/` paths
180
+
181
+ Do not paste API keys, site cookies, or private page data into public issues.