6.7 KiB
KoalaSync AI Onboarding (AI_INIT.md)
Welcome to the KoalaSync project. This file is the primary entry point for any developer or AI agent working on this codebase. It defines the architecture, non-negotiables, and workflows required to maintain the stability and security of the system.
Important
Privacy & Data Sovereignty: KoalaSync follows a strict Zero-External-Requests Policy: The extension and website must not make requests to any third-party domains (Google Fonts, CDNs, etc.). All assets (fonts, icons, scripts) must be self-hosted or use system defaults.
- Font Stack: Use a modern system font stack (e.g., -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif) to maintain a premium look without external dependencies. Prohibit the use of
@importor<link>for external font services.
1. Project Overview
KoalaSync is a specialized tool for synchronized video playback across multiple remote peers. It supports YouTube, Twitch, and native HTML5 video elements.
- Users: Friends or groups wanting to watch synchronized content together.
- Workflow: A user creates a room, shares an invitation link, and all peers in that room are synchronized via a Node.js relay server.
- Identity: Users are identified by a unique hex
peerIdcombined with a customizableusername.
2. Repository Structure
extension/: Chrome Extension (Manifest V3). Contains background service worker, content scripts, and popup UI.server/: Node.js Relay Server using Socket.IO (WebSocket-only).website/: Landing Page & Invitation Bridge (Marketing, Tutorials, and Downloads).shared/: Single Source of Truth for protocol constants and event names.scripts/: Utility scripts (e.g.,sync-constants.sh).docker-compose.yml: Root-level orchestration for the relay server.
Important
Single Source of Truth:
shared/constants.jsandshared/blacklist.jsare the master files. They must be synchronized to theextension/shared/directory using.\scripts\sync-constants.bator./scripts/sync-constants.sh.
- Extension Modules (
background.js,popup.js) import directly from./shared/constants.js.- Content Scripts (
content.js) use a manual synchronous mirror to prevent race conditions during page load. Always verify parity after sync.
3. Mandatory Reading
Before touching any code, you MUST read the following documents in order:
- ARCHITECTURE.md – Detailed communication flows, Dual Heartbeat, and two-phase sync protocol.
- extension/README.md – Extension components, tab structure, and loading process.
- SYNC_GUIDE.md – Protocol constants and synchronization requirements.
4. The "Vanilla JS Mirror" Pattern
To avoid boot-time race conditions in Manifest V3 without a bundler, the following architectural trade-off is enforced:
- Synchronous Execution:
content.jsMUST execute synchronously to catch early media events. - Manual Mirroring:
content.jsmaintains a manual mirror of theEVENTSconstants fromshared/constants.js. - Maintenance: Developers must ensure that any changes to
shared/constants.jsare manually reflected incontent.jsafter running the sync scripts.
5. Design Guidelines
The popup UI follows a strict design system. Do not modify these variables or the layout structure without explicit approval.
- Font: System font stack. MANDATORY: No external CDNs or Google Fonts to ensure 100% privacy.
- Popup Width: Fixed at
320px. - Tab Structure: Must maintain the Room, Sync, Settings, and Dev tabs.
- CSS Variables:
Variable Value Purpose --bg#0f172aMain background --card#1e293bForm and info cards --accent#6366f1Primary actions and branding --success#22c55eSuccess states / Online dot --error#ef4444Errors / Offline dot
5. Non-Negotiables (Core Logic)
The following features are critical and must not be removed or fundamentally altered:
- Two-Phase Force Sync: The
Prepare→ACK→Executeflow ensures all peers are buffered before playback resumes. - Dual Heartbeat:
- Background Heartbeat (30s): Ensures session persistence even without a video element.
- Content Heartbeat (15s): Transmits current video metadata (time, title).
- Dead Peer Pruning: Server "Reaper" disconnects peers after 5 minutes of total silence (no heartbeats or events).
- Deduplication: Server kills old sockets if a user re-joins with the same
peerIdto prevent ghosts. - Platform Specifics: Specialized click-logic for YouTube (
.ytp-play-button) and Twitch. - pollSeekReady(): Polling mechanism that checks
video.readyStatebefore acknowledging sync. - SW Keep-alive: Use of
chrome.alarmsto prevent the Manifest V3 Service Worker from suspending. - Diagnostics: The "Dev" tab provides real-time access to the underlying
<video>state for troubleshooting. - Persistence:
peerIdandusernamemust be stored to remain stable across sessions.
6. Technical Constraints
- No Bundler: The extension uses plain ES Modules. Do not introduce build steps or npm packages into the
extension/folder. - Manual Protocol:
background.jsimplements a subset of the Socket.IO wire protocol natives. - Server Transport: Restricted to
websocketonly. Polling is disabled. - Docker Context: The Docker build must run from the Repo Root.
- Manifest Settings:
run_atmust remaindocument_idle, andall_framesmust remainfalse.
7. Security & Deployment
- Tokens: Security tokens are intentionally managed via
shared/constants.jsand server.env. - Environment:
.envis excluded via.gitignore. Only.env.exampleshould be committed. - Revocation:
MIN_VERSIONcheck on the server is used to deprecate old extension versions. - Invitation Links: Correctly propagate server URLs, Room IDs, and Passwords via the URL hash to the bridge.
8. Common Workflows
Adding a Protocol Event
- Add the event name to
shared/constants.js. - Run the sync script (
.\scripts\sync-constants.bator./scripts/sync-constants.sh). - Implement the handler in
server/index.jsandbackground.js.
Testing Locally
- Load
extension/as an "Unpacked Extension" in Chrome. - Start the server from the root:
docker-compose up --build. - Use different browser profiles or vendors to test multi-peer logic.
- Use the Dev tab to verify real-time video element metadata.
Locking Old Versions
- Increase
APP_VERSIONinshared/constants.js. - Update
MIN_VERSIONin the server's.envfile and restart.