|
@@ -0,0 +1,43 @@
|
|
|
|
|
+# CLAUDE.md
|
|
|
|
|
+
|
|
|
|
|
+This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
|
+
|
|
|
|
|
+## Project Overview
|
|
|
|
|
+
|
|
|
|
|
+Firefox browser extension that manages video playlists and tracks playback history. All data is persisted via the browser's `storage` API — no backend, no IndexedDB. Uses Manifest V2 and vanilla JavaScript with no build step; load via `about:debugging` → "Load Temporary Add-on" → select `manifest.json`.
|
|
|
|
|
+
|
|
|
|
|
+## Code Layout
|
|
|
|
|
+
|
|
|
|
|
+- `popup/` — Extension popup UI (Alpine.js, single-page, multiple views)
|
|
|
|
|
+- `background.js` — Service worker: context menus, storage init, autoplay chaining, history tracking
|
|
|
|
|
+- `content_scripts/content.js` — Injected into YouTube pages; forwards `play`/`pause`/`ended` events to background
|
|
|
|
|
+- `shared/playlist-utils.js` — Shared helpers used by both popup and background (video ID extraction, deduplication, search)
|
|
|
|
|
+
|
|
|
|
|
+## Alpine.js CSP Compliance (Critical)
|
|
|
|
|
+
|
|
|
|
|
+The popup runs under a Content Security Policy that forbids inline JavaScript evaluation. All Alpine.js code must be CSP-compliant:
|
|
|
|
|
+
|
|
|
|
|
+- **No JavaScript expressions in HTML attributes** — `x-show="count === 0"`, `x-text="label()"`, ternaries, method calls are all forbidden
|
|
|
|
|
+- Use `Alpine.data()` binding objects and pre-compute all display values as properties
|
|
|
|
|
+- Bind with `x-bind` or `:attr`; never inline logic in templates
|
|
|
|
|
+
|
|
|
|
|
+Violation examples to avoid: `x-show="items.length > 0"`, `x-text="getName(id)"`, `x-if="a === b"`.
|
|
|
|
|
+
|
|
|
|
|
+## Popup Views
|
|
|
|
|
+
|
|
|
|
|
+The popup is a single-page app; `currentView` controls which view is active:
|
|
|
|
|
+
|
|
|
|
|
+| View | Purpose |
|
|
|
|
|
+|------|---------|
|
|
|
|
|
+| `playlists` | Main view: all playlists and their unviewed videos |
|
|
|
|
|
+| `playlist` | Single-playlist detail with full video list including viewed |
|
|
|
|
|
+| `history` | Playback history with per-event tags |
|
|
|
|
|
+| `saveChannel` | Save a YouTube channel with categories |
|
|
|
|
|
+| `wikiInsp` | Copy video info as wikitext |
|
|
|
|
|
+| `import` | Import playlists from JSON |
|
|
|
|
|
+
|
|
|
|
|
+## Key Constraints
|
|
|
|
|
+
|
|
|
|
|
+- A video can exist in **at most one playlist** — `addVideoToPlaylist()` enforces global deduplication
|
|
|
|
|
+- The 6 default playlists (`listening-long`, `listening-short`, `listening-misc`, `watching-short`, `watching-long`, `slow-tv`) are hardcoded in both `background.js` and the context menu; adding a new playlist requires changes in both places
|
|
|
|
|
+- History is keyed by YouTube video ID; rewatching appends new interaction events rather than overwriting
|