README.md

August 20, 2026 · View on GitHub

chrome-fx

chrome-fx

Official fx WASM terminal, injected on any page.
Talk to the agent and let it drive the current browser.

Chrome 137+ WXT fx

chrome-fx is a Manifest V3 extension that embeds the official fx interactive terminal (createFxTerminal + fx-term.wasm + xterm.js) as a floating overlay. The agent gets an in-memory just-bash workspace plus browser / js commands that click, type, navigate, evaluate JavaScript, and snapshot the live page.

This is an unofficial host for vercel-labs/fx. It is not affiliated with Vercel.

Warning

Vercel AI Gateway only. Production fx cannot use a custom OpenAI-compatible base URL or another vendor’s API key. Sign in with /login or paste a Gateway key. Tracked in vercel-labs/fx#160.

Warning

AGENTS.md is not loaded into the model prompt. The WASM host never attaches /workspace/AGENTS.md as project rules (vercel-labs/fx#157). At the start of a session, tell the agent to read it (cat AGENTS.md). Otherwise it will not know about browser / js, or that it is driving a Chrome tab.

Why this exists

WASM headless ACP (createFxAgent) cannot advertise host tools. The terminal surface is the supported way to get terminal.exec, OAuth /login, slash commands, and the real fx TUI. chrome-fx is that surface, running in Chrome instead of a local CLI.

Features

  • Floating fx button on http(s) pages; click to toggle the panel
  • Drag the button anywhere; the panel stays anchored to it
  • Resize from the opposite corner (top-left by default; flips when the button is on the left half of the page)
  • Official fx TUI: sessions, /login, /model, /setup, prompt history
  • In-memory workspace with live page files (page/a11y.md, page/text.txt, tabs.json, …)
  • browser CLI for tabs, navigation, clicks, typing, eval, screenshots, and more
  • Overlay stays in the browser top layer (Popover API) so page UI cannot cover it
  • API key and fx stores persist in chrome.storage

Requirements

  • Chrome or Edge 137+ — fx WASM needs JSPI
  • A Vercel AI Gateway key, or a Vercel login via /login in the terminal
  • pnpm 9+ for development

Firefox is not a supported runtime today (no JSPI + offscreen combination that fx needs).

Load unpacked

  1. Clone and install:

    git clone https://github.com/Lakphy/chrome-fx.git
    cd chrome-fx
    pnpm install
    pnpm build
    

    pnpm install downloads public/wasm/fx-term.wasm from the official fx try build if it is missing.

  2. Open chrome://extensions, enable Developer mode, click Load unpacked, and select .output/chrome-mv3.

  3. Open a normal https page (not chrome:// or the Chrome Web Store). Click the fx button, or use the toolbar popup → open on this page.

  4. Authenticate:

    • Paste a Vercel AI Gateway key in the popup and save, or
    • Run /login inside the terminal
  5. Pick a model the key can actually use (/model). Gateway free tier only covers a subset of the catalog.

If another machine reports WebAssembly.compile() / script-src 'self', it loaded a production build that lacked 'wasm-unsafe-eval'. Chrome’s default MV3 CSP blocks WASM; pnpm dev injects the token, but older pnpm build output did not. This repo now sets it in wxt.config.ts — rebuild and reload .output/chrome-mv3.

Development

pnpm install
pnpm dev          # WXT watch build → .output/chrome-mv3-dev
pnpm compile      # tsc --noEmit
pnpm build        # production build → .output/chrome-mv3
pnpm wasm         # refresh fx-term.wasm

Reload the unpacked extension after the first pnpm dev. Subsequent watch rebuilds usually hot-apply; if the offscreen host looks stuck, click the restart icon in the panel header.

ScriptWhat it does
pnpm devWatch build for Chrome
pnpm buildProduction MV3 bundle
pnpm zipZip the production build
pnpm compileTypecheck
pnpm wasmFetch fx-term.wasm

Regenerate toolbar icons (black field, white FX):

node scripts/generate-icons.mjs

Usage

Overlay

  • Click the fx button to open or close the panel
  • Drag the button to reposition it; the panel follows
  • Resize from the small square on the opposite corner of the panel
  • When the button crosses the left half of the viewport, the panel flips: button at bottom-left, handle at top-right

chrome://, chrome-extension://, and the Chrome Web Store cannot host the overlay.

Agent workspace

The shell is just-bash at /workspace. There is no git, Node, npm, Python, curl, or host OS.

Because fx does not auto-inject AGENTS.md on WASM, start a session by asking the agent to cat AGENTS.md (or paste that reminder yourself).

Useful entry points:

ls
cat AGENTS.md
cat page/a11y.md
browser help
browser snapshot
browser click "text=Sign in"
browser type "#email" "you@example.com"
browser eval "document.title"
js document.body.style.outline = "3px solid red"
browser navigate example.com

Page files refresh when read:

PathContents
page/url.txtCurrent tab URL
page/title.txtDocument title
page/meta.jsonURL, title, and extra metadata
page/text.txtVisible text
page/html.htmlPage HTML
page/a11y.mdHeading / control tree
tabs.jsonTabs in the current window

Selectors: CSS, #id, text=Visible label, or //xpath. Default target is the tab that opened the panel.

browser commands

browser tabs | tab <id> | info
browser navigate <url> | new [url] | close [id]
browser back | forward | reload
browser snapshot
browser click <selector> | type <selector> <text> | press <Key>
browser hover | focus | wait <selector>
browser scroll up|down|top|bottom|<y>
browser select <selector> <value>
browser eval <javascript>          # js <javascript> is an alias
browser text | html | attr <selector> …
browser cookies | screenshot | fetch <url>

See /workspace/README.md or browser help for the full list.

Architecture

┌──────────── page ────────────┐     ┌──────── service worker ────────┐
│ content script overlay       │     │ routes ports & Chrome APIs     │
│  · fx button + drag/resize   │◄───►│  · chrome.tabs / cookies       │
│  · xterm panel (shadow +     │     │  · storage                     │
│    top-layer popover)        │     │  · scripting.executeScript     │
└──────────────▲───────────────┘     └──────────────▲─────────────────┘
               │                                    │
               │                          ┌─────────▼─────────┐
               │                          │ offscreen document │
               │                          │  · fx-term.wasm    │
               │                          │  · just-bash       │
               │                          │  · browser / js    │
               │                          └───────────────────┘

        toolbar popup (API key + open on this page)
LayerRole
entrypoints/overlay.contentInjects the button and panel; positioning, drag, resize
entrypoints/panelxterm.js UI, talks to the background on chrome-friend-ui
entrypoints/popupGateway key + “open on this page”
entrypoints/backgroundPort router, offscreen lifecycle, Chrome API proxy
entrypoints/offscreenOnly place libfx + WASM may run (needs DOM + fetch)
lib/workspace.tsjust-bash + browser / js
lib/browser-tools.tsImplements browser via chrome.* and page scripts
lib/page-dispatch.tsInjected MAIN-world helpers (click, type, snapshot, …)
lib/fx-host.tscreateFxTerminal, stores, FX_MODEL, AI_GATEWAY_API_KEY

The service worker cannot instantiate WASM. The offscreen document cannot call chrome.tabs directly. Messages are validated in lib/protocol.ts before anything is proxied.

Permissions

PermissionWhy
storage / unlimitedStorageAPI key, fx config, sessions, OAuth, prompt history
tabsList / create / switch / close tabs
scriptingRun page commands in the tab
offscreenHost the WASM runtime
cookiesbrowser cookies
<all_urls>Overlay + page automation on http(s)

Limits

  • Provider / AGENTS.md — see the warnings at the top (fx#160, fx#157).
  • WASM surface — no native processes, OS sandbox, native MCP, subagents, skills, or host filesystem. That is an fx WASM constraint, not this overlay.
  • Restricted pageschrome://, edge://, chrome-extension://, and the Web Store cannot be injected.
  • Free-tier Gateway keys — many catalog models return 403 no_providers_available. Switch with /model or add Gateway credits.
  • Output cap — command previews are clipped (~64 KiB) so the TUI stays usable.

License

Source in this repository is provided as-is for use and modification. fx, libfx, and fx-term.wasm remain under their upstream licenses.