- TypeScript 96%
- JavaScript 3.6%
- Dockerfile 0.3%
- HTML 0.1%
| apps | ||
| docs | ||
| packages/shared | ||
| scripts | ||
| .dockerignore | ||
| .gitignore | ||
| .node-version | ||
| biome.json | ||
| compose.yaml | ||
| lefthook.yml | ||
| package.json | ||
| pnpm-lock.yaml | ||
| pnpm-workspace.yaml | ||
| README.md | ||
| tsconfig.base.json | ||
| vitest.config.ts | ||
Tab Pilot
AI-powered Chrome extension that intelligently organizes your browser tabs into groups.
Features • Architecture • Getting Started • Usage • Development
Screenshots
| Organize | Proposal View | Settings |
|---|---|---|
Replace the placeholders above with real screenshots — open the side panel, take a screenshot, and save to
docs/folder.
Features
Smart Grouping — Click "Organize" and the AI analyzes your tabs by title, URL, metadata, cached summaries, and targeted full page content when needed, then suggests logical groups.
Preview Before Apply — See proposed groups in a color-coded proposal view. Approve, dismiss, or refine with natural language feedback ("move YouTube to Entertainment", "keep GitHub separate").
Existing Group Awareness — Respects your manually created groups. The AI extends them rather than creating duplicates.
Content Extraction — Metadata and cached screenshot summaries are always available to the AI. Full page text is fetched on demand for ambiguous tabs.
AI Memory — Save reusable organization preferences as memories that influence future suggestions.
User Rules — Define deterministic rules ("github.com → Development") that are applied before the AI runs.
Screenshot Summaries — The background service worker scans missing tab summaries, caches them server-side, and shows red/yellow/green status dots in the tab list.
Drag & Drop — Manually move tabs between groups with drag-and-drop in the side panel.
Search — Search across tab titles, URLs, page content, and AI-generated summaries.
Architecture
┌─────────────────────────┐ ┌───────────────────────┐ ┌──────────────┐
│ Chrome Extension │ │ Local Server │ │ Pi Agent │
│ (Side Panel UI) │◄───►│ 127.0.0.1:7777 │◄───►│ openai-codex │
│ │ │ │ │ │
│ React 19 + Vite │ │ Hono + TypeScript │ │ Tool calls │
│ TailwindCSS │ │ SQLite + Drizzle │ │ Summaries │
│ chrome.tabs/tabGroups │ │ Memory & summaries │ │ │
│ @dnd-kit (drag & drop) │ │ Content bridge (SSE) │ │ │
└─────────────────────────┘ └───────────────────────┘ └──────────────┘
Why a local server? Your API key stays on disk (never in the browser), AI orchestration is simpler server-side, and memories, rules, settings, and tab summaries persist in a local SQLite database. Swapping AI providers is a config change.
Monorepo Structure
tab-pilot/
├── packages/shared/ # @tab-orga/shared — TypeScript types
├── apps/extension/ # Chrome extension (React side panel + service worker)
│ ├── manifest.json # Manifest V3
│ ├── src/sidepanel/ # React app (components, hooks, services)
│ ├── src/background/ # Service worker
│ └── src/content/ # Content script (on-demand extraction)
└── apps/server/ # Companion server (Hono on port 7777)
├── src/routes/ # API endpoints
├── src/services/ # Pi agent integration, storage, content bridge
└── src/prompts/ # AI prompt builders
Getting Started
Prerequisites
- Node.js ≥ 22.19.0
- pnpm ≥ 11
- Docker with Compose for the local production server
- Pi Codex auth — run
pnpm pi:loginonce after installing dependencies - Chrome or Chromium ≥ 120
Install & Build
# Clone
git clone https://github.com/beastyrabbit/tab-pilot.git
cd tab-pilot
# Install dependencies
pnpm install --frozen-lockfile
# Authenticate the Pi openai-codex provider
pnpm pi:login
# Build the server and extension
pnpm build
Run the Local Production Server
docker compose up -d --build
docker compose logs -f tab-pilot-server
The server uses Docker host networking and binds to 127.0.0.1:7777 on the host. Runtime data is stored in
apps/server/data. Pi auth is mounted from apps/server/auth.json, so it survives image
rebuilds. Verify with:
curl http://127.0.0.1:7777/api/health
Daily start after the image has already been built:
docker compose up -d
Install the Local CRX
pnpm crx:pack
pnpm crx:install
pnpm crx:pack writes ignored local artifacts under apps/extension/.local/:
tab-pilot.pemis the persistent key. Keep it forever; replacing it changes the extension ID.tab-pilot.crxis the packed extension.updates.xmlis the local Chromium update manifest.chromium-managed-policy.jsonis the managed policy for force-installing the local CRX.chromium-external-extension.jsonis the legacy Linux external install JSON.
pnpm crx:install also tries to write the managed policy JSON to
/etc/chromium/policies/managed/tab-pilot.json. If the current user cannot write there, the script
prints the exact sudo install -Dm644 ... command to run. Restart Chromium after installing or
updating the policy; Tab Pilot should appear as policy-installed without enabling Developer Mode.
If you specifically want the older Linux external extension preferences flow instead of managed
policy, use pnpm crx:install-external.
When changing extension code, run pnpm build, repack with the same PEM key, and bump
apps/extension/manifest.json version when Chromium needs to pick up the update.
Detailed local production docs:
Usage
Organizing Tabs
- Open several tabs across different topics
- Open the Tab Pilot side panel
- Optionally enter a one-off instruction, then click Organize
- Review the AI's proposed groups in the preview
- Optionally type feedback to update the proposal ("put Twitch in its own group")
- Click Apply to create the Chrome tab groups
Settings
- Model — Choose which AI model to use
- General Behavior — Custom instructions (e.g., "homelab is always a good group")
- Organization Thinking — Reasoning level for organize and refine
- Summary Thinking — Reasoning level for screenshot summaries
- Speed — Economy, Standard, or Priority service tier
- Test Mode — Preview without applying changes
- Ungroup all — Remove all tab groups in the current Chrome window from the main toolbar
Memory & Rules
- Memories — View, edit, or clear what the AI has learned. Use "AI Edit" to bulk-manage memories with natural language.
- Rules — Create deterministic rules (e.g.,
github.com → Development) that override the AI.
Development
# Dev mode (server with hot reload)
pnpm dev:server
# Dev mode (extension — rebuild on changes)
pnpm dev:extension
# Build extension for loading
pnpm build:extension
# Build and smoke-check the production server
pnpm build:server
pnpm smoke:server
# Run tests
pnpm test
# Lint & format (Biome)
pnpm lint
pnpm lint:fix
Tech Stack
| Layer | Technology |
|---|---|
| Extension UI | React 19, Vite, TailwindCSS 3, @dnd-kit |
| Extension APIs | chrome.tabs, chrome.tabGroups, chrome.scripting, chrome.debugger, chrome.alarms, chrome.storage |
| Server | Hono, TypeScript, Zod validation, SQLite, Drizzle |
| AI Backend | Pi Agent with openai-codex tool calls |
| Monorepo | pnpm workspaces |
| Quality | Biome (lint + format), Vitest, Lefthook (git hooks) |
Known Issues
- Tab group colors —
chrome.tabGroups.update()correctly sets colors via the API, but Chrome/Chromium may not visually render the color change on some platforms (confirmed Linux/Chromium). This is a Chromium rendering bug — the internal state is correct but the UI doesn't repaint. Manual color changes through Chrome's UI work fine.
License
MIT