LinkSyncServer: - Fix app.py imports, add CORS middleware, lifespan events - Create api/routes.py router aggregator - Create config/settings.py for centralized configuration - Rewrite models/base.py with proper relationships and serialization - Rewrite all API endpoints with real DB integration (auth, links, collections, sync, queries, tags) - Add admin endpoints (user management, stats, audit log) - Complete query parser with recursive descent and proper precedence - Complete query executor with set operations and field filters - Set up Alembic migrations with initial schema - Create web interface (templates, CSS, JS) - Add 42 passing tests (auth, links, collections, queries) - Add deploy.ps1 and deploy.sh scripts - Update README with deployment workflow LinkSyncExtension: - Create utils/api.js (REST client with retries, auth, error handling) - Create utils/sync.js (3 sync modes + conflict detection) - Create utils/collection.js (collection management) - Create utils/query-engine.js (client-side query parser) - Rewrite background.js (sync loop, bookmark events, message routing) - Rewrite popup.js (tabs, settings modal, notifications, CRUD) - Update popup.html (tabbed interface, query builder, modal) - Update popup.css (full redesign) - Create content/content.js (page metadata extraction) - Create options.html/js (dedicated settings page) - Generate icons (48x48, 96x96) - Update manifest.json (host permissions, content scripts, options) - Create AGENTS.md
4.7 KiB
4.7 KiB
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 storageAPI.request(method, path, body)- core request with retries (3x), timeout (10s), rate limit handlingAPI.login(username, password)- authenticates and stores tokenAPI.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)- lexerQueryEngine.parse(expression)- recursive descent parserQueryEngine.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.onMessagefrom 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:
- Open
about:debuggingin Firefox - Click "This Firefox" → "Load Temporary Add-on"
- Select
manifest.jsonfrom the project folder - Click the extension icon to open the popup
- 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