This file provides guidance to Claude Code when working in this repository.
FreeYT is a Safari Web Extension with a native SwiftUI companion app. It redirects supported YouTube URLs to youtube-nocookie.com and exposes a local-first dashboard for protection status, recent activity, trusted exceptions, and setup.
- Host app
- Dashboard-first IA with
Overview,Activity,Exceptions,Trust, andSetup - Guided onboarding and verification flow
- Shared dashboard snapshot backed by the app-group container
- Dashboard-first IA with
- Safari popup
- Primary
Active/Pausedcontrol Today,This Week, andAll Timestats- Current-site quick exception
- Expandable exception management
- Open-dashboard and refresh actions
- Primary
- Background worker
- Owns the extension-side dashboard state
- Tracks recent redirects and daily counts
- Syncs to the native app via Safari native messaging
- Banner content script
- Runs on
youtube-nocookie.compages - Explains that the current route is privacy-enhanced
- Supports dismiss and always-hide behavior
- Runs on
FreeYT/SharedState.swiftStores the shared dashboard snapshot in thegroup.com.freeyt.appapp group.FreeYT/Models/DashboardStore.swiftApp-side observable store for dashboard data, section selection, protection toggling, exceptions, and deep links.FreeYT/LiquidGlassView.swiftMain dashboard shell.FreeYT/Views/Onboarding/OnboardingView.swiftGuided setup flow.
FreeYT Extension/Resources/manifest.jsonMV3 manifest. Includes popup, background worker, permissions, content script, and rule resource registration.FreeYT Extension/Resources/background.jsTracks dashboard state and exception rules.FreeYT Extension/Resources/popup.jsPopup UI state and interaction handling.FreeYT Extension/SafariWebExtensionHandler.swiftNative messaging bridge used for dashboard sync and app deep linking.
The effective snapshot includes:
enabledvideoCountdailyCountslastProtectedAtrecentActivityexceptionslastSyncStatelastSyncTimestamp
User-facing copy uses Exceptions. Extension compatibility paths may still refer to allowlist in storage or bridge payloads.
FreeYT Extension/Resources/rules.json currently contains 7 redirect rules:
- watch
- shorts
- embed
- live
- mobile watch
- short link
- legacy
/v/
All rules operate on main_frame.
Current expected identifiers:
- App bundle ID:
com.freeyt.app - Extension bundle ID:
com.freeyt.app.extension - Widget bundle ID:
com.freeyt.app.widget - App group:
group.com.freeyt.app
The Xcode project, entitlements, shared state, and native messaging bridge should stay aligned with those values.
xcodebuild -project FreeYT.xcodeproj -scheme FreeYT \
-destination 'platform=iOS Simulator,name=iPhone 17' build
xcodebuild -project FreeYT.xcodeproj -scheme FreeYT \
-destination 'platform=macOS,variant=Mac Catalyst' buildSwift tests:
xcodebuild test -project FreeYT.xcodeproj -scheme FreeYT \
-destination 'platform=iOS Simulator,name=iPhone 17'Extension tests:
cd "FreeYT Extension/Tests"
npm test- Prefer the shared snapshot model over adding one-off storage keys or message contracts.
- Keep the popup compact and action-oriented. Deeper education belongs in the host app.
- Keep product copy trust-focused and consumer-facing.
- The extension is Safari-only, but the popup explicitly guards non-Safari user agents.
- Do not document the product as having no content scripts;
banner.jsis intentionally shipped as a small explanatory content script.