agentvibes 4.4.1 → 4.5.0
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.
- package/.agentvibes/config.json +4 -4
- package/.claude/config/reverb-level.txt +1 -1
- package/.claude/github-star-reminder.txt +1 -1
- package/.claude/hooks-windows/bmad-speak.ps1 +112 -0
- package/.claude/hooks-windows/play-tts-piper.ps1 +3 -4
- package/.claude/hooks-windows/play-tts-sapi.ps1 +3 -4
- package/.claude/hooks-windows/play-tts-soprano.ps1 +2 -3
- package/.claude/hooks-windows/play-tts-termux-ssh.ps1 +138 -0
- package/.claude/hooks-windows/play-tts.ps1 +14 -6
- package/.claude/hooks-windows/provider-manager.ps1 +16 -1
- package/CLAUDE.md +4 -0
- package/README.md +39 -9
- package/RELEASE_NOTES.md +39 -0
- package/bin/agent-vibes +1 -1
- package/bin/agentvibes-voice-browser.js +1 -1
- package/bin/bmad-speak.js +52 -0
- package/bin/mcp-server.js +1 -1
- package/bin/test-bmad-pr +1 -1
- package/package.json +1 -1
- package/setup-windows.ps1 +4 -4
- package/src/console/app.js +58 -11
- package/src/console/tabs/agents-tab.js +61 -65
- package/src/console/tabs/help-tab.js +107 -54
- package/src/console/tabs/install-tab.js +107 -47
- package/src/console/tabs/music-tab.js +1030 -1011
- package/src/console/tabs/placeholder-tab.js +27 -0
- package/src/console/tabs/readme-tab.js +9 -7
- package/src/console/tabs/receiver-tab.js +23 -12
- package/src/console/tabs/settings-tab.js +4001 -3783
- package/src/console/tabs/voices-tab.js +1680 -1653
- package/src/console/widgets/personality-picker.js +35 -7
- package/src/console/widgets/reverb-picker.js +9 -6
- package/src/console/widgets/track-picker.js +6 -1
- package/src/i18n/de.js +201 -0
- package/src/i18n/en.js +201 -0
- package/src/i18n/es.js +201 -0
- package/src/i18n/fr.js +201 -0
- package/src/i18n/hi.js +201 -0
- package/src/i18n/ja.js +201 -0
- package/src/i18n/ko.js +201 -0
- package/src/i18n/pt.js +201 -0
- package/src/i18n/strings.js +54 -0
- package/src/i18n/zh-CN.js +201 -0
- package/src/installer/language-screen.js +31 -0
- package/src/installer.js +79 -25
- package/src/services/language-service.js +47 -0
- package/src/utils/file-ownership-verifier.js +2 -2
- package/src/utils/provider-validator.js +9 -13
- package/.claude/hooks-windows/play-tts-windows-piper.ps1 +0 -209
- package/.claude/hooks-windows/play-tts-windows-sapi.ps1 +0 -108
package/.agentvibes/config.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"backgroundMusic": {
|
|
3
3
|
"track": "agent_vibes_cumbia_v1_loop.mp3",
|
|
4
|
-
"enabled":
|
|
5
|
-
"volume":
|
|
4
|
+
"enabled": true,
|
|
5
|
+
"volume": 10
|
|
6
6
|
},
|
|
7
|
+
"voice": "en_US-libritts-high::Ella",
|
|
7
8
|
"provider": "piper",
|
|
8
|
-
"voice": "en_US-libritts-high::Evan-8",
|
|
9
9
|
"effects": {
|
|
10
|
-
"reverbPreset": "
|
|
10
|
+
"reverbPreset": "light"
|
|
11
11
|
}
|
|
12
12
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
light
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
20260329
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
#
|
|
2
|
+
# File: .claude/hooks-windows/bmad-speak.ps1
|
|
3
|
+
#
|
|
4
|
+
# AgentVibes BMAD Voice Integration - Windows
|
|
5
|
+
# Maps BMAD agent display names or agent IDs to voices and triggers TTS.
|
|
6
|
+
# Windows port of .claude/hooks/bmad-speak.sh
|
|
7
|
+
#
|
|
8
|
+
# Usage: bmad-speak.ps1 "Agent Name" "dialogue text"
|
|
9
|
+
# bmad-speak.ps1 "agent-id" "dialogue text"
|
|
10
|
+
#
|
|
11
|
+
|
|
12
|
+
param(
|
|
13
|
+
[Parameter(Mandatory = $true, Position = 0)]
|
|
14
|
+
[string]$AgentNameOrId,
|
|
15
|
+
|
|
16
|
+
[Parameter(Mandatory = $true, Position = 1)]
|
|
17
|
+
[string]$Dialogue
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
21
|
+
$ClaudeDir = Split-Path -Parent $ScriptDir
|
|
22
|
+
$ProjectRoot = Split-Path -Parent $ClaudeDir
|
|
23
|
+
|
|
24
|
+
# Strip markdown formatting — prevent SAPI/Piper from speaking asterisks literally
|
|
25
|
+
$Dialogue = $Dialogue -replace '\*\*', '' -replace '\*', '' -replace '`', ''
|
|
26
|
+
$Dialogue = $Dialogue -replace '\\!', '!' -replace '\\\$', '$'
|
|
27
|
+
|
|
28
|
+
# Check if party mode is disabled
|
|
29
|
+
$PartyModeDisabledFlag = Join-Path $ProjectRoot ".agentvibes\bmad\bmad-party-mode-disabled.flag"
|
|
30
|
+
if (Test-Path $PartyModeDisabledFlag) {
|
|
31
|
+
exit 0
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
# Check if BMAD is installed
|
|
35
|
+
$ManifestFile = Join-Path $ProjectRoot "_bmad\_config\agent-manifest.csv"
|
|
36
|
+
if (-not (Test-Path $ManifestFile)) {
|
|
37
|
+
exit 0
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
# ---------------------------------------------------------------------------
|
|
41
|
+
# Read bmad-voice-map.json for per-agent profile
|
|
42
|
+
$VoiceMapFile = Join-Path $env:USERPROFILE ".agentvibes\bmad-voice-map.json"
|
|
43
|
+
|
|
44
|
+
$AgentVoice = ""
|
|
45
|
+
$AgentPersonality = ""
|
|
46
|
+
|
|
47
|
+
if (Test-Path $VoiceMapFile) {
|
|
48
|
+
try {
|
|
49
|
+
$VoiceMap = Get-Content $VoiceMapFile -Raw | ConvertFrom-Json
|
|
50
|
+
|
|
51
|
+
# Resolve agent ID from display name or direct ID
|
|
52
|
+
$AgentId = $null
|
|
53
|
+
|
|
54
|
+
# Check direct match against manifest column 1
|
|
55
|
+
$ManifestRows = Import-Csv $ManifestFile
|
|
56
|
+
foreach ($row in $ManifestRows) {
|
|
57
|
+
$id = ($row.PSObject.Properties | Select-Object -First 1).Value -replace '^"|"$', ''
|
|
58
|
+
$display = ($row.PSObject.Properties | Select-Object -Skip 1 -First 1).Value -replace '^"|"$', ''
|
|
59
|
+
if ($id -ieq $AgentNameOrId -or $display -like "$AgentNameOrId*") {
|
|
60
|
+
$AgentId = $id
|
|
61
|
+
break
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if ($AgentId -and $VoiceMap.agents.$AgentId) {
|
|
66
|
+
$Profile = $VoiceMap.agents.$AgentId
|
|
67
|
+
if ($Profile.voice) { $AgentVoice = $Profile.voice }
|
|
68
|
+
if ($Profile.personality) { $AgentPersonality = $Profile.personality }
|
|
69
|
+
}
|
|
70
|
+
} catch {
|
|
71
|
+
# Silently degrade — TTS will still play with global settings
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
# ---------------------------------------------------------------------------
|
|
76
|
+
# Locate play-tts.ps1 — prefer project-local, fall back to global
|
|
77
|
+
$PlayTtsLocal = Join-Path $ProjectRoot ".claude\hooks-windows\play-tts.ps1"
|
|
78
|
+
$PlayTtsGlobal = Join-Path $env:USERPROFILE ".claude\hooks-windows\play-tts.ps1"
|
|
79
|
+
$PlayTtsScript = if (Test-Path $PlayTtsLocal) { $PlayTtsLocal } else { $PlayTtsGlobal }
|
|
80
|
+
|
|
81
|
+
if (-not (Test-Path $PlayTtsScript)) {
|
|
82
|
+
exit 0
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
# ---------------------------------------------------------------------------
|
|
86
|
+
# Apply per-agent personality override if set
|
|
87
|
+
$OldPersonality = ""
|
|
88
|
+
$PersonalityFile = Join-Path $ClaudeDir "config\personality.txt"
|
|
89
|
+
if ($AgentPersonality -and (Test-Path (Split-Path $PersonalityFile -Parent))) {
|
|
90
|
+
if (Test-Path $PersonalityFile) {
|
|
91
|
+
$OldPersonality = (Get-Content $PersonalityFile -Raw).Trim()
|
|
92
|
+
}
|
|
93
|
+
Set-Content $PersonalityFile $AgentPersonality -NoNewline
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
try {
|
|
97
|
+
# Speak with agent's voice (or global voice if none configured)
|
|
98
|
+
if ($AgentVoice) {
|
|
99
|
+
& powershell -NoProfile -ExecutionPolicy Bypass -File $PlayTtsScript $Dialogue $AgentVoice
|
|
100
|
+
} else {
|
|
101
|
+
& powershell -NoProfile -ExecutionPolicy Bypass -File $PlayTtsScript $Dialogue
|
|
102
|
+
}
|
|
103
|
+
} finally {
|
|
104
|
+
# Restore original personality
|
|
105
|
+
if ($AgentPersonality -and $PersonalityFile) {
|
|
106
|
+
if ($OldPersonality) {
|
|
107
|
+
Set-Content $PersonalityFile $OldPersonality -NoNewline
|
|
108
|
+
} elseif (Test-Path $PersonalityFile) {
|
|
109
|
+
Remove-Item $PersonalityFile -Force -ErrorAction SilentlyContinue
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#
|
|
2
|
-
# File: .claude/hooks-windows/play-tts-
|
|
2
|
+
# File: .claude/hooks-windows/play-tts-piper.ps1
|
|
3
3
|
#
|
|
4
4
|
# AgentVibes - Windows Piper TTS Provider
|
|
5
5
|
# High-quality neural TTS using Piper.exe
|
|
@@ -162,9 +162,8 @@ $Text = $Text -replace '[{}<>|`~^;]', ''
|
|
|
162
162
|
$Text = $Text -replace '\s+', ' '
|
|
163
163
|
$Text = $Text.Trim()
|
|
164
164
|
|
|
165
|
-
# Create audio file path
|
|
166
|
-
$
|
|
167
|
-
$AudioFile = "$AudioDir\tts-$Timestamp.wav"
|
|
165
|
+
# Create audio file path — SECURITY: use random name instead of predictable timestamp (#130)
|
|
166
|
+
$AudioFile = "$AudioDir\tts-$([System.IO.Path]::GetRandomFileName() -replace '\..*').wav"
|
|
168
167
|
|
|
169
168
|
# Synthesize with Piper
|
|
170
169
|
try {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#
|
|
2
|
-
# File: .claude/hooks-windows/play-tts-
|
|
2
|
+
# File: .claude/hooks-windows/play-tts-sapi.ps1
|
|
3
3
|
#
|
|
4
4
|
# AgentVibes - Windows SAPI TTS Provider (Zero Dependencies)
|
|
5
5
|
# Uses built-in Windows System.Speech API
|
|
@@ -73,9 +73,8 @@ $Text = $Text.Trim()
|
|
|
73
73
|
# Get actual voice name (after selection or default)
|
|
74
74
|
$ActualVoice = $synth.Voice.Name
|
|
75
75
|
|
|
76
|
-
# Create audio file path
|
|
77
|
-
$
|
|
78
|
-
$AudioFile = "$AudioDir\tts-$Timestamp.wav"
|
|
76
|
+
# Create audio file path — SECURITY: use random name instead of predictable timestamp (#130)
|
|
77
|
+
$AudioFile = "$AudioDir\tts-$([System.IO.Path]::GetRandomFileName() -replace '\..*').wav"
|
|
79
78
|
|
|
80
79
|
# Save to WAV file with proper resource cleanup
|
|
81
80
|
$player = $null
|
|
@@ -53,9 +53,8 @@ if (-not (Test-Path $AudioDir)) {
|
|
|
53
53
|
New-Item -ItemType Directory -Path $AudioDir -Force | Out-Null
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
$
|
|
58
|
-
$TempFile = Join-Path $AudioDir "tts-$timestamp-$random.wav"
|
|
56
|
+
# SECURITY: use random name instead of predictable timestamp (#130)
|
|
57
|
+
$TempFile = Join-Path $AudioDir "tts-$([System.IO.Path]::GetRandomFileName() -replace '\..*').wav"
|
|
59
58
|
|
|
60
59
|
# Check WebUI server
|
|
61
60
|
function Test-WebUI {
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
#
|
|
2
|
+
# File: .claude/hooks-windows/play-tts-termux-ssh.ps1
|
|
3
|
+
#
|
|
4
|
+
# AgentVibes - Finally, your AI Agents can Talk Back! Text-to-Speech WITH personality for AI Assistants!
|
|
5
|
+
# Website: https://agentvibes.org
|
|
6
|
+
# Repository: https://github.com/paulpreibisch/AgentVibes
|
|
7
|
+
#
|
|
8
|
+
# Co-created by Paul Preibisch with Claude AI
|
|
9
|
+
# Copyright (c) 2025 Paul Preibisch
|
|
10
|
+
#
|
|
11
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
12
|
+
# you may not use this file except in compliance with the License.
|
|
13
|
+
# You may obtain a copy of the License at
|
|
14
|
+
#
|
|
15
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
16
|
+
#
|
|
17
|
+
# ---
|
|
18
|
+
#
|
|
19
|
+
# @fileoverview Termux SSH TTS Provider (Windows) - Android TTS via SSH tunnel
|
|
20
|
+
# @context Enables TTS output on Android devices when connected via SSH from Windows
|
|
21
|
+
# @architecture SSH-based remote TTS invocation using termux-tts-speak on Android
|
|
22
|
+
# @dependencies ssh.exe (OpenSSH for Windows), termux-tts-speak (on Android), termux-api (on Android)
|
|
23
|
+
# @entrypoints Called by play-tts.ps1 router when provider=termux-ssh
|
|
24
|
+
# @patterns Remote TTS invocation, SSH host alias configuration, graceful fallback
|
|
25
|
+
# @related play-tts.ps1, provider-manager.ps1
|
|
26
|
+
#
|
|
27
|
+
# SETUP INSTRUCTIONS:
|
|
28
|
+
# ===================
|
|
29
|
+
# 1. On Android device (Termux):
|
|
30
|
+
# - Install: pkg install termux-api openssh
|
|
31
|
+
# - Install Termux:API app from F-Droid or Google Play
|
|
32
|
+
# - Start SSH server: sshd
|
|
33
|
+
#
|
|
34
|
+
# 2. On Windows:
|
|
35
|
+
# - Add to %USERPROFILE%\.ssh\config:
|
|
36
|
+
# Host android
|
|
37
|
+
# HostName <your-android-ip>
|
|
38
|
+
# User <your-termux-username>
|
|
39
|
+
# Port 8022
|
|
40
|
+
# IdentityFile ~/.ssh/id_rsa
|
|
41
|
+
#
|
|
42
|
+
# 3. Configure AgentVibes:
|
|
43
|
+
# - echo android > %USERPROFILE%\.claude\termux-ssh-host.txt
|
|
44
|
+
# OR
|
|
45
|
+
# - echo android > .claude\termux-ssh-host.txt (project-local)
|
|
46
|
+
#
|
|
47
|
+
# 4. Set provider:
|
|
48
|
+
# - echo termux-ssh > %USERPROFILE%\.claude\tts-provider.txt
|
|
49
|
+
#
|
|
50
|
+
|
|
51
|
+
param(
|
|
52
|
+
[Parameter(Mandatory = $true, Position = 0)]
|
|
53
|
+
[string]$Text,
|
|
54
|
+
|
|
55
|
+
[Parameter(Mandatory = $false, Position = 1)]
|
|
56
|
+
[string]$VoiceOverride # Not used for termux-ssh, kept for interface compatibility
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
# Resolve ClaudeDir (project-local preferred, fallback to global)
|
|
60
|
+
$ScriptPath = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
61
|
+
$ProjectClaudeDir = Split-Path -Parent $ScriptPath
|
|
62
|
+
if (Test-Path (Join-Path $ProjectClaudeDir "config")) {
|
|
63
|
+
$ClaudeDir = $ProjectClaudeDir
|
|
64
|
+
} else {
|
|
65
|
+
$ClaudeDir = "$env:USERPROFILE\.claude"
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
# @function Get-SshHost
|
|
69
|
+
# @intent Determine SSH host alias for Android device
|
|
70
|
+
# @why Allows users to configure their own SSH connection without hardcoded values
|
|
71
|
+
# Priority: env var > project config > script-dir config > global config
|
|
72
|
+
function Get-SshHost {
|
|
73
|
+
if ($env:TERMUX_SSH_HOST) { return $env:TERMUX_SSH_HOST }
|
|
74
|
+
|
|
75
|
+
$projectFile = Join-Path $ClaudeDir "termux-ssh-host.txt"
|
|
76
|
+
if (Test-Path $projectFile) {
|
|
77
|
+
$val = (Get-Content $projectFile -Raw).Trim()
|
|
78
|
+
if ($val) { return $val }
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
$globalFile = "$env:USERPROFILE\.claude\termux-ssh-host.txt"
|
|
82
|
+
if (Test-Path $globalFile) {
|
|
83
|
+
$val = (Get-Content $globalFile -Raw).Trim()
|
|
84
|
+
if ($val) { return $val }
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return ""
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
# @function Test-SshConnection
|
|
91
|
+
# @intent Quick reachability check before sending TTS
|
|
92
|
+
# @why Prevents long hangs if Android is offline
|
|
93
|
+
function Test-SshConnection {
|
|
94
|
+
param([string]$SshTarget)
|
|
95
|
+
try {
|
|
96
|
+
$null = ssh -o ConnectTimeout=2 -o BatchMode=yes $SshTarget "echo ok" 2>&1
|
|
97
|
+
return $LASTEXITCODE -eq 0
|
|
98
|
+
} catch {
|
|
99
|
+
return $false
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
# --- Main ---
|
|
104
|
+
|
|
105
|
+
if (-not $Text) {
|
|
106
|
+
Write-Host "[ERROR] No text provided for TTS" -ForegroundColor Red
|
|
107
|
+
exit 1
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
$SshAlias = Get-SshHost
|
|
111
|
+
|
|
112
|
+
if (-not $SshAlias) {
|
|
113
|
+
Write-Host "[ERROR] Termux SSH provider not configured" -ForegroundColor Red
|
|
114
|
+
Write-Host " Set SSH host alias in one of:" -ForegroundColor Yellow
|
|
115
|
+
Write-Host " Environment: `$env:TERMUX_SSH_HOST = 'android'" -ForegroundColor Yellow
|
|
116
|
+
Write-Host " Global: echo android > `"$env:USERPROFILE\.claude\termux-ssh-host.txt`"" -ForegroundColor Yellow
|
|
117
|
+
Write-Host " Project: echo android > .claude\termux-ssh-host.txt" -ForegroundColor Yellow
|
|
118
|
+
exit 1
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (-not (Test-SshConnection -SshTarget $SshAlias)) {
|
|
122
|
+
Write-Host "[WARNING] Cannot connect to SSH host '$SshAlias' - Android offline?" -ForegroundColor Yellow
|
|
123
|
+
exit 1
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
# Escape single quotes for safe shell transmission
|
|
127
|
+
$SafeText = $Text -replace "'", "'\'''"
|
|
128
|
+
|
|
129
|
+
# Send TTS to Android asynchronously (audio plays on device)
|
|
130
|
+
$job = Start-Job -ScriptBlock {
|
|
131
|
+
param($alias, $text)
|
|
132
|
+
ssh -o ConnectTimeout=5 $alias "termux-tts-speak '$text'" 2>&1
|
|
133
|
+
} -ArgumentList $SshAlias, $SafeText
|
|
134
|
+
|
|
135
|
+
Write-Host "[OK] TTS sent to Android ($SshAlias) via SSH" -ForegroundColor Green
|
|
136
|
+
|
|
137
|
+
# Output empty string — audio plays on Android, not locally
|
|
138
|
+
Write-Output ""
|
|
@@ -14,15 +14,20 @@ param(
|
|
|
14
14
|
)
|
|
15
15
|
|
|
16
16
|
# Configuration paths
|
|
17
|
-
#
|
|
17
|
+
# Priority: CLAUDE_PROJECT_DIR env var → script's parent project → user profile
|
|
18
18
|
$ScriptPath = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
19
|
-
$ProjectClaudeDir = Join-Path (Split-Path -Parent (Split-Path -Parent $ScriptPath)) ".claude"
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
$ClaudeDir = $ProjectClaudeDir
|
|
20
|
+
if ($env:CLAUDE_PROJECT_DIR -and (Test-Path "$env:CLAUDE_PROJECT_DIR\.claude")) {
|
|
21
|
+
$ClaudeDir = "$env:CLAUDE_PROJECT_DIR\.claude"
|
|
24
22
|
} else {
|
|
25
|
-
$
|
|
23
|
+
$PackageClaudeDir = Join-Path (Split-Path -Parent (Split-Path -Parent $ScriptPath)) ".claude"
|
|
24
|
+
if (Test-Path "$env:USERPROFILE\.claude\tts-provider.txt") {
|
|
25
|
+
$ClaudeDir = "$env:USERPROFILE\.claude"
|
|
26
|
+
} elseif (Test-Path $PackageClaudeDir) {
|
|
27
|
+
$ClaudeDir = $PackageClaudeDir
|
|
28
|
+
} else {
|
|
29
|
+
$ClaudeDir = "$env:USERPROFILE\.claude"
|
|
30
|
+
}
|
|
26
31
|
}
|
|
27
32
|
|
|
28
33
|
$HooksDir = "$ClaudeDir\hooks-windows"
|
|
@@ -56,6 +61,9 @@ switch ($ActiveProvider) {
|
|
|
56
61
|
"soprano" {
|
|
57
62
|
$ProviderScript = "$HooksDir\play-tts-soprano.ps1"
|
|
58
63
|
}
|
|
64
|
+
"termux-ssh" {
|
|
65
|
+
$ProviderScript = "$HooksDir\play-tts-termux-ssh.ps1"
|
|
66
|
+
}
|
|
59
67
|
default {
|
|
60
68
|
Write-Host "[ERROR] Unknown provider: $ActiveProvider" -ForegroundColor Red
|
|
61
69
|
Write-Host "Use: .\provider-manager.ps1 list" -ForegroundColor Yellow
|
|
@@ -22,7 +22,7 @@ if (Test-Path (Join-Path $ProjectClaudeDir "config")) {
|
|
|
22
22
|
$ClaudeDir = "$env:USERPROFILE\.claude"
|
|
23
23
|
}
|
|
24
24
|
$ProviderFile = "$ClaudeDir\tts-provider.txt"
|
|
25
|
-
$ValidProviders = @('piper', 'sapi', 'soprano')
|
|
25
|
+
$ValidProviders = @('piper', 'sapi', 'soprano', 'termux-ssh')
|
|
26
26
|
# Backwards compat: normalize old names
|
|
27
27
|
if ($Provider -eq 'windows-piper') { $Provider = 'piper' }
|
|
28
28
|
if ($Provider -eq 'windows-sapi') { $Provider = 'sapi' }
|
|
@@ -91,6 +91,21 @@ function Get-AvailableProviders {
|
|
|
91
91
|
installed = $sopranoInstalled
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
# Check if termux-ssh is configured (ssh.exe available + host configured)
|
|
95
|
+
$termuxSshConfigured = $false
|
|
96
|
+
$sshExe = Get-Command ssh.exe -ErrorAction SilentlyContinue
|
|
97
|
+
if ($sshExe) {
|
|
98
|
+
$hostFile = "$ClaudeDir\termux-ssh-host.txt"
|
|
99
|
+
$globalHostFile = "$env:USERPROFILE\.claude\termux-ssh-host.txt"
|
|
100
|
+
$termuxSshConfigured = (Test-Path $hostFile) -or (Test-Path $globalHostFile) -or ($env:TERMUX_SSH_HOST -ne "")
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
$available += @{
|
|
104
|
+
name = "termux-ssh"
|
|
105
|
+
description = "Android Termux SSH TTS (plays on Android via termux-tts-speak)"
|
|
106
|
+
installed = $termuxSshConfigured
|
|
107
|
+
}
|
|
108
|
+
|
|
94
109
|
return $available
|
|
95
110
|
}
|
|
96
111
|
|
package/CLAUDE.md
CHANGED
|
@@ -8,6 +8,10 @@
|
|
|
8
8
|
|
|
9
9
|
AgentVibes is a Text-to-Speech system for AI assistants with personality support.
|
|
10
10
|
|
|
11
|
+
### Time Estimates
|
|
12
|
+
|
|
13
|
+
Always estimate in **AI time** — Paul does not write code, that's Claude's job. "30 minutes" means 30 human minutes; the AI equivalent is seconds to a few minutes. When giving estimates, say things like "~10 minutes of AI work" or "quick — a few minutes tops."
|
|
14
|
+
|
|
11
15
|
### Project Uses BMAD Methodology
|
|
12
16
|
|
|
13
17
|
This project follows **BMAD (BMM - Business Model Methodology)** for all story development:
|
package/README.md
CHANGED
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
>
|
|
5
5
|
> 🌐 **[agentvibes.org](https://agentvibes.org)**
|
|
6
6
|
>
|
|
7
|
-
> Professional text-to-speech for **Claude Code**, **Claude Desktop**,
|
|
7
|
+
> Professional text-to-speech for **Claude Code**, **Claude Desktop**, and **OpenClaw** - **Soprano** (Neural), **Piper TTS** (Free!), **macOS Say** (Built-in!), or **Windows SAPI** (Zero Setup!)
|
|
8
8
|
|
|
9
9
|
[](https://www.npmjs.com/package/agentvibes)
|
|
10
10
|
[](https://github.com/paulpreibisch/AgentVibes/actions/workflows/test.yml)
|
|
11
11
|
[](https://github.com/paulpreibisch/AgentVibes/actions/workflows/publish.yml)
|
|
12
12
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
13
13
|
|
|
14
|
-
**Author**: Paul Preibisch ([@997Fire](https://x.com/997Fire)) | **Version**: v4.
|
|
14
|
+
**Author**: Paul Preibisch ([@997Fire](https://x.com/997Fire)) | **Version**: v4.5
|
|
15
15
|
|
|
16
16
|
---
|
|
17
17
|
|
|
@@ -36,11 +36,41 @@
|
|
|
36
36
|
|
|
37
37
|
**AgentVibes adds lively voice narration to your Claude AI sessions!**
|
|
38
38
|
|
|
39
|
-
Whether you're coding in Claude Code, chatting in Claude Desktop,
|
|
39
|
+
Whether you're coding in Claude Code, chatting in Claude Desktop, or running OpenClaw — AgentVibes brings AI to life with professional voices and personalities.
|
|
40
40
|
|
|
41
41
|
---
|
|
42
42
|
|
|
43
|
-
## 🌟 NEW IN v4.
|
|
43
|
+
## 🌟 NEW IN v4.5 — "Speak Every Language" Release
|
|
44
|
+
|
|
45
|
+
### 🌍 Multilingual TUI — 9 Languages
|
|
46
|
+
|
|
47
|
+
Every screen, button, and label in `npx agentvibes` is now fully translated:
|
|
48
|
+
|
|
49
|
+
- **English, Spanish, French, German, Portuguese, Japanese, Korean, Chinese (Simplified), Italian**
|
|
50
|
+
- Language selection on first launch — pick your language before anything else
|
|
51
|
+
- Language sub-tab in Settings — switch live, no restart needed
|
|
52
|
+
- All tab labels, buttons, footer hints, status messages, and BMAD/Receiver tabs translated
|
|
53
|
+
- Per-language i18n files (`src/i18n/en.js`, `es.js`, `fr.js`, ...) with English fallback
|
|
54
|
+
|
|
55
|
+
### 🪟 Windows Security Hardening
|
|
56
|
+
|
|
57
|
+
- **Unpredictable temp files** — `randomUUID()` replaces `Date.now()` in all temp filenames (JS + PowerShell)
|
|
58
|
+
- **No shell injection** — `spawnSync` replaces `execSync(..., { shell: true })` for `which` lookups
|
|
59
|
+
- **Smart music player detection** — `detectMp3Player()` replaces hardcoded `ffplay` on Windows
|
|
60
|
+
- **Boolean fix** — `isWindowsTerminal` now returns `true/false`, not the `WT_SESSION` UUID string
|
|
61
|
+
|
|
62
|
+
### 🎙️ Cross-Platform BMAD Speak
|
|
63
|
+
|
|
64
|
+
BMAD (Build More Architect Dreams) is an AI multi-agent framework where specialized agents — Architect, PM, Developer, QA, and Analyst — collaborate to build software. With this release, every agent in a BMAD party mode session now speaks aloud with their own unique voice, personality, and music on Windows — making each role instantly recognizable.
|
|
65
|
+
|
|
66
|
+
- `bmad-speak.js` — cross-platform entry point; auto-routes to PowerShell on Windows or bash on Mac/Linux
|
|
67
|
+
- `bmad-speak.ps1` — native Windows BMAD speak with per-agent personality routing
|
|
68
|
+
|
|
69
|
+
### 🧪 600 Tests, Zero Failures
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## 🌟 v4.4 — Full Platform Parity Release
|
|
44
74
|
|
|
45
75
|
### 🪟 Windows MCP Parity — 27/27 Tools Working
|
|
46
76
|
|
|
@@ -294,7 +324,7 @@ Configure via: `npx agentvibes` → Music tab
|
|
|
294
324
|
- 🎭 **Multi-Provider Support** - Soprano (neural), Piper TTS (50+ free voices), macOS Say (100+ built-in), or Windows SAPI
|
|
295
325
|
- 🎙️ **27+ Professional AI Voices** - Character voices, accents, and unique personalities
|
|
296
326
|
- 🎙️ **Verbosity Control** - Choose how much Claude speaks (LOW, MEDIUM, HIGH)
|
|
297
|
-
- 🎙️ **AgentVibes MCP** - Natural language control ("Switch to Aria voice") for Claude Code
|
|
327
|
+
- 🎙️ **AgentVibes MCP** - Natural language control ("Switch to Aria voice") for Claude Code & Desktop
|
|
298
328
|
- 🔊 **SSH Audio Optimization** - Auto-detects remote sessions and eliminates static (VS Code Remote SSH, cloud dev)
|
|
299
329
|
|
|
300
330
|
**🎭 Personalization:**
|
|
@@ -345,7 +375,7 @@ All 50+ Piper voices AgentVibes provides are sourced from Hugging Face's open-so
|
|
|
345
375
|
### AgentVibes MCP (Natural Language Control)
|
|
346
376
|
- [🎙️ AgentVibes MCP Overview](#%EF%B8%8F-agentvibes-mcp) - **Easiest way** - Natural language commands
|
|
347
377
|
- [For Claude Desktop](docs/mcp-setup.md#for-claude-desktop) - Windows/WSL setup, Python requirements
|
|
348
|
-
|
|
378
|
+
|
|
349
379
|
- [For Claude Code](docs/mcp-setup.md#for-claude-code) - Project-specific setup
|
|
350
380
|
|
|
351
381
|
### Core Features
|
|
@@ -473,9 +503,9 @@ We've now enhanced this capability by adding an MCP (Model Context Protocol) ser
|
|
|
473
503
|
|
|
474
504
|
Setting it up is straightforward: just add the MCP server to your Claude Code configuration files.
|
|
475
505
|
|
|
476
|
-
But the convenience doesn't stop there. With the MCP server in place, Claude Desktop can now use Agent Vibes too!
|
|
506
|
+
But the convenience doesn't stop there. With the MCP server in place, Claude Desktop can now use Agent Vibes too!
|
|
477
507
|
|
|
478
|
-
We're thrilled about this expansion because it means Claude Desktop
|
|
508
|
+
We're thrilled about this expansion because it means Claude Desktop can finally talk back as well!
|
|
479
509
|
|
|
480
510
|
If you decide to use the MCP server on Claude Desktop, after configuration, give Claude Desktop this command: "every time i give you a command, speak the acknowledgement using agentvibes and the confirmation about what you completed, when done"—and watch the magic happen!
|
|
481
511
|
|
|
@@ -483,7 +513,7 @@ If you decide to use the MCP server on Claude Desktop, after configuration, give
|
|
|
483
513
|
|
|
484
514
|
Just say "Switch to Aria voice" or "Speak in Spanish" instead of typing commands.
|
|
485
515
|
|
|
486
|
-
**Works in:** Claude Desktop, Claude Code
|
|
516
|
+
**Works in:** Claude Desktop, Claude Code
|
|
487
517
|
|
|
488
518
|
**[→ View Complete MCP Setup Guide](docs/mcp-setup.md)** - Full setup for all platforms, configuration examples, available tools, and MCP vs slash commands comparison
|
|
489
519
|
|
package/RELEASE_NOTES.md
CHANGED
|
@@ -1,5 +1,44 @@
|
|
|
1
1
|
# AgentVibes Release Notes
|
|
2
2
|
|
|
3
|
+
## 🌍 v4.5.0 — "Speak Every Language" Release
|
|
4
|
+
|
|
5
|
+
**Release Date:** April 2026
|
|
6
|
+
|
|
7
|
+
Full multilingual TUI support across all 9 languages, complete Windows security hardening, and zero failing tests.
|
|
8
|
+
|
|
9
|
+
### 🌍 Multilingual TUI — 9 Languages
|
|
10
|
+
|
|
11
|
+
Every screen, tab, button, and label in the `npx agentvibes` TUI is now fully translated:
|
|
12
|
+
|
|
13
|
+
- **English, Spanish, French, German, Portuguese, Japanese, Korean, Chinese (Simplified), Italian**
|
|
14
|
+
- Language selection on first launch (Screen 0 of the installer wizard)
|
|
15
|
+
- Language sub-tab in Settings — switch language live without restarting
|
|
16
|
+
- All tab bar labels, button text, footer hints, and status messages translated
|
|
17
|
+
- BMAD tab and SSH Receiver tab fully localized
|
|
18
|
+
- Per-language i18n files (`src/i18n/en.js`, `es.js`, `fr.js`, ...) with English fallback
|
|
19
|
+
|
|
20
|
+
### 🪟 Windows Security & Bug Fixes
|
|
21
|
+
|
|
22
|
+
- **Temp filenames** — All `Date.now()` temp filenames replaced with `randomUUID()` across JS and PowerShell (unpredictable, prevents temp file hijacking)
|
|
23
|
+
- **Shell injection** — `execSync('which ...', { shell: true })` replaced with `spawnSync` (no shell expansion)
|
|
24
|
+
- **Music player** — Hardcoded `ffplay` on Windows replaced with `detectMp3Player()` (respects user's installed player)
|
|
25
|
+
- **Boolean coercion** — `isWindowsTerminal` now correctly returns `true/false` instead of leaking `WT_SESSION` UUID string
|
|
26
|
+
- **Network mount detection** — `.match()` result properly coerced to boolean
|
|
27
|
+
|
|
28
|
+
### 🎙️ Cross-Platform BMAD Speak
|
|
29
|
+
|
|
30
|
+
BMAD (Build More Architect Dreams) is an AI multi-agent framework where specialized agents — Architect, PM, Developer, QA, and Analyst — collaborate to build software. With this release, every agent in a BMAD party mode session now speaks aloud with their own unique voice, personality, and music on Windows — making each role instantly recognizable.
|
|
31
|
+
|
|
32
|
+
- `bin/bmad-speak.js` — cross-platform entry point for BMAD agent speech
|
|
33
|
+
- `.claude/hooks-windows/bmad-speak.ps1` — native Windows BMAD speak with per-agent personality routing
|
|
34
|
+
|
|
35
|
+
### 🧪 Test Suite
|
|
36
|
+
|
|
37
|
+
- 600 tests, 0 failures
|
|
38
|
+
- Full cross-platform coverage (Windows path separators, chmod skip, provider file restore)
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
3
42
|
## 🎉 v4.4.0 — "Full Platform Parity" Release
|
|
4
43
|
|
|
5
44
|
**Release Date:** March 2026
|
package/bin/agent-vibes
CHANGED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* AgentVibes - Cross-platform BMAD agent TTS entry point
|
|
5
|
+
*
|
|
6
|
+
* Delegates to the correct platform script:
|
|
7
|
+
* Windows (non-WSL) → .claude/hooks-windows/bmad-speak.ps1
|
|
8
|
+
* Linux/Mac/WSL → .claude/hooks/bmad-speak.sh
|
|
9
|
+
*
|
|
10
|
+
* Usage: node bin/bmad-speak.js "Agent Name" "dialogue text"
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { spawnSync } from 'node:child_process';
|
|
14
|
+
import path from 'node:path';
|
|
15
|
+
import fs from 'node:fs';
|
|
16
|
+
import os from 'node:os';
|
|
17
|
+
|
|
18
|
+
const [, , agentName, dialogue] = process.argv;
|
|
19
|
+
|
|
20
|
+
if (!agentName || !dialogue) {
|
|
21
|
+
process.stderr.write('Usage: bmad-speak.js "Agent Name" "dialogue text"\n');
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const IS_WINDOWS = process.platform === 'win32' && !process.env.WSL_DISTRO_NAME;
|
|
26
|
+
|
|
27
|
+
// Resolve script path — prefer project-local, fall back to global ~/.claude install
|
|
28
|
+
function resolveScript(relPath) {
|
|
29
|
+
const cwdPath = path.join(process.cwd(), relPath);
|
|
30
|
+
const homePath = path.join(os.homedir(), relPath.replace(/^\.claude[\\/]/, '.claude/'));
|
|
31
|
+
if (fs.existsSync(cwdPath)) return cwdPath;
|
|
32
|
+
if (fs.existsSync(homePath)) return homePath;
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let result;
|
|
37
|
+
|
|
38
|
+
if (IS_WINDOWS) {
|
|
39
|
+
const script = resolveScript('.claude/hooks-windows/bmad-speak.ps1');
|
|
40
|
+
if (!script) process.exit(0);
|
|
41
|
+
result = spawnSync(
|
|
42
|
+
'powershell',
|
|
43
|
+
['-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', script, agentName, dialogue],
|
|
44
|
+
{ stdio: 'inherit' }
|
|
45
|
+
);
|
|
46
|
+
} else {
|
|
47
|
+
const script = resolveScript('.claude/hooks/bmad-speak.sh');
|
|
48
|
+
if (!script) process.exit(0);
|
|
49
|
+
result = spawnSync('bash', [script, agentName, dialogue], { stdio: 'inherit' });
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
process.exit(result.status ?? 0);
|
package/bin/mcp-server.js
CHANGED
package/bin/test-bmad-pr
CHANGED
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": "4.
|
|
4
|
+
"version": "4.5.0",
|
|
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": [
|