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

4.6 KiB

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:

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