From f7b0eb18a8c1914acbdf503b1542064f69337fee Mon Sep 17 00:00:00 2001 From: Ryan Bright Date: Thu, 19 Feb 2026 21:10:05 -0700 Subject: [PATCH 1/2] feat(indicator): embed cue assets and app-owned i18n copy - embed start/stop/complete/cancel cue WAV files in the binary via go:embed\n- remove indicator text and cue-file keys from user config parsing\n- add locale scaffolding with English catalog and fallback behavior\n- update docs/tests for non-configurable indicator assets and text --- README.md | 3 +- apps/sotto/internal/config/defaults.go | 19 ++--- apps/sotto/internal/config/parser_jsonc.go | 45 ++--------- apps/sotto/internal/config/parser_legacy.go | 42 ---------- apps/sotto/internal/config/parser_test.go | 58 ++++---------- apps/sotto/internal/config/types.go | 19 ++--- .../internal/indicator/assets/cancel.wav | Bin 0 -> 15404 bytes .../internal/indicator/assets/complete.wav | Bin 0 -> 41324 bytes .../internal/indicator/assets/toggle_off.wav | Bin 0 -> 25964 bytes .../internal/indicator/assets/toggle_on.wav | Bin 0 -> 25964 bytes apps/sotto/internal/indicator/indicator.go | 19 +++-- .../internal/indicator/indicator_test.go | 9 +-- apps/sotto/internal/indicator/messages.go | 43 +++++++++++ .../sotto/internal/indicator/messages_test.go | 19 +++++ apps/sotto/internal/indicator/sound.go | 73 ++++++++---------- apps/sotto/internal/indicator/sound_test.go | 35 ++------- docs/configuration.md | 18 +---- 17 files changed, 152 insertions(+), 250 deletions(-) create mode 100644 apps/sotto/internal/indicator/assets/cancel.wav create mode 100644 apps/sotto/internal/indicator/assets/complete.wav create mode 100644 apps/sotto/internal/indicator/assets/toggle_off.wav create mode 100644 apps/sotto/internal/indicator/assets/toggle_on.wav create mode 100644 apps/sotto/internal/indicator/messages.go create mode 100644 apps/sotto/internal/indicator/messages_test.go diff --git a/README.md b/README.md index 58a0f7e..26ae657 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,8 @@ Local-first speech-to-text CLI. - indicator backends: - `hypr` notifications - `desktop` (freedesktop notifications, e.g. mako) -- optional WAV cue files for start/stop/complete/cancel +- embedded cue WAV assets for start/stop/complete/cancel (not user-configurable) +- built-in indicator localization scaffolding (English catalog currently shipped) - built-in environment diagnostics via `sotto doctor` ## Platform scope (current) diff --git a/apps/sotto/internal/config/defaults.go b/apps/sotto/internal/config/defaults.go index ce87203..3ce90e7 100644 --- a/apps/sotto/internal/config/defaults.go +++ b/apps/sotto/internal/config/defaults.go @@ -20,19 +20,12 @@ func Default() Config { }, Transcript: TranscriptConfig{TrailingSpace: true}, Indicator: IndicatorConfig{ - Enable: true, - Backend: "hypr", - DesktopAppName: "sotto-indicator", - SoundEnable: true, - SoundStartFile: "", - SoundStopFile: "", - SoundCompleteFile: "", - SoundCancelFile: "", - Height: 28, - TextRecording: "Recording…", - TextProcessing: "Transcribing…", - TextError: "Speech recognition error", - ErrorTimeoutMS: 1600, + Enable: true, + Backend: "hypr", + DesktopAppName: "sotto-indicator", + SoundEnable: true, + Height: 28, + ErrorTimeoutMS: 1600, }, Clipboard: CommandConfig{Raw: clipboard, Argv: mustParseArgv(clipboard)}, Vocab: VocabConfig{ diff --git a/apps/sotto/internal/config/parser_jsonc.go b/apps/sotto/internal/config/parser_jsonc.go index 82f220c..a117853 100644 --- a/apps/sotto/internal/config/parser_jsonc.go +++ b/apps/sotto/internal/config/parser_jsonc.go @@ -49,20 +49,12 @@ type jsoncTranscript struct { } type jsoncIndicator struct { - Enable *bool `json:"enable"` - Backend *string `json:"backend"` - DesktopAppName *string `json:"desktop_app_name"` - SoundEnable *bool `json:"sound_enable"` - SoundStartFile *string `json:"sound_start_file"` - SoundStopFile *string `json:"sound_stop_file"` - SoundCompleteFile *string `json:"sound_complete_file"` - SoundCancelFile *string `json:"sound_cancel_file"` - Height *int `json:"height"` - TextRecording *string `json:"text_recording"` - TextProcessing *string `json:"text_processing"` - TextTranscribing *string `json:"text_transcribing"` - TextError *string `json:"text_error"` - ErrorTimeoutMS *int `json:"error_timeout_ms"` + Enable *bool `json:"enable"` + Backend *string `json:"backend"` + DesktopAppName *string `json:"desktop_app_name"` + SoundEnable *bool `json:"sound_enable"` + Height *int `json:"height"` + ErrorTimeoutMS *int `json:"error_timeout_ms"` } type jsoncVocab struct { @@ -201,34 +193,9 @@ func (payload jsoncConfig) applyTo(cfg *Config) ([]Warning, error) { if payload.Indicator.SoundEnable != nil { cfg.Indicator.SoundEnable = *payload.Indicator.SoundEnable } - if payload.Indicator.SoundStartFile != nil { - cfg.Indicator.SoundStartFile = *payload.Indicator.SoundStartFile - } - if payload.Indicator.SoundStopFile != nil { - cfg.Indicator.SoundStopFile = *payload.Indicator.SoundStopFile - } - if payload.Indicator.SoundCompleteFile != nil { - cfg.Indicator.SoundCompleteFile = *payload.Indicator.SoundCompleteFile - } - if payload.Indicator.SoundCancelFile != nil { - cfg.Indicator.SoundCancelFile = *payload.Indicator.SoundCancelFile - } if payload.Indicator.Height != nil { cfg.Indicator.Height = *payload.Indicator.Height } - if payload.Indicator.TextRecording != nil { - cfg.Indicator.TextRecording = *payload.Indicator.TextRecording - } - if payload.Indicator.TextTranscribing != nil { - cfg.Indicator.TextProcessing = *payload.Indicator.TextTranscribing - warnings = append(warnings, Warning{Message: "indicator.text_transcribing is deprecated; use indicator.text_processing"}) - } - if payload.Indicator.TextProcessing != nil { - cfg.Indicator.TextProcessing = *payload.Indicator.TextProcessing - } - if payload.Indicator.TextError != nil { - cfg.Indicator.TextError = *payload.Indicator.TextError - } if payload.Indicator.ErrorTimeoutMS != nil { cfg.Indicator.ErrorTimeoutMS = *payload.Indicator.ErrorTimeoutMS } diff --git a/apps/sotto/internal/config/parser_legacy.go b/apps/sotto/internal/config/parser_legacy.go index 1e29543..b58faea 100644 --- a/apps/sotto/internal/config/parser_legacy.go +++ b/apps/sotto/internal/config/parser_legacy.go @@ -242,54 +242,12 @@ func applyRootKey(cfg *Config, key, value string) error { return fmt.Errorf("invalid bool for indicator.sound_enable: %w", err) } cfg.Indicator.SoundEnable = b - case "indicator.sound_start_file": - v, err := parseStringValue(value) - if err != nil { - return err - } - cfg.Indicator.SoundStartFile = v - case "indicator.sound_stop_file": - v, err := parseStringValue(value) - if err != nil { - return err - } - cfg.Indicator.SoundStopFile = v - case "indicator.sound_complete_file": - v, err := parseStringValue(value) - if err != nil { - return err - } - cfg.Indicator.SoundCompleteFile = v - case "indicator.sound_cancel_file": - v, err := parseStringValue(value) - if err != nil { - return err - } - cfg.Indicator.SoundCancelFile = v case "indicator.height": n, err := strconv.Atoi(value) if err != nil { return fmt.Errorf("invalid int for indicator.height: %w", err) } cfg.Indicator.Height = n - case "indicator.text_recording": - v, err := parseStringValue(value) - if err != nil { - return err - } - cfg.Indicator.TextRecording = v - case "indicator.text_processing", "indicator.text_transcribing": - v, err := parseStringValue(value) - if err != nil { - return err - } - cfg.Indicator.TextProcessing = v - case "indicator.text_error": - v, err := parseStringValue(value) - if err != nil { - return err - } - cfg.Indicator.TextError = v case "indicator.error_timeout_ms": n, err := strconv.Atoi(value) if err != nil { diff --git a/apps/sotto/internal/config/parser_test.go b/apps/sotto/internal/config/parser_test.go index 6b071cd..3c17c77 100644 --- a/apps/sotto/internal/config/parser_test.go +++ b/apps/sotto/internal/config/parser_test.go @@ -193,27 +193,6 @@ func TestParseIndicatorBackend(t *testing.T) { } } -func TestParseIndicatorTextTranscribingAliasWarning(t *testing.T) { - cfg, warnings, err := Parse(`{"indicator":{"text_transcribing":"Working..."}}`, Default()) - if err != nil { - t.Fatalf("Parse() error = %v", err) - } - if cfg.Indicator.TextProcessing != "Working..." { - t.Fatalf("unexpected text processing value: %q", cfg.Indicator.TextProcessing) - } - - found := false - for _, w := range warnings { - if strings.Contains(w.Message, "text_transcribing") { - found = true - break - } - } - if !found { - t.Fatalf("expected alias warning, warnings=%+v", warnings) - } -} - func TestParseIndicatorSoundEnable(t *testing.T) { cfg, _, err := Parse(`{"indicator":{"sound_enable":false}}`, Default()) if err != nil { @@ -224,32 +203,23 @@ func TestParseIndicatorSoundEnable(t *testing.T) { } } -func TestParseIndicatorSoundFiles(t *testing.T) { - cfg, _, err := Parse(` -{ - "indicator": { - "sound_start_file": "/tmp/start.wav", - "sound_stop_file": "/tmp/stop.wav", - "sound_complete_file": "/tmp/complete.wav", - "sound_cancel_file": "/tmp/cancel.wav" - } -} -`, Default()) - if err != nil { - t.Fatalf("Parse() error = %v", err) - } - - if cfg.Indicator.SoundStartFile != "/tmp/start.wav" { - t.Fatalf("unexpected start file: %q", cfg.Indicator.SoundStartFile) +func TestParseIndicatorTextKeysRejected(t *testing.T) { + _, _, err := Parse(`{"indicator":{"text_recording":"Recording"}}`, Default()) + if err == nil { + t.Fatal("expected error for indicator.text_recording") } - if cfg.Indicator.SoundStopFile != "/tmp/stop.wav" { - t.Fatalf("unexpected stop file: %q", cfg.Indicator.SoundStopFile) + if !strings.Contains(err.Error(), "unknown field") { + t.Fatalf("unexpected error: %v", err) } - if cfg.Indicator.SoundCompleteFile != "/tmp/complete.wav" { - t.Fatalf("unexpected complete file: %q", cfg.Indicator.SoundCompleteFile) +} + +func TestParseIndicatorSoundFileKeysRejected(t *testing.T) { + _, _, err := Parse(`{"indicator":{"sound_start_file":"/tmp/start.wav"}}`, Default()) + if err == nil { + t.Fatal("expected error for indicator.sound_start_file") } - if cfg.Indicator.SoundCancelFile != "/tmp/cancel.wav" { - t.Fatalf("unexpected cancel file: %q", cfg.Indicator.SoundCancelFile) + if !strings.Contains(err.Error(), "unknown field") { + t.Fatalf("unexpected error: %v", err) } } diff --git a/apps/sotto/internal/config/types.go b/apps/sotto/internal/config/types.go index 917a92a..5687a11 100644 --- a/apps/sotto/internal/config/types.go +++ b/apps/sotto/internal/config/types.go @@ -43,19 +43,12 @@ type TranscriptConfig struct { // IndicatorConfig controls visual indicator and audio cue behavior. type IndicatorConfig struct { - Enable bool - Backend string - DesktopAppName string - SoundEnable bool - SoundStartFile string - SoundStopFile string - SoundCompleteFile string - SoundCancelFile string - Height int - TextRecording string - TextProcessing string - TextError string - ErrorTimeoutMS int + Enable bool + Backend string + DesktopAppName string + SoundEnable bool + Height int + ErrorTimeoutMS int } // CommandConfig stores a raw command string and its parsed argv form. diff --git a/apps/sotto/internal/indicator/assets/cancel.wav b/apps/sotto/internal/indicator/assets/cancel.wav new file mode 100644 index 0000000000000000000000000000000000000000..e43191f1392ae59b4dbb0ba57caac4b8fb7a9f4c GIT binary patch literal 15404 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%0D{ced!-vO1qD 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 "${HYPR_ARGS_FILE}" cfg := config.Default().Indicator cfg.SoundEnable = false cfg.Enable = true - cfg.TextRecording = "Recording" - cfg.TextProcessing = "Transcribing" - cfg.TextError = "Speech error" notify := NewHyprNotify(cfg, nil) notify.ShowRecording(context.Background()) @@ -41,9 +38,9 @@ printf '%s\n' "$*" >> "${HYPR_ARGS_FILE}" require.NoError(t, err) lines := strings.Split(strings.TrimSpace(string(data)), "\n") require.Len(t, lines, 4) - require.Equal(t, "--quiet dispatch notify 1 300000 rgb(89b4fa) Recording", lines[0]) - require.Equal(t, "--quiet dispatch notify 1 300000 rgb(cba6f7) Transcribing", lines[1]) - require.Equal(t, "--quiet dispatch notify 3 1600 rgb(f38ba8) Speech error", lines[2]) + require.Equal(t, "--quiet dispatch notify 1 300000 rgb(89b4fa) Recording…", lines[0]) + require.Equal(t, "--quiet dispatch notify 1 300000 rgb(cba6f7) Transcribing…", lines[1]) + require.Equal(t, "--quiet dispatch notify 3 1600 rgb(f38ba8) Speech recognition error", lines[2]) require.Equal(t, "--quiet dispatch dismissnotify", lines[3]) } diff --git a/apps/sotto/internal/indicator/messages.go b/apps/sotto/internal/indicator/messages.go new file mode 100644 index 0000000..a6a29af --- /dev/null +++ b/apps/sotto/internal/indicator/messages.go @@ -0,0 +1,43 @@ +package indicator + +import ( + "os" + "strings" +) + +type locale string + +const ( + localeEnglish locale = "en" +) + +type messages struct { + recording string + processing string + errorText string +} + +func indicatorMessagesFromEnv() messages { + return indicatorMessages(resolveLocale(os.Getenv("LANG"))) +} + +func resolveLocale(raw string) locale { + raw = strings.ToLower(strings.TrimSpace(raw)) + if strings.HasPrefix(raw, "en") { + return localeEnglish + } + return localeEnglish +} + +func indicatorMessages(tag locale) messages { + switch tag { + case localeEnglish: + fallthrough + default: + return messages{ + recording: "Recording…", + processing: "Transcribing…", + errorText: "Speech recognition error", + } + } +} diff --git a/apps/sotto/internal/indicator/messages_test.go b/apps/sotto/internal/indicator/messages_test.go new file mode 100644 index 0000000..669d1a3 --- /dev/null +++ b/apps/sotto/internal/indicator/messages_test.go @@ -0,0 +1,19 @@ +package indicator + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestResolveLocaleDefaultsToEnglish(t *testing.T) { + require.Equal(t, localeEnglish, resolveLocale("en_US.UTF-8")) + require.Equal(t, localeEnglish, resolveLocale("fr_FR.UTF-8")) +} + +func TestIndicatorMessagesEnglish(t *testing.T) { + msg := indicatorMessages(localeEnglish) + require.Equal(t, "Recording…", msg.recording) + require.Equal(t, "Transcribing…", msg.processing) + require.Equal(t, "Speech recognition error", msg.errorText) +} diff --git a/apps/sotto/internal/indicator/sound.go b/apps/sotto/internal/indicator/sound.go index 8a0141a..b0ccd74 100644 --- a/apps/sotto/internal/indicator/sound.go +++ b/apps/sotto/internal/indicator/sound.go @@ -1,17 +1,15 @@ package indicator import ( + "bytes" "context" + "embed" "fmt" "math" - "os" "os/exec" - "path/filepath" - "strings" "time" "github.com/jfreymuth/pulse" - "github.com/rbright/sotto/internal/config" ) // cueKind identifies each cue event used by the session lifecycle. @@ -34,6 +32,14 @@ type toneSpec struct { } var ( + //go:embed assets/toggle_on.wav assets/toggle_off.wav assets/complete.wav assets/cancel.wav + cueAssetFS embed.FS + + startCueWAV = mustCueWAV("assets/toggle_on.wav") + stopCueWAV = mustCueWAV("assets/toggle_off.wav") + completeCueWAV = mustCueWAV("assets/complete.wav") + cancelCueWAV = mustCueWAV("assets/cancel.wav") + startCuePCM = synthesizeCue([]toneSpec{ {frequencyHz: 880, duration: 70 * time.Millisecond, volume: 0.18}, {frequencyHz: 1175, duration: 70 * time.Millisecond, volume: 0.18}, @@ -51,10 +57,10 @@ var ( }) ) -// emitCue plays a configured WAV file when present, otherwise falls back to synthesis. -func emitCue(kind cueKind, cfg config.IndicatorConfig) error { - if path := cuePath(kind, cfg); path != "" { - if err := playCueFile(path); err == nil { +// emitCue plays an embedded WAV cue when available, then falls back to synthesis. +func emitCue(kind cueKind) error { + if data := cueWAV(kind); len(data) > 0 { + if err := playCueData(data); err == nil { return nil } } @@ -67,59 +73,42 @@ func emitCue(kind cueKind, cfg config.IndicatorConfig) error { return playSynthCue(samples) } -// cuePath resolves the configured WAV path for one cue kind. -func cuePath(kind cueKind, cfg config.IndicatorConfig) string { - var raw string +func cueWAV(kind cueKind) []byte { switch kind { case cueStart: - raw = cfg.SoundStartFile + return startCueWAV case cueStop: - raw = cfg.SoundStopFile + return stopCueWAV case cueComplete: - raw = cfg.SoundCompleteFile + return completeCueWAV case cueCancel: - raw = cfg.SoundCancelFile + return cancelCueWAV default: - return "" + return nil } - return expandUserPath(raw) } -// expandUserPath expands `~` prefixes for user-provided cue file paths. -func expandUserPath(raw string) string { - raw = strings.TrimSpace(raw) - if raw == "" { - return "" - } - if raw == "~" { - home, err := os.UserHomeDir() - if err != nil { - return raw - } - return home - } - if !strings.HasPrefix(raw, "~/") { - return raw - } - home, err := os.UserHomeDir() +func mustCueWAV(path string) []byte { + data, err := cueAssetFS.ReadFile(path) if err != nil { - return raw + panic(fmt.Sprintf("load embedded cue %q: %v", path, err)) } - return filepath.Join(home, strings.TrimPrefix(raw, "~/")) + return data } -// playCueFile plays a configured WAV file through pw-play. -func playCueFile(path string) error { - if _, err := os.Stat(path); err != nil { - return fmt.Errorf("stat cue file %q: %w", path, err) +// playCueData plays an embedded WAV payload through pw-play. +func playCueData(data []byte) error { + if len(data) == 0 { + return fmt.Errorf("embedded cue payload is empty") } ctx, cancel := context.WithTimeout(context.Background(), 4*time.Second) defer cancel() - cmd := exec.CommandContext(ctx, "pw-play", "--media-role", "Notification", path) + cmd := exec.CommandContext(ctx, "pw-play", "--media-role", "Notification", "-") + cmd.Stdin = bytes.NewReader(data) if err := cmd.Run(); err != nil { - return fmt.Errorf("play cue file %q: %w", path, err) + return fmt.Errorf("play embedded cue: %w", err) } return nil } diff --git a/apps/sotto/internal/indicator/sound_test.go b/apps/sotto/internal/indicator/sound_test.go index 6ac39a4..5d9fc56 100644 --- a/apps/sotto/internal/indicator/sound_test.go +++ b/apps/sotto/internal/indicator/sound_test.go @@ -1,11 +1,9 @@ package indicator import ( - "path/filepath" "testing" "time" - "github.com/rbright/sotto/internal/config" "github.com/stretchr/testify/require" ) @@ -16,6 +14,13 @@ func TestCueSamplesPresent(t *testing.T) { require.NotEmpty(t, cueSamples(cueCancel)) } +func TestCueEmbeddedWAVPresent(t *testing.T) { + require.NotEmpty(t, cueWAV(cueStart)) + require.NotEmpty(t, cueWAV(cueStop)) + require.NotEmpty(t, cueWAV(cueComplete)) + require.NotEmpty(t, cueWAV(cueCancel)) +} + func TestSynthesizeToneDuration(t *testing.T) { got := synthesizeTone(toneSpec{frequencyHz: 440, duration: 100 * time.Millisecond, volume: 0.2}) want := samplesForDuration(100 * time.Millisecond) @@ -28,32 +33,6 @@ func TestSynthesizeToneInvalidSpecReturnsEmpty(t *testing.T) { require.Empty(t, synthesizeTone(toneSpec{frequencyHz: 440, duration: 100 * time.Millisecond, volume: 0})) } -func TestCuePathMapping(t *testing.T) { - home := t.TempDir() - t.Setenv("HOME", home) - cfg := config.IndicatorConfig{ - SoundStartFile: "~/start.wav", - SoundStopFile: "/tmp/stop.wav", - SoundCompleteFile: "/tmp/complete.wav", - SoundCancelFile: "/tmp/cancel.wav", - } - - require.Equal(t, filepath.Join(home, "start.wav"), cuePath(cueStart, cfg)) - require.Equal(t, "/tmp/stop.wav", cuePath(cueStop, cfg)) - require.Equal(t, "/tmp/complete.wav", cuePath(cueComplete, cfg)) - require.Equal(t, "/tmp/cancel.wav", cuePath(cueCancel, cfg)) -} - -func TestExpandUserPath(t *testing.T) { - home := t.TempDir() - t.Setenv("HOME", home) - - require.Equal(t, home, expandUserPath("~")) - require.Equal(t, filepath.Join(home, "Downloads", "sound.wav"), expandUserPath("~/Downloads/sound.wav")) - require.Equal(t, "/tmp/sound.wav", expandUserPath("/tmp/sound.wav")) - require.Empty(t, expandUserPath(" ")) -} - func TestSamplesForDuration(t *testing.T) { require.Equal(t, 0, samplesForDuration(0)) require.Greater(t, samplesForDuration(25*time.Millisecond), 0) diff --git a/docs/configuration.md b/docs/configuration.md index 0e0feac..c2cd935 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -82,17 +82,12 @@ Top-level object keys: | `indicator.backend` | `hypr` | `hypr` or `desktop` | | `indicator.desktop_app_name` | `sotto-indicator` | required for desktop backend | | `indicator.sound_enable` | `true` | cue sounds switch | -| `indicator.sound_start_file` | empty | optional WAV path | -| `indicator.sound_stop_file` | empty | optional WAV path | -| `indicator.sound_complete_file` | empty | optional WAV path | -| `indicator.sound_cancel_file` | empty | optional WAV path | | `indicator.height` | `28` | indicator size parameter | -| `indicator.text_recording` | `Recording…` | recording label | -| `indicator.text_processing` | `Transcribing…` | processing label | -| `indicator.text_transcribing` | alias | compatibility alias for `indicator.text_processing` | -| `indicator.text_error` | `Speech recognition error` | error label | | `indicator.error_timeout_ms` | `1600` | `>= 0` | +Indicator text and cue assets are now application-owned (embedded in the binary) and are not user-configurable. +Localization support exists in-code with an English catalog shipped by default. + ### command keys | Key | Default | Notes | @@ -166,13 +161,6 @@ default-timeout=0 "backend": "hypr", "desktop_app_name": "sotto-indicator", "sound_enable": true, - "sound_start_file": "", - "sound_stop_file": "", - "sound_complete_file": "", - "sound_cancel_file": "", - "text_recording": "Recording…", - "text_processing": "Transcribing…", - "text_error": "Speech recognition error", "error_timeout_ms": 1600 }, From 78f1013a803467e03cc32f85f41e80c5a19a7f19 Mon Sep 17 00:00:00 2001 From: Ryan Bright Date: Thu, 19 Feb 2026 21:57:09 -0700 Subject: [PATCH 2/2] fix(indicator): honor caller context for cue playback - thread context through playCue -> emitCue -> playCueData\n- wrap playback timeout around caller context instead of Background\n- short-circuit synth fallback when context is canceled\n- align new parser rejection tests to testify/require style --- apps/sotto/internal/config/parser_test.go | 18 ++++++------------ apps/sotto/internal/indicator/indicator.go | 21 ++++++++++++--------- apps/sotto/internal/indicator/sound.go | 21 ++++++++++++++++----- apps/sotto/internal/indicator/sound_test.go | 11 +++++++++++ 4 files changed, 45 insertions(+), 26 deletions(-) diff --git a/apps/sotto/internal/config/parser_test.go b/apps/sotto/internal/config/parser_test.go index 3c17c77..e7cdd6e 100644 --- a/apps/sotto/internal/config/parser_test.go +++ b/apps/sotto/internal/config/parser_test.go @@ -3,6 +3,8 @@ package config import ( "strings" "testing" + + "github.com/stretchr/testify/require" ) func TestParseValidJSONCConfig(t *testing.T) { @@ -205,22 +207,14 @@ func TestParseIndicatorSoundEnable(t *testing.T) { func TestParseIndicatorTextKeysRejected(t *testing.T) { _, _, err := Parse(`{"indicator":{"text_recording":"Recording"}}`, Default()) - if err == nil { - t.Fatal("expected error for indicator.text_recording") - } - if !strings.Contains(err.Error(), "unknown field") { - t.Fatalf("unexpected error: %v", err) - } + require.Error(t, err) + require.Contains(t, err.Error(), "unknown field") } func TestParseIndicatorSoundFileKeysRejected(t *testing.T) { _, _, err := Parse(`{"indicator":{"sound_start_file":"/tmp/start.wav"}}`, Default()) - if err == nil { - t.Fatal("expected error for indicator.sound_start_file") - } - if !strings.Contains(err.Error(), "unknown field") { - t.Fatalf("unexpected error: %v", err) - } + require.Error(t, err) + require.Contains(t, err.Error(), "unknown field") } func TestParseInitializesNilVocabMap(t *testing.T) { diff --git a/apps/sotto/internal/indicator/indicator.go b/apps/sotto/internal/indicator/indicator.go index 6b31466..ddc9eed 100644 --- a/apps/sotto/internal/indicator/indicator.go +++ b/apps/sotto/internal/indicator/indicator.go @@ -48,7 +48,7 @@ func NewHyprNotify(cfg config.IndicatorConfig, logger *slog.Logger) *HyprNotify // ShowRecording signals recording start and emits the start cue. func (h *HyprNotify) ShowRecording(ctx context.Context) { - h.playCue(cueStart) + h.playCue(ctx, cueStart) if !h.cfg.Enable { return } @@ -86,18 +86,18 @@ func (h *HyprNotify) ShowError(ctx context.Context, text string) { } // CueStop emits the stop cue. -func (h *HyprNotify) CueStop(context.Context) { - h.playCue(cueStop) +func (h *HyprNotify) CueStop(ctx context.Context) { + h.playCue(ctx, cueStop) } // CueComplete emits the successful-commit cue. -func (h *HyprNotify) CueComplete(context.Context) { - h.playCue(cueComplete) +func (h *HyprNotify) CueComplete(ctx context.Context) { + h.playCue(ctx, cueComplete) } // CueCancel emits the cancel cue. -func (h *HyprNotify) CueCancel(context.Context) { - h.playCue(cueCancel) +func (h *HyprNotify) CueCancel(ctx context.Context) { + h.playCue(ctx, cueCancel) } // Hide dismisses the active indicator surface. @@ -196,14 +196,17 @@ func (h *HyprNotify) run(ctx context.Context, fn func(context.Context) error) { } // playCue serializes cue playback and emits audio asynchronously. -func (h *HyprNotify) playCue(kind cueKind) { +func (h *HyprNotify) playCue(ctx context.Context, kind cueKind) { if !h.cfg.SoundEnable { return } + if ctx == nil { + ctx = context.Background() + } go func() { h.soundMu.Lock() defer h.soundMu.Unlock() - if err := emitCue(kind); err != nil { + if err := emitCue(ctx, kind); err != nil { h.log("indicator audio cue failed", err) } }() diff --git a/apps/sotto/internal/indicator/sound.go b/apps/sotto/internal/indicator/sound.go index b0ccd74..865034a 100644 --- a/apps/sotto/internal/indicator/sound.go +++ b/apps/sotto/internal/indicator/sound.go @@ -58,13 +58,21 @@ var ( ) // emitCue plays an embedded WAV cue when available, then falls back to synthesis. -func emitCue(kind cueKind) error { +func emitCue(ctx context.Context, kind cueKind) error { + if ctx == nil { + ctx = context.Background() + } + if data := cueWAV(kind); len(data) > 0 { - if err := playCueData(data); err == nil { + if err := playCueData(ctx, data); err == nil { return nil } } + if err := ctx.Err(); err != nil { + return err + } + samples := cueSamples(kind) if len(samples) == 0 { return nil @@ -97,15 +105,18 @@ func mustCueWAV(path string) []byte { } // playCueData plays an embedded WAV payload through pw-play. -func playCueData(data []byte) error { +func playCueData(ctx context.Context, data []byte) error { if len(data) == 0 { return fmt.Errorf("embedded cue payload is empty") } + if ctx == nil { + ctx = context.Background() + } - ctx, cancel := context.WithTimeout(context.Background(), 4*time.Second) + runCtx, cancel := context.WithTimeout(ctx, 4*time.Second) defer cancel() - cmd := exec.CommandContext(ctx, "pw-play", "--media-role", "Notification", "-") + cmd := exec.CommandContext(runCtx, "pw-play", "--media-role", "Notification", "-") cmd.Stdin = bytes.NewReader(data) if err := cmd.Run(); err != nil { return fmt.Errorf("play embedded cue: %w", err) diff --git a/apps/sotto/internal/indicator/sound_test.go b/apps/sotto/internal/indicator/sound_test.go index 5d9fc56..2ec30f9 100644 --- a/apps/sotto/internal/indicator/sound_test.go +++ b/apps/sotto/internal/indicator/sound_test.go @@ -1,6 +1,8 @@ package indicator import ( + "context" + "errors" "testing" "time" @@ -37,3 +39,12 @@ func TestSamplesForDuration(t *testing.T) { require.Equal(t, 0, samplesForDuration(0)) require.Greater(t, samplesForDuration(25*time.Millisecond), 0) } + +func TestEmitCueRespectsCancelledContext(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + cancel() + + err := emitCue(ctx, cueStart) + require.Error(t, err) + require.True(t, errors.Is(err, context.Canceled)) +}