agentvibes 5.9.0 → 5.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/.agentvibes/config.json +3 -12
  2. package/.claude/commands/agent-vibes-bmad-voices.md +117 -117
  3. package/.claude/commands/agent-vibes-rdp.md +24 -24
  4. package/.claude/config/audio-effects.cfg +4 -5
  5. package/.claude/config/audio-effects.cfg.sample +52 -52
  6. package/.claude/config/background-music-enabled.txt +1 -1
  7. package/.claude/docs/TERMUX_SETUP.md +408 -408
  8. package/.claude/github-star-reminder.txt +1 -1
  9. package/.claude/hooks/audio-cache-utils.sh +0 -0
  10. package/.claude/hooks/audio-processor.sh +0 -0
  11. package/.claude/hooks/background-music-manager.sh +0 -0
  12. package/.claude/hooks/bmad-party-speak.sh +0 -0
  13. package/.claude/hooks/bmad-speak-enhanced.sh +0 -0
  14. package/.claude/hooks/bmad-speak.sh +0 -0
  15. package/.claude/hooks/bmad-tts-injector.sh +0 -0
  16. package/.claude/hooks/bmad-voice-manager.sh +0 -0
  17. package/.claude/hooks/clawdbot-receiver-SECURE.sh +0 -0
  18. package/.claude/hooks/clawdbot-receiver.sh +0 -0
  19. package/.claude/hooks/clean-audio-cache.sh +0 -0
  20. package/.claude/hooks/cleanup-cache.sh +0 -0
  21. package/.claude/hooks/configure-rdp-mode.sh +0 -0
  22. package/.claude/hooks/download-extra-voices.sh +0 -0
  23. package/.claude/hooks/effects-manager.sh +0 -0
  24. package/.claude/hooks/github-star-reminder.sh +0 -0
  25. package/.claude/hooks/language-manager.sh +0 -0
  26. package/.claude/hooks/learn-manager.sh +0 -0
  27. package/.claude/hooks/macos-voice-manager.sh +0 -0
  28. package/.claude/hooks/migrate-background-music.sh +0 -0
  29. package/.claude/hooks/migrate-to-agentvibes.sh +0 -0
  30. package/.claude/hooks/optimize-background-music.sh +0 -0
  31. package/.claude/hooks/path-resolver.sh +0 -0
  32. package/.claude/hooks/personality-manager.sh +0 -0
  33. package/.claude/hooks/piper-download-voices.sh +0 -0
  34. package/.claude/hooks/piper-installer.sh +0 -0
  35. package/.claude/hooks/piper-multispeaker-registry.sh +0 -0
  36. package/.claude/hooks/piper-voice-manager.sh +0 -0
  37. package/.claude/hooks/play-tts-agentvibes-receiver-for-voiceless-connections.sh +0 -0
  38. package/.claude/hooks/play-tts-enhanced.sh +0 -0
  39. package/.claude/hooks/play-tts-macos.sh +0 -0
  40. package/.claude/hooks/play-tts-piper.sh +20 -13
  41. package/.claude/hooks/play-tts-soprano.sh +0 -0
  42. package/.claude/hooks/play-tts-ssh-remote.sh +0 -0
  43. package/.claude/hooks/play-tts-termux-ssh.sh +0 -0
  44. package/.claude/hooks/play-tts-windows-receiver.sh +0 -0
  45. package/.claude/hooks/play-tts.sh +0 -0
  46. package/.claude/hooks/prepare-release.sh +0 -0
  47. package/.claude/hooks/provider-commands.sh +0 -0
  48. package/.claude/hooks/provider-manager.sh +0 -0
  49. package/.claude/hooks/replay-target-audio.sh +0 -0
  50. package/.claude/hooks/requirements.txt +6 -6
  51. package/.claude/hooks/sentiment-manager.sh +0 -0
  52. package/.claude/hooks/session-start-tts.sh +0 -0
  53. package/.claude/hooks/soprano-gradio-synth.py +139 -139
  54. package/.claude/hooks/speed-manager.sh +0 -0
  55. package/.claude/hooks/stop-tts.sh +0 -0
  56. package/.claude/hooks/termux-installer.sh +0 -0
  57. package/.claude/hooks/translate-manager.sh +0 -0
  58. package/.claude/hooks/translator.py +237 -237
  59. package/.claude/hooks/tts-queue-worker.sh +0 -0
  60. package/.claude/hooks/tts-queue.sh +0 -0
  61. package/.claude/hooks/verbosity-manager.sh +0 -0
  62. package/.claude/hooks/voice-manager.sh +6 -0
  63. package/.claude/hooks-windows/play-tts-windows-piper.ps1 +22 -16
  64. package/.claude/hooks-windows/soprano-gradio-synth.py +153 -153
  65. package/.claude/verbosity.txt +1 -1
  66. package/.clawdbot/README.md +105 -105
  67. package/.mcp.json +19 -6
  68. package/README.md +1 -1
  69. package/WINDOWS-SETUP.md +208 -208
  70. package/bin/agent-vibes +39 -39
  71. package/bin/agentvibes-voice-browser.js +0 -0
  72. package/bin/agentvibes.js +0 -0
  73. package/bin/mcp-server.js +121 -121
  74. package/bin/mcp-server.sh +0 -0
  75. package/bin/test-bmad-pr +78 -78
  76. package/mcp-server/QUICK_START.md +203 -203
  77. package/mcp-server/README.md +345 -345
  78. package/mcp-server/WINDOWS_SETUP.md +0 -0
  79. package/mcp-server/examples/claude_desktop_config.json +11 -11
  80. package/mcp-server/examples/claude_desktop_config_piper.json +9 -9
  81. package/mcp-server/examples/custom_instructions.md +169 -169
  82. package/mcp-server/install-deps.js +0 -0
  83. package/mcp-server/server.py +1807 -1797
  84. package/mcp-server/test_server.py +0 -0
  85. package/package.json +2 -2
  86. package/src/cli/list-personalities.js +110 -110
  87. package/src/cli/list-voices.js +114 -114
  88. package/src/commands/bmad-voices.js +394 -394
  89. package/src/commands/install-mcp.js +730 -476
  90. package/src/console/app.js +3 -3
  91. package/src/console/brand-colors.js +13 -13
  92. package/src/console/constants/personalities.js +44 -44
  93. package/src/console/tabs/agents-tab.js +6 -6
  94. package/src/console/tabs/help-tab.js +314 -314
  95. package/src/console/tabs/music-tab.js +1 -1
  96. package/src/console/tabs/readme-tab.js +272 -272
  97. package/src/console/tabs/receiver-tab.js +13 -13
  98. package/src/console/tabs/settings-tab.js +2 -2
  99. package/src/console/tabs/setup-tab.js +10 -10
  100. package/src/console/tabs/voices-tab.js +4 -4
  101. package/src/console/widgets/destroy-list.js +25 -25
  102. package/src/console/widgets/notice.js +55 -55
  103. package/src/console/widgets/personality-picker.js +2 -2
  104. package/src/console/widgets/reverb-picker.js +1 -1
  105. package/src/i18n/de.js +202 -202
  106. package/src/i18n/es.js +202 -202
  107. package/src/i18n/fr.js +202 -202
  108. package/src/i18n/hi.js +202 -202
  109. package/src/i18n/ja.js +202 -202
  110. package/src/i18n/ko.js +202 -202
  111. package/src/i18n/pt.js +202 -202
  112. package/src/i18n/strings.js +54 -54
  113. package/src/i18n/zh-CN.js +202 -202
  114. package/src/installer/language-screen.js +31 -31
  115. package/src/installer/music-file-input.js +304 -304
  116. package/src/installer.js +32 -27
  117. package/src/services/config-service.js +264 -264
  118. package/src/services/language-service.js +47 -47
  119. package/src/services/provider-service.js +143 -143
  120. package/src/services/tts-engine-service.js +2 -2
  121. package/src/utils/audio-duration-validator.js +298 -298
  122. package/src/utils/audio-format-validator.js +277 -277
  123. package/src/utils/dependency-checker.js +469 -469
  124. package/src/utils/file-ownership-verifier.js +358 -358
  125. package/src/utils/list-formatter.js +200 -194
  126. package/src/utils/music-file-validator.js +285 -285
  127. package/src/utils/platform-resolver.js +369 -0
  128. package/src/utils/preview-list-prompt.js +136 -136
  129. package/src/utils/provider-validator.js +9 -9
  130. package/src/utils/secure-music-storage.js +412 -412
  131. package/templates/agentvibes-receiver.sh +231 -231
  132. package/templates/audio/welcome-music.mp3 +0 -0
  133. package/.agentvibes/install-manifest.json +0 -330
  134. package/.claude/config/background-music-position.txt +0 -27
  135. package/.claude/config/background-music-volume.txt +0 -1
  136. package/.claude/config/background-music.cfg +0 -1
  137. package/.claude/config/background-music.txt +0 -1
  138. package/.claude/config/language.txt +0 -1
  139. package/.claude/config/reverb-level.txt +0 -1
  140. package/.claude/config/tts-speech-rate.txt +0 -1
  141. package/.claude/config/tts-verbosity.txt +0 -1
  142. package/.claude/hooks/play-tts-agentvibes-receiver.sh +0 -1
  143. package/.claude/hooks-windows/audio-cache-utils.ps1.user.bak +0 -119
  144. package/.claude/hooks-windows/soprano-gradio-synth.py.user.bak +0 -153
  145. package/.claude/piper-voices-dir.txt +0 -1
@@ -1,143 +1,143 @@
1
- /**
2
- * AgentVibes Provider Service
3
- * Story 7.1: Provider & Voice Settings Group
4
- *
5
- * Detects installed TTS providers, reads/writes active provider and voice
6
- * through ConfigService. Gracefully degrades when detection fails.
7
- */
8
-
9
- import { execFileSync } from 'node:child_process';
10
- import fs from 'node:fs';
11
- import path from 'node:path';
12
- import os from 'node:os';
13
-
14
- export class ProviderService {
15
- /**
16
- * @param {import('./config-service.js').ConfigService} configService
17
- */
18
- constructor(configService) {
19
- this._config = configService;
20
- this._installedProviders = null; // cached after first detection
21
- }
22
-
23
- // ---------------------------------------------------------------------------
24
- // Provider
25
-
26
- /**
27
- * Returns the currently active TTS provider from config.
28
- * Defaults to 'piper' if not configured.
29
- * @returns {string}
30
- */
31
- getActiveProvider() {
32
- return this._config.getConfig().provider ?? 'piper';
33
- }
34
-
35
- /**
36
- * Sets the active TTS provider in config AND syncs to .claude/tts-provider.txt
37
- * so the shell hooks (play-tts.sh → provider-manager.sh) pick up the change.
38
- * @param {string} provider
39
- */
40
- setActiveProvider(provider) {
41
- this._config.set('provider', provider);
42
- this._config.setGlobal('provider', provider);
43
- this._syncProviderFile(provider);
44
- }
45
-
46
- /**
47
- * Write provider to .claude/tts-provider.txt so shell hooks stay in sync.
48
- * Writes to projectRoot/.claude/tts-provider.txt if .claude/ exists there,
49
- * otherwise falls back to ~/.claude/tts-provider.txt.
50
- * @param {string} provider
51
- */
52
- _syncProviderFile(provider) {
53
- try {
54
- const projectClaudeDir = path.resolve(this._config.getProjectRoot(), '.claude');
55
- const targetDir = fs.existsSync(projectClaudeDir)
56
- ? projectClaudeDir
57
- : path.resolve(os.homedir(), '.claude');
58
- const targetFile = path.resolve(targetDir, 'tts-provider.txt');
59
- // Verify resolved path stays within targetDir (path traversal guard)
60
- if (!targetFile.startsWith(targetDir + path.sep) && targetFile !== targetDir) return;
61
- fs.mkdirSync(targetDir, { recursive: true });
62
- fs.writeFileSync(targetFile, provider, 'utf8');
63
- } catch {
64
- // Non-fatal — config.json is the authoritative source
65
- }
66
- }
67
-
68
- /**
69
- * Returns an array of installed/available TTS providers.
70
- * Detection uses `which` binary check. Always returns at least ['piper']
71
- * as graceful degradation (piper is the primary supported provider).
72
- * @returns {string[]}
73
- */
74
- getInstalledProviders() {
75
- if (this._installedProviders) return this._installedProviders;
76
-
77
- const providers = [];
78
-
79
- if (this._isAvailable('piper')) providers.push('piper');
80
- if (this._isAvailable('soprano')) providers.push('soprano');
81
-
82
- // macOS Say (darwin only)
83
- if (process.platform === 'darwin' && this._isAvailable('say')) {
84
- providers.push('macos');
85
- }
86
-
87
- // Graceful degradation: always return at least piper
88
- if (providers.length === 0) providers.push('piper');
89
-
90
- this._installedProviders = providers;
91
- return providers;
92
- }
93
-
94
- // ---------------------------------------------------------------------------
95
- // Voice
96
-
97
- /**
98
- * Returns the currently active voice ID from config.
99
- * Falls back to first installed voice if not configured.
100
- * @returns {string|null}
101
- */
102
- getActiveVoiceId() {
103
- const voice = this._config.getConfig().voice;
104
- if (voice) return voice;
105
- // Detect first installed voice instead of hardcoding a default that may not exist
106
- const voicesDir = path.join(os.homedir(), '.claude', 'piper-voices');
107
- try {
108
- const models = fs.readdirSync(voicesDir).filter(f => f.endsWith('.onnx'));
109
- if (models.length > 0) return models[0].replace(/\.onnx$/, '');
110
- } catch { /* dir may not exist */ }
111
- return null;
112
- }
113
-
114
- /**
115
- * Sets the active voice ID in config.
116
- * Writes to both project (if exists) and global config for portability.
117
- * @param {string} voiceId
118
- */
119
- setActiveVoice(voiceId) {
120
- this._config.set('voice', voiceId);
121
- this._config.setGlobal('voice', voiceId);
122
- }
123
-
124
- // ---------------------------------------------------------------------------
125
- // Private
126
-
127
- /**
128
- * Check if a binary is available in PATH using `which`.
129
- * Binary names are all hardcoded (not user input) — safe from injection.
130
- * @param {string} binary - hardcoded binary name ('piper', 'soprano', 'say')
131
- * @returns {boolean}
132
- */
133
- _isAvailable(binary) {
134
- try {
135
- execFileSync('which', [binary], { stdio: 'ignore', timeout: 2000 });
136
- return true;
137
- } catch {
138
- return false;
139
- }
140
- }
141
- }
142
-
143
- export default ProviderService;
1
+ /**
2
+ * AgentVibes Provider Service
3
+ * Story 7.1: Provider & Voice Settings Group
4
+ *
5
+ * Detects installed TTS providers, reads/writes active provider and voice
6
+ * through ConfigService. Gracefully degrades when detection fails.
7
+ */
8
+
9
+ import { execFileSync } from 'node:child_process';
10
+ import fs from 'node:fs';
11
+ import path from 'node:path';
12
+ import os from 'node:os';
13
+
14
+ export class ProviderService {
15
+ /**
16
+ * @param {import('./config-service.js').ConfigService} configService
17
+ */
18
+ constructor(configService) {
19
+ this._config = configService;
20
+ this._installedProviders = null; // cached after first detection
21
+ }
22
+
23
+ // ---------------------------------------------------------------------------
24
+ // Provider
25
+
26
+ /**
27
+ * Returns the currently active TTS provider from config.
28
+ * Defaults to 'piper' if not configured.
29
+ * @returns {string}
30
+ */
31
+ getActiveProvider() {
32
+ return this._config.getConfig().provider ?? 'piper';
33
+ }
34
+
35
+ /**
36
+ * Sets the active TTS provider in config AND syncs to .claude/tts-provider.txt
37
+ * so the shell hooks (play-tts.sh → provider-manager.sh) pick up the change.
38
+ * @param {string} provider
39
+ */
40
+ setActiveProvider(provider) {
41
+ this._config.set('provider', provider);
42
+ this._config.setGlobal('provider', provider);
43
+ this._syncProviderFile(provider);
44
+ }
45
+
46
+ /**
47
+ * Write provider to .claude/tts-provider.txt so shell hooks stay in sync.
48
+ * Writes to projectRoot/.claude/tts-provider.txt if .claude/ exists there,
49
+ * otherwise falls back to ~/.claude/tts-provider.txt.
50
+ * @param {string} provider
51
+ */
52
+ _syncProviderFile(provider) {
53
+ try {
54
+ const projectClaudeDir = path.resolve(this._config.getProjectRoot(), '.claude');
55
+ const targetDir = fs.existsSync(projectClaudeDir)
56
+ ? projectClaudeDir
57
+ : path.resolve(os.homedir(), '.claude');
58
+ const targetFile = path.resolve(targetDir, 'tts-provider.txt');
59
+ // Verify resolved path stays within targetDir (path traversal guard)
60
+ if (!targetFile.startsWith(targetDir + path.sep) && targetFile !== targetDir) return;
61
+ fs.mkdirSync(targetDir, { recursive: true });
62
+ fs.writeFileSync(targetFile, provider, 'utf8');
63
+ } catch {
64
+ // Non-fatal — config.json is the authoritative source
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Returns an array of installed/available TTS providers.
70
+ * Detection uses `which` binary check. Always returns at least ['piper']
71
+ * as graceful degradation (piper is the primary supported provider).
72
+ * @returns {string[]}
73
+ */
74
+ getInstalledProviders() {
75
+ if (this._installedProviders) return this._installedProviders;
76
+
77
+ const providers = [];
78
+
79
+ if (this._isAvailable('piper')) providers.push('piper');
80
+ if (this._isAvailable('soprano')) providers.push('soprano');
81
+
82
+ // macOS Say (darwin only)
83
+ if (process.platform === 'darwin' && this._isAvailable('say')) {
84
+ providers.push('macos');
85
+ }
86
+
87
+ // Graceful degradation: always return at least piper
88
+ if (providers.length === 0) providers.push('piper');
89
+
90
+ this._installedProviders = providers;
91
+ return providers;
92
+ }
93
+
94
+ // ---------------------------------------------------------------------------
95
+ // Voice
96
+
97
+ /**
98
+ * Returns the currently active voice ID from config.
99
+ * Falls back to first installed voice if not configured.
100
+ * @returns {string|null}
101
+ */
102
+ getActiveVoiceId() {
103
+ const voice = this._config.getConfig().voice;
104
+ if (voice) return voice;
105
+ // Detect first installed voice instead of hardcoding a default that may not exist
106
+ const voicesDir = path.join(os.homedir(), '.claude', 'piper-voices');
107
+ try {
108
+ const models = fs.readdirSync(voicesDir).filter(f => f.endsWith('.onnx'));
109
+ if (models.length > 0) return models[0].replace(/\.onnx$/, '');
110
+ } catch { /* dir may not exist */ }
111
+ return null;
112
+ }
113
+
114
+ /**
115
+ * Sets the active voice ID in config.
116
+ * Writes to both project (if exists) and global config for portability.
117
+ * @param {string} voiceId
118
+ */
119
+ setActiveVoice(voiceId) {
120
+ this._config.set('voice', voiceId);
121
+ this._config.setGlobal('voice', voiceId);
122
+ }
123
+
124
+ // ---------------------------------------------------------------------------
125
+ // Private
126
+
127
+ /**
128
+ * Check if a binary is available in PATH using `which`.
129
+ * Binary names are all hardcoded (not user input) — safe from injection.
130
+ * @param {string} binary - hardcoded binary name ('piper', 'soprano', 'say')
131
+ * @returns {boolean}
132
+ */
133
+ _isAvailable(binary) {
134
+ try {
135
+ execFileSync('which', [binary], { stdio: 'ignore', timeout: 2000 }); // NOSONAR
136
+ return true;
137
+ } catch {
138
+ return false;
139
+ }
140
+ }
141
+ }
142
+
143
+ export default ProviderService;
@@ -49,10 +49,10 @@ export function checkEngineInstalled(engineId) {
49
49
  (process.env.USERPROFILE ? path.join(process.env.USERPROFILE, 'AppData', 'Local') : null);
50
50
  if (localAppData && fs.existsSync(path.join(localAppData, 'Programs', 'Piper', 'piper.exe'))) return true;
51
51
  }
52
- execFileSync('where', [binary], { stdio: 'ignore', timeout: 2000 });
52
+ execFileSync('where', [binary], { stdio: 'ignore', timeout: 2000 }); // NOSONAR
53
53
  return true;
54
54
  }
55
- execFileSync('which', [binary], { stdio: 'ignore', timeout: 2000 });
55
+ execFileSync('which', [binary], { stdio: 'ignore', timeout: 2000 }); // NOSONAR
56
56
  return true;
57
57
  } catch {
58
58
  // try next binary