Skip to main content
Bun is the only toolchain: install, run, bundle and test. There is no Node, npm or esbuild step anywhere.

Commands

Browser tests use extended timeouts because they launch real browsers. Build the extension first and run only one E2E invocation at a time. The harness closes the browsers it launched in finally blocks; if a run is interrupted, close its leftover test browsers before starting another. The Chromium harness defaults to Chrome on macOS; set CHROME to use another executable. To exercise simultaneous Chrome and Brave extensions, set BROWSPARK_TEST_SECOND_BROWSER to the Brave executable and run E2E=1 bun test companion/test/multi-browser.e2e.test.ts --timeout 120000. Without this override the test launches two isolated Chrome profiles. The developer-browser test requires all four browsers; BROWSPARK_CHROME, BROWSPARK_BRAVE, BROWSPARK_FIREFOX and BROWSPARK_ZEN override executable discovery. The graph suite uses the same second-browser override and verifies dragging nodes and the canvas, zoom, live updates, logos and fallback names, reduced motion, keyboard access and the per-profile setting. The Firefox extension suite separately loads the built add-on into an isolated Firefox profile and checks sharing, automation and graph dragging; set FIREFOX to override its executable. After UI-only changes, rebuild and refresh the open dashboard tab. Reload the extension after background-process changes, and restart the companion after changing its source. Use the same checkout for both sides; a new companion process relays to an older owner if it still holds the port.

Test fixtures

test-apps/ is served by test-apps/server.ts and provides deterministic pages: a form page, a debug page with console noise, exceptions, timers and a source-mapped script, an iframe page, a second page for navigation, a service worker, a manifest, a JSON API with configurable latency, a download endpoint and a WebSocket echo. The e2e suites drive the real companion through the MCP client against these pages in both modes. Unit and bridge tests cover browser discovery, colliding native tab IDs, connection ownership, per-profile policy and disconnect cleanup. Firefox and Zen use the same MCP registrations with explicit unsupported actions; keep their coverage in sync with the adapter and its guards. The generated capability matrix covers Chromium only.

Adding a tool

  1. Register it with tool(ctx, name, description, zodShape, handler) in the right module under companion/src/tools.ts or companion/src/devtools/. The wrapper handles the per-agent context, the disabled-tool policy and result normalisation.
  2. Write the description for the agent: what it does, when to use it, what to call instead. Descriptions are the agent’s only manual.
  3. Add an example to companion/test/docs-examples.ts and run bun run docs:tools; the generator validates every example against the schema and fails on mismatch.
  4. Cover it in companion/test/e2e.test.ts or devtools.e2e.test.ts.

Docs site

The docs are a Mintlify site in docs/. Hand-written pages are MDX; docs/tools/** is generated. Preview locally with:
and check links with bunx mint broken-links. Deploy by connecting the repository in the Mintlify dashboard with docs as the docs path.

Conventions

  • TypeScript with erasable syntax only (no parameter properties, no enums), so Bun runs the source directly.
  • One zod (v4) across the project; the MCP SDK’s nested copy is deduplicated by the lockfile.
  • Conventional commit messages.
  • UI in the extension is vanilla HTML, CSS and TypeScript with design tokens for light and dark themes; no framework.