## 1. Extension scaffold - [ ] 1.1 Create Manifest V3 `manifest.json` with `sidePanel`, `tabs`, `webNavigation`, `unlimitedStorage` permissions, action icon, and keyboard command binding to open the side panel - [ ] 1.2 Set up the build/dev tooling for a background service worker, a side panel page, and a notes-list page as separate entry points - [ ] 1.3 Wire `chrome.sidePanel.setPanelBehavior({ openPanelOnActionClick: true })` in the background service worker ## 2. Shared storage & key module - [ ] 2.1 Implement `buildNoteKey(url, config)` with the default rule (`scheme://domain/path?search`, hash excluded) and a swappable config - [ ] 2.2 Define the IndexedDB schema: `notes` object store keyed by `id`, non-unique index on the derived URL key, index on `updatedAt` - [ ] 2.3 Implement `getNoteByKey(key)`, `saveNote(key, content, pageMeta)`, `listNotes()` (excludes soft-deleted), filtering `deletedAt == null` in retrieval - [ ] 2.4 Implement soft-delete support at the storage layer (`markDeleted(id)`), even though no UI triggers it in this change ## 3. In-page navigation detection - [ ] 3.1 Listen for `chrome.webNavigation.onHistoryStateUpdated` and `onReferenceFragmentUpdated` in the background service worker - [ ] 3.2 On either event, re-resolve the note key for the affected tab and notify that tab's open side panel (if any) to reload ## 4. Side panel note editor - [ ] 4.1 Build the side panel page shell with a dark theme applied by default - [ ] 4.2 On panel load/tab activation, resolve the active tab's URL to a key via the shared module and load (or initialize) that note - [ ] 4.3 Render the note content in a plain `