Files
bearwave-mac/AGENTS.md
2026-06-25 09:21:42 +02:00

109 lines
4.6 KiB
Markdown

# AGENTS.md
This repository is the native macOS SwiftUI port of BearWave, originally a
Linux/KDE internet radio app.
Do not treat it as a Qt compatibility port. The current repo is a native macOS
desktop app focused on internet radio.
## What This Repo Is
- SwiftPM macOS app targeting `macOS 26`
- SwiftUI desktop UI
- `AVPlayer`-based playback for radio streams
- Radio Browser as the station source
- Local persistence for favorites, recents, manual stations, station folders, and resume state
## Architecture Overview
- `Sources/BearWaveApp/BearWaveApp.swift`
App scene entrypoint, window sizing, commands, menu bar extra, settings scene
- `Sources/BearWaveCore/App/AppModel.swift`
Top-level app coordinator; owns `StationLibrary`, `PlaybackController`, and artwork services
- `Sources/BearWaveCore/Stores/StationLibrary.swift`
Source of truth for station pages, search results, favorites, recents, manual entries, and station folders
- `Sources/BearWaveCore/Stores/PersistenceStore.swift`
JSON-based persistence for radio state
- `Sources/BearWaveCore/Services/RadioBrowserClient.swift`
Radio Browser API wrapper plus local search normalization and ranking
- `Sources/BearWaveCore/Services/PlaybackController.swift`
Shared `AVPlayer` wrapper with explicit playback states, retries, stream metadata via `AVPlayerItemMetadataOutput`, and Now Playing updates
- `Sources/BearWaveCore/Services/StationArtworkLoader.swift`
Favicon and artwork fetch with disk cache
- `Sources/BearWaveCore/Services/NowPlayingArtworkResolver.swift`
Artwork resolution for current playback state
- `Sources/BearWaveCore/Views/`
Sidebar, station list, station detail, player bar, settings, menu bar, mini player
## Current Product Behavior
- Dedicated pages:
`Top`, `Germany`, `Netherlands`, `World`, `Search Results`, `Favorites`, `Recent`, `Manual`
- Search is global and stays independent from the current browse page
- Search ranking intentionally filters naive mid-word matches such as `slam` matching `Islamabad`
- Playback UI exposes explicit states: connecting, buffering, playing, paused, stopped, failed
- A right-side detail panel shows station metadata and current stream metadata when available
- Player controls remain radio-focused: play/pause, stop, volume
- Mini Player is available via `Cmd+M`
- Mini Player target size is `555x110`
- Station folders support create, rename, delete, and station assignment
- Menu bar extra remains active while playback continues
## Build and Run Conventions
Use these commands unless there is a strong reason not to:
```bash
swift build --disable-index-store
CLANG_MODULE_CACHE_PATH=/private/tmp/bearwave-clang-cache swift run --disable-index-store BearWaveChecks
./script/build_and_run.sh
```
The run script:
- kills the previous process
- builds via SwiftPM
- stages a local `.app` into `dist/`
- copies SwiftPM resource bundles manually
- copies `.lproj` localization directories into the bundle
- launches the app bundle
Do not remove the manual resource-bundle copy step from `script/build_and_run.sh`
unless the bundle pipeline is replaced deliberately.
## Important Constraints
- Prefer the internal SSD workspace:
`/Users/sebastian/Development/radioappmac`
- Do not assume the mounted share copy is current.
- The staged app bundle uses ATS exceptions so that `http://` radio streams can play.
- Debug signing and sandbox behavior are intentionally pragmatic and not yet release-ready.
- `PlaybackController` uses `AVPlayerItemMetadataOutput` for stream metadata.
- `MediaPlayer` is imported with `@preconcurrency`.
- `MPMediaItemArtwork` is built from a `CGImage`-backed request handler.
- Main window launch width is dynamic: `1255` on smaller displays, `1600` on wide displays.
- Mini Player target size is `555x110`.
## What To Preserve
- Keep the project native-first for macOS.
- Keep search global and ranking strict.
- Keep explicit playback states; do not regress to a plain boolean model.
- Keep the current split between `BearWaveApp` and `BearWaveCore`.
- Keep the build/run script compatible with local staged app execution.
## Good Next Steps
- Improve release packaging, signing, and notarization
- Add more playback diagnostics per stream failure mode
- Expand tests around playback-state transitions and search ranking
- Add cache eviction for memory and disk caches
- Keep folders clearly positioned as lightweight saved-station organization
## Bad Changes
- Reintroducing page-coupled search behavior
- Replacing explicit playback states with only `isPlaying`
- Moving back toward Qt/KDE abstractions in this repo
- Assuming every stream will provide usable metadata or artwork