@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
package/CHANGELOG.md ADDED
@@ -0,0 +1,1531 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Changed
11
+ - Published to npm as `@empir3/empir3-bridge`.
12
+
13
+ ## [0.3.21] - 2026-06-18
14
+
15
+ ### Added
16
+ - **Playback transport bar.** Replaying a recording now shows a media-player-style transport at the bottom of the page: a draggable scrubber (drag back to rewind — re-runs from the start to that point since actions can't be undone; drag forward to fast-forward), Restart / Pause-Resume / single-Step / Stop buttons, and live speed pills (0.5×/1×/2×/4×). Previously the only options were Rec and Play, with no way to pause, stop, scrub, or change speed once a recording started. Backed by six new interruptible-playback commands (`playback_pause`/`resume`/`stop`/`step`/`speed`/`seek`) that ride the same WS/CDP-mailbox path as Rec/Stop, so the controls work on both http and https pages.
17
+
18
+ ### Fixed
19
+ - The transport bar stays visible across the page navigations a recording performs, and re-syncs its state — including the current action when synced mid-pause — to any overlay that announces mid-playback (so it also shows on https pages, which drive the overlay over the CDP mailbox). (Refines the 0.3.19 transport bar across 0.3.20–0.3.21.)
20
+
21
+ ## [0.3.18] - 2026-06-16
22
+
23
+ ### Fixed
24
+ - **Lent CLIs advertise availability even when Execute is off.** The per-device Execute gate was also blocking the read-only capability `:probe` that a lent CLI uses to report it's installed and authenticated, so `cli_status` could show a lent model as unavailable until Execute was turned on. The read-only `:probe` now passes the gate for every CLI prefix; the actual `:turn` and `github:exec` still require Execute.
25
+
26
+ ## [0.3.15] - 2026-06-16
27
+
28
+ ### Fixed
29
+ - **Tray no longer falsely shows "Daemon not running."** A periodic local-workspace sync was re-hashing the entire synced workspace every 5 seconds, saturating the daemon's event loop enough that health pings timed out and the tray reported the daemon dead while it was actually alive and serving. The sync now re-walks the workspace every 30 seconds instead of every 5, and the dashboard daemon pills reflect true daemon liveness rather than the CDP/browser link state. (0.3.13, 0.3.15–0.3.17.)
30
+
31
+ ## [0.3.13] - 2026-06-16
32
+
33
+ ### Added
34
+ - **Single-call vision for lent CLIs.** Image-bearing turns to Codex, Gemini, Antigravity, and Claude now carry the image into a single CLI turn instead of dropping it or splitting it across a separate caption pass — a lent model can actually see the image you sent, in one call.
35
+
36
+ ### Fixed
37
+ - Browser close lifecycle: debounced the "closed by user" latch to stop a post-refresh flap.
38
+
39
+ ## [0.3.9] - 2026-06-15
40
+
41
+ ### Fixed
42
+ - **Faster, reliable image vision (`:see`).** Fixed the daemon-only hang when attaching an image (null stdin + the bare `claude -p` invocation that works in-daemon), switched the attachment to an absolute `@<path>`, and re-added `--strict-mcp-config` to skip the ~10s MCP startup tax per call. (0.3.5–0.3.9.)
43
+
44
+ ## [0.3.4] - 2026-06-06
45
+
46
+ ### Fixed
47
+ - **Bridge no longer wedges when a second instance launches over a stale one.** The payload daemon binds the bridge + wrapper ports in-process but had no single-instance guard, so a daemon launched while a stale/wedged predecessor still held the ports would collide (EADDRINUSE, zombie Chrome, "CDP direct timeout"). The daemon now reaps a predecessor still holding the bridge/wrapper/CDP ports (only `node.exe`/`chrome.exe` — never an unrelated app) before binding, so a fresh launch reliably replaces a stuck one. The dev launcher (`npm run kill` / `npm start`) had the same gap — its port cleanup skipped the installed payload daemon, leaving two bridges colliding — and now reaps it too.
48
+
49
+ ## [0.3.3] - 2026-06-06
50
+
51
+ First public open-source release.
52
+
53
+ ### Added
54
+ - **`--pair <code>` first-run auto-pairing.** `Empir3Setup.exe --pair <code>` redeems a pre-authorized Empir3 pairing session on first boot, so an install link can pair the bridge to an account with no second login.
55
+ - **Light/dark toggle on the in-page chat panel.**
56
+
57
+ ### Fixed
58
+ - Stopped the in-page chat panel double-rendering messages on socket-capable pages.
59
+
60
+ ## [0.3.2] - 2026-06-04
61
+
62
+ ### Fixed
63
+ - Bootstrapper launcher fixes: supervised no-tray fallback, and the spawned tray is no longer placed in a kill-on-close Job Object (which had been terminating it).
64
+
65
+ ## [0.3.1] - 2026-06-04
66
+
67
+ ### Fixed
68
+ - Tray now launches reliably on a clean machine (a kill-on-close Job Object was killing it). Embedded the application icon in the installer exe.
69
+
70
+ ## [0.3.0] - 2026-06-04
71
+
72
+ ### Changed
73
+ - **Native Go bootstrapper.** Replaced the ~86 MB Node-SEA installer with a ~6.6 MB native `Empir3Setup.exe` that fetches and Ed25519-verifies a signed payload before running anything (schemaVersion 2 manifest + signed Node runtime artifact).
74
+
75
+ ## [0.2.96] - 2026-06-04
76
+
77
+ ### Fixed
78
+ - **Uninstall no longer phones home — it's now a network-free teardown.**
79
+ The bootstrapper ran its full update check (`tryUpdate`, including a payload
80
+ re-download) on `--uninstall` *before* doing anything — i.e. it could fetch
81
+ the very payload it was about to delete, and would stall or misbehave
82
+ offline. `main()` now intercepts `--uninstall` before any network logic and
83
+ tears the install down using only what's already on disk: it delegates to
84
+ the cached payload's canonical uninstall when one is extracted, and falls
85
+ back to a self-contained native cleanup (kill tray + daemon, remove
86
+ autostart, Chrome force-install policy, Start Menu shortcut, and the
87
+ `~/.empir3-bridge` + `%APPDATA%/Empir3` trees) when no usable payload is
88
+ present — so a corrupt or half-installed payload can never leave a user
89
+ unable to uninstall. Native path shows the same completion dialog.
90
+
91
+ ### Changed
92
+ - Bootstrapper internal version → **1.1.0** (`Empir3Setup.exe --bootstrap-version`),
93
+ so the new network-free uninstall is identifiable in the field. This release
94
+ rebuilds `Empir3Setup.exe`, so testing the fix requires re-downloading the
95
+ installer (not just a payload auto-update).
96
+
97
+ ## [0.2.95] - 2026-06-04
98
+
99
+ ### Changed
100
+ - **Uninstall now reassures the user instead of silently vanishing.** After
101
+ 0.2.94 made Uninstall actually work, it gave no feedback — the tray just
102
+ closed, leaving the user unsure whether anything happened. Added a proper
103
+ flow: (1) a native Yes/No confirmation dialog before anything is deleted
104
+ (defaults to No, cannot be undone), (2) an "Uninstalling Empir3…" balloon,
105
+ and (3) a "Empir3 Bridge has been uninstalled" completion dialog shown by
106
+ the bootstrapper once the wipe finishes — necessary because the bootstrapper
107
+ kills the tray as its first step, so the tray can't report completion
108
+ itself. Missing-bootstrapper and spawn failures now raise an error dialog
109
+ instead of failing silently.
110
+
111
+ ## [0.2.94] - 2026-06-04
112
+
113
+ ### Fixed
114
+ - **Tray "Uninstall Empir3" now actually uninstalls.** Clicking Uninstall
115
+ appeared to do nothing — the tray window just closed and every install
116
+ artifact stayed on disk. The tray's uninstall handler looked for
117
+ `Empir3Setup.exe` only *next to the tray exe* (`payload/<version>/`), but the
118
+ bootstrapper lives in `%APPDATA%/Empir3/`, so it never found it and logged
119
+ `bootstrapper not found; cleanup partial` before exiting. The daemon-spawn
120
+ path resolved the bootstrapper correctly via a 4-step chain
121
+ (`EMPIR3_BOOTSTRAP_EXE` → `bridge-bootstrap.json` pointer → autostart reg →
122
+ sibling) while uninstall used only the sibling check. Both paths now share a
123
+ single `resolve_bootstrap_exe()` helper so they can't drift, and Uninstall
124
+ spawns the real `Empir3Setup.exe --uninstall` cleanup.
125
+
126
+ ## [0.2.89] - 2026-06-03
127
+
128
+ ### Added
129
+ - **Antigravity (AGY) surfaced as a first-class lendable CLI.** Google's
130
+ Antigravity headless CLI (`agy`, has `-p/--print`) was probed in the backend
131
+ but invisible — no pane row, not drivable via `cli_run`, undetected by the
132
+ resolver. Now: the resolver finds it at `%LOCALAPPDATA%\agy\bin` / `~/.local/
133
+ bin`; the API & CLIs pane shows an **Antigravity** row with a lend toggle +
134
+ install link; and `cli_run`/`cli_status` accept `model:"agy"` (driven as
135
+ `agy --dangerously-skip-permissions -p @<promptfile>`, mirroring the relay
136
+ turn path). Lending is off by default like the others. Note: the IDE launcher
137
+ `antigravity-ide` is the GUI opener, not the drivable CLI — the bridge needs
138
+ `agy`. Verified detection + auth surface through the live server.
139
+
140
+ ### Added
141
+ - **Detect the Claude Code editor-extension binary.** The Claude Code VS Code /
142
+ Cursor extension bundles a full, headless-capable native `claude` at
143
+ `<ext>/resources/native-binary/claude[.exe]` but never adds it to PATH — so
144
+ `where claude` finds nothing even though Claude works in the editor, and the
145
+ bridge reported NOT INSTALLED. The resolver now finds it (newest extension
146
+ version wins) as a **last resort**, so a user who only has the extension —
147
+ no separate CLI — is auto-detected and can lend Claude without a second
148
+ install. A real standalone install still ranks ahead (PATH / npm). Verified
149
+ the bundled binary runs `--version` → `2.1.161 (Claude Code)`.
150
+
151
+ ### Changed
152
+ - **Detect Claude Code's local-installer location.** Added `~/.claude/local`
153
+ (and `~/.claude/local/node_modules/.bin`) to the well-known toolchain dirs —
154
+ the target of `claude migrate-installer`, also off-PATH.
155
+
156
+ ## [0.2.87] - 2026-06-03
157
+
158
+ ### Changed
159
+ - **CLI detection rewritten in-process (no more `where.exe` / `which`).** The old
160
+ detection shelled out to `where.exe`/`which`, which run with the *daemon's*
161
+ PATH — a tray/GUI-launched process inherits a stripped, stale PATH (winget edits
162
+ the user PATH after the daemon started; node-version-managers expose bins only
163
+ in the shell), so a CLI that resolved fine from the user's terminal read NOT
164
+ INSTALLED in the bridge. Detection is now centralized in a single
165
+ `executable-resolver` (modeled on open-design's runtimes/executables): it splits
166
+ `process.env.PATH` in-process, walks `PATHEXT`, and **augments** the search with
167
+ a cross-platform list of well-known user-toolchain dirs (npm prefix, `%APPDATA%\
168
+ npm`, winget Links + Packages, pnpm, bun, Volta, Scoop, Yarn, cargo, deno,
169
+ `~/.local/bin`, and per-version nvm/fnm node bins). Every shipped CLI (claude,
170
+ codex, gemini, grok, gh, higgsfield) now routes through it — no more scattered
171
+ per-CLI `find*` functions drifting out of sync. Verified: with PATH stripped to
172
+ System32, all six still detect via the well-known dirs.
173
+ - **Per-CLI binary override.** `CLAUDE_BIN`, `CODEX_BIN`, `GEMINI_BIN`, `GROK_BIN`,
174
+ `GH_BIN`, `HIGGSFIELD_BIN` (and `AGY_BIN`) point detection at an exact binary
175
+ when the conventional locations miss — an explicit escape hatch.
176
+
177
+ ## [0.2.86] - 2026-06-03
178
+
179
+ ### Fixed
180
+ - **winget-installed CLIs now detected.** A CLI installed via `winget` lives at
181
+ `%LOCALAPPDATA%\Microsoft\WinGet\Packages\<id>\(bin\)?<exe>` and is exposed via
182
+ the `WinGet\Links` shim — but the daemon's PATH often lacks both (winget edits
183
+ the *user* PATH after the daemon already started), so `where.exe` missed it while
184
+ the user's own shell found it. `findGhBinary` (GitHub CLI) and the generic
185
+ `findKnownWindowsExecutableCandidates` now scan the winget Links + Packages tree
186
+ directly, independent of PATH. Fixes `gh` (and any winget-installed CLI) showing
187
+ NOT INSTALLED when it's actually present.
188
+
189
+ ## [0.2.85] - 2026-06-03
190
+
191
+ ### Added
192
+ - **CLI install help + download links.** Every CLI shown as `NOT INSTALLED` on the
193
+ API & CLIs pane now gets an inline helper row: the exact install command (with a
194
+ Copy button), an "Official page ↗" link, and an **Install** button that runs the
195
+ command in a visible console — plus the nudge *"or just tell your agent to install
196
+ it."* A single `CLI_INSTALL` catalog is the source of truth, also feeding
197
+ `cli_status` (not-installed models now carry `installCommand` + `installUrl`, so a
198
+ user can tell their driving agent "install gemini" and it runs the right command).
199
+ New `POST /api/cli/install` endpoint and a **↻ Re-scan** button so a freshly
200
+ installed CLI is picked up without a full reload.
201
+
202
+ ### Changed
203
+ - **Wider CLI detection.** `findKnownWindowsExecutableCandidates` now also probes
204
+ pnpm (`$PNPM_HOME`), bun, Volta, Scoop shims, winget Links, Yarn, and
205
+ `~/.local/bin` (native installers) — fewer false `NOT INSTALLED`. macOS/Linux
206
+ detection no longer relies on `where.exe`; it falls back to `which -a` plus the
207
+ Homebrew / `/usr/local` / `~/.local/bin` roots.
208
+
209
+ ## [0.2.84] - 2026-06-02
210
+
211
+ ### Added
212
+ - **Click-to-exit on the focus box.** Selecting a `desktop_select_region` now
213
+ shows a small ✕ close button just outside the box's top-right corner; clicking
214
+ it releases the focus region directly (no agent command needed). The button is
215
+ a normal top-most window (reliable click), sits outside the region bounds so
216
+ it's never captured in a region screenshot, and tears down with the focus.
217
+
218
+ ## [0.2.83] - 2026-06-02
219
+
220
+ ### Added
221
+ - **Accuracy Lab** test surface at `/accuracy-lab` — a dense, Photoshop-style UI
222
+ with many small, tightly-packed click targets that scores hit/miss/mean-error,
223
+ a harder click-accuracy stress test than `/desktop-test`. Served from
224
+ `assets/accuracy-lab.html` (staged into the payload for the packaged daemon).
225
+
226
+ ## [0.2.82] - 2026-06-02
227
+
228
+ ### Changed
229
+ - **`desktop_select_region` focus lifecycle — idle-revoke replaces the fixed
230
+ 30-min TTL.** Previously a selected focus region was hard-killed 30 minutes
231
+ after selection regardless of use: the on-screen chip silently vanished and
232
+ the next focus-scoped call quietly grabbed the whole monitor ("lost connection
233
+ with no explanation"). Now the 30-min timer is an *idle* timer — every real
234
+ scoped use (screenshot, click, hover, drag, snapshot_som, cell/point ops,
235
+ showing the grid) resets it via a new internal `touchDesktopFocus()`, so
236
+ active work never drops the region. A region only auto-clears after a full
237
+ 30 minutes with no scoped use. Pure status reads (`desktop_focus_status`) do
238
+ NOT extend the region.
239
+
240
+ ### Added
241
+ - **Persistent ("keep until I release") focus mode.** `desktop_select_region`
242
+ accepts `keepOpen: true` (alias `persist: true`) to create a region with NO
243
+ expiry — it lives until `desktop_release_focus` (or a new selection). A global
244
+ default, settings key `desktopFocusKeepOpenDefault`, makes persistence the
245
+ default for all regions; the per-call flag overrides it either way. Useful for
246
+ long-running watches ("watch this page overnight").
247
+ - **No silent scope loss.** When a focus-scoped `desktop_screenshot` runs but no
248
+ region is active (expired or released), the result is now annotated with
249
+ `focusExpired: true` + a short `focusNote` instead of silently falling back to
250
+ the whole monitor/desktop with no signal. The fall-back capture still happens
251
+ (non-breaking); it's just observable now. Explicit-monitor and `noFocus:true`
252
+ calls are never flagged.
253
+ - **`desktop_focus_status` reports the mode.** Adds `persist` (boolean) and
254
+ `mode` (`"idle-revoke"` | `"persistent"`); `remainingMs` is `null` for
255
+ persistent regions (no expiry) and otherwise the ms until idle auto-clear
256
+ (resets on each scoped use). Adds `ttlMs` for reference.
257
+
258
+ ## [0.2.81] - 2026-06-02
259
+
260
+ ### Added
261
+ - **`cli_status`** — a read-only MCP tool that reports the lent-CLI roster so the
262
+ driving agent can discover what it can run *before* calling `cli_run`. Per
263
+ model (codex / grok / gemini / claude): `available` (installed), `lent` (owner
264
+ toggle on), `authenticated` (signed in), `ready` (all three), and `blocker`
265
+ (`cli_not_installed` / `not_lent` / `not_signed_in` / null). Previously the
266
+ agent only learned a model wasn't usable from a `cli_run` refusal.
267
+
268
+ ### Changed
269
+ - **`bridge_tool_advisor`** now covers two intents it was missing: "pull in
270
+ another model's CLI" (→ `cli_status` first, then `cli_run`) and "generate /
271
+ edit an image or video" (→ `higgsfield_*`).
272
+
273
+ ## [0.2.80] - 2026-06-02
274
+
275
+ ### Fixed
276
+ - **`browser_press` default actions** — pressing Enter (and Space) delivered the
277
+ key event to JS listeners but never fired the browser's default action, so
278
+ "type then Enter to submit/search" silently did nothing and textarea newlines
279
+ didn't insert. CDP only triggers a key's default action when the keyDown
280
+ carries the produced character; `pressKey` (bridge.ts) omitted `text`, unlike
281
+ `typeText` which sets it per char. Now Enter sends `text:'\r'`, Space sends
282
+ `text:' '`, and a bare single-character press (e.g. `"a"`) types that char.
283
+ Verified via a controlled-form CDP A/B test (no-text → 0 submits; `text:'\r'`
284
+ → submit fires).
285
+
286
+ ## [0.2.79] - 2026-06-02
287
+
288
+ ### Fixed
289
+ - **`cli_run` agentic file-writing** — three of the four lent CLIs could not
290
+ actually write files headlessly, each missing its auto-approve flag:
291
+ - **grok** now gets `--always-approve`. grok-build is agentic-first; without
292
+ it any tool call (todo/web/file) blocked on an approval prompt that never
293
+ arrives headlessly → empty stdout *and* no file (affected both text-mode
294
+ structured prompts and agentic writes).
295
+ - **gemini** agentic now gets `--yolo` (was reporting `write_file … not
296
+ available` / read-only).
297
+ - **claude** agentic now gets `--permission-mode acceptEdits` — Write was
298
+ auto-denied yet the model still reported success (silent false-write).
299
+ - **codex** unchanged (already correct via `--sandbox workspace-write`).
300
+ - **`cli_run` working directory** now defaults to the bridge's configured Home
301
+ Directory (Daemon pane, `~/Documents/Empir3`) when no explicit `cwd` is
302
+ passed — matching the interactive launcher and the relay `:cli:turn` path.
303
+ Previously fell back to the daemon's own process dir.
304
+
305
+ ## [0.2.78] - 2026-06-02
306
+
307
+ ### Added
308
+ - **`cli_run` + `cli_runs` + `cli_run_status`** — the
309
+ MCP-facing primitive for lending another model's CLI to the driving agent.
310
+ `cli_run({model: codex|grok|gemini|claude, prompt|promptFile, cwd?, mode?,
311
+ modelId?, background?, timeoutMs?})` runs that CLI one-shot and returns
312
+ `{text, exitCode, durationMs, transcriptPath, status}`. The bridge owns each
313
+ CLI's invocation quirks (Codex `exec --json` on stdin, Grok `--prompt-file`
314
+ to avoid the big-prompt exit-2, Gemini `GEMINI_CLI_TRUST_WORKSPACE` to avoid
315
+ exit-55, stderr-noise stripping) and writes a transcript under
316
+ `~/.empir3-bridge/cli-runs/`. `background:true` returns a run id; poll
317
+ `cli_run_status(id)` / list with `cli_runs`.
318
+
319
+ **Governance:** every run is refused unless that CLI's lend toggle is on
320
+ (the per-model opt-in on the API & CLIs pane) — no keys handed out, the agent
321
+ just borrows the lent seat. Orchestration stays with the calling agent; the
322
+ bridge ships only the primitive (no team/DAG engine). This is distinct from
323
+ the existing relay `<model>:cli:turn` path (Empir3-server-driven streaming),
324
+ which is untouched. `gh` stays its own governed tool; image/video gen stays in
325
+ `higgsfield_*`.
326
+
327
+ ## [0.2.77] - 2026-06-02
328
+
329
+ ### Added
330
+ - **`higgsfield_models`** — lists the live Higgsfield model catalog
331
+ (`[{job_set_type, name, type}]`, type = image/video/text), with an optional
332
+ `type` filter, cached ~5 min. So a controlling LLM discovers valid `model`
333
+ ids instead of guessing — the catalog has 40+ job-set-types and changes as
334
+ Higgsfield adds models. Default ON (read).
335
+
336
+ ### Changed
337
+ - `higgsfield_generate` description + `model`/`image`/`extra` param docs
338
+ rewritten to be self-documenting: `model` is a `job_set_type` from
339
+ `higgsfield_models` (not free-form), text→image vs image-edit (edit models
340
+ need `image`) vs video, and per-model knobs go in `extra`. Any driving LLM
341
+ can now use Higgsfield correctly without trial-and-error.
342
+
343
+ ## [0.2.76] - 2026-06-02
344
+
345
+ ### Changed
346
+ - `desktop_click` now returns a `calibrationHint` (and `monitorAtPoint`) when the
347
+ click lands on a monitor that has no saved click calibration while other
348
+ monitors are calibrated — so an agent can prompt the user to calibrate that
349
+ display. Pure annotation; never changes the click. Closes the last
350
+ reliability nit. (The interactive-snapshot styled-`div`
351
+ item was intentionally not changed: click handlers bound via addEventListener
352
+ are undetectable from the DOM, and the only universal signal — computed
353
+ cursor:pointer — is too noisy to add to default snapshots.)
354
+
355
+ ## [0.2.75] - 2026-06-02
356
+
357
+ ### Added
358
+ - **Browser-page → physical-screen coordinate mapping** —
359
+ three tools that let an agent drive the real OS mouse onto an element in the
360
+ bridge's own Chrome page, no hand-rolled calibration:
361
+ - `desktop_click_page({selector|ref|cssX/cssY, button?, double?})` — real
362
+ OS-level click on a page element (trusted hardware click, vs. synthetic
363
+ `browser_click`).
364
+ - `desktop_pointer_page({selector|ref|cssX/cssY, label?})` — ghost cursor on a
365
+ page element (visual only).
366
+ - `page_to_screen({selector|ref|cssX/cssY})` — inspect-only: returns the
367
+ element's physical virtual-screen coords, the calibrated click coord,
368
+ content-window origin, devicePixelRatio, and CSS rect.
369
+
370
+ The transform is `physical = contentOrigin + css × devicePixelRatio`, then the
371
+ existing per-monitor click calibration. `contentOrigin` is read from the
372
+ Chrome render-widget child window's physical rect (matched by an
373
+ `innerW×DPR / innerH×DPR` size fingerprint among all Chrome windows, with the
374
+ foreground window as tiebreak) — deliberately *not* `window.screenX/Y`, which
375
+ live in a global logical coordinate space that breaks across mixed-DPI
376
+ monitors. Validated to the pixel on a 3-monitor mixed-DPI rig. Windows-only;
377
+ operates on the bridge's own Chrome. `desktop_click_page`/`desktop_pointer_page`
378
+ default OFF (desktop family); `page_to_screen` is read-only and on by default.
379
+
380
+ ## [0.2.74] - 2026-06-02
381
+
382
+ ### Fixed
383
+ - `desktop_screenshot` relay path (`desktop:gui screenshot` / companion): an
384
+ active agent-focus region silently overrode an explicit `monitor` argument.
385
+ Precedence now matches the MCP path — explicit `region` > explicit `monitor`
386
+ > active focus region > default — so asking for a specific monitor while a
387
+ focus region is set returns that monitor, not the focus crop.
388
+ - `bridge_reliability_smoke` now captures the active tab's URL before its
389
+ trusted-click test (which navigates to a throwaway `data:` page) and restores
390
+ it afterward. Running the smoke no longer leaves the user's tab parked on the
391
+ test page.
392
+
393
+ ### Changed
394
+ - `browser_record_stop` returns a `refNote` when an agent-driven recording
395
+ finishes with zero element refs, clarifying that selector/evaluate-fallback
396
+ replay is expected for agent actions (only user/overlay-captured clicks carry
397
+ accessibility-tree refs) — the bare "0 element refs" count read as a failure.
398
+
399
+ ## [0.2.73] - 2026-06-01
400
+
401
+ ### Fixed
402
+ - `browser_text` (and the `desktop:browse text` relay action) no longer includes
403
+ the bridge's own injected overlay UI — the chat sidebar, toolbar, and status
404
+ text ("Bridge Disconnected / Snap / Draw / Send / …"). The overlay roots
405
+ (`id="empir3-*"`) are temporarily detached while reading `innerText`, then
406
+ restored in place within the same JS turn (no flicker), so the returned text
407
+ is just the page under test. This was adding noise that broke downstream
408
+ parsing for agents.
409
+ - `browser_snapshot` likewise skips the injected overlay subtree, so the
410
+ overlay's chat input / mode / toolbar buttons no longer appear as interactive
411
+ element refs that don't belong to the page.
412
+
413
+ ## [0.2.72] - 2026-06-01
414
+
415
+ ### Fixed
416
+ - `bridge_reliability_smoke` overlay-health gate (added in 0.2.71) now snapshots
417
+ overlay health at the *start* of the run instead of the end. The smoke's own
418
+ internal navigation to a `data:` click-test page drops the overlay, so the
419
+ end-of-run reading was always 0 clients and the gate false-failed even when
420
+ the overlay was healthy when the smoke started.
421
+
422
+ ## [0.2.71] - 2026-06-01
423
+
424
+ ### Fixed
425
+ - `desktop_screenshot_zoom` now returns the cropped image inline over MCP (it
426
+ previously returned only a saved path, defeating its purpose).
427
+ - `higgsfield_list` no longer forwards an unsupported `--limit` flag to the CLI;
428
+ the limit is applied client-side after parsing.
429
+ - `bridge_reliability_smoke` now gates on overlay health — it no longer reports
430
+ a passing run when the overlay is injected-but-dead (`overlayHealthy:false` /
431
+ no connected overlay clients).
432
+ - `desktop_screenshot` now lets an explicit `monitor` argument win over an
433
+ active agent-focus region (precedence: explicit region > explicit monitor >
434
+ focus region > all).
435
+ - `desktop_toolbar status` (read-only) now works while the toolbar group is
436
+ disabled, and the standard smoke plan marks the toolbar step optional and
437
+ skips `show` when the group is off instead of always failing.
438
+ - Ghost-cursor (`desktop_pointer_show`) labels now render non-ASCII characters
439
+ correctly (UTF-8); an em dash no longer becomes mojibake.
440
+ - Non-ASCII desktop UIA element names (accented text, icon glyphs) no longer
441
+ arrive mangled as `?`/`??` — desktop PowerShell now emits UTF-8 stdout.
442
+ - `bridge_setup_status` no longer reports a stale, frozen recordings count in
443
+ its saved snapshot that contradicted the live count.
444
+
445
+ ### Changed
446
+ - `desktop_screenshot {grid:true}` now defaults to virtual-screen coordinate
447
+ labels (directly usable with `desktop_click`) instead of axis indices, and the
448
+ `desktop_screenshot_zoom` local grid labels are spaced so they no longer
449
+ overlap on small crops.
450
+ - `desktop_select_region` now draws its instruction banner on every monitor via
451
+ a separate fully-opaque, click-through overlay so the banner is no longer
452
+ faded by the dim veil and it's clear the whole desktop is selectable.
453
+ - Click-calibration targets are far more visible: darker focusing veil, brighter
454
+ pending markers, and a high-contrast halo behind the active bullseye.
455
+ - `desktop_overlay` numbered boxes are now see-through (transparent interiors,
456
+ opaque borders + labels) so the UI behind them stays readable.
457
+ - `browser_snapshot {filter:"interactive"}` now also surfaces elements with
458
+ interactive ARIA state attributes and `contenteditable`.
459
+ - `bridge_setup_status` now reports which connected monitors still lack a saved
460
+ click calibration (`uncalibratedMonitors`).
461
+ - Softened the `browser_record_stop` summary so agent-driven recordings (which
462
+ replay via selector/coordinate steps) no longer read as a failure.
463
+
464
+ ## [0.2.70] - 2026-06-01
465
+
466
+ ### Changed
467
+ - Increased the floating desktop toolbar's usable width and height so the
468
+ recording selector, Open, Refresh, monitor label, and status text render
469
+ without clipping.
470
+
471
+ ## [0.2.69] - 2026-06-01
472
+
473
+ ### Changed
474
+ - Reworked `/desktop-test` so the form controls stay visible beside the
475
+ click/drag/screenshot harness at normal bridge-window widths, making the
476
+ smoke page a more complete one-screen test surface.
477
+
478
+ ## [0.2.68] - 2026-06-01
479
+
480
+ ### Added
481
+ - Added a standard bridge smoke-test plan at `/api/bridge-smoke-test-plan` and
482
+ `npx tsx src/cli.ts smoke-plan` so agents and maintainers use the same quick
483
+ verification flow.
484
+ - Expanded `/desktop-test` into a fuller test lab with click, drag/drop, text,
485
+ textarea, radio, checkbox, select, scroll, screenshot marker, event log, and
486
+ form submission targets.
487
+
488
+ ### Changed
489
+ - Refined the floating desktop toolbar into a branded Empir3 control deck with
490
+ focus tools, release/chat/calibration actions, current monitor context, and a
491
+ compact recording/playback transport bar.
492
+ - Updated bridge testing docs and the agent guide to require `/desktop-test`
493
+ during general bridge verification.
494
+
495
+ ## [0.2.67] - 2026-06-01
496
+
497
+ ### Fixed
498
+ - Agent-driven clicks are now suppressed at the overlay event-capture source
499
+ while recording, so the page does not echo the agent's selector click back as
500
+ a second coordinate click.
501
+
502
+ ## [0.2.66] - 2026-06-01
503
+
504
+ ### Fixed
505
+ - Strengthened recording dedupe so delayed overlay echoes are also compared
506
+ against the last saved recording action, dropping the `0,0` coordinate copy
507
+ that can follow an agent-driven selector click.
508
+
509
+ ## [0.2.65] - 2026-06-01
510
+
511
+ ### Fixed
512
+ - Recording now drops overlay echo events caused by agent-driven browser
513
+ commands, preventing selector clicks from being saved a second time as
514
+ coordinate clicks during replay.
515
+
516
+ ## [0.2.64] - 2026-06-01
517
+
518
+ ### Fixed
519
+ - Overlay readiness now verifies the current page has the injected overlay,
520
+ chat bubble, and cursor hooks before treating the overlay as healthy. Stale
521
+ WebSocket clients on port 3006 no longer prevent reinjection.
522
+ - The overlay health loop now repairs a missing current-page overlay even when
523
+ another tab still has an open overlay WebSocket.
524
+ - Overlay WebSocket connections now declare `role=overlay` and expose their
525
+ open/close state to the bridge DOM health probe for easier diagnostics.
526
+
527
+ ## [0.2.63] - 2026-06-01
528
+
529
+ ### Added
530
+ - Added the 1.6.3 tab-presence model with separate agent-controlled and
531
+ user-focused browser tabs, so opening a new tab does not automatically steal
532
+ control from an agent.
533
+ - Injected tabs now show either the normal chat bubble when the agent controls
534
+ the tab, or a compact target bubble on other tabs with explicit actions to
535
+ set user focus or hand that tab to the agent.
536
+ - Browser tab title and favicon now indicate when a tab is agent-controlled or
537
+ user-focused, and restore when the state moves elsewhere.
538
+ - DOM/ref/selector actions now show a slower virtual in-page agent cursor glide
539
+ and pulse before clicks or field focus, without moving the real mouse.
540
+ - MCP now exposes `browser_tab_state` and `browser_tab_focus` for shared
541
+ tab-control state across local MCP and Empir3/Vincent.
542
+
543
+ ## [0.2.62] - 2026-06-01
544
+
545
+ ### Added
546
+ - The tray now always shows `Release focus`, and it clears the selected focus
547
+ region, agent pointer, focus grid, desktop overlay, and browser annotation
548
+ artifacts even when no region is currently selected from the tray.
549
+ - Desktop Tools now includes first-use Testing Tools And Calibration status,
550
+ recording start/stop/list/load/playback controls, and per-monitor or
551
+ all-monitor click calibration controls.
552
+ - MCP now exposes `bridge_setup_status`, `bridge_setup_save`, and
553
+ `desktop_toolbar` so agents can confirm calibration readiness and open the
554
+ movable desktop tools widget.
555
+ - The tray can open a movable desktop toolbar with focus, release, chat
556
+ injection, record, playback, saved recording selection, and quick monitor
557
+ calibration actions.
558
+
559
+ ### Changed
560
+ - Bridge-owned overlay injection now runs by default so the chat bubble and
561
+ recording/playback hooks are present after startup without relying on the
562
+ extension path alone.
563
+
564
+ ## [0.2.61] - 2026-06-01
565
+
566
+ ### Fixed
567
+ - The browser overlay is now self-healing: when CDP is connected but no overlay
568
+ client is present, the bridge periodically re-injects the overlay instead of
569
+ waiting for a URL change or manual desktop-tools injection.
570
+ - `browser_record_start` now verifies that the overlay client is connected
571
+ before starting capture. If injection fails, recording does not start, so it
572
+ cannot silently save a zero-action recording.
573
+ - Playback now clears the `isPlaying` guard in a `finally` block so a failed
574
+ replay cannot leave the bridge stuck in `Already playing a recording`.
575
+
576
+ ### Added
577
+ - `bridge_overlay_reinject` repairs and verifies the overlay on demand for MCP,
578
+ chat, and direct `/api/command` callers.
579
+
580
+ ## [0.2.60] - 2026-06-01
581
+
582
+ ### Fixed
583
+ - Browser navigation now bypasses the generic CDP fallback chain and confirms
584
+ success from Chrome target metadata after a short direct `Page.navigate`
585
+ attempt. This keeps wrapper/Vincent navigation from timing out after Chrome
586
+ has already moved the tab.
587
+
588
+ ## [0.2.59] - 2026-06-01
589
+
590
+ ### Fixed
591
+ - Browser CDP commands now prefer a fresh page-level websocket before any
592
+ stale persistent socket, avoiding minute-long fallback stalls after tab
593
+ navigation.
594
+ - Bridge `/health` now uses cheap target discovery instead of active
595
+ `Runtime.evaluate` probes, so passive status checks cannot pile up behind
596
+ browser commands.
597
+ - Browser navigation returns from Chrome target metadata and has a wrapper
598
+ timeout, so agents receive a failure instead of hanging indefinitely if
599
+ Chrome does not answer.
600
+
601
+ ## [0.2.58] - 2026-06-01
602
+
603
+ ### Fixed
604
+ - Browser navigation now uses shorter CDP cleanup/readiness probes after
605
+ `Page.navigate`, so wrapper-mediated browser commands can return when Chrome
606
+ has already loaded the page instead of hanging on late readiness checks.
607
+
608
+ ## [0.2.57] - 2026-06-01
609
+
610
+ ### Fixed
611
+ - The HTTP wrapper now talks to the CDP bridge on `127.0.0.1` instead of
612
+ `localhost`, matching the bridge bind address and avoiding localhost
613
+ resolution/loopback stalls during wrapper-mediated browser commands.
614
+
615
+ ## [0.2.56] - 2026-06-01
616
+
617
+ ### Fixed
618
+ - Browser commands now try the already-connected page CDP socket first, then
619
+ fall back to fresh direct/browser-session sockets. This keeps the default
620
+ installed profile responsive while preserving the recovery paths added for
621
+ stale socket states.
622
+
623
+ ## [0.2.55] - 2026-06-01
624
+
625
+ ### Fixed
626
+ - The payload daemon now waits for `/health` to report `status:"connected"`
627
+ before loading the HTTP wrapper, preventing wrapper polling from racing a
628
+ half-started Chrome/CDP bridge.
629
+ - Browser health and page commands now try the direct page CDP websocket first,
630
+ with browser-level `Target.attachToTarget` kept as a fallback, matching the
631
+ path that stays fast in bundled bridge+wrapper runtime smoke tests.
632
+
633
+ ## [0.2.54] - 2026-06-01
634
+
635
+ ### Fixed
636
+ - Browser health and page commands now open a fresh browser-level CDP websocket
637
+ per command before attaching to the active target, matching the live packaged
638
+ runtime where shared in-process websocket requests can stall even while target
639
+ events continue flowing.
640
+
641
+ ## [0.2.53] - 2026-06-01
642
+
643
+ ### Fixed
644
+ - Browser health and page commands now prefer Chrome's browser-level
645
+ `Target.attachToTarget` session path, with direct page websockets only as a
646
+ fallback. This matches the live packaged runtime where browser-level CDP
647
+ stays reliable even when page websocket commands intermittently stall.
648
+
649
+ ## [0.2.52] - 2026-06-01
650
+
651
+ ### Fixed
652
+ - Browser health and commands now use verified per-command page CDP sockets
653
+ without closing the long-lived target-tracking socket, fixing live Chrome
654
+ profiles where the persistent page socket wedges while fresh CDP sockets
655
+ still answer immediately.
656
+
657
+ ## [0.2.51] - 2026-06-01
658
+
659
+ ### Fixed
660
+ - Browser/CDP readiness now requires a real `Runtime.evaluate` round trip
661
+ instead of reporting connected from Chrome target metadata alone, preventing
662
+ false-green status while `text`, `snapshot`, `screenshot`, `navigate`, or
663
+ click commands time out.
664
+ - Browser commands invalidate unhealthy CDP state and retry once instead of
665
+ masking command timeouts as healthy state.
666
+ - The CDP server now refuses to start when its HTTP port is already owned,
667
+ preventing new wrappers from silently adopting stale bridge instances.
668
+ - Direct command aliases for chat history, recordings, bridge reliability, and
669
+ safety tools now match the MCP tool surface and permission checks.
670
+ - Desktop focus grid accepts both the current `action` contract and legacy
671
+ boolean `show`, and pointer calibration correctly honors `area:"all"` while
672
+ returning `success:false` on cancelled/failed calibration.
673
+
674
+ ## [0.2.50] - 2026-05-31
675
+
676
+ ### Fixed
677
+ - Releasing or expiring the agent-focus region now also hides any visible
678
+ agent pointer so stale click guidance does not linger on screen.
679
+
680
+ ### Added
681
+ - The tray menu now shows a direct "Hide agent pointer" action whenever the
682
+ ghost pointer is visible.
683
+
684
+ ## [0.2.49] - 2026-05-31
685
+
686
+ ### Fixed
687
+ - Companion GUI screenshots now honor the active agent-focus region and default
688
+ to a region-relative grid when focus is active, so Vincent no longer falls
689
+ back to full-desktop captures after the user selects an area.
690
+
691
+ ### Added
692
+ - Companion GUI relay support for focus-grid, grid-cell click/pointer, point
693
+ picking, and set-of-mark desktop snapshots.
694
+
695
+ ## [0.2.48] - 2026-05-31
696
+
697
+ ### Fixed
698
+ - Desktop screenshots sent through the Empir3 companion relay now downscale
699
+ oversized PNG captures into bounded JPEG payloads so full-monitor shots do
700
+ not cross the production WebSocket/proxy message-size cliff and time out.
701
+
702
+ ## [0.2.47] - 2026-05-31
703
+
704
+ ### Fixed
705
+ - Release manifests now include a timestamp cache buster on payload and
706
+ signature URLs so the updater cannot fetch stale tarball bytes for a newly
707
+ published version.
708
+
709
+ ## [0.2.46] - 2026-05-31
710
+
711
+ ### Changed
712
+ - CDP overlay injection is now opt-in via `EMPIR3_BRIDGE_CDP_OVERLAY=1` so
713
+ browser-control commands are not blocked by overlay injection on live
714
+ Chrome profiles.
715
+
716
+ ## [0.2.45] - 2026-05-31
717
+
718
+ ### Fixed
719
+ - CDP overlay mailbox polling is now serialized and short-timeout bounded so
720
+ overlay chat cannot starve browser control commands.
721
+
722
+ ## [0.2.44] - 2026-05-31
723
+
724
+ ### Fixed
725
+ - Browser open no longer waits on a long post-navigation `document.readyState`
726
+ eval loop; it returns after Chrome target metadata confirms the new URL.
727
+
728
+ ## [0.2.43] - 2026-05-31
729
+
730
+ ### Fixed
731
+ - Desktop app kill now verifies that targeted PIDs have actually exited before
732
+ reporting success, preventing false-positive `app:kill` results.
733
+
734
+ ## [0.2.42] - 2026-05-31
735
+
736
+ ### Fixed
737
+ - Chrome `/json` helper requests now have a timeout so a stuck local CDP HTTP
738
+ call cannot hang `/health` or downstream browser-control endpoints.
739
+
740
+ ## [0.2.41] - 2026-05-31
741
+
742
+ ### Fixed
743
+ - Browser actions close the old long-lived page CDP websocket before opening
744
+ their fresh per-command websocket, avoiding same-process page CDP contention.
745
+
746
+ ## [0.2.40] - 2026-05-31
747
+
748
+ ### Fixed
749
+ - Browser readiness now uses Chrome target availability instead of the stale
750
+ long-lived page websocket, and browser-level websocket reconnects are
751
+ de-duplicated to avoid reconnect storms.
752
+
753
+ ## [0.2.39] - 2026-05-31
754
+
755
+ ### Fixed
756
+ - Browser navigate now falls back to Chrome target metadata when a page-level
757
+ evaluate times out after the visible navigation has already completed.
758
+
759
+ ## [0.2.38] - 2026-05-31
760
+
761
+ ### Fixed
762
+ - Browser actions now send page-level CDP commands through a fresh target
763
+ websocket per command, so stale long-lived page sockets no longer make
764
+ `browse:open`, `browse:text`, or `browse:snapshot` hang.
765
+
766
+ ## [0.2.37] - 2026-05-31
767
+
768
+ ### Fixed
769
+ - Browser control disables the Chrome permission-denial sweep by default because
770
+ `Browser.setPermission` can wedge the active page CDP websocket on some
771
+ Chrome builds.
772
+
773
+ ## [0.2.36] - 2026-05-31
774
+
775
+ ### Fixed
776
+ - Browser control now proves a newly opened CDP socket with a real round trip
777
+ before using it, and old socket timeouts can no longer reset a newer
778
+ connection.
779
+
780
+ ## [0.2.35] - 2026-05-31
781
+
782
+ ### Fixed
783
+ - Browser control no longer waits on Chrome permission-denial setup during CDP
784
+ connect, preventing `Browser.setPermission` stalls from breaking the freshly
785
+ reconnected browser socket.
786
+
787
+ ## [0.2.34] - 2026-05-31
788
+
789
+ ### Fixed
790
+ - Browser control now liveness-checks the saved CDP websocket before browser
791
+ actions and reconnects when Chrome is still reachable but the old socket has
792
+ gone stale, fixing repeated `browse:open` / `browse:snapshot` timeouts.
793
+ - Browser navigate now rejects a missing URL with a clear error instead of
794
+ throwing an internal `replace` exception.
795
+
796
+ ## [0.2.33] - 2026-05-31
797
+
798
+ ### Fixed
799
+ - Spotify/app launches now prefer known per-user executable paths when
800
+ available and verify that a matching process is running before reporting
801
+ success.
802
+
803
+ ## [0.2.32] - 2026-05-30
804
+
805
+ ### Fixed
806
+ - Plain CLI bridge prompts now explicitly direct tool-capable turns to use
807
+ Empir3 MCP tools for project files and not the CLI's local filesystem tools.
808
+ - Grok Build CLI turns now run from a disposable temp cwd while the MCP shim is
809
+ active, preventing accidental writes into the Bridge install/profile folder.
810
+
811
+ ## [0.2.31] - 2026-05-30
812
+
813
+ ### Fixed
814
+ - Gemini bridge MCP turns now provide a per-turn trusted-folders file so the
815
+ temp `.gemini/settings.json` is actually loaded before headless execution.
816
+ This lets Gemini discover and call Empir3 file tools during Koba builds.
817
+
818
+ ## [0.2.30] - 2026-05-30
819
+
820
+ ### Fixed
821
+ - Gemini bridge turns now use only `--approval-mode yolo` for tool approvals
822
+ and no longer combine it with `-y`, fixing Gemini 0.44's mutually-exclusive
823
+ flag error during Koba builds.
824
+
825
+ ## [0.2.29] - 2026-05-30
826
+
827
+ ### Fixed
828
+ - Gemini bridge turns now append the short `-p` stdin hint after model and MCP
829
+ flags, fixing the CLI help/error path where later flags were parsed as query
830
+ text during Koba builds.
831
+
832
+ ## [0.2.28] - 2026-05-30
833
+
834
+ ### Fixed
835
+ - Codex bridge turns now pass the full specialist prompt over stdin (`codex exec -`)
836
+ instead of argv, fixing Windows `spawn ENAMETOOLONG` failures on Koba builds.
837
+ - Gemini bridge turns now pass long prompts over stdin, with `-p` carrying only a
838
+ short instruction prefix so later model/MCP flags cannot be consumed as the prompt.
839
+ - Grok bridge turns now use the CLI's native `--prompt-file` path and let Grok
840
+ Build use its subscription-backed default model instead of forwarding hosted
841
+ xAI model IDs the local CLI rejects.
842
+
843
+ ## [0.2.26] - 2026-05-30
844
+
845
+ ### Fixed
846
+ - Direct app WebSocket handshakes now mark the bridge connected when the
847
+ server sends `connected`, clearing stale tray "reconnecting/sign in needed"
848
+ state after successful auth.
849
+
850
+ ## [0.2.25] - 2026-05-30
851
+
852
+ ### Fixed
853
+ - Pairing now normalizes stale Empir3 `/relay` URLs to the current `/ws`
854
+ desktop bridge endpoint so paired daemons appear online in app.empir3.
855
+ - Stored bridge auth files with legacy relay URLs are corrected at runtime
856
+ instead of leaving the tray stuck reconnecting.
857
+
858
+ ## [0.2.24] - 2026-05-30
859
+
860
+ ### Fixed
861
+ - Tray Sign in and post-sign-out pairing now open the current wrapper welcome
862
+ page on `:3006` instead of the legacy CDP setup page on `:9867`.
863
+ - Welcome relay/account status now shows rejected stored Empir3 tokens as
864
+ "SIGN IN NEEDED" instead of paired/connected.
865
+
866
+ ## [0.2.23] - 2026-05-30
867
+
868
+ ### Fixed
869
+ - Welcome-page "Apply update" tray commands now use the full update handoff:
870
+ restart the daemon to fetch the payload, then restart the tray binary once
871
+ the new payload is active.
872
+
873
+ ## [0.2.22] - 2026-05-30
874
+
875
+ ### Fixed
876
+ - Relay status now waits for the server's relay authorization event before
877
+ reporting the Empir3 relay as connected, avoiding brief false-green states
878
+ when the websocket opens and is then rejected.
879
+ - Tray status now surfaces rejected Empir3 auth as "Bridge running · sign in
880
+ needed" instead of a generic reconnecting/down state.
881
+
882
+ ## [0.2.21] - 2026-05-30
883
+
884
+ ### Fixed
885
+ - Tray status now shows the local bridge daemon as running when the daemon is
886
+ reachable, instead of showing a generic "Reconnecting..." label while the
887
+ bridge window is already up.
888
+ - Added Empir3 relay websocket keepalive pings, app-level ping replies, and
889
+ close-code logging so relay reconnect loops are easier to diagnose.
890
+
891
+ ## [0.2.20] - 2026-05-30
892
+
893
+ ### Fixed
894
+ - Tray Reconnect/Quit now runs a conservative bridge-owned process cleanup
895
+ for the wrapper, CDP bridge, controlled Chrome profile, and common dev/test
896
+ bridge sessions on `3006`/`3106`/`3206`/`3306`/`9867`/`9222`, so stale
897
+ agent-launched bridge sessions do not block a clean relaunch.
898
+ - Tray update restarts now stop and clean the old daemon before launching the
899
+ new tray binary, reducing port races during payload handoff.
900
+
901
+ ## [0.2.19] - 2026-05-30
902
+
903
+ ### Fixed
904
+ - Hardened daemon startup when the CDP bridge port `9867` is already held by
905
+ a stale bridge instance: the CDP bundle now exits cleanly after warning, so
906
+ the wrapper can continue if the existing bridge health check passes.
907
+ - Tray-supervised daemon stdout/stderr now appends to `bridge.log`, making
908
+ startup crashes diagnosable from the tray menu instead of disappearing into
909
+ `DEVNULL`.
910
+
911
+ ## [0.2.18] - 2026-05-30
912
+
913
+ ### Added
914
+ - Welcome console **Desktop Tools** pane with the local desktop-test harness,
915
+ bridge status, current URL, overlay status, safety state, and safe command
916
+ shortcuts for screenshot, refresh, snapshot, overlay injection, and write
917
+ control revocation.
918
+ - `/desktop-test` now reports total click attempts plus hit/miss counts, and
919
+ logs `click HIT` / `click MISS` so agents can tell whether a desktop click
920
+ fired even when it missed the intended target.
921
+
922
+ ### Changed
923
+ - Welcome relay status now treats paired-but-waiting as a green paired state
924
+ instead of warning yellow, and the overview relay card uses the same honest
925
+ paired/connected status.
926
+ - The top safety shorthand is now clickable `R/W/E`, with each letter toggling
927
+ the matching read/write/execute permission.
928
+ - Tray default menu action now opens `/welcome` on the active wrapper port
929
+ instead of the deprecated `/settings` page.
930
+ - Removed the tray `Enable Higgsfield CLI` menu item.
931
+ - Raised dependency floors and overrides for patched release dependencies
932
+ (`ws`, `fast-uri`, `hono`, `express-rate-limit`, `ip-address`, and `qs`).
933
+ - Hardened localhost browser boundaries: cross-origin browser HTTP mutations
934
+ and WebSocket overlay connections now require the per-launch bridge nonce.
935
+
936
+ ## [0.2.17] - 2026-05-29
937
+
938
+ ### Added
939
+ - **Route `github:probe` / `github:exec` over the empir3 device channel.**
940
+ Wakes up the lendable GitHub CLI end to end: `handleEmpir3Message` now
941
+ handles `github:probe` → `github:probe:result` (presence / auth / account
942
+ / opt-in / scope matrix) and `github:exec` → `github:exec:result`
943
+ (execute-permission + `lendGitHubCli` gated; `githubExec` enforces the
944
+ scope matrix + hard-blocks), parallel to the existing `*:cli:*` handlers
945
+ and correlated by `payload.id`. `github_status` → `github_status:result`
946
+ is read-permission gated. The server half (Vincent/Koba `github` tool) is
947
+ already live in production and routes to this. The enforcement boundary
948
+ (`handlers/github-cli.ts`) is unchanged.
949
+
950
+ ### Added
951
+ - **Lendable GitHub CLI for remote / empir3 team agents.** A new
952
+ `lendGitHubCli` master toggle (default OFF, mirrors the Claude Max lend
953
+ model) lets a remote agent act on GitHub through the user's
954
+ authenticated local `gh` — no token handoff. Surface is empir3-only
955
+ (the `github:exec` relay command); it is deliberately not a local MCP
956
+ tool. A fine-grained scope matrix (`read` / `pr` / `issue` / `repo` /
957
+ `release` / `workflow` / `admin` / `api_write`) gates every command;
958
+ token exfil (`gh auth token`/`logout`), identity swap, aliases, and
959
+ extensions are hard-blocked regardless of scopes, and unrecognized
960
+ commands default-deny. Every gh invocation is recorded in the action
961
+ log. The GitHub CLI is also added to the capability inventory and the
962
+ API & CLIs settings pane (lend toggle + scope checkboxes).
963
+ *(Consumer is dormant until empir3-server routes `github:exec`.)*
964
+
965
+ ### Fixed
966
+ - Codex CLI vision now passes the prompt before `--image`, avoiding the
967
+ repeatable image flag swallowing the prompt as another file path.
968
+
969
+ ## [0.2.8] - 2026-05-28
970
+
971
+ ### Fixed
972
+ - **The `/welcome` bridge surface now reports effective tool readiness
973
+ instead of raw registered tools.** In read-only mode the welcome page
974
+ now shows the actual available set (`21 / 51`) and marks write/execute
975
+ tools as `NEED SAFETY`; after enabling safety it shows `51 / 51 READY`.
976
+ - **Read-safe browser tools stay usable by default.** Navigation,
977
+ scrolling, and refresh now require `read` permission rather than the
978
+ global `execute` toggle, matching the user's expectation that browsing
979
+ and inspecting pages works in the default safe state.
980
+ - **Safety state is honest about global blocks.** `/api/safety` now
981
+ reports `globalSafety`, `allowedByGlobal`, and `blockedByGlobal` so
982
+ the welcome page can distinguish local tool state from globally
983
+ blocked write/execute classes.
984
+ - **Relay status no longer overstates connectivity.** A paired bridge
985
+ without an active relay now displays `PAIRED` instead of `CONNECTED`.
986
+ - **`desktop_snapshot_som` tolerates raw UIA control characters.** The
987
+ JSON sidecar parser now retries after escaping invalid control bytes,
988
+ fixing real desktop snapshots that contain hidden characters in
989
+ accessibility text.
990
+ - **Desktop smoke coverage was expanded across the welcome-era desktop
991
+ tools.** The 2026-05-28 smoke pass covered Paint launch/focus,
992
+ screenshots, UIA/SOM, click/hover/drag, overlay, pointer, focus
993
+ region, focus grid, cell targeting, region pick, and cleanup paths.
994
+
995
+ ## [0.2.7] - 2026-05-28
996
+
997
+ ### Fixed
998
+ - **`browser_highlight` now actually highlights.** The previous
999
+ implementation depended on `window.__empir3_glowElement`, a function
1000
+ the overlay injects on each page. On a freshly-navigated page where
1001
+ the overlay's CDP eval timing was just right, the call would return
1002
+ `Highlighted: <selector>` but apply zero styles. Replaced with a
1003
+ self-contained inline-style apply / restore that doesn't depend on
1004
+ the overlay being injected and uses `!important` so site CSS can't
1005
+ out-specificity the glow. Also returns a `count` field so the caller
1006
+ can tell the selector matched.
1007
+ - **`browser_record_start` now warns when the overlay isn't connected.**
1008
+ Recording is captured browser-side in the injected overlay, which
1009
+ sends each event to the wrapper over websocket. If the overlay's
1010
+ websocket is disconnected (e.g. right after `browser_navigate`),
1011
+ clicks and keystrokes silently vanish — the recording's badge counter
1012
+ ticks up because that's client-only state, but the saved file ends up
1013
+ with zero actions and the agent has no idea anything went wrong.
1014
+ `record_start` now awaits overlay injection, polls for `overlayClients
1015
+ > 0` up to 2s, and returns `{overlayConnected, warning}` so the
1016
+ caller can surface "tell the user to open the chat bubble" before any
1017
+ events are lost.
1018
+ - **`browser_play` no longer reports `passed` on missed coordinate
1019
+ clicks.** When a recorded action lacks a `ref`/`refLabel`/`selector`
1020
+ and falls back to raw coordinates, playback now hit-tests the
1021
+ resulting element. If the click landed on nothing or on a
1022
+ non-interactive container (`DIV`, `BODY`, `SECTION`, etc.), the step
1023
+ is reported as `ok: false` with a warning explaining the recording
1024
+ is coord-only and the viewport probably changed. Summary includes a
1025
+ top-level `warnings` array.
1026
+ - **`desktop_click` hit-test no longer errors with `Cannot find type
1027
+ [System.Windows.Point]`.** The UIA hit-test sidecar uses
1028
+ `System.Windows.Point` (WPF) which lives in `WindowsBase.dll`. That
1029
+ assembly wasn't being loaded, so every successful click came back
1030
+ with a noisy `hit: { error: ... }` payload. Now adds
1031
+ `Add-Type -AssemblyName WindowsBase` before constructing the point.
1032
+ - **`browser_evaluate` errors now include the real exception text.**
1033
+ CDP's `Runtime.evaluate` returns `exceptionDetails.text` ("Uncaught")
1034
+ and the actual error in `exceptionDetails.exception.description`.
1035
+ The bridge was throwing just the former, so top-level `await` and
1036
+ `const` re-declarations produced opaque `Uncaught` failures. Now
1037
+ surfaces the first line of `exception.description` (trimmed to 500
1038
+ chars).
1039
+ - **`browser_recordings` no longer dumps multi-kilobyte `data:` URIs
1040
+ in the listing.** Recordings made from `data:text/html,...` start
1041
+ URLs (cert tests, smoke fixtures) printed the entire encoded URI per
1042
+ row, making the listing unreadable. `data:` URIs collapse to
1043
+ `data:\u2026 (Nb)` and any non-data URL >100 chars truncates to
1044
+ `\u2026`.
1045
+
1046
+ ### Notes
1047
+ - All fixes are surfaced from the user-perspective smoke test
1048
+ conducted 2026-05-28. Findings P1/P1/P1/P2/P3/P3 in that order.
1049
+
1050
+ ## [0.2.6] - 2026-05-29
1051
+
1052
+ ### Reverted
1053
+ - **`desktop_click` rolled back to 0.2.3's `mouse_event` implementation.**
1054
+ 0.2.4 rewrote the click path to use `SendInput` with
1055
+ `MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK`, and 0.2.5 fixed a
1056
+ struct-size bug introduced in 0.2.4. Both changes were based on a
1057
+ misread of the `/desktop-test` diagnostic — I interpreted "click
1058
+ count: 0" as "no click events reached the page", when in fact the
1059
+ page's click count only increments on hits to the green CLICK
1060
+ TARGET button specifically. Every click WAS reaching the page — I
1061
+ was clicking the wrong viewport pixel because I was estimating
1062
+ positions from downsampled screenshots in the agent's chat
1063
+ preview. The 0.2.3 click implementation was correct all along.
1064
+ - 0.2.6 = 0.2.3's `desktop_click` PowerShell body, exactly. No
1065
+ SendInput, no INPUT struct, no virtual-desk normalization. The
1066
+ `mouse_event(LEFTDOWN, 0, 0, ...)` pattern that has worked on
1067
+ native Win32 apps for years is back.
1068
+
1069
+ ### Notes
1070
+ - Version bumped to 0.2.6 (not back-versioned to 0.2.3) so the
1071
+ auto-updater detects the new release on top of users currently
1072
+ running 0.2.4 or 0.2.5.
1073
+ - No other changes. `.mcp.json` shipped in 0.2.3 stays. All
1074
+ documentation / launch-clean work from earlier 0.2.x releases is
1075
+ preserved.
1076
+
1077
+ ## [0.2.5] - 2026-05-29
1078
+
1079
+ ### Fixed
1080
+ - **`desktop_click` INPUT struct size bug.** 0.2.4 introduced the
1081
+ SendInput path but the INPUT struct definition had three bogus
1082
+ padding ints (12 extra bytes), making `Marshal.SizeOf` return 52
1083
+ instead of the canonical Win32 size of 40 (64-bit) / 28 (32-bit).
1084
+ SendInput silently rejected every call (returned 0). Cursor still
1085
+ moved via SetCursorPos so it looked like the click was firing —
1086
+ but no actual click event reached the OS. Page-side counter stayed
1087
+ at 0 on programmatic clicks; manual mouse clicks worked normally.
1088
+ - Removed the bogus padding. Sequential layout adds the correct
1089
+ IntPtr alignment automatically.
1090
+ - Added a `sendInput` diagnostic array to the `desktop_click`
1091
+ response showing the SendInput return value for each of the three
1092
+ events (move / down / up). 1 = success, 0 = failure with extended
1093
+ GetLastError. Future regressions in this area will be immediately
1094
+ visible instead of silently failing.
1095
+
1096
+ ## [0.2.4] - 2026-05-29
1097
+
1098
+ ### Fixed
1099
+ - **Desktop click accuracy on multi-monitor Windows.** `desktop_click`
1100
+ was using `SetCursorPos + mouse_event(BUTTON_DOWN, 0, 0, ...)`. The
1101
+ second call's "fire at current cursor position" semantics drift on
1102
+ per-monitor DPI setups — the OS-level cursor goes to one physical
1103
+ pixel but the click event registers at a different one. Symptom: on
1104
+ a window straddling two monitors with mismatched DPI scaling, the
1105
+ page-side click counter never incremented despite the bridge
1106
+ reporting cursor at the requested coord. Even after a clean
1107
+ five-point per-monitor calibration measuring sub-pixel residuals,
1108
+ the clicks still missed because the bug is in the click delivery
1109
+ itself, not cursor positioning.
1110
+ - Rewrote `desktop_click` to use `SendInput` with
1111
+ `MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK` flags. Each event
1112
+ carries its own absolute target coordinate normalised against the
1113
+ virtual desktop bounds — no reliance on "current cursor position"
1114
+ at the moment of click. This is the canonical Win32 approach for
1115
+ scripted clicks and is DPI-awareness-independent.
1116
+
1117
+ ### Notes
1118
+ - `desktop_hover` and `desktop_drag` still use the legacy
1119
+ `SetCursorPos` path — those code paths reported accurate cursor
1120
+ positioning in smoke tests, so they're left in place. If a
1121
+ regression turns up they get the same SendInput treatment.
1122
+
1123
+ ## [0.2.3] - 2026-05-29
1124
+
1125
+ ### Fixed
1126
+ - Welcome console permissions count was still showing `52 / 52` after
1127
+ 0.2.2 even with no custom providers configured. Server correctly
1128
+ hides `custom_llm` from the family-gate, but the frontend was
1129
+ starting from a static 52-entry `TOOLS` array and falling back to
1130
+ defaults for missing keys (which made `custom_llm` count as
1131
+ enabled-by-default). Now: when a tool is absent from the server's
1132
+ `enabledTools` response, mark `t.hidden = true` and exclude from
1133
+ both the rendered table and all count readouts. Result: `51 / 51 ·
1134
+ 0 BLOCKED` for users with no providers, `52 / 52` after they add
1135
+ their first one.
1136
+ - Pre-existing TypeScript error in `runClaudeCliTurnInternal` —
1137
+ variable declared as `ClaudeCliMcpShim` (undeclared type) instead
1138
+ of `CliMcpShim` (the actual return type of
1139
+ `startClaudeCliMcpShim`). Surfaced after `tsc --noEmit` came back
1140
+ clean post-0.2.2; this error was introduced in a parallel session's
1141
+ gemini/grok handler commit. `tsc --noEmit` is now clean again.
1142
+
1143
+ ## [0.2.2] - 2026-05-29
1144
+
1145
+ ### Changed
1146
+ - **Renamed `openai_chat` → `custom_llm`.** The previous name collided
1147
+ with the OpenAI Codex CLI shown one row away in the same pane and
1148
+ created the wrong mental model — the tool is a generic dispatcher
1149
+ for any OpenAI-compatible endpoint (Ollama, LM Studio, OpenRouter,
1150
+ vLLM, self-hosted), not OpenAI's API. New name maps directly to the
1151
+ "+ Add custom provider" affordance and is future-proof against
1152
+ non-OpenAI-protocol endpoints. Migration is automatic: prior
1153
+ `enabledTools.openai_chat` value carries forward into
1154
+ `enabledTools.custom_llm` on first config load.
1155
+ - **`custom_llm` is now family-gated on `customProviders.length`.**
1156
+ The MCP tool only registers (and the permission only surfaces in
1157
+ the welcome console) when at least one custom provider is
1158
+ configured. Fixes the "1 BLOCKED" phantom in the Overview
1159
+ permissions card for users with no providers — count cleanly
1160
+ reports `N / N` instead of `N / N+1`. Mirrors the existing
1161
+ Higgsfield handler-family-gate pattern.
1162
+ - **Adding the first custom provider auto-enables `custom_llm`** in
1163
+ the same HTTP transaction; removing the last provider auto-disables
1164
+ it. Default flipped to `true` since the cost-opt-in decision now
1165
+ happens at the meaningful moment (when you add a provider).
1166
+
1167
+ ### Documentation
1168
+ - Full README launch-clean pass: refreshed tool inventory (57 tools,
1169
+ sectioned), added API & CLIs section, hero screenshot of welcome
1170
+ console, Troubleshooting section (Higgsfield Windows tar gotcha,
1171
+ "Connected but no tools" MCP failure modes), redrawn architecture
1172
+ diagram showing MCP shim auto-launch + API & CLIs dispatcher node.
1173
+ - SECURITY.md: data-locations split (chat config vs bridge settings
1174
+ paths), custom-provider key storage documented, supported-versions
1175
+ table bumped to 0.2.x.
1176
+ - AGENT_GUIDE: tool count 47 → 57, new §6 "API & CLIs" with
1177
+ `custom_llm` + `higgsfield_*` recipes and family-gate behavior.
1178
+
1179
+ ### Fixed
1180
+ - Pre-existing TypeScript narrowing error in `/api/cli/providers` POST
1181
+ handler (`validateProviderJson` discriminated-union didn't narrow
1182
+ under `strict: false`). Replaced `if (!valid.ok)` with `if ('error'
1183
+ in valid)` — `in`-operator narrowing works without strictNullChecks.
1184
+
1185
+ ## [0.2.1] - 2026-05-28
1186
+
1187
+ ### Added
1188
+ - **Custom OpenAI-compatible providers** — paste a JSON definition
1189
+ (schema: `slug` / `name` /
1190
+ `apiBaseUrl` / optional `models[]` / optional `apiKey`) and the
1191
+ bridge will surface it as a row on the API & CLIs pane alongside the
1192
+ built-in CLIs. Works with Ollama (`http://localhost:11434/v1`),
1193
+ LM Studio (`http://localhost:1234/v1`), llama-server, OpenRouter,
1194
+ Groq Cloud, Together AI, vLLM — anything OpenAI-compatible. Model
1195
+ list auto-populates from `GET /v1/models`. New routes:
1196
+ `POST /api/cli/providers`, `DELETE /api/cli/providers/<slug>`,
1197
+ `POST /api/cli/providers/<slug>/lend`.
1198
+ - **`openai_chat` MCP tool** — `{provider, model, prompt, system?}`
1199
+ fans out to any configured custom provider. Lets MCP clients
1200
+ (Claude Code, Continue, Cursor) route a prompt through a local LLM
1201
+ or cloud aggregator without separate config. Defaults OFF; opt in
1202
+ per session under Permissions → JavaScript (Eval) group's neighbor
1203
+ "Providers" filter.
1204
+ - **Higgsfield URL extractor** now recognizes the array-of-jobs shape
1205
+ with top-level `result_url` that the CLI actually returns (was
1206
+ missing the field, so `url` + `artifactPath` came back null on
1207
+ successful generations). Real-world shape probed during a smoke
1208
+ test and bumped to top of the priority list.
1209
+
1210
+ ### Notes
1211
+ - `lend` toggle on custom-provider rows persists locally but doesn't
1212
+ route through empir3 team agents yet — that's v2 and requires
1213
+ server-side work in the empir3 repo to consume the bridge's
1214
+ capability announcement.
1215
+
1216
+ ## [0.2.0] - 2026-05-27
1217
+
1218
+ ### Fixed
1219
+ - **Auth-launch quoting on Windows** — clicking the Authenticate button
1220
+ for any .cmd-shim provider (Gemini, Higgsfield, Claude) opened a
1221
+ console window with mangled quoting that failed with "is not
1222
+ recognized as an internal or external command". The `start ""`
1223
+ title-slot was eating the path's opening quote. Replaced with a
1224
+ direct `cmd.exe /d /s /c <cliPath> ...args` invocation in a detached
1225
+ console (mirrors `cli-runner.ts`). All five Auth buttons (Claude,
1226
+ Codex, Gemini, Grok, Higgsfield) now open clean.
1227
+ - **Auth-launch cwd** — was inheriting the bridge daemon's install dir,
1228
+ causing Gemini's "trust this folder?" gate to ask about the wrong
1229
+ directory. Now scoped to `settings.homeDirectory` (the bridge's
1230
+ approved project root) so CLIs land inside the empir3 workspace.
1231
+
1232
+ ### Added
1233
+ - **Daemon → Identity block** brings back the old `/settings`-page
1234
+ Device name + Home directory inputs into the new welcome console.
1235
+ Saves through `/api/settings/state`, prefills from `CLI_STATE.bridge`
1236
+ on every refresh. These feed empir3-agent labelling + the
1237
+ project-sync scope.
1238
+
1239
+ ## [0.1.99] - 2026-05-27
1240
+
1241
+ ### Changed
1242
+ - **Sidebar mobile toggle** — when the rail hides at ≤880px viewport, a
1243
+ hamburger button in the topbar pops it back as a floating overlay
1244
+ with a scrim. Closes on nav-click, scrim-click, or Escape.
1245
+ - **Higgsfield two-layer UX** — the family gate (API & CLIs page) and
1246
+ the per-tool toggles (Permissions page) used to look like they did
1247
+ the same thing. Now the API & CLIs column reads "Lend / Tools" with
1248
+ a dynamic label: "3 / 3 tools · configure" when on (link jumps to
1249
+ Permissions and pre-filters Higgsfield) or "tools disabled (3/3
1250
+ configured)" when off. Permissions Higgsfield group gets a yellow
1251
+ banner when the family-gate is off, with a click-through back to
1252
+ API & CLIs. Both pages cross-refresh on toggle.
1253
+
1254
+ ## [0.1.98] - 2026-05-27
1255
+
1256
+ ### Added
1257
+ - **Higgsfield CLI handler** (`src/handlers/higgsfield-cli.ts`) wrapping the
1258
+ user's local `higgsfield` binary. Three new MCP tools:
1259
+ - `higgsfield_status` (read) — returns `{installed, version, authenticated,
1260
+ credentialsPath}`. Auth check is the canonical `higgsfield auth token`
1261
+ exit-code + `hf_*` prefix; never echoes the token.
1262
+ - `higgsfield_list` (read) — proxies `higgsfield generate list --json`
1263
+ after a one-shot `--help` probe.
1264
+ - `higgsfield_generate` (execute, default OFF) — spawns `higgsfield
1265
+ generate create <model> --prompt ... --wait --json`, extracts the
1266
+ result URL via a generic path-priority parser, fetches the artifact,
1267
+ saves to `~/.empir3-bridge/artifacts/higgsfield/`, returns `{raw, url,
1268
+ artifactPath, durationMs}`. Hard-cap on `--wait-timeout` at 20 min,
1269
+ single-job FIFO queue at the handler, pass-through `extra: {...}`
1270
+ flags. Auth-expired / rate-limit / quota classified from stderr.
1271
+ - Generic handler-family gate: `settings.handlers.<name>.enabled` in
1272
+ `bridge-settings.json` (schema is additive; tray toggles flip it). Both
1273
+ the MCP shim (`tools/list` filter at startup) and the bridge dispatcher
1274
+ (per-request) enforce. Future handlers drop in via the same schema.
1275
+ - Tray menu item **"Enable Higgsfield CLI"** (checkbox) — coarse on/off
1276
+ for the whole `higgsfield_*` family.
1277
+ - Welcome console: new **Higgsfield** group/filter under Permissions.
1278
+ - **API & CLIs pane** in the welcome console (sidebar nav "API & CLIs",
1279
+ between MCP Connection and Agent Tools). Replaces the old `/settings`
1280
+ lend toggles with a unified surface covering all five CLIs the bridge
1281
+ knows about: Claude Code, OpenAI Codex, Google Gemini CLI, xAI Grok
1282
+ Build CLI, Higgsfield CLI.
1283
+ - **Per-CLI status row**: install (version), auth (creds-file vs env
1284
+ detection), lend-to-empir3 toggle for inference CLIs, handler-family
1285
+ toggle for Higgsfield.
1286
+ - **API key entry**: Anthropic, OpenAI, Google, xAI. Stored in
1287
+ `~/.empir3-bridge/config.json` under `apiKeys.{provider}`. Legacy
1288
+ `anthropicApiKey` field is mirrored both ways for back-compat.
1289
+ Submitting an empty field never clobbers a saved key.
1290
+ - **Auth button** per CLI (`POST /api/cli/auth`) — spawns the CLI's
1291
+ own login flow in a detached console window so the user can finish
1292
+ in their browser. Each provider's command is encoded in
1293
+ `authLaunchSpec()` (e.g. `claude /login`, `codex login`,
1294
+ `higgsfield auth login`).
1295
+ - Backend: `probeGeminiCli()` (binary `gemini`), `probeGrokCli()` (binary
1296
+ `grok`, fallback to `~/.grok/bin/grok[.exe]` from the xAI installer),
1297
+ `probeHiggsfieldCli()` (wraps the handler). Each gets a
1298
+ `lend{Provider}` settings key (`lendGoogleGemini`, `lendXaiGrok`).
1299
+ Auth signals: file-existence on `~/.claude/.credentials.json`,
1300
+ `~/.codex/auth.json`, `~/.gemini/oauth_creds.json`, `~/.grok/auth.json`,
1301
+ with env-var fallbacks (`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`,
1302
+ `GEMINI_API_KEY`/`GOOGLE_API_KEY`, `GROK_CODE_XAI_API_KEY`/`XAI_API_KEY`).
1303
+
1304
+ ### Changed (welcome console polish)
1305
+ - **Daemon "HEALTHY" tag** in the Process pane now reflects live `s.running`
1306
+ state instead of being hardcoded. Flips to "OFFLINE" (red) when daemon
1307
+ drops, matching the telemetry-strip LED.
1308
+ - **Activity Log detail column** shows a meaningful per-row input summary
1309
+ (URL, ref, selector, coords, monitor, recording name, text length…)
1310
+ instead of the always-`http` source. Same builder feeds the Overview
1311
+ tile and the Activity Log pane.
1312
+ - **Top-bar ⌘K search** is now live — filters the permissions table by
1313
+ tool name + blurb substring as you type, auto-switches to the
1314
+ Permissions pane on first character, Escape clears.
1315
+ - **MCP "Copy snippet"** falls back to pre-selecting the `<pre>` with
1316
+ `window.getSelection()` when `navigator.clipboard.writeText` rejects
1317
+ (headless / unfocused tab), so ⌘C / Ctrl+C completes the copy.
1318
+ - **MCP Calls tile** relabeled "MCP Calls (last 80)" — was misleading
1319
+ because the in-memory action log caps at 80 entries per session.
1320
+ - **Telemetry cells** pre-render Daemon=RUNNING, MCP=READY, PID from
1321
+ `process.pid` so first paint shows the correct state instead of
1322
+ flashing `—` until `refreshStatus()` finishes.
1323
+ - **Focus-grid button label** syncs to the daemon's authoritative state at
1324
+ boot via `/api/desktop/focus` (response now includes
1325
+ `grid: {enabled, running}`), so opening `/welcome` with the grid
1326
+ already showing via another channel no longer mis-labels the button.
1327
+
1328
+ ## [0.1.97] - 2026-05-25
1329
+
1330
+ ### Added
1331
+ - Welcome-page **Command Center**: every system-tray menu item is now also
1332
+ reachable from the bridge's web UI at `/welcome`. Four sections — Daemon
1333
+ (reconnect / open bridge / settings / live log tail), Agent controls
1334
+ (select region, release focus, toggle focus grid, calibrate clicks),
1335
+ Updates (check + Apply update + Auto-update toggle), and Tray lifecycle
1336
+ (Restart tray / Quit / Uninstall, danger-styled with confirm dialogs).
1337
+ Daemon-controllable actions hit the bridge directly; tray-lifecycle
1338
+ actions enqueue a command the tray drains on its next status poll.
1339
+ - `POST /api/shutdown` — graceful daemon exit. The tray supervisor's
1340
+ reconnect path now has the fast path it was already trying to use.
1341
+ - `GET /api/log/tail?lines=N` — bridge.log tail with action-log fallback,
1342
+ feeding the new in-page log viewer.
1343
+ - `GET /api/updates/check` — probes the public manifest, returns
1344
+ `{state, local, remote, newer, manifest}` so the welcome page can show
1345
+ update status without duplicating the tray's manifest URL.
1346
+ - `GET /api/desktop/focus` — quick check whether an agent-focus region is
1347
+ active; powers the Release-focus / Show-focus-grid button enabling.
1348
+ - `POST /api/tray/enqueue` + `GET /api/tray/commands` — whitelisted
1349
+ command queue the welcome page uses for lifecycle commands. Allowed
1350
+ types: `tray_check_updates`, `tray_apply_update`,
1351
+ `tray_toggle_auto_update`, `tray_open_log`, `tray_restart_tray`,
1352
+ `tray_quit`, `tray_uninstall`. Tray drains every status-poll tick (~4s).
1353
+
1354
+ ### Changed
1355
+ - Tray `StatusPoller` now drains `/api/tray/commands` each tick and
1356
+ dispatches each command through the existing menu-action handlers.
1357
+
1358
+ ## [0.1.96] - 2026-05-24
1359
+
1360
+ ### Added
1361
+ - `bridge_tool_advisor` MCP tool — pass `intent` as a one-line description
1362
+ ("click a small icon in Photoshop", "fill in a web form", "guide a
1363
+ tutorial without taking the mouse") and the bridge returns the matching
1364
+ tool family, rationale, and example call sequence. Aimed at agents that
1365
+ don\'t know which of the 47 tools to reach for.
1366
+ - `docs/AGENT_GUIDE.md` — intent-driven decision tree for agents driving
1367
+ the bridge. Organised as See / Find / Act / Point / Manage.
1368
+ - `scripts/smoke-all-tools.mjs` — re-runnable smoke driver that exercises
1369
+ every tool over HTTP and writes a tier-classified markdown report.
1370
+
1371
+ ### Changed
1372
+ - TOOL_META blurbs rewritten for intent-driven discoverability. Key
1373
+ primaries (`browser_snapshot`, `browser_click_ref`, `browser_type_ref`,
1374
+ `desktop_click_ref`, `desktop_snapshot_som`) now state which tool to
1375
+ reach for and what the alternatives are.
1376
+
1377
+ ## [0.1.95] - 2026-05-23
1378
+
1379
+ ### Added
1380
+ - `desktop_snapshot_som` — Set-of-Mark snapshot for the agent-focus region.
1381
+ Runs a UIA enumeration, filters to elements inside the focus (or supplied)
1382
+ region, takes a focus-scoped screenshot, and draws numbered colored boxes
1383
+ (1..N) directly on the image. The agent reads numbers off the image and
1384
+ acts via `desktop_click_ref` — removes pixel-coordinate guessing for native
1385
+ Win32 apps. Returns `empty:true` on CEF/Electron/games where UIA finds
1386
+ nothing (vision-based fallback is Phase 2).
1387
+
1388
+ ### Added
1389
+ - Initial extraction from the Empir3 codebase.
1390
+ - Browser, desktop, reliability, and safety MCP tools for local agent control.
1391
+ - Chrome CDP bridge with persistent profile.
1392
+ - HTTP wrapper layer.
1393
+ - One-command launcher: `empir3-bridge`.
1394
+ - Browser extension for HTTPS overlay support.
1395
+ - Standalone CLI: `tsx src/cli.ts <command>`.
1396
+ - DPI-aware desktop monitor, screenshot, click, hover, and drag tools.
1397
+ - Reliability receipts, `reliability-smoke`, and action log inspection.
1398
+ - Safety status and revoke-control path for disabling write-capable tools.
1399
+ - Local desktop test harness at `/desktop-test`.
1400
+ - Settings page at `/settings` for API key, CLI path, model, system prompt, loop cap, and per-tool toggles.
1401
+ - Per-tool kill switch. Read and navigate tools default on; interaction, desktop, eval, recording, and replay tools default off.
1402
+ - Chat with Claude in the overlay, with BYO API-key and BYO Claude Code CLI modes.
1403
+ - SSE endpoint `POST /api/chat/stream` for HTTP clients.
1404
+ - Conversation transcript endpoints.
1405
+ - OSS docs for safety and testing.
1406
+ - GitHub issue and PR templates.
1407
+ - CI workflow for install, type check, MCP build, and smoke placeholder.
1408
+ - Windows release pipeline for `Empir3Setup.exe`, signed payload manifests, tray app source, and installer UI.
1409
+ - Download publishing helper for `https://app.empir3.com/downloads/`.
1410
+ - CLI and MCP clients automatically read the local bridge nonce and send a legacy `action` field for compatibility with `0.1.27` during the `0.1.28` rollout.
1411
+ - Payload entrypoint startup fix for `0.1.29` so the CommonJS payload parses correctly while still supporting async tray fallback daemon startup.
1412
+ - Payload daemon startup fix for `0.1.30` so packaged bridge bundles load in-process instead of recursively launching `Empir3Setup.exe`.
1413
+ - Restored the tray status endpoint in `0.1.31` so the Windows tray reports the daemon as running instead of showing a false "Daemon not running" state.
1414
+ - Restored packaged daemon nonce creation, the tray's `Open bridge` command, and the wrapper `/welcome` page in `0.1.32`.
1415
+ - Restored the Empir3 pairing flow in `0.1.33` so "Sign in to Empir3" mints a pairing code, opens Empir3, saves the claimed token locally, and restarts into paired mode.
1416
+ - Restored the tray `Sign in` menu item in `0.1.34` for standalone Claude Code mode when no Empir3 auth is present.
1417
+ - Added direct local Empir3 login in `0.1.35` so the bridge can store an explicit user token and override whatever account the browser is currently logged into.
1418
+ - Added a tray `Switch Empir3 account` action in `0.1.36` so paired bridges can intentionally replace the locally stored Empir3 user.
1419
+ - Moved the setup choice screen into the bridge Chrome window in `0.1.37`, with clearer MCP mode vs Empir3 user mode flows and restored MCP config instructions.
1420
+ - Fixed tray `Open bridge` in `0.1.38` so it relaunches and surfaces the controlled bridge Chrome window if Chrome was closed while the daemon stayed running.
1421
+ - Restored Empir3 desktop companion registration and core remote tool handling in `0.1.39` so the web app can see the bridge and run capabilities, system info, window list, desktop screenshot, and agent-browser commands.
1422
+ - Added production/local-dev/custom Empir3 account lanes in `0.1.40`, including persisted auth server metadata, visible bridge sign-out, tray duplicate-instance protection, and a repeatable release certification harness.
1423
+ - Fixed intentional daemon restarts in `0.1.41` so sign-in, sign-out, pairing, and reconnect no longer accumulate tray crash backoff delays during account switching.
1424
+ - Fixed MCP text results in `0.1.42` so empty or structured browser text responses are always returned as protocol-valid strings, and protected the checked-in extension overlay from runtime source rewrites.
1425
+ - Hardened Chrome/CDP readiness in `0.1.43` so early browser commands recover the controlled Chrome session before failing with "Not connected."
1426
+ - Added wrapper-level Chrome wake/retry and consistent `primary` monitor support in `0.1.44`, and made release certification fail MCP tools that return `isError`.
1427
+ - Fixed the 3006 setup-page mode/login JavaScript in `0.1.45`, and added certification checks that parse the welcome script and click through MCP vs Empir3 mode switching.
1428
+ - Fixed 3006 setup-page preservation in `0.1.46` so the 9867 splash is only injected into the controlled bridge welcome page, not over the MCP/Empir3 setup UI.
1429
+ - Restored the legacy Empir3/Vincent companion surface in `0.1.47`: app/process checks, clipboard read/write/clear, shell execute with safety gates, Windows notifications, file push/pull/project/sync writes, full window/GUI dispatch, sysinfo battery/installed, broad capability scans, browser direct action aliases, and MCP `desktop_cursor_position`.
1430
+ - Added a companion surface smoke script in `0.1.47` with optional live browser checks for selector/ref click/type, screenshot shape, snapshot, and evaluate round trips.
1431
+ - Added the visible full live bridge smoke runner in `0.1.48`, covering browser, companion, desktop GUI, MCP, safety restore, and release-readiness checks.
1432
+ - Added updater stale-pointer recovery in `0.1.49` so an already-extracted newer payload is reused instead of falling back when the running tray locks the target directory.
1433
+ - Restored bridge-owned overlay injection and added updater rollback protection in `0.1.50` so chat, snap, annotate, draw, record, and playback keep working when Chrome ignores command-line extension loading.
1434
+ - Added browser scroll movement receipts in `0.1.51` with before/after positions, deltas, max scroll range, and `moved` so short pages no longer look like they actually scrolled.
1435
+ - Added explicit PNG metadata to desktop GUI screenshots in `0.1.51` and legacy companion command aliases such as `execute:run`, `window:active`, and `file:pull`.
1436
+ - Added `0.1.53` overlay usability polish: branded `empir3 Chat`, chat Home/Settings shortcuts, explicit Play/Rec labels, retained recording badges, and branded test/dashboard wordmarks.
1437
+ - Added `0.1.53` empir3 chat mirroring so the paired bridge can replace the local overlay log with the active empir3 project chat and forward overlay messages through the current project.
1438
+ - Removed the stale reduced CDP chat panel so extension and no-extension injection both use the same feature-complete overlay with side switching, annotation, drawing, recording, and saved playback.
1439
+ - Added `0.1.54` relay-compatible desktop screenshot data so `desktop:gui screenshot` returns both top-level image fields and `data.thumbnail`.
1440
+ - Fixed `0.1.55` CSS-selector typing for textareas/contenteditable targets so `browser_type` matches the working `browser_type_ref` behavior instead of throwing from the evaluate shim.
1441
+ - Updated `0.1.56` bridge welcome and launch splash branding to use the empir3 Outfit wordmark, cream/ink palette, lowercase brand copy, and purple `3`.
1442
+ - Updated `0.1.57` chat overlay layout so the top bar owns the empir3 Bridge status, includes an MCP/empir3 mode switch, routes messages to the selected chat lane, and slides page content away from the expanded panel.
1443
+ - Updated `0.1.58` chat overlay behavior so the MCP and empir3 lanes render separate visible transcripts, preventing Claude/MCP test messages from bleeding into Vincent/empir3 chat.
1444
+ - Updated `0.1.59` chat split-pane behavior so the page resizes into the remaining viewport instead of translating off-screen, and the draggable separator live-adjusts both panes.
1445
+ - Updated `0.1.60` chat header responsiveness so Fresh, Side, Close, and toolbar controls stay visible in narrow browser windows and after max-width separator drags.
1446
+ - Updated `0.1.61` chat split-pane fitting so fixed headers and viewport-width page layouts stay inside the resized page pane instead of being covered by the chat panel.
1447
+ - Updated `0.1.62` tray sign-in/sign-out routing so the welcome/login flow opens in the controlled bridge Chrome profile instead of the user's default browser, and welcome errors render in red.
1448
+ - Added `0.1.63` local Codex CLI bridge capability, probe, turn, abort, and tray opt-in groundwork so future non-Vincent team agents can run through a user-owned OpenAI/Codex account without routing Vincent away from empir3.
1449
+ - Restored `0.1.64` Claude CLI bridge relay commands, probe, turn, abort, and tray opt-in so a paired bridge can run text-only Claude Max turns through the user's local Claude Code login again.
1450
+ - Added `0.1.65` bridge control-center settings that combine account status, local Claude/Codex opt-ins, device permissions, chat engine settings, and MCP tool toggles in the bridge-owned browser UI.
1451
+ - Fixed `0.1.66` controlled-browser lifecycle handling so passive URL/status polling no longer relaunches the bridge Chrome after the user intentionally closes it.
1452
+ - Fixed `0.1.67` Codex CLI probing on Windows so the bridge checks the OpenAI Codex app install path even when the tray daemon's PATH does not include it.
1453
+ - Changed `0.1.73` welcome and settings UIs to gate empir3-account content behind sign-in so MCP-only users see a Claude/MCP-focused surface, with the empir3 entry point demoted to a single inline link in the meta footer.
1454
+ - Renamed `0.1.73` settings copy from "Vincent/team" wording to "empir3 agents" and restructured the lending opt-ins as "Use your subscriptions with empir3" with Claude Max + OpenAI Codex active and Google + xAI as coming-soon placeholders.
1455
+ - Added `0.1.73` "empir3 website policy" read-only mirror card on the bridge settings page that shows the current website-set R/W/E permissions and links to app.empir3.com/settings.
1456
+ - Added `0.1.73` enforcement of `empir3Permissions` at the empir3 dispatch entry points (`handleDesktopRelayCommand`, `claude:cli:*`, `codex:cli:*`) so website-driven policy denials surface a distinct error message and the local `globalSafety` continues to act as the final PC veto.
1457
+ - Changed `0.1.73` welcome page layout to move the local bridge safety card from the left brand column into the right shell column so the page no longer reads as a stub-right / long-left mismatch.
1458
+ - Fixed `0.1.74` overlay and SSE chat so Claude actually responds: the SSE `/api/chat/stream` handler was aborting the Claude CLI subprocess immediately because `req.on('close')` fires as soon as the POST body is received (not when the client disconnects), killing the process before it could produce output. Removed the AbortController from the SSE path — the generator terminates naturally and failed `res.write()` calls are already swallowed. Fixed Windows CLI spawn so `claude.cmd` is invoked via `cmd.exe /d /s /c` (separate args) rather than `shell: true` with a pre-quoted path, which was silently mangling the `C:\` backslash.
1459
+
1460
+ ### Changed
1461
+ - Wrapper and CDP HTTP servers now bind to `127.0.0.1` by default.
1462
+ - Chrome remote debugging launches with `--remote-debugging-address=127.0.0.1`.
1463
+ - README rewritten for public OSS launch readiness.
1464
+ - SECURITY and CONTRIBUTING docs rewritten around the current safety model.
1465
+ - Package metadata updated for browser, desktop, computer-use, and MCP discovery.
1466
+ - Single-bridge default. Parallel bridges are still available through env vars.
1467
+ - Per-bridge chat history avoids collisions for non-default wrapper ports.
1468
+ - Profile path moved to `~/.empir3-bridge/profile/`.
1469
+ - Package renamed to `@empir3hq/bridge`.
1470
+ - Package version bumped to `0.1.63` for local Codex CLI bridge-routing groundwork.
1471
+ - Package version bumped to `0.1.39` for Empir3 web-app relay compatibility.
1472
+ - Package version bumped to `0.1.40` for account-mode switching, local-dev login, and certification hardening.
1473
+ - Package version bumped to `0.1.41` for account-switch restart reliability.
1474
+ - Package version bumped to `0.1.42` for MCP protocol result hardening.
1475
+ - Package version bumped to `0.1.43` for bridge launch readiness hardening.
1476
+ - Package version bumped to `0.1.44` for MCP certification correctness and launch/desktop polish.
1477
+ - Package version bumped to `0.1.45` for setup-page interactivity certification.
1478
+ - Package version bumped to `0.1.46` for setup-page visual preservation.
1479
+ - Package version bumped to `0.1.47` for companion command recovery.
1480
+ - Package version bumped to `0.1.48` for live-smoke fixes and to force Windows updater payload refresh.
1481
+ - Package version bumped to `0.1.49` for updater stale-pointer recovery.
1482
+ - Package version bumped to `0.1.50` for packaged overlay reliability, updater rollback protection, and visible desktop smoke fixes.
1483
+ - Package version bumped to `0.1.53` for bridge chat usability, active empir3 chat mirroring, replay control discoverability, and removal of the stale reduced CDP overlay.
1484
+ - Package version bumped to `0.1.54` for relay desktop screenshot certification compatibility.
1485
+ - Package version bumped to `0.1.55` for selector-mode typing certification.
1486
+ - Package version bumped to `0.1.56` for welcome page and launch splash brand alignment.
1487
+ - Package version bumped to `0.1.57` for chat overlay lane switching and page-shift usability.
1488
+ - Package version bumped to `0.1.58` for chat lane transcript separation.
1489
+ - Package version bumped to `0.1.59` for real split-pane resizing.
1490
+ - Package version bumped to `0.1.60` for narrow chat header control visibility.
1491
+ - Package version bumped to `0.1.61` for transform-based page-pane fitting.
1492
+ - Package version bumped to `0.1.62` for controlled-browser tray sign-in and clearer welcome-page error styling.
1493
+ - Package version bumped to `0.1.65` for the bridge settings control center and tray double-click settings launcher.
1494
+ - Package version bumped to `0.1.66` for user-closed bridge Chrome lifecycle handling.
1495
+ - Package version bumped to `0.1.67` for Windows Codex CLI probing from the bridge settings page.
1496
+ - Package version bumped to `0.1.74` for overlay/SSE chat response fix and Windows CLI spawn fix.
1497
+ - The HTTP and WebSocket command handlers accept both `type` and legacy `action` command shapes.
1498
+ - Big "Select an area to share with the agent" banner on the region-select overlay in `0.1.82` so the dimmed screen is no longer a silent UI puzzle for users.
1499
+ - Active-focus frame: while a region is set via `desktop_select_region`, a click-through green rectangle is drawn just outside the region (so screenshots stay clean) plus an "Agent focus active · WxH" chip above/below it, in `0.1.82`.
1500
+ - Fixed silent focus-chip spawn in `0.1.83`: `detached: true + stdio: 'ignore' + windowsHide: true` combined caused powershell.exe to exit before the WinForms message loop started, so neither the old chip nor the new frame ever rendered. Drop `detached:true` and rely on the tray's Job Object to tear the child down on bridge shutdown.
1501
+ - Agent ghost cursor in `0.1.84`: click-through pointer overlay with `desktop_pointer_show/move/pulse/hide/status` MCP tools. Agents can point at specific screen coords without taking over the user's real mouse; optional label pill + pulse-ring animation for "look here" emphasis.
1502
+ - Click calibration in `0.1.84`: tray "Calibrate agent clicks…" menu item runs an interactive capture overlay — user clicks where they see the ghost cursor, bridge stores the (clicked - target) delta in `bridge-settings.json`, and `desktop_click` applies it automatically thereafter. Exposes `desktop_calibrate_pointer` + `desktop_calibration_status` for agent-driven recalibration.
1503
+ - TOOL_META registration in `0.1.85`: the 7 new pointer + calibration tools now appear in the Bridge control center's "Local tool permissions" panel so users can veto them per-tool. Reads (status) default on, writes (show/move/pulse/hide/calibrate) default off — same pattern as desktop_click.
1504
+ - Multi-point per-monitor calibration in `0.1.86`: replaces the single-click v1 offset with 5-point capture per monitor (corners + center) and a per-axis affine fit `actual = scale * requested + offset`. Catches DPI/scaling drift at the screen edges, not just uniform shift. Settings shape bumped to `desktopCalibration.version = 2` (legacy v1 still honored as a fallback uniform offset). `desktop_calibrate_pointer` now accepts `monitor: "primary" | "all" | "<id>"`. Bridge `applyCalibration` looks up the monitor containing the requested coord and uses its fit; falls through to identity outside calibrated monitors.
1505
+ - `desktop_pointer_show/move/pulse` now route through the same calibration in `0.1.86` so "where the agent points" matches "where the agent would click". Pass `noCalibration: true` to render at raw coords.
1506
+ - New `desktop_screenshot_zoom { x, y, radius? }` tool in `0.1.86`: returns a tight native-resolution crop centered on (x, y) with a green marker at the exact center. Agent-side fix for pixel-accurate character-level pointing — eliminates the visual estimation error from inspecting downscaled full-screen captures.
1507
+ - Calibration hardening in `0.1.87`: live test exposed that one mis-clicked target (user clicked elsewhere because the first bullseye was hidden BEHIND the instruction banner) ruined the whole affine fit (scale=0.75, residual 475px), making EVERY subsequent click worse than no calibration. Three fixes:
1508
+ - Bullseye targets are now 4× bigger (48px vs 28px) with a "Click here N/M" badge directly under each so users can't misidentify them.
1509
+ - Target insets bumped to 25% horizontal + banner-aware vertical so top targets never get covered by the title banner.
1510
+ - Bridge does MAD-based outlier rejection on captured points and refuses to persist a fit whose scale drifts more than 5% from 1.0 — both backstops against the same class of bug.
1511
+ - Focus-relative coords in `0.1.88`: `desktop_click`, `desktop_hover`, `desktop_drag`, `desktop_pointer_show/move/pulse`, and `desktop_screenshot_zoom` now accept `space: "focus"`. When set, the bridge adds the active agent-focus region's origin to (x, y) before any downstream work. Agents can read coords directly off a focus-cropped screenshot (where 0,0 = top-left of the user's selection) and pass them straight through, no manual offset math. Eliminates a whole class of "which coord system are we in" bugs that came up while clicking Zara's nose.
1512
+ - Focus-aware defaults in `0.1.89` (user feedback: "why aren't you just focused on the area I selected"):
1513
+ - `desktop_screenshot` now overlays a coord grid by default when an agent-focus region is active. Labels are FOCUS-RELATIVE (top-left = 0,0) so the agent can read a target's coords straight off the gridded image and pass them as `{x, y, space: "focus"}`. Pass `grid: false` to opt out.
1514
+ - `desktop_calibrate_pointer` defaults to `area: "focus"` when a focus region is active — the calibration overlay covers just the focus region, with 5 targets placed inside it. Smaller blast radius (no whole-monitor takeover) and a tighter fit for the area the user actually cares about. Override with `area: "monitor"` to calibrate the whole monitor.
1515
+ - Readable grid + grid-on-zoom in `0.1.90`: grid label font bumped from Consolas 9 → 12 bold so labels survive when full-focus screenshots get downscaled by chat UIs. `desktop_screenshot_zoom` now overlays a grid by default with step ~radius/6 (clamped 10–50px) and crop-local labels — agents can refine a coord from one zoom instead of dart-throwing.
1516
+ - Chess-board cell addressing in `0.1.91` (user designed the spec): focus screenshots now overlay a sparse axis grid — ~16 cells across the larger dimension with integer pill labels on the top and left edges only (no in-cell label clutter). Labels survive any chat downscale. Pair with new `desktop_click_cell { col, row, subX?, subY? }` and `desktop_pointer_cell { col, row }` tools to address targets by cell instead of pixel. "Nose looks like cell 8,7" → `desktop_click_cell col:8 row:7` lands at the cell center; subX/subY in [-0.5, 0.5] for sub-cell precision. Cell step is `max(focus.width, focus.height) / 16` clamped to [20, 200] — both grid renderer and click_cell read from the same helper so they stay in sync.
1517
+ - On-screen focus grid overlay in `0.1.92`: tray "Show focus grid" item (visible when a focus region is active) draws the SAME chess-board grid as a click-through overlay directly on the user's screen. Human and agent share one coord system in real time — user reads "nose is at cell 8,7" off their screen and the agent calls `desktop_click_cell col:8 row:7`, no screenshot round-trip, no eyeballing a downscaled image. Also exposed as `desktop_focus_grid { action }` MCP tool. Auto-respawns when the focus region moves; auto-dies when focus is released.
1518
+ - `desktop_pick_point` in `0.1.93`: agent asks user "click the spot you want me to target", a translucent capture overlay appears over the focus region, user clicks once, bridge returns the click as focus-relative pixel, absolute pixel, AND chess-board cell coords. Eliminates "click HERE → I guess where HERE is" entirely when the human can show the AI. Best paired with desktop_click_cell using the returned col/row/subX/subY.
1519
+ - Tray status anti-flap in `0.1.94`: user reported the tray icon kept flipping green↔red even though the daemon process was up and the relay was working. Two changes:
1520
+ - HTTP status-poll timeout bumped 1.0s → 3.0s and interval 2.0s → 4.0s so transient daemon stalls (PS spawns, brief WS reconnects, GC) don't time out the poll.
1521
+ - Stickiness: a failed poll is now ignored if the last successful poll was within 1 cycle — only after 2 consecutive misses does the menu surface "Disconnected." A real daemon crash still shows correctly within ~12s; a flap that resolves in one cycle is invisible to the user. Tray.log still records every state transition for debugging.
1522
+
1523
+ ### Fixed
1524
+ - Fixed `desktop:execute` shell safety in `0.1.48` so PowerShell `Remove-Item -Recurse -Force` is blocked before execution.
1525
+ - Fixed negative wheel deltas for `desktop:gui:scroll` in `0.1.48`.
1526
+ - Fixed bridge-driven browser recording in `0.1.48` so agent-initiated click/type/press/scroll/navigate actions are captured for playback.
1527
+ - Fixed updater fallback in `0.1.49` when `.version` says an older payload but the tray is already running from a newer extracted payload directory.
1528
+
1529
+ ## [0.1.0] - TBD
1530
+
1531
+ First public release. Pending standalone smoke test on fresh Windows and macOS machines.