agentvibes 5.6.7 → 5.6.9
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/LITE-MODE.md +236 -0
- package/.agentvibes/README.md +136 -0
- package/.agentvibes/backup/session-start-tts.sh.20251210_212814 +141 -0
- package/.agentvibes/backups/agents/analyst_20260204_144958.md +78 -0
- package/.agentvibes/backups/agents/architect_20260204_144958.md +72 -0
- package/.agentvibes/backups/agents/dev_20260204_144958.md +74 -0
- package/.agentvibes/backups/agents/pm_20260204_144958.md +72 -0
- package/.agentvibes/backups/agents/quick-flow-solo-dev_20260204_144958.md +64 -0
- package/.agentvibes/backups/agents/sm_20260204_144958.md +87 -0
- package/.agentvibes/backups/agents/tea_20260204_144958.md +79 -0
- package/.agentvibes/backups/agents/tech-writer_20260204_144958.md +82 -0
- package/.agentvibes/backups/agents/ux-designer_20260204_144958.md +80 -0
- package/.agentvibes/config/README-personality-defaults.md +162 -0
- package/.agentvibes/config/agentvibes.json +1 -0
- package/.agentvibes/config/mode.txt +1 -0
- package/.agentvibes/config/personality-voice-defaults.default.json +21 -0
- package/.agentvibes/config/save-audio.txt +1 -0
- package/.agentvibes/config/voice-metadata.json +160 -0
- package/.agentvibes/config.json +38 -1
- package/.agentvibes/hooks/help.sh +191 -0
- package/.agentvibes/hooks/post-tool-use-lite.sh +111 -0
- package/.agentvibes/hooks/save-audio-manager.sh +162 -0
- package/.agentvibes/hooks/session-start-full-optimized.sh +102 -0
- package/.agentvibes/hooks/session-start-full.sh +142 -0
- package/.agentvibes/hooks/session-start-lite-v2.sh +34 -0
- package/.agentvibes/hooks/session-start-lite.sh +29 -0
- package/.agentvibes/hooks/stop-lite.sh +115 -0
- package/.agentvibes/hooks/switch-mode.sh +215 -0
- package/.agentvibes/output-styles/audio-summary.md +30 -0
- package/.claude/audio/voice-samples/piper/alan.wav +0 -0
- package/.claude/audio/voice-samples/piper/amy.wav +0 -0
- package/.claude/audio/voice-samples/piper/charlotte.wav +0 -0
- package/.claude/audio/voice-samples/piper/joe.wav +0 -0
- package/.claude/audio/voice-samples/piper/john.wav +0 -0
- package/.claude/audio/voice-samples/piper/katherine.wav +0 -0
- package/.claude/audio/voice-samples/piper/kristin.wav +0 -0
- package/.claude/audio/voice-samples/piper/linda.wav +0 -0
- package/.claude/audio/voice-samples/piper/marcus.wav +0 -0
- package/.claude/audio/voice-samples/piper/ryan.wav +0 -0
- package/.claude/commands/agent-vibes/provider.md +0 -0
- 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 +6 -1
- package/.claude/config/background-music-position.txt +8 -6
- package/.claude/config/reverb-level.txt +0 -0
- package/.claude/docs/TERMUX_SETUP.md +408 -408
- package/.claude/github-star-reminder.txt +1 -1
- package/.claude/hooks/audio-cache-utils.sh +0 -0
- package/.claude/hooks/audio-processor.sh +0 -0
- package/.claude/hooks/background-music-manager.sh +0 -0
- package/.claude/hooks/bmad-party-manager.sh +225 -0
- package/.claude/hooks/bmad-party-speak.sh +0 -0
- package/.claude/hooks/bmad-speak-enhanced.sh +0 -0
- package/.claude/hooks/bmad-speak.sh +0 -0
- package/.claude/hooks/bmad-tts-injector.sh +0 -0
- package/.claude/hooks/bmad-voice-manager.sh +0 -0
- package/.claude/hooks/clawdbot-receiver-SECURE.sh +0 -0
- package/.claude/hooks/clawdbot-receiver.sh +0 -0
- package/.claude/hooks/clean-audio-cache.sh +0 -0
- package/.claude/hooks/cleanup-cache.sh +0 -0
- package/.claude/hooks/configure-rdp-mode.sh +0 -0
- package/.claude/hooks/download-extra-voices.sh +0 -0
- package/.claude/hooks/effects-manager.sh +0 -0
- package/.claude/hooks/github-star-reminder.sh +0 -0
- package/.claude/hooks/language-manager.sh +0 -0
- package/.claude/hooks/learn-manager.sh +0 -0
- package/.claude/hooks/macos-voice-manager.sh +0 -0
- package/.claude/hooks/migrate-background-music.sh +0 -0
- package/.claude/hooks/migrate-to-agentvibes.sh +0 -0
- package/.claude/hooks/optimize-background-music.sh +0 -0
- package/.claude/hooks/path-resolver.sh +0 -0
- package/.claude/hooks/personality-manager.sh +0 -0
- package/.claude/hooks/piper-download-voices.sh +0 -0
- package/.claude/hooks/piper-installer.sh +0 -0
- package/.claude/hooks/piper-multispeaker-registry.sh +0 -0
- package/.claude/hooks/piper-voice-manager.sh +0 -0
- package/.claude/hooks/play-tts-agentvibes-receiver-for-voiceless-connections.sh +0 -0
- package/.claude/hooks/play-tts-enhanced.sh +0 -0
- package/.claude/hooks/play-tts-macos.sh +0 -0
- package/.claude/hooks/play-tts-piper.sh +40 -2
- package/.claude/hooks/play-tts-soprano.sh +0 -0
- package/.claude/hooks/play-tts-ssh-remote.sh +0 -0
- package/.claude/hooks/play-tts-termux-ssh.sh +0 -0
- package/.claude/hooks/play-tts-windows-receiver.sh +0 -0
- package/.claude/hooks/play-tts.sh +13 -0
- package/.claude/hooks/post-response.sh +41 -0
- package/.claude/hooks/prepare-release.sh +0 -0
- package/.claude/hooks/provider-commands.sh +0 -0
- package/.claude/hooks/provider-manager.sh +0 -0
- package/.claude/hooks/replay-target-audio.sh +0 -0
- package/.claude/hooks/sentiment-manager.sh +0 -0
- package/.claude/hooks/session-start-tts.sh +48 -13
- package/.claude/hooks/soprano-gradio-synth.py +0 -0
- package/.claude/hooks/speed-manager.sh +0 -0
- package/.claude/hooks/stop-tts.sh +0 -0
- package/.claude/hooks/stop.sh +63 -0
- package/.claude/hooks/termux-installer.sh +0 -0
- package/.claude/hooks/translate-manager.sh +0 -0
- package/.claude/hooks/translator.py +0 -0
- package/.claude/hooks/tts-queue-worker.sh +0 -0
- package/.claude/hooks/tts-queue.sh +0 -0
- package/.claude/hooks/verbosity-manager.sh +0 -0
- package/.claude/hooks/voice-manager.sh +0 -0
- package/.claude/hooks-windows/audio-cache-utils.ps1 +119 -119
- package/.claude/hooks-windows/play-tts-piper.ps1 +26 -1
- package/.claude/hooks-windows/play-tts.ps1 +25 -1
- package/.claude/hooks-windows/session-start-tts.ps1 +28 -9
- package/.claude/piper-voices-dir.txt +1 -0
- package/.claude/settings.json +2 -2
- package/.clawdbot/README.md +105 -105
- package/.mcp.json +32 -3
- package/CLAUDE.md +9 -0
- package/README.md +21 -3
- package/RELEASE_NOTES.md +61 -0
- package/WINDOWS-SETUP.md +208 -208
- package/bin/agent-vibes +0 -0
- package/bin/agentvibes-voice-browser.js +59 -4
- package/bin/agentvibes.js +0 -0
- package/bin/ensure-soprano-running.sh +43 -0
- package/bin/mcp-server.js +121 -121
- package/bin/mcp-server.sh +0 -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/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 +177 -130
- package/mcp-server/server.py +1797 -1787
- package/mcp-server/test_server.py +0 -0
- package/package.json +1 -1
- package/src/console/app.js +6 -0
- package/src/console/tabs/music-tab.js +18 -2
- package/src/console/widgets/format-utils.js +11 -2
- package/src/installer.js +38 -37
- package/src/services/llm-provider-service.js +28 -9
- package/src/utils/voice-names.js +2 -0
- package/templates/agentvibes-receiver.sh +0 -0
- package/templates/audio/welcome-music.mp3 +0 -0
- package/.claude/hooks/play-tts-agentvibes-receiver.sh +0 -1
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "agentvibes",
|
|
4
|
-
"version": "5.6.
|
|
4
|
+
"version": "5.6.9",
|
|
5
5
|
"description": "Now your AI Agents can finally talk back! Professional TTS voice for Claude Code, Claude Desktop (via MCP), and Clawdbot with multi-provider support.",
|
|
6
6
|
"homepage": "https://agentvibes.org",
|
|
7
7
|
"keywords": [
|
package/src/console/app.js
CHANGED
|
@@ -30,6 +30,7 @@ import { createReceiverTab } from './tabs/receiver-tab.js';
|
|
|
30
30
|
import { createAgentsTab } from './tabs/agents-tab.js';
|
|
31
31
|
import { ConfigService } from '../services/config-service.js';
|
|
32
32
|
import { ProviderService } from '../services/provider-service.js';
|
|
33
|
+
import { seedAllLlmDefaultsSync } from '../services/llm-provider-service.js';
|
|
33
34
|
|
|
34
35
|
const _dir = path.dirname(fileURLToPath(import.meta.url));
|
|
35
36
|
const _pkg = JSON.parse(readFileSync(path.join(_dir, '../../package.json'), 'utf8'));
|
|
@@ -893,6 +894,11 @@ export class AgentVibesConsole {
|
|
|
893
894
|
* @returns {Promise<AgentVibesConsole>}
|
|
894
895
|
*/
|
|
895
896
|
export async function launchConsole(opts = {}) {
|
|
897
|
+
// Seed per-LLM piper defaults into the project config on every TUI launch.
|
|
898
|
+
// This guarantees play-tts.ps1 always finds a piper engine row for each LLM
|
|
899
|
+
// and never silently falls back to the global windows-sapi provider.
|
|
900
|
+
seedAllLlmDefaultsSync(process.cwd());
|
|
901
|
+
|
|
896
902
|
const app = new AgentVibesConsole(opts);
|
|
897
903
|
await app.init();
|
|
898
904
|
return app;
|
|
@@ -225,6 +225,19 @@ function _setMusic(configService, update) {
|
|
|
225
225
|
configService.set('backgroundMusic', { ...current, ...update });
|
|
226
226
|
}
|
|
227
227
|
|
|
228
|
+
/**
|
|
229
|
+
* Sync the background-music-enabled.txt flag file so bash hooks see the change.
|
|
230
|
+
* The TUI stores enabled state in config.json, but audio-processor.sh and
|
|
231
|
+
* play-tts-piper.sh read from this .txt file — they must stay in sync.
|
|
232
|
+
* @param {boolean} enabled
|
|
233
|
+
*/
|
|
234
|
+
export function applyEnabledToFile(enabled) {
|
|
235
|
+
const enabledFile = path.join(process.cwd(), '.claude', 'config', 'background-music-enabled.txt');
|
|
236
|
+
try {
|
|
237
|
+
fs.writeFileSync(enabledFile, enabled ? 'true' : 'false', 'utf-8');
|
|
238
|
+
} catch { /* non-fatal */ }
|
|
239
|
+
}
|
|
240
|
+
|
|
228
241
|
/**
|
|
229
242
|
* Patch the 'default' entry in audio-effects.cfg to use the given track.
|
|
230
243
|
* play-tts-piper.sh reads the track from audio-effects.cfg (not from config.json),
|
|
@@ -431,7 +444,9 @@ export function createMusicTab(screen, services) {
|
|
|
431
444
|
|
|
432
445
|
const toggleBtn = _createBtn(_tl('musicToggleBtn'), () => {
|
|
433
446
|
const { enabled } = _getMusic(configService);
|
|
434
|
-
|
|
447
|
+
const next = !enabled;
|
|
448
|
+
_setMusic(configService, { enabled: next });
|
|
449
|
+
applyEnabledToFile(next); // sync bash hooks (audio-processor.sh reads this file)
|
|
435
450
|
refreshDisplay();
|
|
436
451
|
});
|
|
437
452
|
toggleBtn.bottom = 4;
|
|
@@ -772,8 +787,9 @@ export function createMusicTab(screen, services) {
|
|
|
772
787
|
}
|
|
773
788
|
|
|
774
789
|
function _saveLocally() {
|
|
775
|
-
_setMusic(configService, { track: trackId });
|
|
790
|
+
_setMusic(configService, { track: trackId, enabled: true });
|
|
776
791
|
applyTrackToAudioEffects(trackId);
|
|
792
|
+
applyEnabledToFile(true); // saving a track implies enabling music
|
|
777
793
|
refreshDisplay();
|
|
778
794
|
_showTrackChangedNotice(displayName);
|
|
779
795
|
}
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
* circular imports between widgets and tabs.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
import { uniquifyVoiceName } from '../../utils/voice-names.js';
|
|
9
|
+
|
|
8
10
|
const TRACK_NAMES = Object.freeze({
|
|
9
11
|
'agentvibes_soft_flamenco_loop.mp3': '🎻 Soft Flamenco',
|
|
10
12
|
'agent_vibes_bachata_v1_loop.mp3': '🎺 Bachata',
|
|
@@ -60,8 +62,15 @@ export function formatVoiceName(voice) {
|
|
|
60
62
|
|
|
61
63
|
let name;
|
|
62
64
|
if (voice.includes('::')) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
+
const speakerPart = voice.split('::')[1];
|
|
66
|
+
if (speakerPart.includes('_')) {
|
|
67
|
+
// 16Speakers format (Rose_Ibex) — already a complete name, just normalise display
|
|
68
|
+
name = speakerPart.replace(/_/g, ' ');
|
|
69
|
+
} else {
|
|
70
|
+
// LibriTTS / single-word names: append deterministic surname
|
|
71
|
+
// "Mary" → "Mary Bell", "Mary-7" → "Mary Hayes"
|
|
72
|
+
name = uniquifyVoiceName(speakerPart);
|
|
73
|
+
}
|
|
65
74
|
} else {
|
|
66
75
|
const parts = voice.split('-');
|
|
67
76
|
const QUALITIES = new Set(['high', 'medium', 'low']);
|
package/src/installer.js
CHANGED
|
@@ -4054,17 +4054,18 @@ async function configureSessionStartHook(targetDir, spinner) {
|
|
|
4054
4054
|
existingSettings.hooks = {};
|
|
4055
4055
|
}
|
|
4056
4056
|
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4057
|
+
// Windows uses SessionStart; Linux/macOS/WSL uses UserPromptSubmit.
|
|
4058
|
+
// Both point to the global $HOME path so updates to the hook script
|
|
4059
|
+
// take effect immediately without needing per-project reinstalls.
|
|
4060
|
+
const hookKey = isNativeWindows() ? 'SessionStart' : 'UserPromptSubmit';
|
|
4061
|
+
const hookCommand = isNativeWindows()
|
|
4062
|
+
? 'powershell -NoProfile -ExecutionPolicy Bypass -File "$HOME\\.claude\\hooks-windows\\session-start-tts.ps1"'
|
|
4063
|
+
: 'bash "$HOME/.claude/hooks/session-start-tts.sh"';
|
|
4064
|
+
|
|
4065
|
+
if (!existingSettings.hooks[hookKey]) {
|
|
4066
|
+
existingSettings.hooks[hookKey] = [{
|
|
4067
|
+
hooks: [{ type: 'command', command: hookCommand }]
|
|
4068
|
+
}];
|
|
4068
4069
|
|
|
4069
4070
|
if (!existingSettings.$schema) {
|
|
4070
4071
|
existingSettings.$schema = templateSettings.$schema;
|
|
@@ -5045,8 +5046,8 @@ async function updateCommandFiles(targetDir, spinner) {
|
|
|
5045
5046
|
* These hooks contain bug fixes (e.g. markdown stripping) that must propagate
|
|
5046
5047
|
* on every `npx agentvibes update` regardless of target directory.
|
|
5047
5048
|
*/
|
|
5048
|
-
const CRITICAL_HOOKS = ['stop-tts.sh', 'stop.sh', 'play-tts.sh', 'session-start-tts.sh', 'bmad-party-speak.sh'];
|
|
5049
|
-
const CRITICAL_HOOKS_WINDOWS = ['play-tts.ps1', 'session-start-tts.ps1', 'bmad-speak.ps1', 'bmad-party-speak.ps1'];
|
|
5049
|
+
const CRITICAL_HOOKS = ['stop-tts.sh', 'stop.sh', 'play-tts.sh', 'play-tts-piper.sh', 'audio-processor.sh', 'session-start-tts.sh', 'bmad-party-speak.sh'];
|
|
5050
|
+
const CRITICAL_HOOKS_WINDOWS = ['play-tts.ps1', 'play-tts-piper.ps1', 'audio-processor.ps1', 'session-start-tts.ps1', 'bmad-speak.ps1', 'bmad-party-speak.ps1'];
|
|
5050
5051
|
|
|
5051
5052
|
/**
|
|
5052
5053
|
* Update critical hooks in the global ~/.claude/hooks/ directory if it exists.
|
|
@@ -5056,45 +5057,38 @@ const CRITICAL_HOOKS_WINDOWS = ['play-tts.ps1', 'session-start-tts.ps1', 'bmad-s
|
|
|
5056
5057
|
* @returns {Promise<number>} Number of hooks updated
|
|
5057
5058
|
*/
|
|
5058
5059
|
async function updateGlobalHooks(srcHooksDir, homeDirOverride) {
|
|
5059
|
-
const
|
|
5060
|
+
const homeDir = homeDirOverride || os.homedir();
|
|
5061
|
+
const globalHooksDir = path.join(homeDir, '.claude', 'hooks');
|
|
5060
5062
|
let updated = 0;
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
return 0; // global hooks dir not present — nothing to do
|
|
5065
|
-
}
|
|
5063
|
+
|
|
5064
|
+
// Always ensure the global hooks dir exists so registered $HOME hooks resolve.
|
|
5065
|
+
await fs.mkdir(globalHooksDir, { recursive: true });
|
|
5066
5066
|
|
|
5067
5067
|
for (const hook of CRITICAL_HOOKS) {
|
|
5068
5068
|
const destPath = path.join(globalHooksDir, hook);
|
|
5069
5069
|
const srcPath = path.join(srcHooksDir, hook);
|
|
5070
5070
|
try {
|
|
5071
|
-
await fs.access(destPath); // only update if already installed
|
|
5072
5071
|
await fs.copyFile(srcPath, destPath);
|
|
5073
5072
|
await fs.chmod(destPath, 0o750);
|
|
5074
5073
|
updated++;
|
|
5075
5074
|
} catch {
|
|
5076
|
-
//
|
|
5075
|
+
// src missing — skip silently
|
|
5077
5076
|
}
|
|
5078
5077
|
}
|
|
5079
5078
|
|
|
5080
|
-
// Also
|
|
5081
|
-
const globalHooksWindowsDir = path.join(
|
|
5079
|
+
// Also ensure Windows global hooks-windows dir and scripts are up to date.
|
|
5080
|
+
const globalHooksWindowsDir = path.join(homeDir, '.claude', 'hooks-windows');
|
|
5082
5081
|
const srcHooksWindowsDir = path.join(path.dirname(srcHooksDir), 'hooks-windows');
|
|
5083
|
-
|
|
5084
|
-
|
|
5085
|
-
|
|
5086
|
-
|
|
5087
|
-
|
|
5088
|
-
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
} catch {
|
|
5093
|
-
// file not in global dir or src missing — skip silently
|
|
5094
|
-
}
|
|
5082
|
+
await fs.mkdir(globalHooksWindowsDir, { recursive: true });
|
|
5083
|
+
for (const hook of CRITICAL_HOOKS_WINDOWS) {
|
|
5084
|
+
const destPath = path.join(globalHooksWindowsDir, hook);
|
|
5085
|
+
const srcPath = path.join(srcHooksWindowsDir, hook);
|
|
5086
|
+
try {
|
|
5087
|
+
await fs.copyFile(srcPath, destPath);
|
|
5088
|
+
updated++;
|
|
5089
|
+
} catch {
|
|
5090
|
+
// src missing — skip silently
|
|
5095
5091
|
}
|
|
5096
|
-
} catch {
|
|
5097
|
-
// hooks-windows dir not present — nothing to do
|
|
5098
5092
|
}
|
|
5099
5093
|
|
|
5100
5094
|
return updated;
|
|
@@ -5337,6 +5331,13 @@ async function install(options = {}) {
|
|
|
5337
5331
|
await copyBackgroundMusicFiles(targetDir, silentSpinner);
|
|
5338
5332
|
await copyConfigFiles(targetDir, silentSpinner);
|
|
5339
5333
|
await copyCodexFiles(targetDir, silentSpinner);
|
|
5334
|
+
|
|
5335
|
+
// Populate global ~/.claude/hooks[/-windows]/ so $HOME hook paths resolve
|
|
5336
|
+
// on first install (not just on update).
|
|
5337
|
+
const hooksSubdirInstall = isNativeWindows() ? 'hooks-windows' : 'hooks';
|
|
5338
|
+
const srcHooksDirInstall = path.join(__dirname, '..', '.claude', hooksSubdirInstall);
|
|
5339
|
+
await updateGlobalHooks(srcHooksDirInstall);
|
|
5340
|
+
|
|
5340
5341
|
await configureSessionStartHook(targetDir, silentSpinner);
|
|
5341
5342
|
await configurePartyModeHook(targetDir, silentSpinner);
|
|
5342
5343
|
await installPluginManifest(targetDir, silentSpinner);
|
|
@@ -92,8 +92,17 @@ const DEFAULT_LLM_CONFIGS = {
|
|
|
92
92
|
};
|
|
93
93
|
|
|
94
94
|
function ensureDefaultLlmConfigSync(llmKey, targetDir) {
|
|
95
|
-
|
|
96
|
-
|
|
95
|
+
// Check only the project dir — a global config row must not prevent seeding
|
|
96
|
+
// per-project defaults (otherwise new installs silently inherit a different
|
|
97
|
+
// project's voice/pretext and the per-LLM piper engine is never written,
|
|
98
|
+
// causing play-tts.ps1 to fall through to the global SAPI provider).
|
|
99
|
+
const resolvedDir = targetDir || process.env.INIT_CWD || process.cwd();
|
|
100
|
+
const projectCfgPath = path.join(resolvedDir, '.claude', 'config', 'audio-effects.cfg');
|
|
101
|
+
const cfgKey = `llm:${llmKey}`;
|
|
102
|
+
try {
|
|
103
|
+
const content = fsSync.readFileSync(projectCfgPath, 'utf8');
|
|
104
|
+
if (content.split('\n').some(line => line.startsWith(cfgKey + '|'))) return;
|
|
105
|
+
} catch { /* file not found — continue to seed */ }
|
|
97
106
|
|
|
98
107
|
const defaults = DEFAULT_LLM_CONFIGS[llmKey];
|
|
99
108
|
if (!defaults) return;
|
|
@@ -101,6 +110,17 @@ function ensureDefaultLlmConfigSync(llmKey, targetDir) {
|
|
|
101
110
|
saveLlmConfigSync(llmKey, defaults, targetDir);
|
|
102
111
|
}
|
|
103
112
|
|
|
113
|
+
/**
|
|
114
|
+
* Seed piper defaults for every LLM in DEFAULT_LLM_CONFIGS into the project dir.
|
|
115
|
+
* Called at install time so play-tts.ps1 always finds a per-LLM piper row in the
|
|
116
|
+
* project config and never silently falls back to the global windows-sapi provider.
|
|
117
|
+
*/
|
|
118
|
+
export function seedAllLlmDefaultsSync(targetDir) {
|
|
119
|
+
for (const llmKey of Object.keys(DEFAULT_LLM_CONFIGS)) {
|
|
120
|
+
ensureDefaultLlmConfigSync(llmKey, targetDir);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
104
124
|
// ── Provider install-checks ─────────────────────────────────────────────────
|
|
105
125
|
|
|
106
126
|
export async function checkClaudeInstalled(targetDir) {
|
|
@@ -902,13 +922,12 @@ export function saveLlmConfigSync(llmKey, config, targetDir) {
|
|
|
902
922
|
const sanitize = (v) => (v || '').replace(/[\|\n\r\x00]/g, '');
|
|
903
923
|
const cfgLine = `${cfgKey}|${sanitize(config.effects)}|${sanitize(config.bgTrack)}|${sanitize(config.bgVolume)}|${sanitize(config.voice)}|${sanitize(config.pretext)}|${sanitize(config.ttsEngine)}`;
|
|
904
924
|
const resolvedTargetDir = targetDir || process.env.INIT_CWD || process.cwd();
|
|
905
|
-
// When targetDir is explicitly passed, write
|
|
906
|
-
//
|
|
907
|
-
//
|
|
908
|
-
const cfgPath =
|
|
909
|
-
(
|
|
910
|
-
|
|
911
|
-
: resolveCfgPath(resolvedTargetDir));
|
|
925
|
+
// When targetDir is explicitly passed, always write to the project dir — never follow
|
|
926
|
+
// config.sourcePath back to the global ~/.claude/config (it may have been loaded from there
|
|
927
|
+
// as a "default seed" for a new project, and writing back would pollute other projects).
|
|
928
|
+
const cfgPath = targetDir
|
|
929
|
+
? path.join(resolvedTargetDir, '.claude', 'config', 'audio-effects.cfg')
|
|
930
|
+
: (config.sourcePath || resolveCfgPath(resolvedTargetDir));
|
|
912
931
|
|
|
913
932
|
try {
|
|
914
933
|
let content = '';
|
package/src/utils/voice-names.js
CHANGED
|
@@ -35,6 +35,8 @@ export function uniquifyVoiceName(rawName) {
|
|
|
35
35
|
const idx = (n - 1) % SURNAME_POOL.length;
|
|
36
36
|
return `${base} ${SURNAME_POOL[idx]}`;
|
|
37
37
|
}
|
|
38
|
+
// n=1 (or 0): strip the suffix — "Mary-1" → "Mary Bell" is cleaner than "Mary-1 Bell"
|
|
39
|
+
return `${base} ${SURNAME_POOL[0]}`;
|
|
38
40
|
}
|
|
39
41
|
if (/\s/.test(rawName)) return rawName;
|
|
40
42
|
return `${rawName} ${SURNAME_POOL[0]}`;
|
|
File without changes
|
|
File without changes
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
play-tts-agentvibes-receiver-for-voiceless-connections.sh
|