UNPKG

browser-extension-manager

Version:
818 lines (649 loc) 30 kB
# Browser Extension Manager (BEM) ## Identity Browser Extension Manager (BEM) is a comprehensive framework for building modern browser extensions. It provides a template-based development system with built-in build tools, component architecture, theming support, and best practices for creating cross-browser extensions. ## Quick Start ### For Consuming Projects (Extensions Built Using BEM) 1. Run `npx bxm setup` to initialize the project 2. Run `npm start` to start development 3. Load `packaged/raw/` directory in browser as unpacked extension 4. Edit files in `src/` - changes auto-reload via WebSocket ### For Framework Development (This Repository) 1. Run `npm start` to watch and compile framework changes 2. Test changes in a consuming project by linking: `npm link` (in BEM) then `npm link browser-extension-manager` (in consuming project) 3. Changes in `src/` compile to `dist/` automatically ## Architecture Overview ### Component-Based System Extensions are organized around **components**, each representing a distinct part: **Core Components:** - `background` - Service worker (background script) - `popup` - Browser action popup - `options` - Options/settings page - `sidepanel` - Chrome side panel - `content` - Content scripts injected into web pages - `pages` - Custom extension pages (e.g., dashboard, welcome) **Each component has three parts:** 1. **View** - HTML in `src/views/[component]/index.html` 2. **Styles** - SCSS in `src/assets/css/components/[component]/index.scss` 3. **Script** - JS in `src/assets/js/components/[component]/index.js` **Compilation output:** - `dist/views/[component]/index.html` - `dist/assets/css/components/[component].bundle.css` - `dist/assets/js/components/[component].bundle.js` ### Two-Tier Architecture **Framework Layer** (`src/` in this repository): - Core framework code and components - Default templates and configurations - Build system and tooling - Published to npm as `browser-extension-manager` **Project Layer** (consuming extension projects): - User's extension-specific code - Overrides and customizations - Receives defaults from `src/defaults/` via the `defaults` gulp task ## Framework Structure (This Repository) ``` browser-extension-manager/ ├── src/ # Framework source code │ ├── assets/ # Framework assets │ │ ├── css/ # SCSS framework │ │ │ ├── browser-extension-manager.scss # Main entry point │ │ │ ├── core/ # Core styles (utilities, animations, initialize) │ │ │ ├── components/ # Component-specific styles (popup, options, content, pages) │ │ │ └── bundles/ # Custom bundle SCSS files │ │ ├── js/ # JavaScript framework │ │ │ └── main.js │ │ ├── themes/ # Theme system │ │ │ ├── _template/ # Template for creating new themes │ │ │ ├── bootstrap/ # Bootstrap theme (full Bootstrap 5 source) │ │ │ └── classy/ # Classy theme (Bootstrap + custom design system) │ │ └── vendor/ # Vendor assets │ ├── defaults/ # Default project structure (copied to consuming projects) │ │ ├── src/ │ │ │ ├── assets/ │ │ │ │ ├── css/ │ │ │ │ │ ├── main.scss # Global styles entry point │ │ │ │ │ └── components/ # Component-specific overrides │ │ │ │ ├── js/ │ │ │ │ │ └── components/ # Component JavaScript │ │ │ │ ├── images/ │ │ │ │ └── vendor/ │ │ │ ├── views/ # HTML views (templates) │ │ │ ├── manifest.json # Extension manifest (user-editable) │ │ │ └── _locales/ # Internationalization │ │ ├── hooks/ # Build hooks │ │ ├── config/ # Configuration files │ │ └── CLAUDE.md # Project documentation template │ ├── config/ # Framework configuration │ │ ├── manifest.json # Default manifest configuration │ │ └── page-template.html # HTML template for views │ ├── gulp/ # Build system │ │ ├── main.js # Gulp entry point │ │ ├── tasks/ # Gulp tasks │ │ │ ├── defaults.js # Copy default files to project │ │ │ ├── distribute.js # Distribute project files to dist/ │ │ │ ├── sass.js # Compile SCSS │ │ │ ├── webpack.js # Bundle JavaScript │ │ │ ├── html.js # Process HTML views │ │ │ ├── icons.js # Generate icon sizes │ │ │ ├── package.js # Package extension for distribution │ │ │ ├── audit.js # Run audits │ │ │ └── serve.js # Development server │ │ └── plugins/ # Custom plugins │ │ └── webpack/ │ │ └── strip-dev-blocks.js # Strip dev-only code │ ├── lib/ # Utility libraries │ │ ├── extension.js # Cross-browser extension API wrapper │ │ ├── logger.js # Logging utility │ │ └── logger-lite.js # Lightweight logger │ ├── commands/ # CLI commands │ │ ├── setup.js # Setup project │ │ ├── clean.js # Clean build artifacts │ │ └── version.js # Version management │ ├── build.js # Build manager class │ ├── background.js # Background script manager │ ├── popup.js # Popup manager │ ├── options.js # Options manager │ ├── sidepanel.js # Sidepanel manager │ ├── page.js # Page manager │ ├── content.js # Content script manager │ └── cli.js # CLI entry point ├── dist/ # Compiled framework (published to npm) ├── bin/ # CLI binaries │ └── browser-extension-manager ├── package.json └── CLAUDE.md # This file ``` ## Consuming Project Structure When users create a project using BEM, they get this structure: ``` my-extension/ ├── src/ │ ├── assets/ │ │ ├── css/ │ │ │ ├── main.scss # Global styles │ │ │ └── components/ # Component-specific styles │ │ ├── js/ │ │ │ └── components/ # Component JavaScript │ │ ├── images/ │ │ │ └── icon.png # Source icon (1024x1024) │ │ └── vendor/ │ ├── views/ # HTML templates │ ├── _locales/ # i18n translations │ └── manifest.json # Extension manifest ├── config/ │ └── config.json # BEM configuration ├── hooks/ │ ├── build:pre.js # Pre-build hook │ └── build:post.js # Post-build hook ├── dist/ # Compiled files (gitignored) ├── packaged/ # Packaged extension (gitignored) │ ├── raw/ # Load this in browser │ └── extension.zip # Production build └── package.json ``` ## Development Instructions ### Creating a New Component When adding a new component type to the framework: 1. **Create framework component styles:** ``` src/assets/css/components/[component]/index.scss ``` 2. **Create default template files:** ``` src/defaults/src/assets/css/components/[component]/index.scss src/defaults/src/assets/js/components/[component]/index.js src/defaults/src/views/[component]/index.html ``` 3. **Create manager class (if needed):** ```javascript // src/[component].js const Manager = require('./build.js'); class ComponentManager extends Manager { constructor(options) { super(options); } } module.exports = ComponentManager; ``` 4. **Export in package.json:** ```json { "exports": { "./component": "./dist/component.js" } } ``` ### Modifying the Build System **Key gulp tasks:** - **defaults** ([gulp/tasks/defaults.js](src/gulp/tasks/defaults.js)) - Copies template files from `dist/defaults/` to consuming projects - **distribute** ([gulp/tasks/distribute.js](src/gulp/tasks/distribute.js)) - Copies project files to `dist/` - **sass** ([gulp/tasks/sass.js](src/gulp/tasks/sass.js)) - Compiles SCSS with sophisticated load path system - **webpack** ([gulp/tasks/webpack.js](src/gulp/tasks/webpack.js)) - Bundles JavaScript with Babel - **html** ([gulp/tasks/html.js](src/gulp/tasks/html.js)) - Processes HTML views into templates (see HTML Templating below) - **package** ([gulp/tasks/package.js](src/gulp/tasks/package.js)) - Creates packaged extension ### HTML Templating HTML views in `src/views/` are processed through a two-step templating system using `{{ }}` brackets. **Available variables:** - `{{ brand.name }}` - Brand name from config - `{{ brand.url }}` - Brand URL from config - `{{ page.name }}` - Component name (e.g., `popup`, `pages/index`) - `{{ page.path }}` - Full view path - `{{ page.title }}` - Page title (defaults to brand name) - `{{ theme.appearance }}` - Theme appearance (`dark` or `light`) - `{{ cacheBust }}` - Cache-busting timestamp **Example usage in views:** ```html <a href="{{ brand.url }}/pricing">Upgrade to Premium</a> <p>Welcome to {{ brand.name }}</p> ``` **How it works:** 1. Your view file (`src/views/[component]/index.html`) is templated first 2. The result is injected into [page-template.html](src/config/page-template.html) 3. The outer template is processed with the same variables - **serve** ([gulp/tasks/serve.js](src/gulp/tasks/serve.js)) - WebSocket server for live reload ### Modifying Themes **Theme location:** [src/assets/themes/](src/assets/themes/) **Available themes:** - `bootstrap` - Pure Bootstrap 5.3+ - `classy` - Bootstrap + custom design system - `_template` - Template for new themes **Theme structure:** ``` src/assets/themes/[theme-id]/ ├── _config.scss # Theme variables (with !default) ├── _theme.scss # Theme entry point ├── scss/ # Theme-specific SCSS └── js/ # Theme-specific JS ``` **To create a new theme:** 1. Copy `_template/` to new directory 2. Customize `_config.scss` variables 3. Add theme-specific styles in `scss/` 4. Users activate via `config/config.json` ### Working with the Defaults System **Location:** [src/defaults/](src/defaults/) **How it works:** 1. Files in `src/defaults/` are the starter template 2. During build, they're copied to `dist/defaults/` 3. When users run `npx bxm setup`, files copy from `dist/defaults/` to their project 4. File behavior controlled by `FILE_MAP` in [gulp/tasks/defaults.js](src/gulp/tasks/defaults.js) **File map rules:** ```javascript const FILE_MAP = { 'src/**/*': { overwrite: false }, // Never overwrite user code 'hooks/**/*': { overwrite: false }, // Never overwrite hooks '.nvmrc': { template: { node: '22' } }, // Template with data // ... }; ``` **Rule types:** - `overwrite: false` - Never replace if exists - `overwrite: true` - Always update - `skip: function` - Dynamic skip logic - `template: data` - Run templating - `name: function` - Rename file ### CSS Architecture **Main entry:** [src/assets/css/browser-extension-manager.scss](src/assets/css/browser-extension-manager.scss) **Core modules:** - [core/_initialize.scss](src/assets/css/core/_initialize.scss) - Base resets - [core/_utilities.scss](src/assets/css/core/_utilities.scss) - Utility classes - [core/_animations.scss](src/assets/css/core/_animations.scss) - Animations **Component system:** Each component can have framework defaults in `src/assets/css/components/[name]/index.scss` **Load path resolution:** 1. Framework CSS (`node_modules/browser-extension-manager/dist/assets/css`) 2. Active theme (`node_modules/browser-extension-manager/dist/assets/themes/[theme-id]`) 3. Project dist (`dist/assets/css`) 4. node_modules This enables: ```scss @use 'browser-extension-manager' as * with ($primary: #5B47FB); @use 'theme' as *; // Resolves to active theme @use 'components/popup' as *; // Import default component styles ``` ### JavaScript Architecture **Manager classes:** [src/background.js](src/background.js), [src/popup.js](src/popup.js), [src/options.js](src/options.js), [src/sidepanel.js](src/sidepanel.js), [src/page.js](src/page.js), [src/content.js](src/content.js) **Extension API wrapper:** [src/lib/extension.js](src/lib/extension.js) A universal/agnostic API wrapper that enables cross-browser extension development. Write your extension once and it works on Chrome, Firefox, Edge, and other browsers. **How it works:** - Detects and normalizes APIs from `chrome.*`, `browser.*`, and `window.*` namespaces - Automatically selects the correct API based on what's available in the current browser - Exports a singleton with unified access to all extension APIs **Supported APIs:** `action`, `alarms`, `bookmarks`, `browsingData`, `browserAction`, `certificateProvider`, `commands`, `contentSettings`, `contextMenus`, `cookies`, `debugger`, `declarativeContent`, `declarativeNetRequest`, `devtools`, `dns`, `documentScan`, `downloads`, `enterprise`, `events`, `extension`, `extensionTypes`, `fileBrowserHandler`, `fileSystemProvider`, `fontSettings`, `gcm`, `history`, `i18n`, `identity`, `idle`, `input`, `instanceID`, `management`, `notifications`, `offscreen`, `omnibox`, `pageAction`, `permissions`, `platformKeys`, `power`, `printerProvider`, `privacy`, `proxy`, `runtime`, `scripting`, `search`, `sessions`, `sidePanel`, `storage`, `tabGroups`, `tabs`, `topSites`, `tts`, `ttsEngine`, `userScripts`, `vpnProvider`, `wallpaper`, `webNavigation`, `webRequest`, `windows` **Usage:** ```javascript // Exposed via manager - no separate import needed const Manager = new (require('browser-extension-manager/popup')); Manager.initialize().then(() => { const { extension } = Manager; // Works on Chrome, Firefox, Edge, etc. extension.tabs.query({ active: true }, (tabs) => { ... }); extension.storage.get('key', (result) => { ... }); extension.runtime.sendMessage({ type: 'hello' }); }); ``` **Storage normalization:** The wrapper automatically resolves `storage` to `storage.sync` if available, falling back to `storage.local`. **Auth Helpers:** [src/lib/auth-helpers.js](src/lib/auth-helpers.js) Provides cross-context auth synchronization and reusable auth UI event handlers. ### Cross-Context Auth Architecture **Background.js is the source of truth** for authentication. Browser extensions have multiple isolated JavaScript contexts (background, popup, options, pages, sidepanel) - each runs its own Firebase instance. BEM syncs them via messaging (no storage). **Sign-in Flow:** ``` User clicks .auth-signin-btn → openAuthPage() opens https://{authDomain}/token?authSourceTabId=123 → Website authenticates, redirects to /token?authToken=xxx → background.js tabs.onUpdated detects authDomain URL with authToken param → background.js signs in with signInWithCustomToken() → background.js broadcasts token to all open contexts via postMessage() → Closes the /token tab, reactivates original tab → Open contexts receive broadcast and sign in with the token ``` **Context Load Flow:** ``` Context loads (popup, page, options, sidepanel) → Web Manager initializes, waits for auth to settle via auth.listen({once: true}) → Sends bxm:syncAuth message to background with local UID → Background compares UIDs: → Same UID (including both null) → already in sync, no action → Different UID → background fetches fresh custom token from server, sends to context → Background signed out, context signed in → tells context to sign out ``` **Sign-out Flow:** ``` User clicks .auth-signout-btn → Web Manager signs out that context's Firebase → setupSignOutListener() detects sign-out, sends bxm:signOut to background → background.js signs out its Firebase → background.js broadcasts bxm:signOut to all other contexts → All contexts sign out ``` **Key Implementation Details:** 1. **No storage**: Auth state is NOT stored in `chrome.storage`. Firebase persists sessions in IndexedDB per context. Web Manager handles UI bindings. 2. **Firebase in service workers**: Static ES6 imports are required. Dynamic `import()` fails with webpack chunking in service workers. 3. **Config path**: `authDomain` is at `config.firebase.app.config.authDomain` (loaded via BEM_BUILD_JSON). 4. **Required permission**: `tabs` permission needed for `tabs.onUpdated` listener. **Functions:** - `syncWithBackground(context)` - Compares context's UID with background's UID on load, syncs if different - `setupAuthBroadcastListener(context)` - Listens for sign-in/sign-out broadcasts from background - `setupSignOutListener(context)` - Notifies background when context signs out - `setupAuthEventListeners(context)` - Sets up delegated click handlers for auth buttons - `openAuthPage(context, options)` - Opens auth page on the website with authSourceTabId for tab restoration **Auth Button CSS Classes:** Add these classes to your HTML elements to enable automatic auth handling: | Class | Description | Action | |-------|-------------|--------| | `.auth-signin-btn` | Sign in button | Opens `/token` page on website (authDomain) | | `.auth-signout-btn` | Sign out button | Handled by Web Manager (triggers storage sync via auth listener) | | `.auth-account-btn` | Account button | Opens `/account` page on website | **Example usage:** ```html <!-- Sign In Button (shown when logged out) --> <button class="btn auth-signin-btn" data-wm-bind="@show !auth.user"> Sign In </button> <!-- Account Dropdown (shown when logged in) --> <div data-wm-bind="@show auth.user" hidden> <a class="auth-account-btn" href="#">Account</a> <button class="auth-signout-btn">Sign Out</button> </div> ``` **Reactive bindings:** - `data-wm-bind="@show auth.user"` - Show when logged in - `data-wm-bind="@show !auth.user"` - Show when logged out - `data-wm-bind="@text auth.user.displayName"` - Display user's name - `data-wm-bind="@text auth.user.email"` - Display user's email - `data-wm-bind="@attr src auth.user.photoURL"` - Set avatar image src **Logger:** [src/lib/logger.js](src/lib/logger.js) - Full logging utility - [src/lib/logger-lite.js](src/lib/logger-lite.js) for lightweight contexts **Template replacement:** Webpack plugin replaces markers during build: - `%%% version %%%` → package version - `%%% brand.name %%%` → brand name - `%%% environment %%%` → 'production' or 'development' - `%%% liveReloadPort %%%` → WebSocket port - `%%% webManagerConfiguration %%%` → JSON config ### Build Hooks System **Hook locations:** - `hooks/build:pre.js` - Before packaging - `hooks/build:post.js` - After packaging **Hook structure:** ```javascript module.exports = async function (index) { // index contains build information console.log('Hook running...'); }; ``` **Implementation:** [src/gulp/tasks/package.js](src/gulp/tasks/package.js) loads and executes hooks ### CLI System **Entry point:** [bin/browser-extension-manager](bin/browser-extension-manager) **CLI implementation:** [src/cli.js](src/cli.js) **Commands:** [src/commands/](src/commands/) - [setup.js](src/commands/setup.js) - Initialize project - [clean.js](src/commands/clean.js) - Clean build artifacts - [version.js](src/commands/version.js) - Show version **Aliases in package.json:** ```json { "bin": { "ext": "bin/browser-extension-manager", "xm": "bin/browser-extension-manager", "bxm": "bin/browser-extension-manager", "browser-extension-manager": "bin/browser-extension-manager" } } ``` ## Best Practices for Framework Development ### File Organization 1. **Keep framework code in src/** - Never edit `dist/` directly 2. **Use modular design** - Per Ian's standards, build modular code, not one giant file 3. **Maintain defaults/** - Keep template files up-to-date 4. **Document changes** - Update CLAUDE.md ### Coding Standards (Per Ian's Preferences) **Short-circuit pattern:** ```javascript // Good const $el = document.querySelector('...'); if (!$el) { return; } // Long code block // Bad if ($el) { // Long code block } ``` **Logical operators:** ```javascript // Good const a = b || c || d; // Bad const a = b || c || d; ``` **DOM element naming:** ```javascript const $submitBtn = document.querySelector('#submit'); const $emailInput = document.querySelector('#email'); ``` **File operations:** ```javascript // Prefer fs-jetpack const jetpack = require('fs-jetpack'); jetpack.write('file.txt', 'content'); ``` ### Backwards Compatibility **Per Ian's instructions:** - **DO NOT** make changes backwards compatible unless explicitly requested - Most changes are for unreleased code or local development - If we develop something and change it later, just change it - don't maintain old way - Only add backwards compatibility when specifically asked ### Version Control **Commit:** - `src/` - All framework source code - `package.json` - Package configuration - Documentation (CLAUDE.md) **Ignore:** - `dist/` - Compiled framework (generated by prepare-package) - `node_modules/` ## Testing Changes ### Local Testing 1. **Make changes in src/** 2. **Compile:** `npm start` (watches and compiles to dist/) 3. **Link locally:** ```bash npm link ``` 4. **In consuming project:** ```bash npm link browser-extension-manager npm start ``` 5. **Test in browser:** Load `packaged/raw/` directory ### Testing Build System **Test individual gulp tasks:** ```bash cd consuming-project/ npm run gulp -- [task-name] ``` **Available tasks:** - `defaults` - Test template copying - `sass` - Test SCSS compilation - `webpack` - Test JS bundling - `html` - Test HTML processing - `package` - Test extension packaging ### Testing CLI **In this repository:** ```bash ./bin/browser-extension-manager setup ./bin/browser-extension-manager clean ./bin/browser-extension-manager version ``` **Or via npm:** ```bash npx bxm setup npx bxm clean npx bxm version ``` ## Publishing Updates ### Preparation 1. **Update version** in [package.json](package.json) 2. **Compile framework:** ```bash npm run prepare ``` 3. **Test in consuming project** 4. **Update documentation** if needed ### Publishing to npm ```bash npm publish ``` **Published package includes:** - `dist/` - Compiled framework - `bin/` - CLI binaries - `package.json` - `README.md` **Excluded via .npmignore:** - `src/` - Source code (users don't need this) - Development files ## Common Development Tasks ### Adding a Utility Class **Location:** [src/assets/css/core/_utilities.scss](src/assets/css/core/_utilities.scss) ```scss // Add new utility .shadow-lg { box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1); } ``` ### Adding a Theme Variable **Location:** [src/assets/themes/classy/_config.scss](src/assets/themes/classy/_config.scss) (or relevant theme) ```scss $new-color: #FF6B6B !default; // Make available to consumers @forward '../bootstrap/scss/bootstrap.scss' with ( $new-color: $new-color ); ``` ### Adding a Webpack Alias **Location:** [src/gulp/tasks/webpack.js](src/gulp/tasks/webpack.js) ```javascript resolve: { alias: { '__new_alias__': path.resolve(paths.root, 'path/to/directory'), } } ``` ### Adding a Template Replacement **Location:** [src/gulp/tasks/webpack.js](src/gulp/tasks/webpack.js) ```javascript new ReplacePlugin({ patterns: [ { find: /%%% newVariable %%%/g, replacement: 'value' } ] }) ``` ### Modifying Default Manifest **Location:** [src/config/manifest.json](src/config/manifest.json) ```json5 { // Add new default permission permissions: [ 'storage', 'newPermission' ] } ``` **Compilation:** [src/gulp/tasks/package.js](src/gulp/tasks/package.js) merges user manifest with defaults ## Troubleshooting Framework Development ### Changes not appearing in consuming project 1. **Rebuild framework:** `npm run prepare` 2. **Reinstall in consuming project:** `npm install browser-extension-manager@latest` 3. **Or use local link:** `npm link` (in BEM) then `npm link browser-extension-manager` (in project) ### Gulp task errors 1. **Check task file:** [src/gulp/tasks/](src/gulp/tasks/) 2. **Verify paths** are correct 3. **Check for syntax errors** 4. **Test task individually:** `npm run gulp -- task-name` ### SCSS compilation errors 1. **Check load paths** in [src/gulp/tasks/sass.js](src/gulp/tasks/sass.js) 2. **Verify theme structure** 3. **Check for circular imports** 4. **Test with minimal SCSS** to isolate issue ### Template replacement not working 1. **Check pattern** in [src/gulp/tasks/webpack.js](src/gulp/tasks/webpack.js) 2. **Verify replacement value** is correct 3. **Check if file is processed** by webpack ## Notable Dependencies ### Web Manager BEM integrates **Web Manager** for Firebase, analytics, and web services functionality. Each component manager initializes Web Manager automatically with configuration from `config/config.json`. **Web Manager API:** - Study the Web Manager API and documentation in the sibling repository - Location: `../web-manager/` (relative to this project) - GitHub: https://github.com/itw-creative-works/web-manager - npm: https://www.npmjs.com/package/web-manager **Usage in BEM:** ```javascript const Manager = new (require('browser-extension-manager/popup')); Manager.initialize().then(() => { const { webManager } = Manager; // Web Manager provides: // - Firebase (Firestore, Auth, Storage, etc.) // - Analytics // - User management // - Utilities const db = webManager.libraries.firebase.firestore(); }); ``` ### Other Key Dependencies - **Gulp** - Build system and task automation - **Webpack** - JavaScript bundling with Babel transpilation - **Sass** - CSS preprocessing with advanced features - **fs-jetpack** - File operations (per Ian's preference) - **wonderful-fetch** - HTTP requests - **wonderful-version** - Version management - **ws** - WebSocket server for live reload ## Resources - **GitHub**: https://github.com/itw-creative-works/browser-extension-manager - **npm**: https://www.npmjs.com/package/browser-extension-manager - **Chrome Extensions**: https://developer.chrome.com/docs/extensions/ - **Firefox Add-ons**: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions ## Key Files Reference **Build System:** - [src/gulp/main.js](src/gulp/main.js) - Gulp entry point - [src/gulp/tasks/](src/gulp/tasks/) - All build tasks - [src/build.js](src/build.js) - Build manager base class **Manager Classes:** - [src/background.js](src/background.js) - Background script manager - [src/popup.js](src/popup.js) - Popup manager - [src/options.js](src/options.js) - Options manager - [src/sidepanel.js](src/sidepanel.js) - Sidepanel manager - [src/page.js](src/page.js) - Custom page manager - [src/content.js](src/content.js) - Content script manager **Utilities:** - [src/lib/extension.js](src/lib/extension.js) - Cross-browser API wrapper - [src/lib/auth-helpers.js](src/lib/auth-helpers.js) - Cross-context auth sync (see Auth Architecture section above) - [src/lib/logger.js](src/lib/logger.js) - Logging utility - [src/cli.js](src/cli.js) - CLI implementation **Auth System (Cross-Context):** - [src/background.js](src/background.js) - Source of truth; `handleSyncAuth()`, `handleSignOut()`, `broadcastAuthToken()` - [src/lib/auth-helpers.js](src/lib/auth-helpers.js) - `syncWithBackground()`, `setupAuthBroadcastListener()`, `setupSignOutListener()` **CSS Framework:** - [src/assets/css/browser-extension-manager.scss](src/assets/css/browser-extension-manager.scss) - Main entry - [src/assets/css/core/](src/assets/css/core/) - Core styles - [src/assets/css/components/](src/assets/css/components/) - Component styles - [src/assets/themes/](src/assets/themes/) - Theme system **Templates:** - [src/defaults/](src/defaults/) - Project starter template - [src/config/manifest.json](src/config/manifest.json) - Default manifest - [src/config/page-template.html](src/config/page-template.html) - HTML template **CLI:** - [bin/browser-extension-manager](bin/browser-extension-manager) - CLI entry - [src/commands/](src/commands/) - CLI commands