agentvibes 5.11.2 → 5.12.0-alpha.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 +1 -15
- package/.claude/activation-instructions +54 -54
- package/.claude/commands/agent-vibes-bmad-voices.md +117 -117
- package/.claude/commands/agent-vibes-rdp.md +24 -24
- package/.claude/config/audio-effects.cfg +5 -5
- package/.claude/config/background-music-enabled.txt +1 -1
- package/.claude/docs/TERMUX_SETUP.md +408 -408
- package/.claude/github-star-reminder.txt +1 -1
- package/.claude/hooks/audio-processor.sh +1 -1
- package/.claude/hooks/background-music-manager.sh +2 -1
- package/.claude/hooks/bmad-speak-enhanced.sh +37 -22
- package/.claude/hooks/bmad-speak.sh +26 -8
- package/.claude/hooks/play-tts-agentvibes-receiver-for-voiceless-connections.sh +1 -1
- package/.claude/hooks/play-tts-kokoro.sh +9 -0
- package/.claude/hooks/play-tts-piper.sh +13 -1
- package/.claude/hooks/play-tts-ssh-remote.sh +78 -5
- package/.claude/hooks/play-tts-termux-ssh.sh +1 -1
- package/.claude/hooks/play-tts.sh +85 -4
- package/.claude/hooks-windows/background-music-manager.ps1 +2 -1
- package/.claude/hooks-windows/play-tts-kokoro.ps1 +14 -0
- package/.claude/hooks-windows/play-tts.ps1 +163 -30
- package/.claude/hooks-windows/voice-manager-windows.ps1 +101 -1
- package/.clawdbot/README.md +105 -105
- package/LICENSE +190 -190
- package/RELEASE_NOTES.md +29 -0
- package/WINDOWS-SETUP.md +208 -208
- package/bin/agent-vibes +39 -39
- package/bin/mcp-server.js +121 -121
- package/bin/mcp-server.sh +6 -19
- package/bin/resolve-utterance.js +137 -0
- 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/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/pyproject.toml +52 -52
- package/mcp-server/requirements.txt +2 -2
- package/mcp-server/server.py +280 -99
- package/mcp-server/test_mcp_correctness.py +486 -0
- package/mcp-server/test_server.py +395 -395
- package/mcp-server/test_windows_script_parity.py +341 -336
- package/package.json +3 -2
- package/setup-windows.ps1 +867 -815
- 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/console/app.js +13 -2
- package/src/console/brand-colors.js +13 -13
- package/src/console/constants/personalities.js +44 -44
- package/src/console/tabs/agents-tab.js +82 -9
- package/src/console/tabs/help-tab.js +314 -314
- package/src/console/tabs/music-tab.js +7 -1
- package/src/console/tabs/readme-tab.js +272 -272
- package/src/console/tabs/settings-tab.js +29 -1
- package/src/console/tabs/setup-tab.js +4 -4
- package/src/console/widgets/destroy-list.js +25 -25
- package/src/console/widgets/notice.js +55 -55
- package/src/console/widgets/track-picker.js +3 -3
- package/src/i18n/de.js +0 -1
- package/src/i18n/en.js +0 -1
- package/src/i18n/es.js +0 -1
- package/src/i18n/fr.js +0 -1
- package/src/i18n/hi.js +0 -1
- package/src/i18n/ja.js +0 -1
- package/src/i18n/ko.js +0 -1
- package/src/i18n/pt.js +0 -1
- package/src/i18n/zh-CN.js +0 -1
- package/src/installer/language-screen.js +31 -31
- package/src/installer/music-file-input.js +304 -304
- package/src/installer.js +205 -15
- package/src/services/config-service.js +264 -264
- package/src/services/language-service.js +47 -47
- package/src/services/llm-provider-service.js +7 -7
- package/src/services/utterance-loader.js +280 -0
- package/src/services/utterance-resolver.js +526 -0
- package/src/utils/audio-format-validator.js +277 -277
- package/src/utils/dependency-checker.js +469 -469
- package/src/utils/file-ownership-verifier.js +358 -358
- package/src/utils/music-file-validator.js +285 -285
- package/src/utils/preview-list-prompt.js +144 -144
- package/src/utils/secure-music-storage.js +412 -412
- package/templates/agentvibes-receiver.sh +74 -12
- package/voice-assignments.json +8245 -0
- package/.agentvibes/install-manifest.json +0 -342
- package/.claude/config/background-music-position.txt +0 -27
- package/.claude/config/background-music-volume.txt +0 -1
- package/.claude/config/background-music.cfg +0 -1
- package/.claude/config/background-music.txt +0 -1
- package/.claude/config/language.txt +0 -1
- package/.claude/config/personality.txt +0 -1
- package/.claude/config/tts-speech-rate.txt +0 -1
- package/.claude/config/tts-verbosity.txt +0 -1
- package/.claude/hooks-windows/audio-cache-utils.ps1.user.bak +0 -119
- package/.claude/hooks-windows/soprano-gradio-synth.py.user.bak +0 -153
- package/.claude/piper-voices-dir.txt +0 -1
- package/.mcp.json +0 -22
|
@@ -213,7 +213,7 @@ if ($BgEnabled -or $HasReverb) {
|
|
|
213
213
|
# 1. Key - Must start with "llm:" followed by the LLM name
|
|
214
214
|
# 2. REVERB_PRESET - One of: off, light, medium, heavy, cathedral (or blank)
|
|
215
215
|
# 3. BACKGROUND_FILE - Filename relative to .claude/audio/tracks/ (or blank)
|
|
216
|
-
# 4. BACKGROUND_VOLUME - Float 0.0-1.0 (or blank for default 0.
|
|
216
|
+
# 4. BACKGROUND_VOLUME - Float 0.0-1.0 (or blank for default 0.20)
|
|
217
217
|
# 5. VOICE - Provider voice name to use (or blank for global default)
|
|
218
218
|
# 6. PRETEXT - Text prepended to all TTS utterances (or blank)
|
|
219
219
|
# 7. ENGINE - Windows engine: windows-sapi, windows-piper, soprano (or blank)
|
|
@@ -263,6 +263,99 @@ if (-not $llm) {
|
|
|
263
263
|
# the POSIX play-tts.sh so the cross-platform contract is symmetric.
|
|
264
264
|
$env:AGENTVIBES_LLM_KEY = "llm:$llm"
|
|
265
265
|
|
|
266
|
+
# ── Utterance Resolver (AVI-S8.5 Stage 2) ────────────────────────────────────
|
|
267
|
+
# Single source of truth for the voice + engine decision, mirroring the bash
|
|
268
|
+
# play-tts.sh port. Resolve the plan ONCE and adopt its voice (per-LLM voice
|
|
269
|
+
# wins over an LLM-echoed explicit override — R2) and, below, its local engine
|
|
270
|
+
# (a kokoro-shaped voice forces the kokoro engine and engine aliases normalize —
|
|
271
|
+
# R1/F5). FAIL-SAFE: if node or the resolver bundle isn't reachable (e.g. an
|
|
272
|
+
# installed ~/.claude that predates the bundle-shipping installer), $PlanOk
|
|
273
|
+
# stays $false and the legacy logic below runs unchanged — Windows TTS never
|
|
274
|
+
# breaks on a missing bridge. AGENTVIBES_RESOLVER_CLI lets the installer (or
|
|
275
|
+
# tests) point at the resolver bundle when it lives outside the hooks tree.
|
|
276
|
+
|
|
277
|
+
# Map a resolver engine name to its Windows provider script. Returns $null for
|
|
278
|
+
# engines with no local Windows script (e.g. elevenlabs/macos) so the caller
|
|
279
|
+
# keeps the current provider rather than breaking playback.
|
|
280
|
+
function Resolve-ProviderScriptForEngine {
|
|
281
|
+
param([string]$Engine, [string]$HooksRoot)
|
|
282
|
+
switch ($Engine) {
|
|
283
|
+
{ $_ -in "windows-sapi", "sapi" } {
|
|
284
|
+
$s = "$HooksRoot\play-tts-sapi.ps1"
|
|
285
|
+
if (-not (Test-Path $s)) { $s = "$HooksRoot\play-tts-windows-sapi.ps1" }
|
|
286
|
+
return $s
|
|
287
|
+
}
|
|
288
|
+
{ $_ -in "windows-piper", "piper" } {
|
|
289
|
+
$s = "$HooksRoot\play-tts-piper.ps1"
|
|
290
|
+
if (-not (Test-Path $s)) { $s = "$HooksRoot\play-tts-windows-piper.ps1" }
|
|
291
|
+
return $s
|
|
292
|
+
}
|
|
293
|
+
"soprano" { return "$HooksRoot\play-tts-soprano.ps1" }
|
|
294
|
+
"kokoro" { return "$HooksRoot\play-tts-kokoro.ps1" }
|
|
295
|
+
default { return $null }
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
$_OrigExplicitVoice = $VoiceOverride # raw positional voice, before any per-LLM override
|
|
300
|
+
$PlanOk = $false
|
|
301
|
+
$PlanVoice = ""
|
|
302
|
+
$PlanEngine = ""
|
|
303
|
+
$PlanVoiceIsOverride = $false
|
|
304
|
+
# F-3: the SSH-receiver watcher forwards the sender's engine via -ProviderOverride
|
|
305
|
+
# (a parameter the resolver can't see). Seed AGENTVIBES_FORCE_PROVIDER from it so
|
|
306
|
+
# the resolver honors the forwarded provider instead of defaulting the plan engine
|
|
307
|
+
# to piper (which dropped a forwarded windows-sapi/soprano voice → wrong/no audio).
|
|
308
|
+
if ($ProviderOverride) {
|
|
309
|
+
# A fresh -ProviderOverride for THIS request must win over any stale/inherited
|
|
310
|
+
# AGENTVIBES_FORCE_PROVIDER in the environment (a validated allowlist only).
|
|
311
|
+
switch ($ProviderOverride) {
|
|
312
|
+
{ $_ -in @('piper','soprano','macos','windows-sapi','sapi','kokoro','elevenlabs','windows-piper') } {
|
|
313
|
+
$env:AGENTVIBES_FORCE_PROVIDER = $ProviderOverride
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
$_ResolverCli = ""
|
|
318
|
+
foreach ($_cand in @(
|
|
319
|
+
$env:AGENTVIBES_RESOLVER_CLI,
|
|
320
|
+
(Join-Path $ScriptPath "..\agentvibes-resolver\bin\resolve-utterance.js"),
|
|
321
|
+
(Join-Path $ScriptPath "..\..\bin\resolve-utterance.js"),
|
|
322
|
+
(Join-Path $ScriptPath "resolve-utterance.js"))) {
|
|
323
|
+
if ($_cand -and (Test-Path $_cand)) { $_ResolverCli = $_cand; break }
|
|
324
|
+
}
|
|
325
|
+
$_NodeCmd = Get-Command node -ErrorAction SilentlyContinue
|
|
326
|
+
if ($_ResolverCli -and $_NodeCmd) {
|
|
327
|
+
# Voice provenance (F-1): AGENTVIBES_VOICE_SOURCE lets a caller declare it
|
|
328
|
+
# (MCP/watcher → user-explicit/agent-profile); audition never demotes; else
|
|
329
|
+
# llm-echo (parroted get_config voice, which the per-LLM row overrides — R2).
|
|
330
|
+
$_VoiceSource = if ($env:AGENTVIBES_VOICE_SOURCE) { $env:AGENTVIBES_VOICE_SOURCE }
|
|
331
|
+
elseif ($env:AGENTVIBES_EFFECTS_PREVIEW) { "audition" }
|
|
332
|
+
else { "llm-echo" }
|
|
333
|
+
$_ResolverPackageRoot = Split-Path -Parent $ClaudeDir
|
|
334
|
+
$_ResolverProjectDir = if ($env:CLAUDE_PROJECT_DIR) { $env:CLAUDE_PROJECT_DIR } else { $_ResolverPackageRoot }
|
|
335
|
+
$_ResolverArgs = @('--format', 'json', '--text', $Text, '--llm', $llm,
|
|
336
|
+
'--voice-source', $_VoiceSource, '--project-dir', $_ResolverProjectDir,
|
|
337
|
+
'--package-root', $_ResolverPackageRoot)
|
|
338
|
+
# Only pass --voice when there IS an explicit voice; an absent flag tells the
|
|
339
|
+
# resolver "no explicit override" (so per-LLM routing applies cleanly).
|
|
340
|
+
if ($_OrigExplicitVoice) { $_ResolverArgs += @('--voice', $_OrigExplicitVoice) }
|
|
341
|
+
try {
|
|
342
|
+
$_PlanJson = & $_NodeCmd.Source $_ResolverCli @_ResolverArgs 2>$null
|
|
343
|
+
if ($LASTEXITCODE -eq 0 -and $_PlanJson) {
|
|
344
|
+
$_Plan = ($_PlanJson | Out-String).Trim() | ConvertFrom-Json
|
|
345
|
+
if ($_Plan) {
|
|
346
|
+
$PlanOk = $true
|
|
347
|
+
if ($_Plan.voice) { $PlanVoice = [string]$_Plan.voice }
|
|
348
|
+
if ($_Plan.engine) { $PlanEngine = [string]$_Plan.engine }
|
|
349
|
+
$PlanVoiceIsOverride = [bool]$_Plan.voiceIsOverride
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
} catch {
|
|
353
|
+
# Any bridge failure (bad JSON, nonzero exit, missing bundle) fails safe
|
|
354
|
+
# to the legacy logic below.
|
|
355
|
+
$PlanOk = $false
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
266
359
|
# --- Lookup per-LLM config in audio-effects.cfg ------------------------------
|
|
267
360
|
# Scan project config first, then user-profile config. Stop at first match.
|
|
268
361
|
# Variables are intentionally prefixed with _ to distinguish LLM-local state
|
|
@@ -320,8 +413,20 @@ $_LlmFound = $false
|
|
|
320
413
|
# 3. BMAD agent voice from bmad-voice-map.json (resolved in provider scripts)
|
|
321
414
|
# 4. Global active voice from tts-provider.txt / active-voice.txt
|
|
322
415
|
|
|
323
|
-
#
|
|
324
|
-
|
|
416
|
+
# Adopt the resolver's voice when a plan resolved (AVI-S8.5 Stage 2). The plan
|
|
417
|
+
# already applied the R2 precedence (per-LLM voice wins over an LLM-echoed
|
|
418
|
+
# explicit override; genuine explicit/audition voices still win), so take it
|
|
419
|
+
# verbatim. FAIL-SAFE fallback: with no plan, use the legacy explicit-wins order
|
|
420
|
+
# (explicit -VoiceOverride > per-LLM voice).
|
|
421
|
+
# F-2: adopt the plan voice ONLY when it's a real override (explicit pick or
|
|
422
|
+
# per-LLM row) — not the provider's stored voice file. A plain provider-file
|
|
423
|
+
# voice is left empty here so the provider script does its own file+model+speaker
|
|
424
|
+
# resolution (adopting it as an explicit override skips piper's multi-speaker
|
|
425
|
+
# lookup and plays speaker 0). Engine coupling (R1) still applies regardless.
|
|
426
|
+
if ($PlanOk -and $PlanVoiceIsOverride -and $PlanVoice) {
|
|
427
|
+
$VoiceOverride = $PlanVoice
|
|
428
|
+
}
|
|
429
|
+
elseif (-not $PlanOk -and $_LlmVoice -and -not $VoiceOverride) {
|
|
325
430
|
$VoiceOverride = $_LlmVoice
|
|
326
431
|
}
|
|
327
432
|
|
|
@@ -398,31 +503,45 @@ if ($OverrideEffects -ne "" -and $OverrideEffects -in @("off", "light", "medium"
|
|
|
398
503
|
# piper/sapi for that LLM's normal text responses that use Piper voices — must
|
|
399
504
|
# NOT redirect it to an incompatible engine, or synthesis fails silently
|
|
400
505
|
# (Piper can't find the Kokoro voice model → no audio, exit 0).
|
|
401
|
-
$
|
|
402
|
-
|
|
403
|
-
#
|
|
404
|
-
#
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
#
|
|
412
|
-
#
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
"
|
|
423
|
-
"
|
|
424
|
-
|
|
425
|
-
|
|
506
|
+
if ($PlanOk -and $PlanEngine) {
|
|
507
|
+
# Resolver plan is authoritative for the LOCAL engine (AVI-S8.5 Stage 2):
|
|
508
|
+
# this cures the kokoro/piper voice->engine coupling (R1) and normalizes
|
|
509
|
+
# engine aliases like windows-sapi->sapi (F5), replacing the legacy heuristic
|
|
510
|
+
# below. An engine with no local Windows script (elevenlabs/macos) leaves the
|
|
511
|
+
# current provider in place.
|
|
512
|
+
$_PlanScript = Resolve-ProviderScriptForEngine -Engine $PlanEngine -HooksRoot $HooksDir
|
|
513
|
+
if ($_PlanScript) { $ProviderScript = $_PlanScript }
|
|
514
|
+
}
|
|
515
|
+
else {
|
|
516
|
+
# Legacy voice->engine heuristic — ONLY on the fallback path (no resolver
|
|
517
|
+
# plan). When a plan resolved, the resolver already coupled voice->engine
|
|
518
|
+
# correctly above, so this is skipped.
|
|
519
|
+
$_VoiceIsKokoro = $VoiceOverride -match '^[a-z]{2}_[a-z0-9_]+$'
|
|
520
|
+
if ($_VoiceIsKokoro) {
|
|
521
|
+
# A Kokoro-format voice forces the Kokoro engine regardless of the per-LLM
|
|
522
|
+
# ENGINE column or the global tts-provider.txt default.
|
|
523
|
+
$ProviderScript = "$HooksDir\play-tts-kokoro.ps1"
|
|
524
|
+
}
|
|
525
|
+
elseif ($_LlmEngine) {
|
|
526
|
+
# Accept both canonical Windows names and the cross-platform aliases the TUI
|
|
527
|
+
# writes (e.g. "piper" saved on a Linux/WSL install that is later read on
|
|
528
|
+
# Windows, or "sapi" as a short form). Unknown values keep the global default.
|
|
529
|
+
# Mirror the global-provider switch: prefer the PS-5.1-compatible script name,
|
|
530
|
+
# fall back to the alternate name if the first doesn't exist on disk.
|
|
531
|
+
switch ($_LlmEngine) {
|
|
532
|
+
{ $_ -in "windows-sapi", "sapi" } {
|
|
533
|
+
$ProviderScript = "$HooksDir\play-tts-sapi.ps1"
|
|
534
|
+
if (-not (Test-Path $ProviderScript)) { $ProviderScript = "$HooksDir\play-tts-windows-sapi.ps1" }
|
|
535
|
+
}
|
|
536
|
+
{ $_ -in "windows-piper", "piper" } {
|
|
537
|
+
$ProviderScript = "$HooksDir\play-tts-piper.ps1"
|
|
538
|
+
if (-not (Test-Path $ProviderScript)) { $ProviderScript = "$HooksDir\play-tts-windows-piper.ps1" }
|
|
539
|
+
}
|
|
540
|
+
"soprano" { $ProviderScript = "$HooksDir\play-tts-soprano.ps1" }
|
|
541
|
+
"kokoro" { $ProviderScript = "$HooksDir\play-tts-kokoro.ps1" }
|
|
542
|
+
default {
|
|
543
|
+
Write-Host "[INFO] play-tts.ps1: Unrecognised engine '$_LlmEngine' — keeping default provider" -ForegroundColor DarkGray
|
|
544
|
+
}
|
|
426
545
|
}
|
|
427
546
|
}
|
|
428
547
|
}
|
|
@@ -437,7 +556,20 @@ elseif ($_LlmEngine) {
|
|
|
437
556
|
|
|
438
557
|
# --- Diagnostic output -------------------------------------------------------
|
|
439
558
|
# Set AGENTVIBES_VERBOSE=1 in the shell environment to print routing state.
|
|
559
|
+
# The bare `provider=`/`voice=`/`plan=` lines mirror play-tts.sh's verbose
|
|
560
|
+
# DECISION echo so the resolved engine/voice can be characterization-tested
|
|
561
|
+
# without producing real audio (see test/windows/play-tts-resolver.Tests.ps1).
|
|
440
562
|
if ($env:AGENTVIBES_VERBOSE -eq "1") {
|
|
563
|
+
$_ProviderName = switch -Wildcard ($ProviderScript) {
|
|
564
|
+
"*play-tts-kokoro.ps1" { "kokoro" }
|
|
565
|
+
"*soprano*" { "soprano" }
|
|
566
|
+
"*piper*" { "piper" }
|
|
567
|
+
"*sapi*" { "sapi" }
|
|
568
|
+
default { Split-Path -Leaf $ProviderScript }
|
|
569
|
+
}
|
|
570
|
+
Write-Output "provider=$_ProviderName"
|
|
571
|
+
Write-Output "voice=$VoiceOverride"
|
|
572
|
+
Write-Output ("plan=" + $(if ($PlanOk) { "ok" } else { "fallback" }))
|
|
441
573
|
Write-Host "[DEBUG] play-tts.ps1 LLM routing: llm=$llm | voice=$VoiceOverride | engine=$_LlmEngine | pretext=$_LlmPretext" -ForegroundColor DarkCyan
|
|
442
574
|
Write-Host "[DEBUG] play-tts.ps1 LLM routing: reverb=$ReverbLevel | HasFfmpeg=$HasFfmpeg | BgEnabled=$BgEnabled | script=$ProviderScript" -ForegroundColor DarkCyan
|
|
443
575
|
}
|
|
@@ -574,8 +706,9 @@ if (($BgEnabled -or $HasReverb) -and $HasFfmpeg) {
|
|
|
574
706
|
$BgTrackPath = Join-Path $TracksDir "agent_vibes_bachata_v1_loop.mp3"
|
|
575
707
|
}
|
|
576
708
|
|
|
577
|
-
# Get volume (default 0.
|
|
578
|
-
|
|
709
|
+
# Get volume (default 0.20) — per-message override takes precedence
|
|
710
|
+
# TODO(AVI-S8.6): generate this constant from the shared JSON source of truth.
|
|
711
|
+
$BgVolume = "0.20"
|
|
579
712
|
$VolumeFile = "$ConfigDir\background-music-volume.txt"
|
|
580
713
|
if (Test-Path $VolumeFile) {
|
|
581
714
|
$vol = (Get-Content $VolumeFile -Raw).Trim()
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
param(
|
|
8
8
|
[Parameter(Position = 0)]
|
|
9
|
-
[ValidateSet('list', 'switch', 'get')]
|
|
9
|
+
[ValidateSet('list', 'switch', 'get', 'replay')]
|
|
10
10
|
[string]$Command = 'list',
|
|
11
11
|
|
|
12
12
|
[Parameter(Position = 1)]
|
|
@@ -155,6 +155,102 @@ function Show-CurrentVoice {
|
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
+
# Play an audio file without blocking the caller (mirrors voice-manager.sh's
|
|
159
|
+
# `afplay "$AUDIO_FILE" &` / `paplay ... &` background playback). Prefers
|
|
160
|
+
# ffplay (handles wav/mp3/aiff); falls back to System.Media.SoundPlayer
|
|
161
|
+
# (.Play(), which is inherently async — wav only).
|
|
162
|
+
function Start-ReplayPlayback {
|
|
163
|
+
param([string]$FilePath)
|
|
164
|
+
|
|
165
|
+
# Stay silent while the automated test suite is running (same convention
|
|
166
|
+
# as play-tts.ps1's Invoke-AudioPlay).
|
|
167
|
+
if (Test-Path (Join-Path $env:USERPROFILE ".agentvibes-tests-running")) { return }
|
|
168
|
+
|
|
169
|
+
$ffplayCmd = Get-Command ffplay -ErrorAction SilentlyContinue
|
|
170
|
+
if ($ffplayCmd) {
|
|
171
|
+
Start-Process -FilePath $ffplayCmd.Source `
|
|
172
|
+
-ArgumentList @("-autoexit", "-nodisp", "-loglevel", "quiet", $FilePath) `
|
|
173
|
+
-WindowStyle Hidden | Out-Null
|
|
174
|
+
return
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
try {
|
|
178
|
+
$player = New-Object System.Media.SoundPlayer $FilePath
|
|
179
|
+
$player.Play()
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
Write-Host "[WARN] Could not start playback: $_" -ForegroundColor Yellow
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
# Replay the Nth most recent TTS audio file (mirrors voice-manager.sh's
|
|
187
|
+
# `replay` case: resolve the audio dir, validate N (1-10), pick the file by
|
|
188
|
+
# most-recent-mtime, and play it in the background).
|
|
189
|
+
function Replay-Audio {
|
|
190
|
+
param([string]$NArg)
|
|
191
|
+
|
|
192
|
+
$AudioDir = $null
|
|
193
|
+
if ($env:CLAUDE_PROJECT_DIR -and (Test-Path (Join-Path $env:CLAUDE_PROJECT_DIR ".claude"))) {
|
|
194
|
+
$AudioDir = Join-Path $env:CLAUDE_PROJECT_DIR ".claude\audio"
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
# Walk up from cwd looking for a .claude directory (same fallback as voice-manager.sh).
|
|
198
|
+
# Use a plain string path throughout: Get-Location returns a PathInfo (.Path),
|
|
199
|
+
# but Get-Item returns a DirectoryInfo (no .Path) — mixing them made the second
|
|
200
|
+
# iteration do Join-Path $null and throw a terminating error.
|
|
201
|
+
$dirPath = (Get-Location).Path
|
|
202
|
+
while ($dirPath) {
|
|
203
|
+
$candidate = Join-Path $dirPath ".claude"
|
|
204
|
+
if (Test-Path $candidate) {
|
|
205
|
+
$AudioDir = Join-Path $candidate "audio"
|
|
206
|
+
break
|
|
207
|
+
}
|
|
208
|
+
$parent = Split-Path $dirPath -Parent
|
|
209
|
+
if (-not $parent -or $parent -eq $dirPath) { break }
|
|
210
|
+
$dirPath = $parent
|
|
211
|
+
}
|
|
212
|
+
if (-not $AudioDir) {
|
|
213
|
+
$AudioDir = Join-Path $ClaudeDir "audio"
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
$N = 1
|
|
218
|
+
if ($NArg) {
|
|
219
|
+
if ($NArg -notmatch '^\d+$') {
|
|
220
|
+
Write-Host "[ERROR] Invalid argument. Please use a number (1-10)" -ForegroundColor Red
|
|
221
|
+
exit 1
|
|
222
|
+
}
|
|
223
|
+
$N = [int]$NArg
|
|
224
|
+
}
|
|
225
|
+
if ($N -lt 1 -or $N -gt 10) {
|
|
226
|
+
Write-Host "[ERROR] Number out of range. Please choose 1-10" -ForegroundColor Red
|
|
227
|
+
exit 1
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (-not (Test-Path $AudioDir)) {
|
|
231
|
+
Write-Host "[ERROR] No audio history found" -ForegroundColor Red
|
|
232
|
+
Write-Host "Audio files are stored in: $AudioDir"
|
|
233
|
+
exit 1
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
$files = @(Get-ChildItem -Path $AudioDir -File -ErrorAction SilentlyContinue |
|
|
237
|
+
Where-Object { $_.Name -match '^tts-.*\.(wav|mp3|aiff)$' } |
|
|
238
|
+
Sort-Object LastWriteTime -Descending)
|
|
239
|
+
|
|
240
|
+
if ($files.Count -lt $N) {
|
|
241
|
+
Write-Host "[ERROR] Audio #$N not found in history" -ForegroundColor Red
|
|
242
|
+
Write-Host "Total audio files available: $($files.Count)"
|
|
243
|
+
exit 1
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
$target = $files[$N - 1]
|
|
247
|
+
Write-Host "[REPLAY] Replaying audio #${N}:" -ForegroundColor Cyan
|
|
248
|
+
Write-Host " File: $($target.Name)"
|
|
249
|
+
Write-Host " Path: $($target.FullName)"
|
|
250
|
+
|
|
251
|
+
Start-ReplayPlayback $target.FullName
|
|
252
|
+
}
|
|
253
|
+
|
|
158
254
|
# Main command routing
|
|
159
255
|
switch ($Command) {
|
|
160
256
|
'list' {
|
|
@@ -173,4 +269,8 @@ switch ($Command) {
|
|
|
173
269
|
'get' {
|
|
174
270
|
Show-CurrentVoice
|
|
175
271
|
}
|
|
272
|
+
|
|
273
|
+
'replay' {
|
|
274
|
+
Replay-Audio $VoiceName
|
|
275
|
+
}
|
|
176
276
|
}
|
package/.clawdbot/README.md
CHANGED
|
@@ -1,105 +1,105 @@
|
|
|
1
|
-
# Clawdbot Integration
|
|
2
|
-
|
|
3
|
-
AgentVibes TTS integration for Clawdbot - the AI assistant framework.
|
|
4
|
-
|
|
5
|
-
## What is Clawdbot?
|
|
6
|
-
|
|
7
|
-
Clawdbot is a powerful AI assistant framework that connects Claude AI to messaging platforms (WhatsApp, Telegram, Discord, etc.) and provides extensible skills.
|
|
8
|
-
|
|
9
|
-
**Website**: https://clawd.bot
|
|
10
|
-
**GitHub**: https://github.com/clawdbot/clawdbot
|
|
11
|
-
|
|
12
|
-
## AgentVibes + Clawdbot
|
|
13
|
-
|
|
14
|
-
This integration provides Clawdbot with professional TTS capabilities using AgentVibes:
|
|
15
|
-
|
|
16
|
-
- **Free & Offline**: No API costs, works without internet
|
|
17
|
-
- **50+ Voices**: Professional AI voices in 30+ languages
|
|
18
|
-
- **Remote SSH Support**: Audio tunnels from server to local machine
|
|
19
|
-
- **Zero Setup**: Automatic when AgentVibes is installed
|
|
20
|
-
|
|
21
|
-
## Installation
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
npx agentvibes install
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
That's it! AgentVibes is ready to use.
|
|
28
|
-
|
|
29
|
-
## Usage from Clawdbot
|
|
30
|
-
|
|
31
|
-
Once installed, use AgentVibes for TTS:
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
npx agentvibes speak "Hello from Clawdbot"
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
## Features
|
|
38
|
-
|
|
39
|
-
- **Automatic Detection**: Clawdbot automatically uses AgentVibes when available
|
|
40
|
-
- **Voice Selection**: 50+ voices across 30+ languages
|
|
41
|
-
- **SSH Tunneling**: Audio plays on local machine from remote servers
|
|
42
|
-
- **Zero Config**: Works out of the box once AgentVibes is installed
|
|
43
|
-
|
|
44
|
-
## Remote SSH Audio
|
|
45
|
-
|
|
46
|
-
When running Clawdbot on a remote server, set up PulseAudio tunneling so audio plays on your local machine:
|
|
47
|
-
|
|
48
|
-
**Quick Setup:**
|
|
49
|
-
|
|
50
|
-
1. **Remote server** (`~/.bashrc`):
|
|
51
|
-
```bash
|
|
52
|
-
export PULSE_SERVER=tcp:localhost:14713
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
2. **Local machine** (`~/.ssh/config`):
|
|
56
|
-
```
|
|
57
|
-
Host your-server
|
|
58
|
-
RemoteForward 14713 localhost:14713
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
3. **Connect and test**:
|
|
62
|
-
```bash
|
|
63
|
-
ssh your-server
|
|
64
|
-
agentvibes speak "Testing remote audio"
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
**Full guide**: https://github.com/paulpreibisch/AgentVibes/blob/master/docs/remote-audio-setup.md
|
|
68
|
-
|
|
69
|
-
## Documentation
|
|
70
|
-
|
|
71
|
-
- **Skill Documentation**: [skill/SKILL.md](skill/SKILL.md)
|
|
72
|
-
- **AgentVibes Docs**: https://agentvibes.org
|
|
73
|
-
- **Clawdbot Docs**: https://docs.clawd.bot
|
|
74
|
-
|
|
75
|
-
## Architecture
|
|
76
|
-
|
|
77
|
-
```
|
|
78
|
-
Clawdbot Request
|
|
79
|
-
↓
|
|
80
|
-
AgentVibes Skill (this)
|
|
81
|
-
↓
|
|
82
|
-
AgentVibes CLI (agentvibes speak)
|
|
83
|
-
↓
|
|
84
|
-
Piper TTS Engine
|
|
85
|
-
↓
|
|
86
|
-
PulseAudio → SSH Tunnel → Local Speakers
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
## Development
|
|
90
|
-
|
|
91
|
-
The skill is automatically packaged with AgentVibes npm releases. To update:
|
|
92
|
-
|
|
93
|
-
1. Edit `skill/SKILL.md`
|
|
94
|
-
2. Test with Clawdbot
|
|
95
|
-
3. Commit to AgentVibes repo
|
|
96
|
-
4. Publish new AgentVibes version
|
|
97
|
-
|
|
98
|
-
## Support
|
|
99
|
-
|
|
100
|
-
- **AgentVibes Issues**: https://github.com/paulpreibisch/AgentVibes/issues
|
|
101
|
-
- **Clawdbot Issues**: https://github.com/clawdbot/clawdbot/issues
|
|
102
|
-
|
|
103
|
-
## License
|
|
104
|
-
|
|
105
|
-
Apache 2.0 - Same as AgentVibes
|
|
1
|
+
# Clawdbot Integration
|
|
2
|
+
|
|
3
|
+
AgentVibes TTS integration for Clawdbot - the AI assistant framework.
|
|
4
|
+
|
|
5
|
+
## What is Clawdbot?
|
|
6
|
+
|
|
7
|
+
Clawdbot is a powerful AI assistant framework that connects Claude AI to messaging platforms (WhatsApp, Telegram, Discord, etc.) and provides extensible skills.
|
|
8
|
+
|
|
9
|
+
**Website**: https://clawd.bot
|
|
10
|
+
**GitHub**: https://github.com/clawdbot/clawdbot
|
|
11
|
+
|
|
12
|
+
## AgentVibes + Clawdbot
|
|
13
|
+
|
|
14
|
+
This integration provides Clawdbot with professional TTS capabilities using AgentVibes:
|
|
15
|
+
|
|
16
|
+
- **Free & Offline**: No API costs, works without internet
|
|
17
|
+
- **50+ Voices**: Professional AI voices in 30+ languages
|
|
18
|
+
- **Remote SSH Support**: Audio tunnels from server to local machine
|
|
19
|
+
- **Zero Setup**: Automatic when AgentVibes is installed
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npx agentvibes install
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
That's it! AgentVibes is ready to use.
|
|
28
|
+
|
|
29
|
+
## Usage from Clawdbot
|
|
30
|
+
|
|
31
|
+
Once installed, use AgentVibes for TTS:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npx agentvibes speak "Hello from Clawdbot"
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Features
|
|
38
|
+
|
|
39
|
+
- **Automatic Detection**: Clawdbot automatically uses AgentVibes when available
|
|
40
|
+
- **Voice Selection**: 50+ voices across 30+ languages
|
|
41
|
+
- **SSH Tunneling**: Audio plays on local machine from remote servers
|
|
42
|
+
- **Zero Config**: Works out of the box once AgentVibes is installed
|
|
43
|
+
|
|
44
|
+
## Remote SSH Audio
|
|
45
|
+
|
|
46
|
+
When running Clawdbot on a remote server, set up PulseAudio tunneling so audio plays on your local machine:
|
|
47
|
+
|
|
48
|
+
**Quick Setup:**
|
|
49
|
+
|
|
50
|
+
1. **Remote server** (`~/.bashrc`):
|
|
51
|
+
```bash
|
|
52
|
+
export PULSE_SERVER=tcp:localhost:14713
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
2. **Local machine** (`~/.ssh/config`):
|
|
56
|
+
```
|
|
57
|
+
Host your-server
|
|
58
|
+
RemoteForward 14713 localhost:14713
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
3. **Connect and test**:
|
|
62
|
+
```bash
|
|
63
|
+
ssh your-server
|
|
64
|
+
agentvibes speak "Testing remote audio"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**Full guide**: https://github.com/paulpreibisch/AgentVibes/blob/master/docs/remote-audio-setup.md
|
|
68
|
+
|
|
69
|
+
## Documentation
|
|
70
|
+
|
|
71
|
+
- **Skill Documentation**: [skill/SKILL.md](skill/SKILL.md)
|
|
72
|
+
- **AgentVibes Docs**: https://agentvibes.org
|
|
73
|
+
- **Clawdbot Docs**: https://docs.clawd.bot
|
|
74
|
+
|
|
75
|
+
## Architecture
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
Clawdbot Request
|
|
79
|
+
↓
|
|
80
|
+
AgentVibes Skill (this)
|
|
81
|
+
↓
|
|
82
|
+
AgentVibes CLI (agentvibes speak)
|
|
83
|
+
↓
|
|
84
|
+
Piper TTS Engine
|
|
85
|
+
↓
|
|
86
|
+
PulseAudio → SSH Tunnel → Local Speakers
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Development
|
|
90
|
+
|
|
91
|
+
The skill is automatically packaged with AgentVibes npm releases. To update:
|
|
92
|
+
|
|
93
|
+
1. Edit `skill/SKILL.md`
|
|
94
|
+
2. Test with Clawdbot
|
|
95
|
+
3. Commit to AgentVibes repo
|
|
96
|
+
4. Publish new AgentVibes version
|
|
97
|
+
|
|
98
|
+
## Support
|
|
99
|
+
|
|
100
|
+
- **AgentVibes Issues**: https://github.com/paulpreibisch/AgentVibes/issues
|
|
101
|
+
- **Clawdbot Issues**: https://github.com/clawdbot/clawdbot/issues
|
|
102
|
+
|
|
103
|
+
## License
|
|
104
|
+
|
|
105
|
+
Apache 2.0 - Same as AgentVibes
|