Files
DavidSaylor 09d30427f4 Complete LinkSyncServer and LinkSyncExtension implementation
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
2026-05-19 13:21:26 -05:00

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 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