agentvibes 5.7.4 → 5.7.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -78,7 +78,7 @@ const COLORS = {
78
78
  noticeFg: 'white',
79
79
  btnBg: 'blue',
80
80
  btnFg: 'white',
81
- btnFocusBg: 'cyan',
81
+ btnFocusBg: '#2e7d32',
82
82
  removeBg: 'red',
83
83
  removeFocusBg: 'magenta',
84
84
  cfgBg: 'green',
@@ -354,7 +354,7 @@ export function createSetupTab(screen, services) {
354
354
  content: ' Install ', tags: true, mouse: true, keys: true, hidden: true,
355
355
  style: {
356
356
  fg: COLORS.btnFg, bg: COLORS.btnBg,
357
- focus: { fg: 'black', bg: COLORS.btnFocusBg },
357
+ focus: { fg: 'white', bg: COLORS.btnFocusBg },
358
358
  },
359
359
  });
360
360
 
@@ -534,7 +534,7 @@ export function createSetupTab(screen, services) {
534
534
  style: {
535
535
  fg: COLORS.btnFg,
536
536
  bg: COLORS.btnBg,
537
- focus: { fg: 'black', bg: COLORS.btnFocusBg },
537
+ focus: { fg: 'white', bg: COLORS.btnFocusBg },
538
538
  },
539
539
  });
540
540
 
@@ -870,10 +870,12 @@ export function createSetupTab(screen, services) {
870
870
  padding: { left: 1, right: 1 },
871
871
  style: {
872
872
  bg: 'blue', fg: 'white',
873
- focus: { bg: 'cyan', fg: 'black', bold: true },
874
- hover: { bg: 'cyan', fg: 'black', bold: true },
873
+ focus: { bg: '#2e7d32', fg: 'white', bold: true },
874
+ hover: { bg: '#2e7d32', fg: 'white', bold: true },
875
875
  },
876
876
  });
877
+ btn.on('focus', () => { btn.style.bg = '#2e7d32'; btn.style.fg = 'white'; screen.render(); });
878
+ btn.on('blur', () => { btn.style.bg = 'blue'; btn.style.fg = 'white'; screen.render(); });
877
879
  btn.key(['enter', 'space'], () => onClick());
878
880
  btn.on('click', () => onClick());
879
881
  return btn;
@@ -1115,7 +1117,7 @@ export function createSetupTab(screen, services) {
1115
1117
  style: {
1116
1118
  fg: COLORS.labelFg, bg: COLORS.contentBg,
1117
1119
  border: { fg: 'cyan' },
1118
- selected: { bg: 'blue', fg: 'white', bold: true },
1120
+ selected: { bg: 'blue', fg: 'black', bold: true },
1119
1121
  },
1120
1122
  });
1121
1123
  picker.setFront();
@@ -1154,7 +1156,7 @@ export function createSetupTab(screen, services) {
1154
1156
  style: {
1155
1157
  fg: COLORS.labelFg, bg: COLORS.contentBg,
1156
1158
  border: { fg: 'cyan' },
1157
- selected: { bg: 'blue', fg: 'white', bold: true },
1159
+ selected: { bg: 'blue', fg: 'black', bold: true },
1158
1160
  },
1159
1161
  });
1160
1162
  picker.setFront();
@@ -1268,7 +1270,7 @@ export function createSetupTab(screen, services) {
1268
1270
  style: {
1269
1271
  fg: COLORS.labelFg, bg: COLORS.contentBg,
1270
1272
  border: { fg: 'cyan' },
1271
- selected: { bg: 'blue', fg: 'white', bold: true },
1273
+ selected: { bg: 'blue', fg: 'black', bold: true },
1272
1274
  },
1273
1275
  });
1274
1276
  picker.setFront();
@@ -1326,7 +1328,7 @@ export function createSetupTab(screen, services) {
1326
1328
  style: {
1327
1329
  fg: COLORS.labelFg, bg: COLORS.contentBg,
1328
1330
  border: { fg: 'cyan' },
1329
- selected: { bg: 'blue', fg: 'white', bold: true },
1331
+ selected: { bg: 'blue', fg: 'black', bold: true },
1330
1332
  },
1331
1333
  });
1332
1334
  picker.setFront();
@@ -1364,7 +1366,7 @@ export function createSetupTab(screen, services) {
1364
1366
  style: {
1365
1367
  fg: COLORS.labelFg, bg: COLORS.contentBg,
1366
1368
  border: { fg: 'cyan' },
1367
- selected: { bg: 'blue', fg: 'white', bold: true },
1369
+ selected: { bg: 'blue', fg: 'black', bold: true },
1368
1370
  },
1369
1371
  });
1370
1372
  picker.setFront();
@@ -1400,7 +1402,7 @@ export function createSetupTab(screen, services) {
1400
1402
  style: {
1401
1403
  fg: COLORS.labelFg, bg: COLORS.contentBg,
1402
1404
  border: { fg: 'cyan' },
1403
- selected: { bg: 'blue', fg: 'white', bold: true },
1405
+ selected: { bg: 'blue', fg: 'black', bold: true },
1404
1406
  },
1405
1407
  });
1406
1408
  picker.setFront();
@@ -1501,10 +1503,12 @@ export function createSetupTab(screen, services) {
1501
1503
  padding: { left: 1, right: 1 },
1502
1504
  style: {
1503
1505
  bg: 'blue', fg: 'white',
1504
- focus: { bg: 'cyan', fg: 'black', bold: true },
1505
- hover: { bg: 'cyan', fg: 'black', bold: true },
1506
+ focus: { bg: '#2e7d32', fg: 'white', bold: true },
1507
+ hover: { bg: '#2e7d32', fg: 'white', bold: true },
1506
1508
  },
1507
1509
  });
1510
+ btn.on('focus', () => { btn.style.bg = '#2e7d32'; btn.style.fg = 'white'; screen.render(); });
1511
+ btn.on('blur', () => { btn.style.bg = 'blue'; btn.style.fg = 'white'; screen.render(); });
1508
1512
  btn.key(['enter', 'space'], () => onClick());
1509
1513
  btn.on('click', () => onClick());
1510
1514
  return btn;
@@ -1618,11 +1622,15 @@ export function createSetupTab(screen, services) {
1618
1622
  let _closed = false;
1619
1623
  navigationService?.openModal(null, _closeModal);
1620
1624
 
1625
+ const _folderName = path.basename(targetDir);
1626
+ const _folderPretext = _folderName
1627
+ ? _folderName.charAt(0).toUpperCase() + _folderName.slice(1) + ' here'
1628
+ : '';
1621
1629
  const defaultPretext = {
1622
- 'claude-code': 'Claude Code here',
1623
- 'copilot': 'Copilot here',
1624
- 'codex': 'Codex here',
1625
- 'default': path.basename(targetDir), // default to project folder name
1630
+ 'claude-code': _folderPretext,
1631
+ 'copilot': _folderPretext,
1632
+ 'codex': _folderPretext,
1633
+ 'default': _folderPretext,
1626
1634
  };
1627
1635
 
1628
1636
  // Read global defaults for display
@@ -1747,10 +1755,12 @@ export function createSetupTab(screen, services) {
1747
1755
  style: {
1748
1756
  bg: 'blue',
1749
1757
  fg: 'white',
1750
- focus: { bg: 'cyan', fg: 'black', bold: true },
1751
- hover: { bg: 'cyan', fg: 'black', bold: true },
1758
+ focus: { bg: '#2e7d32', fg: 'white', bold: true },
1759
+ hover: { bg: '#2e7d32', fg: 'white', bold: true },
1752
1760
  },
1753
1761
  });
1762
+ btn.on('focus', () => { btn.style.bg = '#2e7d32'; btn.style.fg = 'white'; screen.render(); });
1763
+ btn.on('blur', () => { btn.style.bg = 'blue'; btn.style.fg = 'white'; screen.render(); });
1754
1764
  btn.key(['enter', 'space'], () => onClick());
1755
1765
  btn.on('click', () => onClick());
1756
1766
  return btn;
@@ -2172,7 +2182,7 @@ export function createSetupTab(screen, services) {
2172
2182
  style: {
2173
2183
  fg: COLORS.labelFg, bg: COLORS.contentBg,
2174
2184
  border: { fg: 'blue' },
2175
- selected: { bg: 'green', fg: 'white', bold: true },
2185
+ selected: { bg: 'green', fg: 'black', bold: true },
2176
2186
  item: { fg: COLORS.labelFg },
2177
2187
  },
2178
2188
  });
@@ -2431,8 +2441,6 @@ export function createSetupTab(screen, services) {
2431
2441
  const inputBox = blessed.textbox({
2432
2442
  parent: editModal, top: 3, left: 2, right: 2, height: 3,
2433
2443
  border: { type: 'line' },
2434
- inputOnFocus: true,
2435
- value: draft.pretext,
2436
2444
  style: {
2437
2445
  fg: 'white', bg: 'black',
2438
2446
  border: { fg: 'blue' },
@@ -2440,21 +2448,79 @@ export function createSetupTab(screen, services) {
2440
2448
  },
2441
2449
  });
2442
2450
 
2451
+ let _editClosed = false;
2452
+ let _cursor = (draft.pretext || '').length;
2453
+ inputBox.value = draft.pretext || '';
2454
+
2455
+ function _renderPretext() {
2456
+ const val = inputBox.value;
2457
+ const lpos = inputBox._getCoords();
2458
+ if (!lpos) { screen.render(); return; }
2459
+ const contentWidth = Math.max(1, (lpos.xl - lpos.xi) - inputBox.iwidth);
2460
+ const start = _cursor > contentWidth - 1 ? _cursor - contentWidth + 1 : 0;
2461
+ inputBox.setContent(val.slice(start));
2462
+ screen.render();
2463
+ screen.program.cup(lpos.yi + inputBox.itop, lpos.xi + inputBox.ileft + (_cursor - start));
2464
+ }
2465
+
2466
+ const _prevGrabKeys = screen.grabKeys;
2443
2467
  function _closeEdit(save) {
2468
+ if (_editClosed) return;
2469
+ _editClosed = true;
2470
+ inputBox.removeAllListeners('keypress');
2471
+ screen.grabKeys = _prevGrabKeys;
2472
+ screen.program.hideCursor();
2444
2473
  if (save) {
2445
- const val = (inputBox.getValue() || '').trim().slice(0, 200);
2446
- draft.pretext = val;
2474
+ draft.pretext = (inputBox.value || '').trim().slice(0, 200);
2447
2475
  }
2448
2476
  destroyList(editModal, screen);
2449
2477
  onDone();
2450
2478
  }
2451
2479
 
2452
- inputBox.key(['enter'], () => _closeEdit(true));
2453
- inputBox.key(['escape'], () => _closeEdit(false));
2480
+ // Guard: if editModal is destroyed externally without _closeEdit being called,
2481
+ // restore grab state so TUI stays responsive.
2482
+ editModal.once('destroy', () => {
2483
+ if (!_editClosed) {
2484
+ _editClosed = true;
2485
+ inputBox.removeAllListeners('keypress');
2486
+ screen.grabKeys = _prevGrabKeys;
2487
+ screen.program.hideCursor();
2488
+ }
2489
+ });
2454
2490
 
2491
+ screen.grabKeys = true;
2455
2492
  inputBox.focus();
2456
- inputBox.readInput(() => {});
2457
- screen.render();
2493
+ screen.render(); // Layout pass so _getCoords() returns valid coords on first _renderPretext
2494
+ screen.program.showCursor();
2495
+ _renderPretext();
2496
+
2497
+ inputBox.on('keypress', function(ch, key) {
2498
+ if (_editClosed) return;
2499
+ const val = inputBox.value;
2500
+ if (key.name === 'enter') { _closeEdit(true); return; }
2501
+ if (key.name === 'escape') { _closeEdit(false); return; }
2502
+ if (key.name === 'home' || (key.ctrl && key.name === 'a')) {
2503
+ _cursor = 0;
2504
+ } else if (key.name === 'end' || (key.ctrl && key.name === 'e')) {
2505
+ _cursor = val.length;
2506
+ } else if (key.name === 'left') {
2507
+ if (_cursor > 0) _cursor--; else return;
2508
+ } else if (key.name === 'right') {
2509
+ if (_cursor < val.length) _cursor++; else return;
2510
+ } else if (key.name === 'backspace') {
2511
+ if (_cursor > 0) { inputBox.value = val.slice(0, _cursor - 1) + val.slice(_cursor); _cursor--; }
2512
+ else return;
2513
+ } else if (key.name === 'delete') {
2514
+ if (_cursor < val.length) { inputBox.value = val.slice(0, _cursor) + val.slice(_cursor + 1); }
2515
+ else return;
2516
+ } else if (ch && !key.ctrl && !key.meta && !/^[\x00-\x08\x0b-\x0c\x0e-\x1f\x7f]$/.test(ch)) {
2517
+ inputBox.value = val.slice(0, _cursor) + ch + val.slice(_cursor);
2518
+ _cursor++;
2519
+ } else {
2520
+ return;
2521
+ }
2522
+ _renderPretext();
2523
+ });
2458
2524
  }
2459
2525
 
2460
2526
  // ── Saved toast ───────────────────────────────────────────────────────────
@@ -13,7 +13,7 @@ import path from 'node:path';
13
13
  import os from 'node:os';
14
14
  import { spawn } from 'node:child_process';
15
15
  import { fileURLToPath } from 'node:url';
16
- import { buildAudioEnv, detectWavPlayer } from '../audio-env.js';
16
+ import { buildAudioEnv, detectWavPlayer, getAllWavPlayers } from '../audio-env.js';
17
17
  import { SURNAME_POOL, uniquifyVoiceName } from '../../utils/voice-names.js';
18
18
 
19
19
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
@@ -1022,9 +1022,9 @@ export function createVoicesTab(screen, services) {
1022
1022
  return;
1023
1023
  }
1024
1024
 
1025
- // Play the synthesized wav in its own process group so we can kill it
1026
- const _wavP = detectWavPlayer(_spawnEnv);
1027
- if (!_wavP) {
1025
+ // Play the synthesized wav try each installed player until one succeeds
1026
+ const _wavPlayers = getAllWavPlayers(_spawnEnv);
1027
+ if (_wavPlayers.length === 0) {
1028
1028
  _playingVoiceId = null;
1029
1029
  _playingProcess = null;
1030
1030
  previewLine.setContent(`{red-fg}No audio player found. Install ffmpeg.{/red-fg}`);
@@ -1033,44 +1033,62 @@ export function createVoicesTab(screen, services) {
1033
1033
  try { fs.unlinkSync(tempWav); } catch {}
1034
1034
  return;
1035
1035
  }
1036
- const playProc = spawn(_wavP.bin, _wavP.args(tempWav), {
1037
- stdio: 'ignore',
1038
- detached: !isWindows,
1039
- windowsHide: true,
1040
- env: _spawnEnv,
1041
- });
1036
+
1042
1037
  // Race note: _playingVoiceId could change between piper exit and here
1043
1038
  // if the user stops playback. Re-check before assigning to avoid orphan.
1044
1039
  if (_playingVoiceId !== voiceId) { try { fs.unlinkSync(tempWav); } catch {} return; }
1045
- _playingProcess = playProc;
1046
1040
 
1047
1041
  previewLine.setContent(`{${COLORS.activeFg}-fg}♪ Playing: ${voiceId} (Enter/Space to stop){/${COLORS.activeFg}-fg}`);
1048
1042
  screen.render();
1049
1043
 
1050
- playProc.on('exit', (code) => {
1051
- if (_playingVoiceId === voiceId) {
1044
+ function _tryNextPlayer(remainingPlayers) {
1045
+ if (!remainingPlayers.length) {
1052
1046
  _playingVoiceId = null;
1053
1047
  _playingProcess = null;
1048
+ previewLine.setContent(`{red-fg}♪ Audio playback failed (no audio device?) — check your provider in Setup{/red-fg}`);
1049
+ screen.render();
1050
+ setTimeout(() => { if (!_closed) { previewLine.setContent(_listFocused ? HINT_TEXT : ''); screen.render(); } }, 5000);
1051
+ try { fs.unlinkSync(tempWav); } catch {}
1052
+ return;
1053
+ }
1054
+ const [wavP, ...rest] = remainingPlayers;
1055
+ const playProc = spawn(wavP.bin, wavP.args(tempWav), {
1056
+ stdio: 'ignore',
1057
+ detached: !isWindows,
1058
+ windowsHide: true,
1059
+ env: _spawnEnv,
1060
+ });
1061
+ if (_playingVoiceId !== voiceId) {
1062
+ try { playProc.kill(); } catch {}
1063
+ try { fs.unlinkSync(tempWav); } catch {}
1064
+ return;
1065
+ }
1066
+ _playingProcess = playProc;
1067
+
1068
+ playProc.on('exit', (code) => {
1069
+ if (_playingVoiceId !== voiceId) {
1070
+ try { fs.unlinkSync(tempWav); } catch {}
1071
+ return;
1072
+ }
1054
1073
  if (code !== 0) {
1055
- previewLine.setContent(`{red-fg}♪ Audio playback failed (no audio device?) check your provider in Setup{/red-fg}`);
1056
- screen.render();
1057
- setTimeout(() => { if (!_closed) { previewLine.setContent(_listFocused ? HINT_TEXT : ''); screen.render(); } }, 5000);
1074
+ // This player failed — try the next one
1075
+ _tryNextPlayer(rest);
1058
1076
  } else {
1077
+ _playingVoiceId = null;
1078
+ _playingProcess = null;
1059
1079
  previewLine.setContent(_listFocused ? HINT_TEXT : '');
1060
- refreshDisplay(); // clears (playing) label
1080
+ refreshDisplay();
1081
+ try { fs.unlinkSync(tempWav); } catch {}
1061
1082
  }
1062
- }
1063
- try { fs.unlinkSync(tempWav); } catch {}
1064
- });
1083
+ });
1065
1084
 
1066
- playProc.on('error', () => {
1067
- _playingVoiceId = null;
1068
- _playingProcess = null;
1069
- previewLine.setContent(`{red-fg}♪ Audio player not found — install ffmpeg or check your provider in Setup{/red-fg}`);
1070
- screen.render();
1071
- setTimeout(() => { if (!_closed) { previewLine.setContent(_listFocused ? HINT_TEXT : ''); screen.render(); } }, 5000);
1072
- try { fs.unlinkSync(tempWav); } catch {}
1073
- });
1085
+ playProc.on('error', () => {
1086
+ if (_playingVoiceId !== voiceId) { try { fs.unlinkSync(tempWav); } catch {} return; }
1087
+ _tryNextPlayer(rest);
1088
+ });
1089
+ }
1090
+
1091
+ _tryNextPlayer(_wavPlayers);
1074
1092
  });
1075
1093
 
1076
1094
  piper.on('error', () => {
@@ -1122,7 +1140,7 @@ export function createVoicesTab(screen, services) {
1122
1140
  padding: { left: 1, right: 1 },
1123
1141
  style: {
1124
1142
  bg: COLORS.btnDefault,
1125
- fg: 'white',
1143
+ fg: 'bright-white',
1126
1144
  focus: { bg: COLORS.btnFocus, fg: COLORS.btnFocusFg, bold: true },
1127
1145
  hover: { bg: COLORS.btnFocus, fg: COLORS.btnFocusFg, bold: true },
1128
1146
  },
@@ -1136,7 +1154,7 @@ export function createVoicesTab(screen, services) {
1136
1154
  });
1137
1155
  btn.on('blur', () => {
1138
1156
  btn.style.bg = COLORS.btnDefault;
1139
- btn.style.fg = 'white';
1157
+ btn.style.fg = 'bright-white';
1140
1158
  const raw = btn.content.replace(/[►◄]/g, '').trim();
1141
1159
  btn.setContent(raw);
1142
1160
  screen.render();
@@ -1306,7 +1324,7 @@ export function createVoicesTab(screen, services) {
1306
1324
  padding: { left: 1, right: 1 },
1307
1325
  style: {
1308
1326
  bg,
1309
- fg: 'white',
1327
+ fg: 'bright-white',
1310
1328
  focus: { bg: COLORS.btnFocus, fg: COLORS.btnFocusFg, bold: true },
1311
1329
  hover: { bg: COLORS.btnFocus, fg: COLORS.btnFocusFg, bold: true },
1312
1330
  },
@@ -1341,7 +1359,7 @@ export function createVoicesTab(screen, services) {
1341
1359
  padding: { left: 1, right: 1 },
1342
1360
  style: {
1343
1361
  bg: '#e65100',
1344
- fg: 'white',
1362
+ fg: 'bright-white',
1345
1363
  focus: { bg: COLORS.btnFocus, fg: COLORS.btnFocusFg, bold: true },
1346
1364
  hover: { bg: COLORS.btnFocus, fg: COLORS.btnFocusFg, bold: true },
1347
1365
  },
@@ -1550,7 +1568,7 @@ export function createVoicesTab(screen, services) {
1550
1568
  padding: { left: 1, right: 1 },
1551
1569
  style: {
1552
1570
  bg,
1553
- fg: 'white',
1571
+ fg: 'bright-white',
1554
1572
  focus: { bg: COLORS.btnFocus, fg: COLORS.btnFocusFg, bold: true },
1555
1573
  hover: { bg: COLORS.btnFocus, fg: COLORS.btnFocusFg, bold: true },
1556
1574
  },
package/src/installer.js CHANGED
@@ -74,6 +74,7 @@ import { promptForCustomMusic } from './installer/music-file-input.js';
74
74
  import { createPreviewListPrompt } from './utils/preview-list-prompt.js';
75
75
  import { selectLanguage } from './installer/language-screen.js';
76
76
  import { t } from './i18n/strings.js';
77
+ import { seedAllLlmDefaultsSync } from './services/llm-provider-service.js';
77
78
 
78
79
  const __filename = fileURLToPath(import.meta.url);
79
80
  const __dirname = path.dirname(__filename);
@@ -1248,12 +1249,20 @@ async function collectConfiguration(options = {}) {
1248
1249
  config.provider = process.platform === 'darwin' ? 'macos' : 'piper';
1249
1250
  config.defaultVoice = process.platform === 'darwin' ? 'Samantha' : 'en_US-ryan-high';
1250
1251
  }
1251
- const homeDir = process.env.HOME || process.env.USERPROFILE;
1252
+ const homeDir = process.env.HOME || process.env.USERPROFILE || os.homedir();
1252
1253
  config.piperPath = path.join(homeDir, '.claude', 'piper-voices');
1253
1254
  // AI agent / non-interactive defaults: no reverb, no background music, no hermes
1254
1255
  config.reverb = 'none';
1255
1256
  config.backgroundMusic = { enabled: false, track: 'agentvibes_soft_flamenco_loop.mp3' };
1256
1257
  config.hermes = { enabled: false };
1258
+ // Use folder name as project identity when no existing pretext is set
1259
+ if (!config.pretext) {
1260
+ const folderName = path.basename(process.cwd());
1261
+ // Guard empty basename (e.g. process.cwd() === '/' in some Docker containers)
1262
+ if (folderName) {
1263
+ config.pretext = folderName.charAt(0).toUpperCase() + folderName.slice(1) + ' here';
1264
+ }
1265
+ }
1257
1266
  return config;
1258
1267
  }
1259
1268
 
@@ -5761,6 +5770,11 @@ Troubleshooting:
5761
5770
  }
5762
5771
  // Do NOT unlink tts-pretext.txt when blank — user may have set it via MCP or manually.
5763
5772
 
5773
+ // Seed project-level llm: rows with empty pretext so global ~/.claude/config/audio-effects.cfg
5774
+ // "Claude Code here" rows don't override tts-pretext.txt (play-tts.sh stops searching when it
5775
+ // finds a row with a voice, then falls through to tts-pretext.txt for the pretext).
5776
+ seedAllLlmDefaultsSync(targetDir);
5777
+
5764
5778
  // Apply reverb setting
5765
5779
  const selectedReverb = userConfig.reverb;
5766
5780
  if (selectedReverb && selectedReverb !== 'off') {
@@ -59,7 +59,7 @@ const DEFAULT_LLM_CONFIGS = {
59
59
  bgTrack: 'agent_vibes_chillwave_v2_loop.mp3',
60
60
  bgVolume: '0.15',
61
61
  voice: 'en_US-lessac-high',
62
- pretext: 'Claude Code here',
62
+ pretext: '',
63
63
  ttsEngine: 'piper',
64
64
  },
65
65
  copilot: {
@@ -67,7 +67,7 @@ const DEFAULT_LLM_CONFIGS = {
67
67
  bgTrack: 'agent_vibes_bossa_nova_v2_loop.mp3',
68
68
  bgVolume: '0.15',
69
69
  voice: 'en_US-libritts-high::Anna-11',
70
- pretext: 'Copilot here',
70
+ pretext: '',
71
71
  ttsEngine: 'piper',
72
72
  },
73
73
  codex: {
@@ -78,7 +78,7 @@ const DEFAULT_LLM_CONFIGS = {
78
78
  // Windows Piper installs (loads the model, exits with no output).
79
79
  // lessac-high works reliably, so use it as the default for codex.
80
80
  voice: 'en_US-lessac-high',
81
- pretext: 'Codex here',
81
+ pretext: '',
82
82
  ttsEngine: 'piper',
83
83
  },
84
84
  hermes: {
@@ -86,7 +86,7 @@ const DEFAULT_LLM_CONFIGS = {
86
86
  bgTrack: 'agent_vibes_bachata_v1_loop.mp3',
87
87
  bgVolume: '0.15',
88
88
  voice: 'en_US-libritts-high::Leo-8',
89
- pretext: 'Hermes here',
89
+ pretext: '',
90
90
  ttsEngine: 'piper',
91
91
  },
92
92
  };