Desktop Material

Audio system (narrator, sound effects, per-repository music)

An optional, settings-gated audio layer. Every part is off by default and designed never to become annoying. Three cooperating parts:

  1. Spoken narrator (TTS) — speaks selected, meaningful app events (commit, push, pull, success, errors) via the renderer SpeechSynthesis API, with natural voices for both English (en-US) and Hong Kong Cantonese (zh-HK). Rate-limited by a configurable cooldown so it never chatters.
  2. Sound effects (SFX) — short cues synthesized with the Web Audio API (no bundled audio assets), one recognizable gesture per event category, with a volume control.
  3. Per-repository music — an optional user-chosen track looped quietly for the active repository, pausable at any time.

User workflow

Open Settings → Appearance → Language to set the app-wide playfulness levels for English and Cantonese independently from 1–5. These sliders sit beside the language-mode selector, remain available when audio is off, persist immediately, and control the tone of both on-screen copy and narration. Level 1 is fully serious and level 5 is maximum fun; facts, error copy, destructive actions, and safety messages remain clear at every level.

Open Settings → Sound for audio itself. The master switch gates the entire audio system; the three parts each have their own enable toggle, volume slider, and previews. The narrator adds a minimum-gap slider and a preview. Music is chosen per repository via a file picker (mp3/ogg/wav/m4a/flac/aac). Quiet hours and a "follow reduced-motion" toggle round out the anti-annoyance controls.

Event routing

App events reach audio through the in-app notification centre. App diffs the newest-first notification list on every AppStore update and forwards only genuinely new (non-replayed, deduped) entries to AudioCueStore. Startup history is seeded silently. Each NotificationCentreKind maps to an audio cue category (categoryForNotificationKind).

Anti-annoyance rules (pure, tested)

decideAudioActions (in app/src/lib/audio/audio-throttle.ts) is a pure function — the clock is passed in — so throttling is fully unit-tested:

Localization and tone

Spoken line templates live in app/src/lib/audio/narrator-lines.ts, separate from logic, with English and Cantonese variants per category and three tone bands the funny-level selects (1–2 plain, 3 light, 4–5 playful). Error lines are level-independent and clear. The spoken locale follows the persisted language mode (bilingual mode speaks one side). All Settings copy is localized through i18n-resources (settings.sound*) in English, Cantonese, and bilingual.

Persistence

normalizeAudioSettings, parse/serializeAudioSettings, and the repo-music map helpers are pure and round-trip tested.

Accessibility and safety

Failure modes

Verification

This category has no HTTP API. Postman collections are not applicable.