Files
pastilhasandClaude Opus 5 52934f52dc browser, extracted from the platform — extension, relay and all
Your own Chrome, driven from Officer. Not a headless one: it attaches to the browser you are already
signed into, which is the whole difference from /scrape, and /scrape stays behind in the platform.

The relay is a sidecar now, and that is the point. It was a second Bun.serve inside the platform
process on its own port, which is exactly why it was switched off on 2026-08-13 — "the platform serves
one port". A sidecar is a process allowed its own listeners, so the objection stops applying instead of
being argued with.

The boundary across it is deliberately small: two questions, who is connected and what tabs they have,
because only those live in memory on the relay side. Screenshots, evaluation and navigation still go
straight down cdp.ts's own WebSocket to the relay's /cdp endpoint, exactly as before — routing page
bytes through the platform would be work for nothing.

Three normally-breaking changes taken now because now they are free, each already recommended in a
comment by whoever switched the relay off. Its own signing key instead of borrowing getKey('jwt'). Its
own table instead of the platform's user_integrations. And the port kept at 18792 on purpose, because
the port is an input to the token HMAC as well as an address — moving it fails every pairing silently,
and the extension blames the address. user_integrations held zero browser-relay rows, checked in
Postgres rather than assumed, so there was nothing to unpair.

The screen became panels. BrowserScreen.tsx rendered TabList and TabPreview through appType: null
placeholders; both components were already self-contained and took no props, so the screen had nothing
to pass and simply went.

Not tested end to end — no browser has been paired since the move, and that needs a Chrome and a
person. BLOCKERS.md says so rather than the commit implying otherwise.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 01:04:09 +00:00

1.8 KiB

Officer Browser Relay — Setup Guide

Prerequisites

  • Officer server running (bun dev)
  • Google Chrome or Chromium-based browser on your machine
  • Both machines on the same Tailscale network (or localhost for local dev)

Steps

1. Verify relay is running

Check the server logs for [browser-relay] listening on port 18792.

2. Get your relay credentials

Open Officer dashboard → Browser screen (or /browser). The setup card shows your server address, port, and relay token.

3. Load the extension in Chrome

  1. Open chrome://extensions
  2. Enable Developer mode (top-right toggle)
  3. Click Load unpacked
  4. Select src/extensions/browser-relay/

4. Configure the extension

  1. The options page opens automatically after install (or right-click extension → Options)
  2. Enter the Server address (Officer's IP — e.g. your Tailscale IP, or 127.0.0.1 for local)
  3. Enter the Port (default 18792)
  4. Paste your Relay token from step 2
  5. Click Save — status should show green "Relay reachable and authenticated"

5. Attach a tab

  1. Navigate to any webpage in Chrome
  2. Click the Officer Browser Relay extension icon in the toolbar
  3. Badge shows ON (cyan) = attached

6. Use from the dashboard

  1. Open /browser in Officer
  2. Your attached tab appears in the left panel
  3. Click it to see a live screenshot in the right panel
  4. Use the URL bar to navigate, or the JS console to evaluate expressions

Troubleshooting

  • Red ! badge: Relay not reachable — check server address/port/token
  • … badge: Reconnecting — relay was temporarily unavailable
  • Tab not appearing: Make sure the extension badge shows ON, and refresh the dashboard
  • Screenshot blank: The tab may be on a chrome:// page (not supported by CDP)