Skip to content

feat: Chrome extension + monorepo restructure#10

Open
jiweiyuan wants to merge 14 commits into
mainfrom
feat/chrome-extension-monorepo
Open

feat: Chrome extension + monorepo restructure#10
jiweiyuan wants to merge 14 commits into
mainfrom
feat/chrome-extension-monorepo

Conversation

@jiweiyuan

Copy link
Copy Markdown
Contributor

Summary

  • Add a Manifest V3 Chrome extension that connects to the REPL server via WebSocket (/ws endpoint) using JSON-RPC 2.0, providing tabs, DOM, page, and cookie control through Chrome Extensions APIs
  • Restructure repo into workspace monorepo: packages/protocol (shared types), packages/cli (server + CLI), extension/ (Chrome extension built with esbuild)
  • Visual feedback inspired by Playwriter: ghost cursor with smooth CSS transitions and element highlight overlays

Test plan

  • bun test — 37/37 unit + repl tests pass (no regressions)
  • bun run build:ext — extension builds without errors
  • Load extension/dist/ in Chrome developer mode → no errors
  • Start server (browseruse --start) → extension connects (green dot in popup)
  • Send tabs.list via WebSocket → returns current tabs
  • Send dom.click → clicks element with visual cursor feedback
  • Send page.screenshot → returns base64 PNG

🤖 Generated with Claude Code

…e as monorepo

Add a Manifest V3 Chrome extension that connects to the REPL server via
WebSocket (/ws endpoint) using JSON-RPC 2.0. The extension provides
tabs, DOM, page, and cookie control through Chrome Extensions APIs,
with Playwriter-inspired visual feedback (ghost cursor, element highlight).

Restructure the repo into a workspace monorepo with three symmetric packages:
- packages/protocol: shared @browseruse/protocol JSON-RPC types
- packages/cli: server, CLI, and CDP session (@browseruse/cli)
- extension/: Chrome extension (built with esbuild)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
jiweiyuan added 13 commits May 11, 2026 18:41
…ull CDP access

Replace the offscreen WebSocket bridge with native messaging
(chrome.runtime.connectNative) and replace chrome.tabs/scripting/cookies
APIs with chrome.debugger for full CDP protocol access (all 56 domains,
652 methods) without requiring --remote-debugging-port=9222.

- Add native messaging host bridge (native-host.ts) that relays between
  Chrome's stdin/stdout protocol and the REPL server WebSocket
- Add install script for native host manifest (macOS/Linux)
- Add debugger-handler.ts for chrome.debugger attach/detach/sendCommand
- Rewrite service worker to use connectNative instead of offscreen doc
- Reduce content script to visual feedback only (cursor, highlight, ripple)
- Update ws-handler to fall back to extension debugger for session.cdpRaw
- Remove offscreen document, page-handlers, network-handlers

BREAKING CHANGE: extension no longer uses offscreen WebSocket bridge or
chrome.scripting/cookies APIs. All page/DOM/network operations must now
go through session.cdpRaw or debugger.sendCommand via chrome.debugger.
Update root package.json scripts, tsconfig references, .gitignore,
and fix relative paths in build.ts and install.ts to reflect the
new location two levels below the repo root.
Drop chrome.runtime.connectNative / native-host bridge in favor of a
direct WebSocket connection to ws://127.0.0.1:9876/ws from the service
worker. Remove nativeMessaging permission, delete native-host.ts and
native-messaging-host.json template. Rewrite install.ts to clean up
legacy native host manifests. Add AUTH_FAILED error code to protocol.

BREAKING CHANGE: the extension no longer uses native messaging; the
native host bridge and install --extension-id workflow are removed.
Listen on ~/.browseruse/browseruse.sock for NDJSON control protocol,
enabling Sarea and scripts to communicate with the REPL without HTTP.
Refactor runServer() to accept ServerOptions (silent, controlSocket)
and return ServerContext (session, server, startedAt). Add socket
cleanup on SIGINT/SIGTERM and /quit.
The root tsconfig.json references packages/protocol but the package
had no tsconfig.json, causing tsc --noEmit to fail.
Pre-flight fetch to /health verifies the server is a browseruse REPL
before attempting a WebSocket upgrade, preventing 404 errors when a
different service or older REPL without /ws occupies the port.
Shows an "Open Sarea" button in the extension popup when the REPL
server is not connected, allowing users to launch the Sarea app
directly via its io.corespeed.sarea:// URL scheme.
Replace placeholder extension icons with Sarea lion cub icon
(16/48/128px). Remove Open Sarea button from popup to keep
the UI minimal.
Resolve the browseruse extension from the Sarea app bundle
(Resources/browseruse-extension/) or from the development tree
(packages/extension/dist/). Pass --load-extension and
--disable-extensions-except flags so the extension is loaded
automatically without manual installation.

Also update the release workflow to build and package the
extension as browseruse-extension-{version}.zip alongside
the CLI binaries.
The CLI entry point moved from src/cli.ts to
packages/cli/src/cli.ts during the monorepo restructure.
Only use --load-extension for non-system profiles where the store
extension isn't installed. For system profiles, skip it to avoid
loading a duplicate alongside the Chrome Web Store version.

Also remove --disable-extensions-except so user-installed extensions
(including the store version) are not disabled.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant