fix(tui): harden voice.record + TextInput paste + super-mod reserved list

Three round-7 Copilot follow-ups on #19835:

- voice.record start handler used _load_cfg().get('voice', {}).get(...) without
  shape checks, so malformed YAML (bool/scalar/list) returned 5025 instead of
  using VAD defaults. Centralized _voice_cfg_dict() helper and type-guarded
  silence_threshold/silence_duration with numeric fallbacks.
- TextInput pass-through check moved above paste/copy handling so configured
  voice chords (ctrl+v / alt+v / cmd+v) beat the composer's paste/copy
  defaults.
- parser now also rejects super+{c,d,l,v} — on macOS those are
  copy/exit/clear/paste and would be advertised in /voice status but never
  actually toggle recording.
This commit is contained in:
Brooklyn Nicholson
2026-05-04 15:15:54 -05:00
parent ff4e478fcc
commit be8223130b
5 changed files with 100 additions and 22 deletions
+16 -3
View File
@@ -207,10 +207,23 @@ describe('parseVoiceRecordKey (#18994)', () => {
expect(parseVoiceRecordKey('ctrl+c')).toEqual(DEFAULT_VOICE_RECORD_KEY)
expect(parseVoiceRecordKey('ctrl+d')).toEqual(DEFAULT_VOICE_RECORD_KEY)
expect(parseVoiceRecordKey('ctrl+l')).toEqual(DEFAULT_VOICE_RECORD_KEY)
// Alt- and super-modifier versions of those letters are NOT
// intercepted, so they remain usable.
// Alt-modifier versions of those letters are NOT intercepted, so
// they remain usable.
expect(parseVoiceRecordKey('alt+c').mod).toBe('alt')
expect(parseVoiceRecordKey('super+l').mod).toBe('super')
})
it('rejects super+{c,d,l,v} — mac action-mod chords are claimed before voice', async () => {
const { DEFAULT_VOICE_RECORD_KEY, parseVoiceRecordKey } = await importPlatform('linux')
// On macOS super+c/d/l/v are copy / exit / clear / paste. Reject at
// parse time so /voice status doesn't advertise dead bindings.
expect(parseVoiceRecordKey('super+c')).toEqual(DEFAULT_VOICE_RECORD_KEY)
expect(parseVoiceRecordKey('super+d')).toEqual(DEFAULT_VOICE_RECORD_KEY)
expect(parseVoiceRecordKey('super+l')).toEqual(DEFAULT_VOICE_RECORD_KEY)
expect(parseVoiceRecordKey('super+v')).toEqual(DEFAULT_VOICE_RECORD_KEY)
// Other super letters still work (no global chord claims them).
expect(parseVoiceRecordKey('super+b').mod).toBe('super')
expect(parseVoiceRecordKey('super+o').mod).toBe('super')
})
// Round-5 Copilot review regressions on #19835.