Files
BrowserOS/CLAUDE.md
Nikhil 14ab8fe97e feat: add new CDP tools and improve tool ergonomics (#396)
* feat: add new CDP tools for links, hidden pages/windows, show/move

- get_page_links: extract deduplicated links from a page via evaluate
- new_hidden_page: open a hidden tab for background automation
- create_hidden_window: create a hidden window for background automation
- show_page: restore a hidden page back into a visible window
- move_page: move a tab to a different window or position
- Default includeLinks to false in get_page_content

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: use AX tree for get_page_links, add tests, fix test scripts

- Refactor get_page_links to use accessibility tree instead of raw JS
  evaluate — more reliable for role="link" elements and shadow DOM
- Add extractLinkNodes() to snapshot.ts and getPageLinks() to browser.ts
- Add tests for get_page_links (constructed HTML with dedup/filtering),
  new_hidden_page, show_page, move_page, create_hidden_window
- Fix root package.json test scripts to match server's actual scripts
- Update CLAUDE.md test docs to reflect current structure

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 10:38:23 -08:00

6.5 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Coding guidelines

  • Use extensionless imports. Do not use .js extensions in TypeScript imports. Bun resolves .ts files automatically.
    // ✅ Correct
    import { foo } from './utils'
    import type { Bar } from '../types'
    
    // ❌ Wrong
    import { foo } from './utils.js'
    
  • Write minimal code comments. Only add comments for non-obvious logic, complex algorithms, or critical warnings. Skip comments for self-explanatory code, obvious function names, and simple operations.
  • Logger messages should not include [prefix] tags (e.g., [Config], [HTTP Server]). Source tracking automatically adds file:line:function in development mode.
  • Avoid magic constants scattered in the codebase. Use @browseros/shared for all shared configuration:
    • @browseros/shared/constants/ports - Port numbers (DEFAULT_PORTS, TEST_PORTS)
    • @browseros/shared/constants/timeouts - Timeout values (TIMEOUTS)
    • @browseros/shared/constants/limits - Rate limits, pagination, content limits (RATE_LIMITS, AGENT_LIMITS, etc.)
    • @browseros/shared/constants/urls - External service URLs (EXTERNAL_URLS)
    • @browseros/shared/constants/paths - File system paths (PATHS)
    • @browseros/shared/types/logger - Logger interface types (LoggerInterface, LogLevel)

File Naming Convention

Use kebab-case for all file and folder names:

Type Convention Example
Multi-word files kebab-case gemini-agent.ts, mcp-context.ts
Single-word files lowercase types.ts, browser.ts, index.ts
Test files .test.ts suffix mcp-context.test.ts
Folders kebab-case controller-server/, rate-limiter/

Classes remain PascalCase in code, but live in kebab-case files:

// file: gemini-agent.ts
export class GeminiAgent { ... }

Project Overview

BrowserOS Server - The automation engine inside BrowserOS. This MCP server powers the built-in AI agent and lets external tools like claude-code or gemini-cli control the browser. Starts automatically when BrowserOS launches.

Bun Preferences

Default to using Bun instead of Node.js:

  • Use bun <file> instead of node <file>
  • Use bun test instead of jest or vitest
  • Use bun install instead of npm install
  • Use bun run <script> instead of npm run <script>
  • Bun automatically loads .env (no dotenv needed)

Common Commands

# Start server (development)
bun run start                    # Loads .env.dev automatically

# Testing
bun run test                     # Run tool tests (requires BrowserOS running)
bun run test:tools               # Same as above
bun run test:integration         # Run integration tests
bun run test:sdk                 # Run SDK tests

# Run a single test file
bun --env-file=.env.development test apps/server/tests/path/to/file.test.ts

# Linting
bun run lint                     # Check with Biome
bun run lint:fix                 # Auto-fix with Biome

# Type checking
bun run typecheck                # TypeScript build check

# Build
bun run dev:server               # Build server for development
bun run dev:ext                  # Build extension for development
bun run dist:server              # Build server for production (all targets)
bun run dist:ext                 # Build extension for production

Architecture

This is a monorepo with three packages in apps/:

Server (apps/server)

The main MCP server that exposes browser automation tools via HTTP/SSE.

Entry point: apps/server/src/index.tsapps/server/src/main.ts

Key components:

  • src/tools/ - MCP tool definitions, split into:
    • cdp-based/ - Tools using Chrome DevTools Protocol (network, console, emulation, input, etc.)
    • controller-based/ - Tools using the browser extension (navigation, clicks, screenshots, tabs, history, bookmarks)
  • src/controller-server/ - WebSocket server that bridges to the browser extension
    • ControllerBridge handles WebSocket connections with extension clients
    • ControllerContext wraps the bridge for tool handlers
  • src/common/ - Shared utilities (McpContext, PageCollector, browser connection, identity, db)
  • src/agent/ - AI agent functionality (Gemini adapter, rate limiting, session management)
  • src/http/ - Hono HTTP server with MCP, health, and provider routes

Tool types:

  • CDP tools require a direct CDP connection (--cdp-port)
  • Controller tools work via the browser extension over WebSocket

Shared (packages/shared)

Shared constants, types, and configuration used by both server and extension. Avoids magic numbers.

Structure:

  • src/constants/ - Configuration values (ports, timeouts, limits, urls, paths)
  • src/types/ - Shared type definitions (logger)

Exports: @browseros/shared/constants/*, @browseros/shared/types/*

Controller Extension (apps/controller-ext)

Chrome extension that receives commands from the server via WebSocket.

Entry point: src/background/index.tsBrowserOSController

Structure:

  • src/actions/ - Action handlers organized by domain (browser/, tab/, bookmark/, history/)
  • src/adapters/ - Chrome API adapters (TabAdapter, BookmarkAdapter, HistoryAdapter)
  • src/websocket/ - WebSocket client that connects to the server

Communication Flow

AI Agent/MCP Client → HTTP Server (Hono) → Tool Handler
                                              ↓
                        CDP (direct) ←── or ──→ WebSocket → Extension → Chrome APIs

Creating Packages

When creating new packages in this monorepo:

  • Location: Packages go in packages/, apps go in apps/
  • No index.ts: Don't create or export an index.ts - it inflates the bundle with all exports
  • Separate export files: Keep exports in individual files (e.g., logger.ts, ports.ts)
  • Import pattern: import { X } from "@my-package/name/logger" - only imports what's needed

package.json exports: Must include both types and default for TypeScript:

"exports": {
  "./constants/ports": {
    "types": "./src/constants/ports.ts",
    "default": "./src/constants/ports.ts"
  },
  "./types/logger": {
    "types": "./src/types/logger.ts",
    "default": "./src/types/logger.ts"
  }
}

Test Organization

Tests are in apps/server/tests/:

  • tools/ - Tool tests (require BrowserOS running with CDP)
  • browser/ - Browser backend tests
  • agent/ - Agent tests (compaction, rate limiter)
  • sdk/ - Agent SDK tests
  • __helpers__/ - Test utilities and fixtures