Backend: one SSE stream for messages, selection, poll and connection status; reconnect with backoff; no on-disk Innertube session cache; mock only with MOCK_CHAT=1; binds to 127.0.0.1; serves client/out so production runs on one port. Full URLs for links YouTube truncates in chat.
Client: components split out, Lucide icons, stream title and status, on-air strip, search, pause, keyboard shortcuts, overlay settings dialog. Overlay themes, position, size, animation and auto-hide via URL, sized for 1080p and scaled with the source. New blueprint theme for the brand background.
Removed Tailwind, better-sqlite3, zod, the timezone helpers, Cline memory bank and AGENTS.md. Added ESLint, node:test tests and CI.
Removes the console.log spam that was triggered on every incoming chat message
when the store exceeded MAX_REGULAR_MESSAGES. The trimming logic still works
silently in the background.
Add ID deduplication mechanism to handle cases where YouTube message IDs might not be unique in high-frequency chat scenarios. The system now tracks seen IDs and appends a counter suffix when duplicates are encountered, preventing message ID collisions.
Add backend support for YouTube live polls including:
- Poll event handling and state tracking
- New `/poll/current` endpoint for current poll data
- Server-sent events stream at `/poll/stream` for real-time updates
- Poll emitter for broadcasting poll changes to clients
Expand YouTube chat ingestion to handle membership gift events including purchases and redemptions. Update SuperChat extraction to support multiple paid message types and improve field name handling. Display membership level in overlay for gift events.