This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Auto Tab Groups is a cross-browser extension (Chrome & Firefox) that automatically groups browser tabs by domain with custom rules support. Built with WXT framework and TypeScript, targeting Manifest V3 for both browsers.
bun installbun run build # Build for both browsers
bun run build:chrome # Build for Chrome (.output/chrome-mv3/)
bun run build:firefox # Build for Firefox (.output/firefox-mv3/)
bun run zip # Create distribution zips
bun run zip:chrome # Create Chrome zip
bun run zip:firefox # Create Firefox zipbun run dev # Start WXT dev server (default browser)
bun run dev:chrome # Start Chrome dev with hot reload
bun run dev:firefox # Start Firefox dev with hot reload (uses MV2)bun run lint # Run Biome linter
bun run lint:fix # Auto-fix Biome linting issues
bun run format # Format with Biome
bun run format:check # Check Biome formatting
bun run typecheck # Run TypeScript type checking
bun run code:check # Run Biome check and typecheck
bun run code:fix # Fix lint and formatting issues with Biomebun test # Run Vitest unit tests
bun run test:e2e # Build and run Playwright E2E testsThe extension uses a stateless architecture where the browser's tab groups API is the authoritative source. Service workers can restart at any time, so all state is persisted to browser storage and reloaded on startup.
/
├── wxt.config.ts # WXT configuration with browser-specific manifests
├── entrypoints/ # Extension entry points
│ ├── background.ts # Service worker
│ ├── popup/ # Popup UI
│ ├── sidebar/ # Sidebar UI (Chrome side panel, Firefox sidebar)
│ └── rules-modal.unlisted/ # Rules editor modal
├── services/ # Business logic
│ ├── TabGroupService.ts # Core tab grouping logic
│ ├── RulesService.ts # Custom rules management
│ └── TabGroupState.ts # State management
├── utils/ # Utilities
│ ├── DomainUtils.ts # Domain extraction with ccSLD support
│ ├── UrlPatternMatcher.ts # URL pattern matching
│ ├── RulesUtils.ts # Rule validation helpers
│ ├── Constants.ts # Tab group colors
│ └── storage.ts # WXT storage utilities
├── types/ # TypeScript types
│ ├── rules.ts # CustomRule, TabGroupColor types
│ ├── storage.ts # Storage schema types
│ └── messages.ts # Message types for background communication
├── public/ # Static assets (icons)
└── tests/ # Tests
├── *.test.ts # Vitest unit tests
└── e2e/ # Playwright E2E tests
- WXT Framework: Modern extension framework with TypeScript, hot reload, and unified manifest
- Browser Compatibility: WXT handles browser-specific manifest generation automatically
- Stateless Operations: No complex in-memory state - always query browser for current groups
- Title-Based Matching: Groups are identified by their title (domain name or custom rule name)
Background service (entrypoints/background.ts) handles:
- Loading state from storage on startup via
ensureStateLoaded() - Message-based communication with popup/sidebar
- Tab event listeners for automatic grouping
- State must be reloaded after service worker restarts
- Tab URL changes → Extract domain
- Check custom rules first (priority over domain grouping)
- Determine expected group title
- Find existing group by title or create new one
- Move tab to appropriate group if needed
- TabGroupService: Core grouping logic, handles tab operations
- RulesService: Manages custom grouping rules (multiple domains → single group)
- TabGroupState: In-memory state synchronized with browser storage
- DomainUtils: Domain extraction with ccSLD support (e.g., .co.uk, .com.au)
- UrlPatternMatcher: URL pattern matching for rules
Rules allow grouping multiple domains under a single named group:
- Stored in browser local storage
- Priority over automatic domain grouping
- Support for minimum tabs threshold (per-rule and global)
- Import/export functionality for backup/sharing
entrypoints/background.ts- Main service workerservices/TabGroupService.ts- Tab grouping logicservices/RulesService.ts- Custom rules managementutils/DomainUtils.ts- Domain processing with ccSLD supportutils/UrlPatternMatcher.ts- URL pattern matchingentrypoints/popup/main.ts- Extension popup UIentrypoints/rules-modal.unlisted/main.ts- Custom rules UIwxt.config.ts- WXT and manifest configuration
- Always test in both Chrome and Firefox after changes
- Service workers restart frequently - ensure state persistence works
- Use
browserglobal (provided by WXT) for cross-browser API calls - Group titles must be unique - handle conflicts appropriately
- Minimum tabs threshold: Groups auto-create when threshold met, auto-disband when below
- Always run
bun run code:checkafter making changes - Firefox dev mode uses MV2 for hot reload support; production builds use MV3
Firefox MV3 dev mode doesn't support hot reload due to a Mozilla bug. The dev:firefox script uses --mv2 flag for hot reload. Production builds (build:firefox) use MV3.