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
107 lines
4.7 KiB
Markdown
107 lines
4.7 KiB
Markdown
# 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
|