Follow-on to #21. /say today exposes subcommands only (on|off|voice|voices|stop|status) and every knob is an environment variable read once at load: DANKVOICE_VOICE, DANKVOICE_PLAYER, DANKVOICE_MAX, DANKVOICE_AUTO. Choosing a voice or an audio sink means restarting the session with a different env — and the three silent-session incident (2026-10-18) showed the missing knob is which output device the player targets (pw-play --target, paplay --device=): with PipeWire remembering an offline Bluetooth sink as the configured default, audio synthesized fine and played into nowhere.
Scope
/say menu — interactive options list via ctx.ui.select, mirroring the pi-peon settings pattern:
Auto-speak: toggle on/off (footer 🔊 reflects it)
Voice… — pick from the frank-tts roster
Output device… — enumerate PipeWire sinks (wpctl list audio sinks), plus "system default"; used as pw-play --target / paplay --device=
Speak a test phrase — synthesize + play through the current selection (proves the audio path audibly)
Persist choices to ~/.omp/agent/extensions/dankvoice.json (DANKVOICE_CONFIG override); env vars still win, then file, then defaults.
Bare /say opens the menu; help keeps the text listing.
Acceptance
bats tests/dankvoice.bats green, incl. new scenarios: menu lists all options; choosing a device routes the player invocation through --target <sink>; a menu-set voice is used by the next utterance and survives a restart of the extension; wpctl absent degrades to system-default-only.
Live pty TUI smoke: /say menu renders, test phrase audible.
# dankvoice: `/say` options menu
Follow-on to #21. `/say` today exposes subcommands only (`on|off|voice|voices|stop|status`) and every knob is an environment variable read once at load: `DANKVOICE_VOICE`, `DANKVOICE_PLAYER`, `DANKVOICE_MAX`, `DANKVOICE_AUTO`. Choosing a voice or an audio sink means restarting the session with a different env — and the three silent-session incident (2026-10-18) showed the missing knob is **which output device the player targets** (`pw-play --target`, `paplay --device=`): with PipeWire remembering an offline Bluetooth sink as the configured default, audio synthesized fine and played into nowhere.
## Scope
- `/say menu` — interactive options list via `ctx.ui.select`, mirroring the pi-peon settings pattern:
- Auto-speak: toggle on/off (footer `🔊` reflects it)
- Voice… — pick from the frank-tts roster
- Output device… — enumerate PipeWire sinks (`wpctl list audio sinks`), plus "system default"; used as `pw-play --target` / `paplay --device=`
- Player… — pw-play / paplay / ffplay, whichever exist
- Spoken-char cap… — 300 / 700 / 1500 / 3000
- Speak a test phrase — synthesize + play through the *current* selection (proves the audio path audibly)
- Persist choices to `~/.omp/agent/extensions/dankvoice.json` (`DANKVOICE_CONFIG` override); env vars still win, then file, then defaults.
- Bare `/say` opens the menu; `help` keeps the text listing.
## Acceptance
- `bats tests/dankvoice.bats` green, incl. new scenarios: menu lists all options; choosing a device routes the player invocation through `--target <sink>`; a menu-set voice is used by the next utterance and survives a restart of the extension; `wpctl` absent degrades to system-default-only.
- Live pty TUI smoke: `/say menu` renders, test phrase audible.
---
cwd: /home/blank/.omp/wt/wt-20261018-204442-7c8a99d · session: 01a1525d-0a05-7615-ba60-58e9b20495d1
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
dankvoice:
/sayoptions menuFollow-on to #21.
/saytoday exposes subcommands only (on|off|voice|voices|stop|status) and every knob is an environment variable read once at load:DANKVOICE_VOICE,DANKVOICE_PLAYER,DANKVOICE_MAX,DANKVOICE_AUTO. Choosing a voice or an audio sink means restarting the session with a different env — and the three silent-session incident (2026-10-18) showed the missing knob is which output device the player targets (pw-play --target,paplay --device=): with PipeWire remembering an offline Bluetooth sink as the configured default, audio synthesized fine and played into nowhere.Scope
/say menu— interactive options list viactx.ui.select, mirroring the pi-peon settings pattern:🔊reflects it)wpctl list audio sinks), plus "system default"; used aspw-play --target/paplay --device=~/.omp/agent/extensions/dankvoice.json(DANKVOICE_CONFIGoverride); env vars still win, then file, then defaults./sayopens the menu;helpkeeps the text listing.Acceptance
bats tests/dankvoice.batsgreen, incl. new scenarios: menu lists all options; choosing a device routes the player invocation through--target <sink>; a menu-set voice is used by the next utterance and survives a restart of the extension;wpctlabsent degrades to system-default-only./say menurenders, test phrase audible.cwd: /home/blank/.omp/wt/wt-20261018-204442-7c8a99d · session: 01a1525d-0a05-7615-ba60-58e9b20495d1