Side panel: `sidepanel.html`
The default chat UI. Persistent chat history, model badge, model picker, slash commands, past-chats drawer, mascot. Most users live here.
The Browy extension is a Chromium MV3 extension that hosts three UI surfaces (side panel, DevTools panel, options page) and talks to the native host over a single native-messaging port.
extension/├── manifest.json ← MV3 manifest, permissions, background SW├── background.js ← service worker — port owner, tool dispatch├── sidepanel.html / .js ← chat UI (default surface)├── devtools.html / .js ← registers the DevTools panel├── panel.html / .js / .css ← the actual DevTools CLI surface├── options.html / .js ← Settings (model, tools, install help)├── content/ ← injected scripts (snapshot, evaluate_js)└── icons/ ← toolbar + store assetsA single chrome.runtime.connectNative('com.browy.host') port lives
on the service worker. It’s the one and only channel to the host.
All three UI surfaces post chrome.runtime.sendMessage to the
service worker, which forwards as native-messaging frames.
Side panel: `sidepanel.html`
The default chat UI. Persistent chat history, model badge, model picker, slash commands, past-chats drawer, mascot. Most users live here.
DevTools panel: `panel.html`
The terminal-style REPL. Registered by devtools.js via
chrome.devtools.panels.create('Browy', …). Shares the agent
backend with the side panel and is bound to the inspected target.
See the DevTools CLI page.
Options: `options.html`
Model picker, tool toggles, sign-in status, and install help when the host isn’t reachable. Opens via Chrome’s standard extension options entry or Browy’s toolbar menu.
When the host says “call snapshot with these args”, the SW:
chrome.debugger.attach(target, '1.3') against
the focused tab if it isn’t already attached.Accessibility.getFullAXTree,
Input.dispatchMouseEvent, Network.enable, etc.) and shapes
the result into the tool’s expected return type.The Yellow Banner of Doom (Chrome’s “Browy started debugging…” notice) is Chrome’s mandatory disclosure for any extension using the DevTools Protocol. We don’t try to suppress it. See Permissions → debugger.
Everything user-visible is in chrome.storage.local:
chat:<id> → {messages, sessionId, createdAt, title}active_chat_idsettings.model, settings.theme,
settings.reasoning_effort, settings.tools (per-tool toggles)lastActiveTabId, used to restore which tab the
agent acts on after Chrome restartsNothing leaves the local profile. There is no remote sync.
The extension/content/ scripts are injected on demand for the
evaluate_js and query_dom tools. Most agent perception goes
through CDP rather than content scripts, because CDP gives access to
shadow DOM, iframes, and the accessibility tree without
cross-origin friction.
The extension ships as-is, with no bundler step. extension/ is a
plain Chromium extension folder. The installer copies it to your
Downloads directory; you load it with chrome://extensions →
Load unpacked. The same files are also packaged into the CRX served
by the Chrome Web Store and Edge Add-ons listings.