agentvibes 3.5.5 → 3.5.8

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.
Files changed (78) hide show
  1. package/.claude/commands/agent-vibes/provider.md +0 -0
  2. package/.claude/config/background-music-position.txt +27 -0
  3. package/.claude/config/background-music-volume.txt +1 -1
  4. package/.claude/config/background-music.cfg +1 -0
  5. package/.claude/config/background-music.txt +1 -0
  6. package/.claude/config/tts-speech-rate.txt +1 -0
  7. package/.claude/config/tts-verbosity.txt +1 -0
  8. package/.claude/github-star-reminder.txt +1 -0
  9. package/.claude/hooks/audio-cache-utils.sh +0 -0
  10. package/.claude/hooks/audio-processor.sh +0 -0
  11. package/.claude/hooks/background-music-manager.sh +0 -0
  12. package/.claude/hooks/bmad-party-manager.sh +225 -0
  13. package/.claude/hooks/bmad-speak-enhanced.sh +0 -0
  14. package/.claude/hooks/bmad-speak.sh +0 -0
  15. package/.claude/hooks/bmad-tts-injector.sh +0 -0
  16. package/.claude/hooks/bmad-voice-manager.sh +0 -0
  17. package/.claude/hooks/clawdbot-receiver-SECURE.sh +0 -0
  18. package/.claude/hooks/clawdbot-receiver.sh +0 -0
  19. package/.claude/hooks/clean-audio-cache.sh +0 -0
  20. package/.claude/hooks/cleanup-cache.sh +0 -0
  21. package/.claude/hooks/configure-rdp-mode.sh +0 -0
  22. package/.claude/hooks/download-extra-voices.sh +0 -0
  23. package/.claude/hooks/effects-manager.sh +0 -0
  24. package/.claude/hooks/github-star-reminder.sh +0 -0
  25. package/.claude/hooks/language-manager.sh +0 -0
  26. package/.claude/hooks/learn-manager.sh +0 -0
  27. package/.claude/hooks/macos-voice-manager.sh +0 -0
  28. package/.claude/hooks/migrate-background-music.sh +0 -0
  29. package/.claude/hooks/migrate-to-agentvibes.sh +0 -0
  30. package/.claude/hooks/optimize-background-music.sh +0 -0
  31. package/.claude/hooks/personality-manager.sh +0 -0
  32. package/.claude/hooks/piper-download-voices.sh +0 -0
  33. package/.claude/hooks/piper-installer.sh +0 -0
  34. package/.claude/hooks/piper-multispeaker-registry.sh +0 -0
  35. package/.claude/hooks/piper-voice-manager.sh +0 -0
  36. package/.claude/hooks/play-tts-enhanced.sh +0 -0
  37. package/.claude/hooks/play-tts-macos.sh +0 -0
  38. package/.claude/hooks/play-tts-piper.sh +0 -0
  39. package/.claude/hooks/play-tts-soprano.sh +0 -0
  40. package/.claude/hooks/play-tts-ssh-remote.sh +0 -0
  41. package/.claude/hooks/play-tts-termux-ssh.sh +0 -0
  42. package/.claude/hooks/play-tts.sh +1 -1
  43. package/.claude/hooks/prepare-release.sh +0 -0
  44. package/.claude/hooks/provider-commands.sh +0 -0
  45. package/.claude/hooks/provider-manager.sh +2 -2
  46. package/.claude/hooks/replay-target-audio.sh +0 -0
  47. package/.claude/hooks/sentiment-manager.sh +0 -0
  48. package/.claude/hooks/session-start-tts.sh +0 -0
  49. package/.claude/hooks/soprano-gradio-synth.py +0 -0
  50. package/.claude/hooks/speed-manager.sh +0 -0
  51. package/.claude/hooks/stop.sh +38 -0
  52. package/.claude/hooks/termux-installer.sh +0 -0
  53. package/.claude/hooks/translate-manager.sh +0 -0
  54. package/.claude/hooks/translator.py +0 -0
  55. package/.claude/hooks/tts-queue-worker.sh +0 -0
  56. package/.claude/hooks/tts-queue.sh +0 -0
  57. package/.claude/hooks/verbosity-manager.sh +0 -0
  58. package/.claude/hooks/voice-manager.sh +0 -0
  59. package/.claude/piper-voices-dir.txt +1 -0
  60. package/.mcp.json +34 -0
  61. package/README.md +10 -25
  62. package/RELEASE_NOTES.md +78 -0
  63. package/bin/agent-vibes +21 -26
  64. package/bin/mcp-server.js +0 -0
  65. package/bin/mcp-server.sh +0 -0
  66. package/bin/test-bmad-pr +0 -0
  67. package/mcp-server/WINDOWS_SETUP.md +0 -0
  68. package/mcp-server/install-deps.js +0 -0
  69. package/mcp-server/test_server.py +0 -0
  70. package/package.json +1 -1
  71. package/setup-windows.ps1 +61 -13
  72. package/src/installer.js +87 -12
  73. package/src/utils/provider-validator.js +456 -0
  74. package/templates/agentvibes-receiver.sh +0 -0
  75. package/templates/audio/welcome-music.mp3 +0 -0
  76. package/.claude/config/background-music-default.txt +0 -1
  77. package/.claude/config/background-music-enabled.txt +0 -1
  78. package/.claude/config/reverb-level.txt +0 -1
package/bin/agent-vibes CHANGED
@@ -16,30 +16,25 @@ const __dirname = path.dirname(__filename);
16
16
  // Check if we're running in an npx temporary directory
17
17
  const isNpxExecution = __dirname.includes('_npx') || __dirname.includes('.npm');
18
18
 
19
- // If running via npx, we need to handle things differently
20
- if (isNpxExecution) {
21
- const arguments_ = process.argv.slice(2);
22
-
23
- // Use the installer for all commands
24
- const installerPath = path.join(__dirname, '..', 'src', 'installer.js');
25
-
26
- if (!fs.existsSync(installerPath)) {
27
- console.error('Error: Could not find installer.js at', installerPath);
28
- console.error('Current directory:', __dirname);
29
- process.exit(1);
30
- }
31
-
32
- try {
33
- // Security: Use execFileSync with array args to prevent command injection
34
- // Arguments are passed as array elements, not string interpolation
35
- execFileSync('node', [installerPath, ...arguments_], {
36
- stdio: 'inherit',
37
- cwd: path.dirname(__dirname),
38
- });
39
- } catch (error) {
40
- process.exit(error.status || 1);
41
- }
42
- } else {
43
- // Local execution - use installer directly
44
- import('../src/installer.js');
19
+ // Get CLI arguments
20
+ const arguments_ = process.argv.slice(2);
21
+
22
+ // Use the installer for all commands
23
+ const installerPath = path.join(__dirname, '..', 'src', 'installer.js');
24
+
25
+ if (!fs.existsSync(installerPath)) {
26
+ console.error('Error: Could not find installer.js at', installerPath);
27
+ console.error('Current directory:', __dirname);
28
+ process.exit(1);
29
+ }
30
+
31
+ try {
32
+ // Security: Use execFileSync with array args to prevent command injection
33
+ // Arguments are passed as array elements, not string interpolation
34
+ execFileSync('node', [installerPath, ...arguments_], {
35
+ stdio: 'inherit',
36
+ cwd: isNpxExecution ? path.dirname(__dirname) : process.cwd(),
37
+ });
38
+ } catch (error) {
39
+ process.exit(error.status || 1);
45
40
  }
package/bin/mcp-server.js CHANGED
File without changes
package/bin/mcp-server.sh CHANGED
File without changes
package/bin/test-bmad-pr CHANGED
File without changes
File without changes
File without changes
File without changes
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "agentvibes",
4
- "version": "3.5.5",
4
+ "version": "3.5.8",
5
5
  "description": "Now your AI Agents can finally talk back! Professional TTS voice for Claude Code, Claude Desktop (via MCP), and Clawdbot with multi-provider support.",
6
6
  "homepage": "https://agentvibes.org",
7
7
  "keywords": [
package/setup-windows.ps1 CHANGED
@@ -330,6 +330,13 @@ Write-Ok "Installed $CopiedCount TTS scripts"
330
330
 
331
331
  Write-Section "Choose Your TTS Provider"
332
332
 
333
+ # Check if pip is available
334
+ $PipAvailable = $false
335
+ try {
336
+ $pipTest = & pip --version 2>$null
337
+ if ($pipTest) { $PipAvailable = $true }
338
+ } catch {}
339
+
333
340
  # Check Soprano availability
334
341
  $SopranoAvailable = $false
335
342
  try {
@@ -341,12 +348,14 @@ try {
341
348
  if ($response.StatusCode -eq 200) { $SopranoAvailable = $true }
342
349
  } catch {}
343
350
 
344
- # Check if pip has soprano-tts
351
+ # Check if pip has soprano-tts (only if pip is available)
345
352
  $SopranoInstalled = $false
346
- try {
347
- $pipResult = & pip show soprano-tts 2>$null
348
- if ($pipResult) { $SopranoInstalled = $true }
349
- } catch {}
353
+ if ($PipAvailable) {
354
+ try {
355
+ $pipResult = & pip show soprano-tts 2>$null
356
+ if ($pipResult) { $SopranoInstalled = $true }
357
+ } catch {}
358
+ }
350
359
 
351
360
  if (-not $Provider) {
352
361
  Write-Host " [1] Soprano (Best Quality)" -ForegroundColor White
@@ -407,15 +416,54 @@ if ($Provider -eq "soprano") {
407
416
  Write-Info "Start it with: soprano-tts --share"
408
417
  Write-Info "Or run it in WSL and forward port 7860"
409
418
  } else {
410
- Write-Warn "Soprano not detected"
411
- Write-Host ""
412
- Write-Host " To install Soprano:" -ForegroundColor White
413
- Write-Host " pip install soprano-tts" -ForegroundColor Cyan
419
+ Write-Warn "Soprano TTS not detected"
414
420
  Write-Host ""
415
- Write-Host " Or use Soprano in WSL with port forwarding:" -ForegroundColor White
416
- Write-Host " ssh -L 7860:localhost:7860 your-wsl-host" -ForegroundColor Cyan
417
- Write-Host ""
418
- Write-Info "AgentVibes will work once Soprano is accessible on port 7860"
421
+
422
+ if (-not $PipAvailable) {
423
+ Write-Error "pip is not available on this system"
424
+ Write-Info "Please install Python 3 with pip, then run:"
425
+ Write-Host " pip install soprano-tts" -ForegroundColor Cyan
426
+ Write-Host ""
427
+ } else {
428
+ # Offer to install Soprano
429
+ $installChoice = Read-Host "Would you like to install Soprano now? (y/n, default: y)"
430
+
431
+ if ($installChoice -eq "" -or $installChoice -eq "y" -or $installChoice -eq "Y") {
432
+ Write-Info "Installing Soprano TTS..."
433
+ Write-Host ""
434
+
435
+ try {
436
+ & pip install soprano-tts 2>&1 | Tee-Object -Variable pipOutput | Write-Host
437
+
438
+ # Re-check if installation succeeded
439
+ $SopranoInstalled = $false
440
+ try {
441
+ $pipResult = & pip show soprano-tts 2>$null
442
+ if ($pipResult) { $SopranoInstalled = $true }
443
+ } catch {}
444
+
445
+ if ($SopranoInstalled) {
446
+ Write-Ok "Soprano TTS installed successfully!"
447
+ Write-Info "Start it with: soprano-tts --share"
448
+ } else {
449
+ Write-Error "Installation may have failed. Please check the output above."
450
+ Write-Info "You can try installing manually: pip install soprano-tts"
451
+ }
452
+ } catch {
453
+ Write-Error "Installation failed: $_"
454
+ Write-Info "Please install manually: pip install soprano-tts"
455
+ }
456
+ } else {
457
+ Write-Host ""
458
+ Write-Host " To install Soprano manually:" -ForegroundColor White
459
+ Write-Host " pip install soprano-tts" -ForegroundColor Cyan
460
+ Write-Host ""
461
+ Write-Host " Or use Soprano in WSL with port forwarding:" -ForegroundColor White
462
+ Write-Host " ssh -L 7860:localhost:7860 your-wsl-host" -ForegroundColor Cyan
463
+ Write-Host ""
464
+ Write-Info "AgentVibes will work once Soprano is accessible on port 7860"
465
+ }
466
+ }
419
467
  }
420
468
  }
421
469
 
package/src/installer.js CHANGED
@@ -61,6 +61,12 @@ import {
61
61
  assignVoice,
62
62
  resetBmadVoices,
63
63
  } from './commands/bmad-voices.js';
64
+ import {
65
+ validateProvider,
66
+ getProviderInstallCommand,
67
+ getProviderDisplayName,
68
+ attemptProviderInstallation,
69
+ } from './utils/provider-validator.js';
64
70
 
65
71
  const __filename = fileURLToPath(import.meta.url);
66
72
  const __dirname = path.dirname(__filename);
@@ -869,6 +875,78 @@ async function collectConfiguration(options = {}) {
869
875
  return null;
870
876
  }
871
877
 
878
+ // Validate provider installation before accepting selection
879
+ console.log(chalk.gray(`\n Checking for ${getProviderDisplayName(provider)}...`));
880
+ const validation = await validateProvider(provider);
881
+
882
+ if (!validation.installed) {
883
+ const displayName = getProviderDisplayName(provider);
884
+ console.log(chalk.yellow(`\n⚠️ ${validation.message}`));
885
+
886
+ const { action } = await inquirer.prompt([{
887
+ type: 'list',
888
+ name: 'action',
889
+ message: 'What would you like to do?',
890
+ choices: [
891
+ { name: chalk.green('Install now (recommended)'), value: 'install' },
892
+ { name: 'Choose a different provider', value: 'back' },
893
+ { name: 'I\'ll install it myself later', value: 'skip' }
894
+ ]
895
+ }]);
896
+
897
+ if (action === 'install') {
898
+ console.log(chalk.cyan(`\n📦 Installing ${displayName}...\n`));
899
+
900
+ // Use smart installation with fallbacks
901
+ const installResult = await attemptProviderInstallation(provider);
902
+
903
+ if (installResult.success && installResult.verified) {
904
+ // Installation succeeded AND verified
905
+ console.log(chalk.green(`\n✓ ${displayName} installed and verified!\n`));
906
+ console.log(chalk.gray(` Method: ${installResult.command}`));
907
+ console.log(chalk.green(` Status: Ready to use\n`));
908
+ } else if (installResult.success) {
909
+ // Installation command ran but verification failed
910
+ console.log(chalk.yellow(`\n⚠️ Installation command completed, but verification failed\n`));
911
+ console.log(chalk.gray(` The installation may have been blocked by system protection (PEP 668).\n`));
912
+ console.log(chalk.cyan(` Try one of these solutions:\n`));
913
+ console.log(chalk.gray(` 1. Use pipx (avoids system protection):\n pipx install soprano-tts\n`));
914
+ console.log(chalk.gray(` 2. Create a virtual environment:\n python3 -m venv ~/my-env\n ~/my-env/bin/pip install soprano-tts\n`));
915
+
916
+ // Pause before returning to provider selection
917
+ await inquirer.prompt([{
918
+ type: 'confirm',
919
+ name: 'continue',
920
+ message: 'Press Enter to go back to provider selection',
921
+ default: true
922
+ }]);
923
+
924
+ return null; // Go back to provider selection
925
+ } else {
926
+ console.log(chalk.red(`\n❌ ${installResult.message}\n`));
927
+
928
+ // Pause before returning to provider selection
929
+ await inquirer.prompt([{
930
+ type: 'confirm',
931
+ name: 'continue',
932
+ message: 'Press Enter to go back to provider selection',
933
+ default: true
934
+ }]);
935
+
936
+ return null; // Go back to provider selection
937
+ }
938
+ } else if (action === 'back') {
939
+ // Go back to provider selection
940
+ return null;
941
+ } else if (action === 'skip') {
942
+ console.log(chalk.yellow(`\n⚠️ No problem! You can set it up anytime with:\n ${getProviderInstallCommand(provider)}\n`));
943
+ }
944
+ } else {
945
+ // Provider detected and ready to use
946
+ const displayName = getProviderDisplayName(provider);
947
+ console.log(chalk.green(`\n✓ ${displayName} Detected and selected!\n`));
948
+ }
949
+
872
950
  config.provider = provider;
873
951
 
874
952
  // Handle special receiver mode for Termux
@@ -1602,20 +1680,17 @@ function showWelcome() {
1602
1680
  * Shown during install and update commands
1603
1681
  */
1604
1682
  function getReleaseInfoBoxen() {
1605
- return chalk.cyan.bold('📦 AgentVibes v3.5.5 - Native Windows Support: Soprano, Piper & SAPI\n\n') +
1683
+ return chalk.cyan.bold('📦 AgentVibes v3.5.8 - Provider Validation Security & UX Improvements\n\n') +
1606
1684
  chalk.green.bold('🎙️ WHAT\'S NEW:\n\n') +
1607
- chalk.cyan('AgentVibes v3.5.5 brings native Windows support with three TTS providers (Soprano neural,\n') +
1608
- chalk.cyan('Piper offline, Windows SAPI), background music selection from 16 genre tracks, reverb effects\n') +
1609
- chalk.cyan('via ffmpeg, and verbosity control. Includes 8 Windows hook scripts, beautiful PowerShell\n') +
1610
- chalk.cyan('installer with figlet banner, and 46 new Windows-specific unit tests.\n\n') +
1611
- chalk.yellow('🙏 Thanks to @nathanchase (Soprano), @alexeyv (Windows SAPI), @bmadcode (BMAD Method)!\n\n') +
1685
+ chalk.cyan('Critical security and reliability update for provider detection. Fixes command injection\n') +
1686
+ chalk.cyan('vulnerabilities, prevents HOME directory injection attacks, and improves UX with explicit\n') +
1687
+ chalk.cyan('provider detection messaging. Soprano TTS installed via pipx now correctly detected.\n\n') +
1612
1688
  chalk.green.bold('✨ KEY HIGHLIGHTS:\n\n') +
1613
- chalk.gray(' 🖥️ Native Windows TTS - Soprano, Piper, and Windows SAPI providers. No WSL needed!\n') +
1614
- chalk.gray(' 🎵 Background Music - 16 genre tracks (Bachata, Flamenco, Bossa Nova, City Pop, and more)\n') +
1615
- chalk.gray(' 🎛️ Reverb & Effects - 5 reverb levels via ffmpeg aecho filter\n') +
1616
- chalk.gray(' 🔊 Verbosity Control - High, Medium, or Low transparency levels\n') +
1617
- chalk.gray(' 🎨 Beautiful Installer - Figlet banner, directory explanations, provider detection\n') +
1618
- chalk.gray(' 🧪 93/93 Tests Passing - 46 Windows + 47 cross-platform\n\n') +
1689
+ chalk.gray(' 🔐 Security Fixes - Fixed command injection, HOME injection prevention, path traversal\n') +
1690
+ chalk.gray(' Provider Detection - Soprano via pipx now correctly detected\n') +
1691
+ chalk.gray(' 💬 Better Messaging - Explicit detection confirmation, detailed error messages\n') +
1692
+ chalk.gray(' 🧪 Enhanced Tests - Verification of actual detection values\n') +
1693
+ chalk.gray(' 🐛 Debug Support - Added logging for troubleshooting\n\n') +
1619
1694
  chalk.gray('📖 Full Release Notes: RELEASE_NOTES.md\n') +
1620
1695
  chalk.gray('🌐 Website: https://agentvibes.org\n') +
1621
1696
  chalk.gray('📦 Repository: https://github.com/paulpreibisch/AgentVibes\n\n') +