# AGENTS.md - LinkSyncExtension ## Project Overview LinkSyncExtension is a Firefox browser extension that synchronizes bookmarks with LinkSyncServer. It provides a popup UI for managing bookmarks, collections, and queries, with a background script handling automatic synchronization. ## Architecture ``` LinkSyncExtension/ ├── manifest.json # Firefox extension manifest v2 ├── popup.html/js/css # Main popup UI (bookmarks, collections, queries) ├── background.html/js # Background page with sync engine ├── options.html/js # Dedicated settings page ├── content/content.js # Content script for page metadata extraction ├── utils/ │ ├── api.js # REST API client with retries, auth, error handling │ ├── sync.js # Sync engine (3 modes + conflict detection) │ ├── collection.js # Collection management wrapper │ ├── query-engine.js # Client-side query parser │ └── bookmark.js # Bookmark parsing/merging utilities ├── icons/ │ ├── icon-48.png │ └── icon-96.png └── tests/ └── README.md # Manual testing checklist ``` ## Communication Pattern ``` popup.js/options.js ──browser.runtime.sendMessage──> background.js background.js ────────────────────────────────────> API (LinkSyncServer) background.js ──browser.bookmarks.*───────────────> Firefox bookmarks content.js ─────browser.runtime.onMessage─────────> popup.js ``` All API calls go through `utils/api.js`. The popup sends messages to the background script, which handles the actual API communication. This keeps the API token in the background context. ## Key Modules ### utils/api.js - `API.init()` - loads settings from storage - `API.request(method, path, body)` - core request with retries (3x), timeout (10s), rate limit handling - `API.login(username, password)` - authenticates and stores token - `API.testConnection()` - hits /health endpoint - CRUD methods for links, collections, queries, sync ### utils/sync.js - `SyncEngine.runSync()` - main sync entry point - Three modes: bi-directional, browser-authoritative, server-authoritative - `SyncEngine.detectConflicts()` - finds title mismatches between browser and server - Uses `browser.bookmarks.getTree()` for local bookmarks ### utils/query-engine.js - `QueryEngine.tokenize(expression)` - lexer - `QueryEngine.parse(expression)` - recursive descent parser - `QueryEngine.validate(expression)` - returns {valid, ast} or {valid, error} - Supports: TERM, TERM_SET, FIELD (url/tag/title/description/path/id), AND, OR, XOR, parentheses ### background.js - Listens for `browser.runtime.onMessage` from popup/options - Handles bookmark change events (`onCreated`, `onChanged`, `onRemoved`) - Auto-sync timer (5 min interval when enabled) - Message types: SYNC_NOW, GET_SETTINGS, SAVE_SETTINGS, TEST_CONNECTION, LOGIN, GET_BOOKMARKS, CREATE_BOOKMARK, UPDATE_BOOKMARK, DELETE_BOOKMARK, GET_COLLECTIONS, EXECUTE_QUERY, PARSE_QUERY ### popup.js - Tabbed interface: Bookmarks, Collections, Query - Settings modal (server URL, API key, sync mode, deletions, auto-sync) - Toast notifications (success/error/info, auto-dismiss after 3s) - Bookmark form with auto-fill from current tab - Search filter for bookmarks - Query builder with parse/execute buttons ## Storage Keys | Key | Type | Description | |-----|------|-------------| | `linksync_server_url` | string | Server base URL | | `linksync_api_key` | string | JWT bearer token | | `linksync_sync_mode` | string | bi-directional / browser-authoritative / server-authoritative | | `linksync_deletions` | boolean | Enable deletions during sync | | `linksync_auto_sync` | boolean | Enable 5-minute auto-sync | | `linksync_last_sync` | string | ISO timestamp of last sync | | `linksync_syncing` | boolean | Currently syncing flag | | `linksync_pending` | boolean | Has pending local changes | ## Testing Browser extensions require manual testing in Firefox: 1. Open `about:debugging` in Firefox 2. Click "This Firefox" → "Load Temporary Add-on" 3. Select `manifest.json` from the project folder 4. Click the extension icon to open the popup 5. Right-click the icon → "Options" for settings page See `tests/README.md` for the full manual testing checklist. ## Development Notes - Manifest v2 for Firefox compatibility - Background page (not service worker) for Firefox support - All API calls use Bearer token auth (matching server's JWT implementation) - Content script runs on all pages to extract metadata - No external dependencies - pure browser APIs