Browser extension for Pilo AI-powered web automation. The extension adds a side panel to your browser that lets you run Pilo automation tasks interactively on any page, without leaving the browser.
The Pilo extension is bundled with @tabstack/pilo. After installing the npm package, use the pilo extension install command to load it into your browser.
Chrome stable ignores the --load-extension flag when launched programmatically, so the extension must be loaded manually:
pilo extension install chromeThis command prints the extension directory path and step-by-step instructions:
- Open Chrome and navigate to
chrome://extensions - Enable Developer mode (toggle in the top-right corner)
- Click Load unpacked
- Select the extension directory printed by the command above
Firefox supports loading the extension directly from the CLI via web-ext:
# Launch Firefox with the extension loaded (persistent profile)
pilo extension install firefox
# Launch Firefox with a temporary profile
pilo extension install firefox --tmpThe extension supports multiple AI providers:
- OpenAI - Cloud service with API key authentication
- OpenRouter - Cloud service with API key authentication (default)
- Google Generative AI - Cloud service with API key authentication
- Ollama - Local models with optional API key
To use Ollama with the browser extension, you need to configure CORS settings so the extension can reach the local server.
Option 1: Enable in the Ollama app
- Open Ollama app settings
- Enable "Expose Ollama to the network"
- Restart Ollama if needed
Option 2: Set an environment variable
OLLAMA_ORIGINS="*" ollama serveIn the extension settings:
- Provider: Select "Ollama (Local)"
- Base URL: Default is
http://localhost:11434/api - Model: Use any model you have installed (e.g.,
llama3,qwen3-vl) - API Key: Optional (leave empty for local use)
- Node.js
^22.0.0 - pnpm
9.0.0
Install dependencies from the monorepo root:
pnpm installRun the extension in a live-reloading browser instance:
# From the monorepo root:
pnpm run dev:extension -- --chrome # Chrome with persistent profile
pnpm run dev:extension -- --firefox # Firefox with persistent profile
# With a temporary profile (fresh state on every run):
pnpm run dev:extension -- --chrome --tmp
pnpm run dev:extension -- --firefox --tmp
# From inside packages/extension:
pnpm dev -- --chrome
pnpm dev -- --firefox
pnpm dev -- --chrome --tmpThe --tmp flag starts the browser with a clean temporary profile. Use it when you want to test the extension from a blank state.
# From the monorepo root or inside packages/extension:
pnpm run build:chrome # Build for Chrome (MV3)
pnpm run build:firefox # Build for Firefox (MV2)
# Build both (used by the root publish pipeline):
pnpm run build:publishBuild output is written to .output/chrome-mv3/ and .output/firefox-mv2/ inside packages/extension.
# Unit tests (Vitest)
pnpm test
# End-to-end tests (Playwright)
pnpm test:e2e
# End-to-end tests in headless mode
pnpm test:e2e:headlesspnpm typecheckpackages/extension/
├── src/
│ ├── ui/ # Side panel React components, hooks, and stores
│ ├── background/ # Service worker (AgentManager, ExtensionBrowser)
│ ├── content/ # Content script entry
│ └── shared/ # Types, utilities, and stores shared across entrypoints
├── entrypoints/ # WXT entrypoints (sidepanel, background, content)
├── scripts/ # Dev script (dev.ts)
└── test/ # Test files
The extension is built with WXT and React. It imports from pilo-core/core (the browser-safe subset of the core library) rather than pilo-core, which avoids pulling in Node.js-only dependencies.