# CLAUDE.md ## Project Overview **Memos Clipper** is a Chrome Extension (Manifest V3) that clips web pages or text selections and saves them to a [Memos](https://usememos.com) instance in Markdown format. ## Architecture Three-part Chrome extension: - **`src/content.js`** — Content script injected into pages; extracts HTML and converts it to Markdown - **`src/popup.html` / `src/popup.js`** — Main popup UI: editor, preview, image gallery, send button - **`src/settings.html` / `src/settings.js`** — Options page: Memos URL, API token, defaults - **`src/background.js`** — Service worker (minimal; onInstalled listener only) ## Tech Stack - **Runtime**: Chrome MV3 (Manifest V3) - **Language**: Vanilla JavaScript (ES6+), no frontend framework - **Styling**: Tailwind CSS v4 + PostCSS + Autoprefixer; CSS variables for theming; dark mode via `prefers-color-scheme` - **Markdown**: Custom HTML→Markdown converter in `content.js`; `marked` npm package for preview rendering - **Build**: Vite v8 with `vite-plugin-static-copy` ## Build & Development ```bash npm install # Install dependencies npm run dev # Dev server with hot reload npm run build # Production build → dist/ npm run preview # Preview built output ``` Load the extension in Chrome: **Extensions → Load unpacked → select `dist/`** ## Key Implementation Details ### API Integration - Memos API v1: `/api/v1/memos`, `/api/v1/attachments` - Requires Memos v0.22+ - Bearer token auth via `chrome.storage.sync` - Attachment flow: create memo first (`POST /api/v1/memos`), then upload each attachment via `POST /api/v1/attachments` (JSON + base64 `content` + `memo: "memos/{id}"`), then patch the memo content to replace original image URLs with attachment URLs (`PATCH /api/v1/memos/{id}`) ### Content Extraction - Removes boilerplate: nav, ads, sidebars, cookie banners (45+ selectors) - Supports full-page and selection-only modes - Converts: headings, lists, tables, code blocks, links, images, blockquotes ### Image Handling - Filters images smaller than 32px (icons/tracking pixels) - Deduplicates images - Supports data URIs - Uploads images as attachments (`POST /api/v1/attachments`) with base64-encoded content and `memo` reference - Memo is created first; attachment uploads include `memo: "memos/{id}"` to associate them immediately - After all uploads, memo content is patched to replace original image URLs with attachment file URLs - Attachment file URL pattern: `{memosUrl}/file/attachments/{id}` ### Storage - `chrome.storage.sync` for cross-device settings (URL, token, defaults) ## Project Structure ``` src/ ├── manifest.json # MV3 config (permissions, entry points) ├── popup.html/.js/.css # Main extension popup ├── settings.html/.js/.css # Options page ├── content.js # Page content extractor ├── background.js # Service worker └── icons/ # 16, 32, 48, 128px PNG icons dist/ # Build output (gitignored) vite.config.js package.json ``` ## Permissions - `activeTab`, `scripting`, `storage` - Host permissions: `` (needed for cross-origin image fetching and API calls)