agentvibes 4.0.1 → 4.4.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/bmad/bmad-voices.md +69 -69
- package/.agentvibes/config.json +12 -0
- package/.claude/activation-instructions +54 -54
- package/.claude/audio/tracks/README.md +52 -52
- package/.claude/commands/agent-vibes/add.md +21 -21
- package/.claude/commands/agent-vibes/agent-vibes.md +101 -101
- package/.claude/commands/agent-vibes/agent.md +79 -79
- package/.claude/commands/agent-vibes/background-music.md +111 -111
- package/.claude/commands/agent-vibes/bmad.md +198 -198
- package/.claude/commands/agent-vibes/clean.md +18 -18
- package/.claude/commands/agent-vibes/cleanup.md +18 -18
- package/.claude/commands/agent-vibes/commands.json +145 -145
- package/.claude/commands/agent-vibes/effects.md +97 -97
- package/.claude/commands/agent-vibes/get.md +9 -9
- package/.claude/commands/agent-vibes/hide.md +91 -91
- package/.claude/commands/agent-vibes/language.md +23 -23
- package/.claude/commands/agent-vibes/learn.md +67 -67
- package/.claude/commands/agent-vibes/list.md +13 -13
- package/.claude/commands/agent-vibes/mute.md +37 -37
- package/.claude/commands/agent-vibes/preview.md +17 -17
- package/.claude/commands/agent-vibes/provider.md +68 -68
- package/.claude/commands/agent-vibes/replay-target.md +14 -14
- package/.claude/commands/agent-vibes/sample.md +12 -12
- package/.claude/commands/agent-vibes/set-favorite-voice.md +84 -84
- package/.claude/commands/agent-vibes/set-pretext.md +65 -65
- package/.claude/commands/agent-vibes/set-speed.md +41 -41
- package/.claude/commands/agent-vibes/show.md +84 -84
- package/.claude/commands/agent-vibes/switch.md +87 -87
- package/.claude/commands/agent-vibes/target-voice.md +26 -26
- package/.claude/commands/agent-vibes/target.md +30 -30
- package/.claude/commands/agent-vibes/translate.md +68 -68
- package/.claude/commands/agent-vibes/unmute.md +45 -45
- package/.claude/commands/agent-vibes/verbosity.md +89 -89
- package/.claude/commands/agent-vibes/whoami.md +7 -7
- package/.claude/commands/agent-vibes-bmad-voices.md +117 -117
- package/.claude/commands/agent-vibes-rdp.md +24 -24
- package/.claude/config/agentvibes.json +1 -0
- package/.claude/config/audio-effects.cfg +3 -2
- package/.claude/config/audio-effects.cfg.sample +52 -52
- package/.claude/config/background-music-volume.txt +1 -0
- package/.claude/config/intro-text.txt +1 -0
- package/.claude/config/piper-speech-rate.txt +4 -0
- package/.claude/config/piper-target-speech-rate.txt +1 -0
- package/.claude/config/reverb-level.txt +1 -0
- package/.claude/config/tts-speech-rate.txt +4 -0
- package/.claude/config/tts-target-speech-rate.txt +1 -0
- package/.claude/docs/TERMUX_SETUP.md +408 -408
- package/.claude/github-star-reminder.txt +1 -1
- package/.claude/hooks/README-TTS-QUEUE.md +135 -135
- package/.claude/hooks/audio-cache-utils.sh +246 -246
- package/.claude/hooks/audio-processor.sh +433 -389
- package/.claude/hooks/background-music-manager.sh +404 -404
- package/.claude/hooks/bmad-speak-enhanced.sh +165 -165
- package/.claude/hooks/bmad-speak.sh +269 -112
- package/.claude/hooks/bmad-tts-injector.sh +568 -568
- package/.claude/hooks/bmad-voice-manager.sh +928 -928
- package/.claude/hooks/clawdbot-receiver-SECURE.sh +129 -129
- package/.claude/hooks/clawdbot-receiver.sh +107 -107
- package/.claude/hooks/clean-audio-cache.sh +22 -22
- package/.claude/hooks/cleanup-cache.sh +106 -106
- package/.claude/hooks/configure-rdp-mode.sh +137 -137
- package/.claude/hooks/download-extra-voices.sh +244 -244
- package/.claude/hooks/effects-manager.sh +268 -268
- package/.claude/hooks/github-star-reminder.sh +154 -154
- package/.claude/hooks/language-manager.sh +362 -362
- package/.claude/hooks/learn-manager.sh +492 -492
- package/.claude/hooks/macos-voice-manager.sh +205 -205
- package/.claude/hooks/migrate-background-music.sh +125 -125
- package/.claude/hooks/migrate-to-agentvibes.sh +161 -161
- package/.claude/hooks/optimize-background-music.sh +87 -87
- package/.claude/hooks/path-resolver.sh +60 -60
- package/.claude/hooks/personality-manager.sh +448 -448
- package/.claude/hooks/piper-download-voices.sh +225 -225
- package/.claude/hooks/piper-installer.sh +292 -292
- package/.claude/hooks/piper-multispeaker-registry.sh +171 -171
- package/.claude/hooks/piper-voice-manager.sh +24 -3
- package/.claude/hooks/play-tts-agentvibes-receiver-for-voiceless-connections.sh +90 -90
- package/.claude/hooks/play-tts-enhanced.sh +105 -70
- package/.claude/hooks/play-tts-macos.sh +368 -345
- package/.claude/hooks/play-tts-piper.sh +679 -578
- package/.claude/hooks/play-tts-soprano.sh +356 -320
- package/.claude/hooks/play-tts-ssh-remote.sh +167 -88
- package/.claude/hooks/play-tts-termux-ssh.sh +169 -169
- package/.claude/hooks/play-tts.sh +301 -298
- package/.claude/hooks/prepare-release.sh +54 -54
- package/.claude/hooks/provider-commands.sh +617 -617
- package/.claude/hooks/provider-manager.sh +399 -399
- package/.claude/hooks/replay-target-audio.sh +95 -95
- package/.claude/hooks/requirements.txt +6 -6
- package/.claude/hooks/sentiment-manager.sh +201 -201
- package/.claude/hooks/session-start-tts.sh +81 -71
- package/.claude/hooks/soprano-gradio-synth.py +139 -139
- package/.claude/hooks/speed-manager.sh +291 -291
- package/.claude/hooks/stop-tts.sh +84 -0
- package/.claude/hooks/termux-installer.sh +261 -261
- package/.claude/hooks/translate-manager.sh +341 -341
- package/.claude/hooks/translator.py +237 -237
- package/.claude/hooks/tts-queue-worker.sh +145 -114
- package/.claude/hooks/tts-queue.sh +165 -136
- package/.claude/hooks/verbosity-manager.sh +178 -178
- package/.claude/hooks/voice-manager.sh +548 -544
- package/.claude/hooks-windows/audio-cache-utils.ps1 +119 -119
- package/.claude/hooks-windows/background-music-manager.ps1 +348 -0
- package/.claude/hooks-windows/clean-audio-cache.ps1 +53 -0
- package/.claude/hooks-windows/download-extra-voices.ps1 +185 -0
- package/.claude/hooks-windows/effects-manager.ps1 +294 -0
- package/.claude/hooks-windows/language-manager.ps1 +193 -0
- package/.claude/hooks-windows/learn-manager.ps1 +241 -0
- package/.claude/hooks-windows/personality-manager.ps1 +266 -0
- package/.claude/hooks-windows/play-tts-piper.ps1 +209 -0
- package/.claude/hooks-windows/play-tts-sapi.ps1 +108 -0
- package/.claude/hooks-windows/play-tts-soprano.ps1 +159 -158
- package/.claude/hooks-windows/play-tts-windows-piper.ps1 +50 -5
- package/.claude/hooks-windows/play-tts-windows-sapi.ps1 +108 -108
- package/.claude/hooks-windows/play-tts.ps1 +344 -266
- package/.claude/hooks-windows/provider-manager.ps1 +29 -10
- package/.claude/hooks-windows/session-start-tts.ps1 +124 -124
- package/.claude/hooks-windows/soprano-gradio-synth.py +153 -153
- package/.claude/hooks-windows/speed-manager.ps1 +166 -0
- package/.claude/hooks-windows/verbosity-manager.ps1 +119 -0
- package/.claude/hooks-windows/voice-manager-windows.ps1 +92 -8
- package/.claude/output-styles/agent-vibes.md +202 -202
- package/.claude/personalities/angry.md +14 -14
- package/.claude/personalities/annoying.md +14 -14
- package/.claude/personalities/crass.md +14 -14
- package/.claude/personalities/dramatic.md +14 -14
- package/.claude/personalities/dry-humor.md +50 -50
- package/.claude/personalities/flirty.md +20 -20
- package/.claude/personalities/funny.md +14 -14
- package/.claude/personalities/grandpa.md +32 -32
- package/.claude/personalities/millennial.md +14 -14
- package/.claude/personalities/moody.md +14 -14
- package/.claude/personalities/normal.md +16 -16
- package/.claude/personalities/pirate.md +14 -14
- package/.claude/personalities/poetic.md +14 -14
- package/.claude/personalities/professional.md +14 -14
- package/.claude/personalities/rapper.md +55 -55
- package/.claude/personalities/robot.md +14 -14
- package/.claude/personalities/sarcastic.md +38 -38
- package/.claude/personalities/sassy.md +14 -14
- package/.claude/personalities/surfer-dude.md +14 -14
- package/.claude/personalities/zen.md +14 -14
- package/.claude/settings.json +15 -15
- package/.claude/verbosity.txt +1 -1
- package/.clawdbot/README.md +105 -105
- package/.clawdbot/skill/SKILL.md +241 -241
- package/.mcp.json +12 -0
- package/CLAUDE.md +170 -181
- package/README.md +2029 -1909
- package/RELEASE_NOTES.md +1310 -66
- package/WINDOWS-SETUP.md +208 -208
- package/bin/agent-vibes +39 -39
- package/bin/agentvibes-voice-browser.js +1840 -1826
- package/bin/agentvibes.js +48 -2
- package/bin/mcp-server.js +121 -121
- package/bin/mcp-server.sh +206 -206
- package/bin/test-bmad-pr +78 -78
- package/mcp-server/QUICK_START.md +203 -203
- package/mcp-server/README.md +345 -345
- package/mcp-server/WINDOWS_SETUP.md +260 -260
- package/mcp-server/docs/troubleshooting-audio.md +313 -313
- package/mcp-server/examples/claude_desktop_config.json +11 -11
- package/mcp-server/examples/claude_desktop_config_piper.json +9 -9
- package/mcp-server/examples/custom_instructions.md +169 -169
- package/mcp-server/install-deps.js +130 -130
- package/mcp-server/pyproject.toml +52 -52
- package/mcp-server/requirements.txt +2 -2
- package/mcp-server/server.py +1465 -1417
- package/mcp-server/test_server.py +395 -395
- package/mcp-server/test_windows_script_parity.py +336 -0
- package/package.json +110 -112
- package/setup-windows.ps1 +815 -815
- package/src/bmad-detector.js +71 -71
- package/src/cli/list-personalities.js +110 -110
- package/src/cli/list-voices.js +114 -114
- package/src/commands/bmad-voices.js +394 -394
- package/src/commands/install-mcp.js +476 -476
- package/src/console/app.js +824 -806
- package/src/console/audio-env.js +20 -1
- package/src/console/brand-colors.js +13 -13
- package/src/console/constants/personalities.js +44 -0
- package/src/console/footer-config.js +50 -46
- package/src/console/modals/modal-overlay.js +247 -247
- package/src/console/navigation.js +62 -61
- package/src/console/tabs/agents-tab.js +1684 -369
- package/src/console/tabs/help-tab.js +261 -261
- package/src/console/tabs/install-tab.js +1007 -991
- package/src/console/tabs/music-tab.js +22 -8
- package/src/console/tabs/placeholder-tab.js +53 -46
- package/src/console/tabs/readme-tab.js +267 -267
- package/src/console/tabs/receiver-tab.js +1472 -0
- package/src/console/tabs/settings-tab.js +185 -402
- package/src/console/tabs/voices-tab.js +100 -21
- package/src/console/widgets/destroy-list.js +25 -0
- package/src/console/widgets/format-utils.js +89 -0
- package/src/console/widgets/notice.js +55 -0
- package/src/console/widgets/personality-picker.js +185 -0
- package/src/console/widgets/reverb-picker.js +94 -0
- package/src/console/widgets/track-picker.js +285 -0
- package/src/installer/music-file-input.js +304 -304
- package/src/installer.js +5882 -5777
- package/src/services/agent-voice-store.js +423 -163
- package/src/services/config-service.js +264 -264
- package/src/services/navigation-service.js +123 -123
- package/src/services/provider-service.js +132 -132
- package/src/services/verbosity-service.js +157 -157
- package/src/utils/audio-duration-validator.js +298 -298
- package/src/utils/audio-format-validator.js +277 -277
- package/src/utils/dependency-checker.js +469 -466
- package/src/utils/file-ownership-verifier.js +358 -358
- package/src/utils/list-formatter.js +194 -194
- package/src/utils/music-file-validator.js +285 -275
- package/src/utils/preview-list-prompt.js +136 -136
- package/src/utils/provider-validator.js +96 -12
- package/src/utils/secure-music-storage.js +412 -412
- package/templates/agentvibes-receiver.sh +482 -162
- package/templates/audio/welcome-music.mp3 +0 -0
- package/voice-assignments.json +8244 -8244
- package/.claude/config/background-music-position.txt +0 -1
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
File: mcp-server/test_windows_script_parity.py
|
|
4
|
+
|
|
5
|
+
AgentVibes - Finally, your AI Agents can Talk Back! Text-to-Speech WITH personality for AI Assistants!
|
|
6
|
+
Website: https://agentvibes.org
|
|
7
|
+
Repository: https://github.com/paulpreibisch/AgentVibes
|
|
8
|
+
|
|
9
|
+
Co-created by Paul Preibisch with Claude AI
|
|
10
|
+
Copyright (c) 2025 Paul Preibisch
|
|
11
|
+
|
|
12
|
+
Licensed under the Apache License, Version 2.0
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
@fileoverview Windows script parity tests - proves missing scripts break MCP tools
|
|
17
|
+
@context Test-first approach: these tests SHOULD FAIL until Windows scripts are ported
|
|
18
|
+
@architecture pytest-style tests validating script existence and MCP integration
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
import os
|
|
22
|
+
import sys
|
|
23
|
+
import platform
|
|
24
|
+
from pathlib import Path
|
|
25
|
+
|
|
26
|
+
# Add the mcp-server directory to path
|
|
27
|
+
sys.path.insert(0, str(Path(__file__).parent))
|
|
28
|
+
|
|
29
|
+
IS_WINDOWS = platform.system() == "Windows" and not os.environ.get("WSL_DISTRO_NAME")
|
|
30
|
+
|
|
31
|
+
# Resolve project paths
|
|
32
|
+
PROJECT_ROOT = Path(__file__).parent.parent
|
|
33
|
+
HOOKS_WINDOWS = PROJECT_ROOT / ".claude" / "hooks-windows"
|
|
34
|
+
HOOKS_LINUX = PROJECT_ROOT / ".claude" / "hooks"
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# =============================================================
|
|
38
|
+
# Suite 1: Every .sh script called by MCP must have a .ps1
|
|
39
|
+
# =============================================================
|
|
40
|
+
|
|
41
|
+
# Scripts the MCP server calls via _run_script() with hardcoded .sh names
|
|
42
|
+
# The auto-conversion (server.py:902-903) converts .sh -> .ps1
|
|
43
|
+
MCP_HARDCODED_SCRIPTS = [
|
|
44
|
+
"provider-manager",
|
|
45
|
+
"learn-manager",
|
|
46
|
+
"speed-manager",
|
|
47
|
+
"download-extra-voices",
|
|
48
|
+
"verbosity-manager",
|
|
49
|
+
"clean-audio-cache",
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
# Scripts set via class constants (already .ps1 on Windows)
|
|
53
|
+
MCP_CLASS_CONSTANT_SCRIPTS = [
|
|
54
|
+
"voice-manager-windows", # VOICE_MANAGER_SCRIPT override
|
|
55
|
+
"personality-manager", # PERSONALITY_MANAGER_SCRIPT
|
|
56
|
+
"language-manager", # LANGUAGE_MANAGER_SCRIPT
|
|
57
|
+
"background-music-manager", # BACKGROUND_MUSIC_MANAGER_SCRIPT
|
|
58
|
+
"effects-manager", # EFFECTS_MANAGER_SCRIPT
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def test_hardcoded_scripts_have_ps1():
|
|
63
|
+
"""Every .sh script called via _run_script must have a .ps1 in hooks-windows/"""
|
|
64
|
+
print("\nTesting hardcoded .sh -> .ps1 script parity...")
|
|
65
|
+
missing = []
|
|
66
|
+
|
|
67
|
+
for script_name in MCP_HARDCODED_SCRIPTS:
|
|
68
|
+
ps1_path = HOOKS_WINDOWS / f"{script_name}.ps1"
|
|
69
|
+
sh_path = HOOKS_LINUX / f"{script_name}.sh"
|
|
70
|
+
|
|
71
|
+
sh_exists = sh_path.exists()
|
|
72
|
+
ps1_exists = ps1_path.exists()
|
|
73
|
+
|
|
74
|
+
if sh_exists and not ps1_exists:
|
|
75
|
+
missing.append(script_name)
|
|
76
|
+
print(f" FAIL: {script_name}.sh exists but {script_name}.ps1 is MISSING")
|
|
77
|
+
elif ps1_exists:
|
|
78
|
+
print(f" PASS: {script_name}.ps1 exists")
|
|
79
|
+
else:
|
|
80
|
+
print(f" SKIP: {script_name}.sh doesn't exist either")
|
|
81
|
+
|
|
82
|
+
if missing:
|
|
83
|
+
print(f"\n {len(missing)} missing .ps1 scripts: {', '.join(missing)}")
|
|
84
|
+
assert len(missing) == 0, (
|
|
85
|
+
f"Missing Windows scripts for MCP: {', '.join(missing)}. "
|
|
86
|
+
f"These MCP tools silently fail on Windows."
|
|
87
|
+
)
|
|
88
|
+
print(" All hardcoded scripts have .ps1 equivalents")
|
|
89
|
+
return True
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def test_class_constant_scripts_exist():
|
|
93
|
+
"""Every script set via class constants must exist in hooks-windows/"""
|
|
94
|
+
print("\nTesting class constant script existence...")
|
|
95
|
+
missing = []
|
|
96
|
+
|
|
97
|
+
for script_name in MCP_CLASS_CONSTANT_SCRIPTS:
|
|
98
|
+
ps1_path = HOOKS_WINDOWS / f"{script_name}.ps1"
|
|
99
|
+
if not ps1_path.exists():
|
|
100
|
+
missing.append(script_name)
|
|
101
|
+
print(f" FAIL: {script_name}.ps1 is MISSING")
|
|
102
|
+
else:
|
|
103
|
+
print(f" PASS: {script_name}.ps1 exists")
|
|
104
|
+
|
|
105
|
+
if missing:
|
|
106
|
+
print(f"\n {len(missing)} missing .ps1 scripts: {', '.join(missing)}")
|
|
107
|
+
assert len(missing) == 0, (
|
|
108
|
+
f"Missing Windows scripts (class constants): {', '.join(missing)}. "
|
|
109
|
+
f"These MCP tools fail on Windows."
|
|
110
|
+
)
|
|
111
|
+
print(" All class constant scripts exist")
|
|
112
|
+
return True
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
# =============================================================
|
|
116
|
+
# Suite 2: MCP _run_script returns proper errors for missing scripts
|
|
117
|
+
# =============================================================
|
|
118
|
+
|
|
119
|
+
def test_run_script_error_for_missing():
|
|
120
|
+
"""Verify _run_script returns 'Script not found' for missing scripts (Windows only)"""
|
|
121
|
+
if not IS_WINDOWS:
|
|
122
|
+
print("\nSkipping _run_script test (not Windows)")
|
|
123
|
+
return True
|
|
124
|
+
|
|
125
|
+
print("\nTesting _run_script error handling for missing scripts...")
|
|
126
|
+
try:
|
|
127
|
+
from server import AgentVibesServer
|
|
128
|
+
import asyncio
|
|
129
|
+
|
|
130
|
+
server = AgentVibesServer()
|
|
131
|
+
|
|
132
|
+
async def check_missing():
|
|
133
|
+
# Try calling a script we know doesn't exist
|
|
134
|
+
result = await server._run_script("definitely-does-not-exist.ps1", [])
|
|
135
|
+
assert "Script not found" in result, (
|
|
136
|
+
f"Expected 'Script not found' for missing script, got: {result}"
|
|
137
|
+
)
|
|
138
|
+
print(" PASS: _run_script returns 'Script not found' for missing scripts")
|
|
139
|
+
|
|
140
|
+
asyncio.run(check_missing())
|
|
141
|
+
return True
|
|
142
|
+
|
|
143
|
+
except ImportError:
|
|
144
|
+
print(" SKIP: MCP library not installed")
|
|
145
|
+
return True
|
|
146
|
+
except Exception as e:
|
|
147
|
+
print(f" FAIL: {e}")
|
|
148
|
+
return False
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
# =============================================================
|
|
152
|
+
# Suite 3: MCP tools that depend on missing scripts
|
|
153
|
+
# =============================================================
|
|
154
|
+
|
|
155
|
+
MCP_TOOL_SCRIPT_MAP = {
|
|
156
|
+
"set_speed": "speed-manager",
|
|
157
|
+
"get_speed": "speed-manager",
|
|
158
|
+
"set_learn_mode": "learn-manager",
|
|
159
|
+
"set_verbosity": "verbosity-manager",
|
|
160
|
+
"get_verbosity": "verbosity-manager",
|
|
161
|
+
"mute": "verbosity-manager",
|
|
162
|
+
"unmute": "verbosity-manager",
|
|
163
|
+
"is_muted": "verbosity-manager",
|
|
164
|
+
"set_personality": "personality-manager",
|
|
165
|
+
"list_personalities": "personality-manager",
|
|
166
|
+
"set_language": "language-manager",
|
|
167
|
+
"clean_audio_cache": "clean-audio-cache",
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def test_mcp_tools_have_backing_scripts():
|
|
172
|
+
"""Every MCP tool must have its backing script on Windows"""
|
|
173
|
+
print("\nTesting MCP tool -> script mapping on Windows...")
|
|
174
|
+
broken_tools = []
|
|
175
|
+
|
|
176
|
+
for tool_name, script_name in MCP_TOOL_SCRIPT_MAP.items():
|
|
177
|
+
ps1_path = HOOKS_WINDOWS / f"{script_name}.ps1"
|
|
178
|
+
if not ps1_path.exists():
|
|
179
|
+
broken_tools.append((tool_name, script_name))
|
|
180
|
+
print(f" FAIL: MCP tool '{tool_name}' -> {script_name}.ps1 MISSING")
|
|
181
|
+
else:
|
|
182
|
+
print(f" PASS: MCP tool '{tool_name}' -> {script_name}.ps1 exists")
|
|
183
|
+
|
|
184
|
+
if broken_tools:
|
|
185
|
+
tool_list = ", ".join(f"{t[0]} ({t[1]}.ps1)" for t in broken_tools)
|
|
186
|
+
print(f"\n {len(broken_tools)} broken MCP tools: {tool_list}")
|
|
187
|
+
assert len(broken_tools) == 0, (
|
|
188
|
+
f"Broken MCP tools on Windows: "
|
|
189
|
+
+ ", ".join(f"{t[0]}" for t in broken_tools)
|
|
190
|
+
)
|
|
191
|
+
print(" All MCP tools have backing scripts")
|
|
192
|
+
return True
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
# =============================================================
|
|
196
|
+
# Suite 4: Provider naming validation
|
|
197
|
+
# =============================================================
|
|
198
|
+
|
|
199
|
+
def test_provider_names_consistent():
|
|
200
|
+
"""Verify MCP server accepts unified provider names"""
|
|
201
|
+
if not IS_WINDOWS:
|
|
202
|
+
print("\nSkipping provider naming test (not Windows)")
|
|
203
|
+
return True
|
|
204
|
+
|
|
205
|
+
print("\nTesting provider naming consistency...")
|
|
206
|
+
try:
|
|
207
|
+
from server import AgentVibesServer
|
|
208
|
+
|
|
209
|
+
server = AgentVibesServer()
|
|
210
|
+
|
|
211
|
+
# The MCP server hardcodes different valid providers per platform
|
|
212
|
+
# On Windows: ["windows-piper", "windows-sapi", "soprano"]
|
|
213
|
+
# The provider-manager.ps1 also accepts: ["piper", "sapi"]
|
|
214
|
+
# This creates a mismatch where scripts accept names MCP rejects
|
|
215
|
+
|
|
216
|
+
# Read the valid_providers from set_provider source
|
|
217
|
+
import inspect
|
|
218
|
+
source = inspect.getsource(server.set_provider)
|
|
219
|
+
|
|
220
|
+
if "windows-piper" in source and "piper" not in source.replace("windows-piper", ""):
|
|
221
|
+
print(" INFO: MCP only accepts 'windows-piper', not 'piper' on Windows")
|
|
222
|
+
print(" INFO: But provider-manager.ps1 accepts both")
|
|
223
|
+
print(" WARN: This creates a one-way trap - consider unifying to 'piper'")
|
|
224
|
+
|
|
225
|
+
# Check that play-tts scripts match provider names
|
|
226
|
+
for provider in ["piper", "sapi", "soprano"]:
|
|
227
|
+
windows_name = f"play-tts-windows-{provider}.ps1"
|
|
228
|
+
unified_name = f"play-tts-{provider}.ps1"
|
|
229
|
+
has_windows = (HOOKS_WINDOWS / windows_name).exists()
|
|
230
|
+
has_unified = (HOOKS_WINDOWS / unified_name).exists()
|
|
231
|
+
|
|
232
|
+
if has_windows and not has_unified:
|
|
233
|
+
print(f" WARN: {windows_name} exists but {unified_name} does not")
|
|
234
|
+
print(f" Auto-conversion from play-tts-{provider}.sh would look for {unified_name}")
|
|
235
|
+
|
|
236
|
+
print(" Provider naming test complete (warnings above need fixing)")
|
|
237
|
+
return True
|
|
238
|
+
|
|
239
|
+
except ImportError:
|
|
240
|
+
print(" SKIP: MCP library not installed")
|
|
241
|
+
return True
|
|
242
|
+
except Exception as e:
|
|
243
|
+
print(f" FAIL: {e}")
|
|
244
|
+
return False
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
# =============================================================
|
|
248
|
+
# Suite 5: Voice manager naming mismatch
|
|
249
|
+
# =============================================================
|
|
250
|
+
|
|
251
|
+
def test_voice_manager_naming():
|
|
252
|
+
"""voice-manager.sh auto-converts to voice-manager.ps1 but file is voice-manager-windows.ps1"""
|
|
253
|
+
print("\nTesting voice-manager naming consistency...")
|
|
254
|
+
|
|
255
|
+
# The auto-conversion would produce voice-manager.ps1
|
|
256
|
+
auto_converted = HOOKS_WINDOWS / "voice-manager.ps1"
|
|
257
|
+
actual_file = HOOKS_WINDOWS / "voice-manager-windows.ps1"
|
|
258
|
+
linux_file = HOOKS_LINUX / "voice-manager.sh"
|
|
259
|
+
|
|
260
|
+
print(f" Linux script: voice-manager.sh exists = {linux_file.exists()}")
|
|
261
|
+
print(f" Auto-converted name: voice-manager.ps1 exists = {auto_converted.exists()}")
|
|
262
|
+
print(f" Actual Windows file: voice-manager-windows.ps1 exists = {actual_file.exists()}")
|
|
263
|
+
|
|
264
|
+
if actual_file.exists() and not auto_converted.exists():
|
|
265
|
+
print(" WARN: Naming mismatch detected!")
|
|
266
|
+
print(" MCP class constant overrides this, but it's fragile")
|
|
267
|
+
# This is informational, not a hard failure since the class constant handles it
|
|
268
|
+
# But it should be fixed for consistency
|
|
269
|
+
|
|
270
|
+
if linux_file.exists():
|
|
271
|
+
assert auto_converted.exists() or actual_file.exists(), (
|
|
272
|
+
"voice-manager has no Windows equivalent at all"
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
print(" Voice manager naming test complete")
|
|
276
|
+
return True
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
# =============================================================
|
|
280
|
+
# Main
|
|
281
|
+
# =============================================================
|
|
282
|
+
|
|
283
|
+
def main():
|
|
284
|
+
"""Run all parity tests"""
|
|
285
|
+
print("=" * 60)
|
|
286
|
+
print("AgentVibes Windows Script Parity Tests")
|
|
287
|
+
print(f"Platform: {platform.system()} (IS_WINDOWS={IS_WINDOWS})")
|
|
288
|
+
print(f"hooks-windows/: {HOOKS_WINDOWS}")
|
|
289
|
+
print("=" * 60)
|
|
290
|
+
|
|
291
|
+
tests = [
|
|
292
|
+
("Hardcoded .sh scripts have .ps1 equivalents", test_hardcoded_scripts_have_ps1),
|
|
293
|
+
("Class constant scripts exist", test_class_constant_scripts_exist),
|
|
294
|
+
("_run_script error handling", test_run_script_error_for_missing),
|
|
295
|
+
("MCP tools have backing scripts", test_mcp_tools_have_backing_scripts),
|
|
296
|
+
("Provider naming consistency", test_provider_names_consistent),
|
|
297
|
+
("Voice manager naming", test_voice_manager_naming),
|
|
298
|
+
]
|
|
299
|
+
|
|
300
|
+
results = []
|
|
301
|
+
for name, test_func in tests:
|
|
302
|
+
try:
|
|
303
|
+
result = test_func()
|
|
304
|
+
results.append((name, result, None))
|
|
305
|
+
except AssertionError as e:
|
|
306
|
+
print(f"\n ASSERTION FAILED: {e}")
|
|
307
|
+
results.append((name, False, str(e)))
|
|
308
|
+
except Exception as e:
|
|
309
|
+
print(f"\n ERROR: {e}")
|
|
310
|
+
results.append((name, False, str(e)))
|
|
311
|
+
|
|
312
|
+
print("\n" + "=" * 60)
|
|
313
|
+
print("PARITY TEST RESULTS")
|
|
314
|
+
print("=" * 60)
|
|
315
|
+
|
|
316
|
+
passed = sum(1 for _, result, _ in results if result)
|
|
317
|
+
failed = sum(1 for _, result, _ in results if not result)
|
|
318
|
+
|
|
319
|
+
for name, result, error in results:
|
|
320
|
+
status = "PASS" if result else "FAIL"
|
|
321
|
+
print(f" [{status}] {name}")
|
|
322
|
+
if error:
|
|
323
|
+
print(f" {error[:100]}")
|
|
324
|
+
|
|
325
|
+
print("=" * 60)
|
|
326
|
+
print(f"Passed: {passed}/{len(results)} Failed: {failed}/{len(results)}")
|
|
327
|
+
|
|
328
|
+
if failed > 0:
|
|
329
|
+
print(f"\n{failed} test(s) failed — these represent missing Windows scripts")
|
|
330
|
+
print("See GitHub issue #157 for the full platform parity plan")
|
|
331
|
+
|
|
332
|
+
return 1 if failed > 0 else 0
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
if __name__ == "__main__":
|
|
336
|
+
sys.exit(main())
|
package/package.json
CHANGED
|
@@ -1,112 +1,110 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json.schemastore.org/package.json",
|
|
3
|
-
"name": "agentvibes",
|
|
4
|
-
"version": "4.0
|
|
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
|
-
"homepage": "https://agentvibes.org",
|
|
7
|
-
"keywords": [
|
|
8
|
-
"tts",
|
|
9
|
-
"text-to-speech",
|
|
10
|
-
"piper-tts",
|
|
11
|
-
"claude-code",
|
|
12
|
-
"claude-desktop",
|
|
13
|
-
"clawdbot",
|
|
14
|
-
"mcp",
|
|
15
|
-
"model-context-protocol",
|
|
16
|
-
"voice",
|
|
17
|
-
"ai",
|
|
18
|
-
"narration",
|
|
19
|
-
"agent-vibes"
|
|
20
|
-
],
|
|
21
|
-
"repository": {
|
|
22
|
-
"type": "git",
|
|
23
|
-
"url": "git+https://github.com/paulpreibisch/AgentVibes.git"
|
|
24
|
-
},
|
|
25
|
-
"license": "Apache-2.0",
|
|
26
|
-
"author": "Paul Preibisch <paul@paulpreibisch.com>",
|
|
27
|
-
"type": "module",
|
|
28
|
-
"main": "src/installer.js",
|
|
29
|
-
"bin": {
|
|
30
|
-
"agentvibes": "bin/agentvibes.js",
|
|
31
|
-
"agent-vibes": "bin/agent-vibes",
|
|
32
|
-
"agentvibes-mcp-server": "bin/mcp-server.js",
|
|
33
|
-
"agentvibes-voice-browser": "bin/agentvibes-voice-browser.js",
|
|
34
|
-
"test-bmad-pr": "bin/test-bmad-pr"
|
|
35
|
-
},
|
|
36
|
-
"files": [
|
|
37
|
-
"bin/",
|
|
38
|
-
"src/",
|
|
39
|
-
"templates/*.sh",
|
|
40
|
-
"templates/*.md",
|
|
41
|
-
"templates/audio/*.mp3",
|
|
42
|
-
"mcp-server/*.py",
|
|
43
|
-
"mcp-server/*.js",
|
|
44
|
-
"mcp-server/*.md",
|
|
45
|
-
"mcp-server/*.txt",
|
|
46
|
-
"mcp-server/*.toml",
|
|
47
|
-
"mcp-server/*.json",
|
|
48
|
-
"mcp-server/docs/",
|
|
49
|
-
"mcp-server/examples/",
|
|
50
|
-
".claude/commands/agent-vibes/",
|
|
51
|
-
".claude/commands/agent-vibes-bmad-voices.md",
|
|
52
|
-
".claude/commands/agent-vibes-rdp.md",
|
|
53
|
-
".claude/hooks/",
|
|
54
|
-
".claude/hooks-windows/",
|
|
55
|
-
".claude/personalities/",
|
|
56
|
-
".claude/output-styles/",
|
|
57
|
-
".claude/audio/tracks/",
|
|
58
|
-
".claude/config/",
|
|
59
|
-
".claude/docs/",
|
|
60
|
-
".claude/language-voices.yaml",
|
|
61
|
-
".claude/settings.json",
|
|
62
|
-
".claude/activation-instructions",
|
|
63
|
-
".claude/piper-voices-dir.txt",
|
|
64
|
-
".claude/verbosity.txt",
|
|
65
|
-
".claude/github-star-reminder.txt",
|
|
66
|
-
".claude/audio/voice-samples/",
|
|
67
|
-
"voice-assignments.json",
|
|
68
|
-
".agentvibes/",
|
|
69
|
-
".clawdbot/",
|
|
70
|
-
".mcp.json",
|
|
71
|
-
"setup-windows.ps1",
|
|
72
|
-
"WINDOWS-SETUP.md",
|
|
73
|
-
"README.md",
|
|
74
|
-
"RELEASE_NOTES.md",
|
|
75
|
-
"LICENSE",
|
|
76
|
-
"CLAUDE.md"
|
|
77
|
-
],
|
|
78
|
-
"scripts": {
|
|
79
|
-
"install-local": "node src/installer.js install",
|
|
80
|
-
"postinstall": "node mcp-server/install-deps.js",
|
|
81
|
-
"install-mcp-deps": "node mcp-server/install-deps.js",
|
|
82
|
-
"voice-browser": "node bin/agentvibes-voice-browser.js",
|
|
83
|
-
"test": "npm run test:syntax && AGENTVIBES_TEST_MODE=true bats test/unit/*.bats && npm run test:coverage",
|
|
84
|
-
"test:syntax": "node -c src/installer.js && node -c mcp-server/install-deps.js",
|
|
85
|
-
"test:bats": "AGENTVIBES_TEST_MODE=true bats test/unit/*.bats",
|
|
86
|
-
"test:node": "node --test test/unit/*.test.js",
|
|
87
|
-
"test:coverage": "c8 --reporter=lcov --reporter=text node --test test/unit/*.test.js",
|
|
88
|
-
"test:verbose": "AGENTVIBES_TEST_MODE=true bats -t test/unit/*.bats"
|
|
89
|
-
},
|
|
90
|
-
"dependencies": {
|
|
91
|
-
"@inquirer/search": "^3.1.3",
|
|
92
|
-
"
|
|
93
|
-
"
|
|
94
|
-
"
|
|
95
|
-
"
|
|
96
|
-
"
|
|
97
|
-
"
|
|
98
|
-
"
|
|
99
|
-
"
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
112
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/package.json",
|
|
3
|
+
"name": "agentvibes",
|
|
4
|
+
"version": "4.4.0",
|
|
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
|
+
"homepage": "https://agentvibes.org",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"tts",
|
|
9
|
+
"text-to-speech",
|
|
10
|
+
"piper-tts",
|
|
11
|
+
"claude-code",
|
|
12
|
+
"claude-desktop",
|
|
13
|
+
"clawdbot",
|
|
14
|
+
"mcp",
|
|
15
|
+
"model-context-protocol",
|
|
16
|
+
"voice",
|
|
17
|
+
"ai",
|
|
18
|
+
"narration",
|
|
19
|
+
"agent-vibes"
|
|
20
|
+
],
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/paulpreibisch/AgentVibes.git"
|
|
24
|
+
},
|
|
25
|
+
"license": "Apache-2.0",
|
|
26
|
+
"author": "Paul Preibisch <paul@paulpreibisch.com>",
|
|
27
|
+
"type": "module",
|
|
28
|
+
"main": "src/installer.js",
|
|
29
|
+
"bin": {
|
|
30
|
+
"agentvibes": "bin/agentvibes.js",
|
|
31
|
+
"agent-vibes": "bin/agent-vibes",
|
|
32
|
+
"agentvibes-mcp-server": "bin/mcp-server.js",
|
|
33
|
+
"agentvibes-voice-browser": "bin/agentvibes-voice-browser.js",
|
|
34
|
+
"test-bmad-pr": "bin/test-bmad-pr"
|
|
35
|
+
},
|
|
36
|
+
"files": [
|
|
37
|
+
"bin/",
|
|
38
|
+
"src/",
|
|
39
|
+
"templates/*.sh",
|
|
40
|
+
"templates/*.md",
|
|
41
|
+
"templates/audio/*.mp3",
|
|
42
|
+
"mcp-server/*.py",
|
|
43
|
+
"mcp-server/*.js",
|
|
44
|
+
"mcp-server/*.md",
|
|
45
|
+
"mcp-server/*.txt",
|
|
46
|
+
"mcp-server/*.toml",
|
|
47
|
+
"mcp-server/*.json",
|
|
48
|
+
"mcp-server/docs/",
|
|
49
|
+
"mcp-server/examples/",
|
|
50
|
+
".claude/commands/agent-vibes/",
|
|
51
|
+
".claude/commands/agent-vibes-bmad-voices.md",
|
|
52
|
+
".claude/commands/agent-vibes-rdp.md",
|
|
53
|
+
".claude/hooks/",
|
|
54
|
+
".claude/hooks-windows/",
|
|
55
|
+
".claude/personalities/",
|
|
56
|
+
".claude/output-styles/",
|
|
57
|
+
".claude/audio/tracks/",
|
|
58
|
+
".claude/config/",
|
|
59
|
+
".claude/docs/",
|
|
60
|
+
".claude/language-voices.yaml",
|
|
61
|
+
".claude/settings.json",
|
|
62
|
+
".claude/activation-instructions",
|
|
63
|
+
".claude/piper-voices-dir.txt",
|
|
64
|
+
".claude/verbosity.txt",
|
|
65
|
+
".claude/github-star-reminder.txt",
|
|
66
|
+
".claude/audio/voice-samples/",
|
|
67
|
+
"voice-assignments.json",
|
|
68
|
+
".agentvibes/",
|
|
69
|
+
".clawdbot/",
|
|
70
|
+
".mcp.json",
|
|
71
|
+
"setup-windows.ps1",
|
|
72
|
+
"WINDOWS-SETUP.md",
|
|
73
|
+
"README.md",
|
|
74
|
+
"RELEASE_NOTES.md",
|
|
75
|
+
"LICENSE",
|
|
76
|
+
"CLAUDE.md"
|
|
77
|
+
],
|
|
78
|
+
"scripts": {
|
|
79
|
+
"install-local": "node src/installer.js install",
|
|
80
|
+
"postinstall": "node mcp-server/install-deps.js",
|
|
81
|
+
"install-mcp-deps": "node mcp-server/install-deps.js",
|
|
82
|
+
"voice-browser": "node bin/agentvibes-voice-browser.js",
|
|
83
|
+
"test": "npm run test:syntax && AGENTVIBES_TEST_MODE=true bats test/unit/*.bats && npm run test:coverage",
|
|
84
|
+
"test:syntax": "node -c src/installer.js && node -c mcp-server/install-deps.js",
|
|
85
|
+
"test:bats": "AGENTVIBES_TEST_MODE=true bats test/unit/*.bats",
|
|
86
|
+
"test:node": "node --test test/unit/*.test.js",
|
|
87
|
+
"test:coverage": "c8 --reporter=lcov --reporter=text node --test test/unit/*.test.js",
|
|
88
|
+
"test:verbose": "AGENTVIBES_TEST_MODE=true bats -t test/unit/*.bats"
|
|
89
|
+
},
|
|
90
|
+
"dependencies": {
|
|
91
|
+
"@inquirer/search": "^3.1.3",
|
|
92
|
+
"blessed": "^0.1.81",
|
|
93
|
+
"boxen": "^7.0.0",
|
|
94
|
+
"chalk": "^5.0.0",
|
|
95
|
+
"commander": "^10.0.0",
|
|
96
|
+
"figlet": "^1.6.0",
|
|
97
|
+
"inquirer": "^12.0.0",
|
|
98
|
+
"js-yaml": "^4.1.1",
|
|
99
|
+
"ora": "^6.0.0"
|
|
100
|
+
},
|
|
101
|
+
"engines": {
|
|
102
|
+
"node": ">=16.0.0"
|
|
103
|
+
},
|
|
104
|
+
"publishConfig": {
|
|
105
|
+
"access": "public"
|
|
106
|
+
},
|
|
107
|
+
"devDependencies": {
|
|
108
|
+
"c8": "^10.1.3"
|
|
109
|
+
}
|
|
110
|
+
}
|