Skip to content

feat(indicator): embed cue assets and app-owned i18n copy#2

Merged
rbright merged 2 commits intomainfrom
feat/embedded-indicator-cues
Feb 20, 2026
Merged

feat(indicator): embed cue assets and app-owned i18n copy#2
rbright merged 2 commits intomainfrom
feat/embedded-indicator-cues

Conversation

@rbright
Copy link
Owner

@rbright rbright commented Feb 20, 2026

Summary

  • embed indicator cue WAV assets in the binary (go:embed) and play them directly via pw-play
  • remove user-configurable indicator cue-file/text keys from config parsing
  • add app-owned indicator localization scaffolding with English catalog + fallback
  • update docs and tests to reflect non-configurable indicator cue/text behavior

Why

  • removes dependency on machine-local files (for example ~/Downloads/*.wav)
  • keeps indicator UX assets and copy versioned with the application binary
  • sets up a clean path for future locale catalogs while shipping English only today

Breaking change

Indicator config keys removed:

  • indicator.sound_start_file
  • indicator.sound_stop_file
  • indicator.sound_complete_file
  • indicator.sound_cancel_file
  • indicator.text_recording
  • indicator.text_processing
  • indicator.text_error
  • indicator.text_transcribing

Verification

  • go test ./apps/sotto/...
  • just fmt
  • just ci-check
  • nix build 'path:.#sotto'

Summary by CodeRabbit

  • New Features

    • Indicator audio cues (start, stop, complete, cancel) are now embedded and standardized.
    • Built-in localization scaffolding added for indicator text messages with English translation shipped by default.
  • Documentation

    • Configuration docs updated to reflect that indicator assets and texts are embedded and not user-configurable.
  • Bug Fixes

    • Configuration parsing now rejects removed/unsupported indicator keys to prevent ambiguous or ignored settings.

- 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
@coderabbitai
Copy link

coderabbitai bot commented Feb 20, 2026

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Walkthrough

This pull request removes user-configurable indicator cue WAV files and text labels from the configuration schema, embedding WAV cue assets and adding an internal localization scaffold (English catalog shipped). Indicator playback now uses embedded data with context-aware playback and falls back to synthesis.

Changes

Cohort / File(s) Summary
Configuration Schema Removal
apps/sotto/internal/config/types.go, apps/sotto/internal/config/defaults.go, apps/sotto/internal/config/parser_jsonc.go, apps/sotto/internal/config/parser_legacy.go
Removed indicator config fields: SoundStartFile, SoundStopFile, SoundCompleteFile, SoundCancelFile, TextRecording, TextProcessing, TextError. Cleared corresponding defaults and parsing/legacy handling; unknown indicator keys now produce parse errors.
Localization & Embedded Assets
apps/sotto/internal/indicator/messages.go, apps/sotto/internal/indicator/sound.go
Added internal locale/messages module resolving LANG -> messages (currently English). Replaced filesystem-based cue files with embedded WAV assets via go:embed (start/stop/complete/cancel), introduced in-memory WAV playback (playCueData → pipe to pw-play), and preserved synth fallback.
Indicator Implementation Updates
apps/sotto/internal/indicator/indicator.go
Added unexported messages field to HyprNotify, initialized from environment. Updated ShowRecording/ShowTranscribing/ShowError to use messages. Changed cue playback APIs: playCue now accepts context.Context, and CueStop/CueComplete/CueCancel signatures now accept context.Context and propagate context to emit/play routines.
Tests
apps/sotto/internal/config/parser_test.go, apps/sotto/internal/indicator/indicator_test.go, apps/sotto/internal/indicator/messages_test.go, apps/sotto/internal/indicator/sound_test.go
Replaced warning-based tests with strict rejection tests for removed config keys. Added tests for locale resolution and presence of embedded WAVs, and for emitCue respecting canceled contexts. Removed tests that validated path expansion and filesystem cue-path mapping. Updated indicator text expectations to new message strings.
Documentation
README.md, docs/configuration.md
Updated feature list and configuration documentation to state that indicator cue assets and text labels are embedded and not user-configurable; added note about built-in localization scaffolding (English catalog shipped).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 I dug up cues from deep inside,
Embedded tunes now softly glide.
Locale whispers, English cheer,
Playback listens when contexts veer —
A rabbit hums, the changes bide. 🎶

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and accurately summarizes the main changes: embedding WAV cue assets and implementing application-owned internationalization copy for the indicator feature.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/embedded-indicator-cues

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.5.0)

Error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/docs/product/migration-guide for migration instructions
The command is terminated due to an error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/docs/product/migration-guide for migration instructions


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/sotto/internal/config/parser_test.go`:
- Around line 206-223: Replace t.Fatal/t.Fatalf usage in
TestParseIndicatorTextKeysRejected and TestParseIndicatorSoundFileKeysRejected
with testify's require helpers to match project test conventions: use
require.Error/require.ErrorContains (or require.Contains on err.Error()) for the
expected error checks and require.NoError/require.Nil where appropriate;
reference the Parse and Default calls to assert that an error was returned and
that the error message contains "unknown field". Ensure you import
"github.com/stretchr/testify/require" in the test file.

In `@apps/sotto/internal/indicator/sound.go`:
- Around line 60-66: The cue playback is dropping the caller's context so
cancellation isn't propagated; update playCue to accept a context.Context and
have the callers (ShowRecording, CueStop, CueComplete, CueCancel) pass their
context through, then change emitCue to emitCue(ctx context.Context, kind
cueKind) and playCueData to playCueData(ctx context.Context, data []byte);
inside playCueData wrap the incoming ctx with a timeout using
context.WithTimeout(ctx, ...) (instead of context.Background()) and ensure the
cancel is deferred so playback can be cancelled by the original context.

- 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
@rbright rbright merged commit 82c6554 into main Feb 20, 2026
2 checks passed
@rbright rbright deleted the feat/embedded-indicator-cues branch February 20, 2026 05:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant