agentvibes 5.6.9 → 5.7.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 +3 -38
- package/.claude/commands/agent-vibes/provider.md +0 -0
- package/.claude/config/audio-effects.cfg +1 -1
- package/.claude/config/background-music-position.txt +6 -8
- package/.claude/config/reverb-level.txt +0 -0
- package/.claude/github-star-reminder.txt +1 -1
- package/.claude/hooks/bmad-tts-injector.sh +49 -21
- package/.claude/hooks/provider-commands.sh +16 -4
- package/.claude/hooks/provider-manager.sh +38 -0
- package/.claude/hooks/stop.sh +2 -27
- package/.claude/hooks/voice-manager.sh +50 -2
- package/.claude/hooks-windows/play-tts.ps1 +34 -1
- package/.claude/hooks-windows/tts-watcher.ps1 +122 -0
- package/.claude/piper-voices-dir.txt +1 -1
- package/.mcp.json +13 -33
- package/README.md +6 -8
- package/RELEASE_NOTES.md +32 -0
- package/bin/agent-vibes +39 -39
- package/package.json +1 -1
- package/src/bmad-detector.js +85 -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/brand-colors.js +13 -13
- package/src/console/constants/personalities.js +44 -44
- package/src/console/tabs/help-tab.js +314 -314
- package/src/console/tabs/readme-tab.js +272 -272
- package/src/console/widgets/destroy-list.js +25 -25
- package/src/console/widgets/notice.js +55 -55
- package/src/console/widgets/personality-picker.js +213 -213
- package/src/i18n/de.js +202 -202
- package/src/i18n/es.js +202 -202
- package/src/i18n/fr.js +202 -202
- package/src/i18n/hi.js +202 -202
- package/src/i18n/ja.js +202 -202
- package/src/i18n/ko.js +202 -202
- package/src/i18n/pt.js +202 -202
- package/src/i18n/strings.js +54 -54
- package/src/i18n/zh-CN.js +202 -202
- package/src/installer/language-screen.js +31 -31
- package/src/installer/music-file-input.js +304 -304
- package/src/installer.js +70 -7
- package/src/services/agent-voice-store.js +59 -12
- package/src/services/config-service.js +264 -264
- package/src/services/language-service.js +47 -47
- package/src/services/provider-service.js +143 -143
- 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 -469
- 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 -285
- package/src/utils/preview-list-prompt.js +136 -136
- package/src/utils/secure-music-storage.js +412 -412
- package/.agentvibes/LITE-MODE.md +0 -236
- package/.agentvibes/README.md +0 -136
- package/.agentvibes/backup/session-start-tts.sh.20251210_212814 +0 -141
- package/.agentvibes/backups/agents/analyst_20260204_144958.md +0 -78
- package/.agentvibes/backups/agents/architect_20260204_144958.md +0 -72
- package/.agentvibes/backups/agents/dev_20260204_144958.md +0 -74
- package/.agentvibes/backups/agents/pm_20260204_144958.md +0 -72
- package/.agentvibes/backups/agents/quick-flow-solo-dev_20260204_144958.md +0 -64
- package/.agentvibes/backups/agents/sm_20260204_144958.md +0 -87
- package/.agentvibes/backups/agents/tea_20260204_144958.md +0 -79
- package/.agentvibes/backups/agents/tech-writer_20260204_144958.md +0 -82
- package/.agentvibes/backups/agents/ux-designer_20260204_144958.md +0 -80
- package/.agentvibes/config/README-personality-defaults.md +0 -162
- package/.agentvibes/config/agentvibes.json +0 -1
- package/.agentvibes/config/mode.txt +0 -1
- package/.agentvibes/config/personality-voice-defaults.default.json +0 -21
- package/.agentvibes/config/save-audio.txt +0 -1
- package/.agentvibes/config/voice-metadata.json +0 -160
- package/.agentvibes/hooks/help.sh +0 -191
- package/.agentvibes/hooks/post-tool-use-lite.sh +0 -111
- package/.agentvibes/hooks/save-audio-manager.sh +0 -162
- package/.agentvibes/hooks/session-start-full-optimized.sh +0 -102
- package/.agentvibes/hooks/session-start-full.sh +0 -142
- package/.agentvibes/hooks/session-start-lite-v2.sh +0 -34
- package/.agentvibes/hooks/session-start-lite.sh +0 -29
- package/.agentvibes/hooks/stop-lite.sh +0 -115
- package/.agentvibes/hooks/switch-mode.sh +0 -215
- package/.agentvibes/output-styles/audio-summary.md +0 -30
- 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/hooks/post-response.sh +0 -41
- package/bin/ensure-soprano-running.sh +0 -43
package/src/installer.js
CHANGED
|
@@ -4570,9 +4570,8 @@ async function handleMcpConfiguration(targetDir, options) {
|
|
|
4570
4570
|
* @param {string} targetDir - Base installation directory to validate bmadPath is within
|
|
4571
4571
|
*/
|
|
4572
4572
|
async function processBmadTtsInjections(bmadPath, targetDir) {
|
|
4573
|
-
// Security:
|
|
4574
|
-
|
|
4575
|
-
if (!isPathSafe(bmadPath, targetDir)) {
|
|
4573
|
+
// Security: bmadPath must be within targetDir OR home dir (BMAD may be installed globally at ~/_bmad)
|
|
4574
|
+
if (!isPathSafe(bmadPath, targetDir) && !isPathSafe(bmadPath, os.homedir())) {
|
|
4576
4575
|
console.error(chalk.red('⚠️ Security: Invalid BMAD path detected'));
|
|
4577
4576
|
return;
|
|
4578
4577
|
}
|
|
@@ -4841,14 +4840,17 @@ async function handleBmadIntegration(targetDir, options = {}) {
|
|
|
4841
4840
|
}
|
|
4842
4841
|
|
|
4843
4842
|
// Process TTS_INJECTION markers in BMAD files if they exist
|
|
4844
|
-
//
|
|
4845
|
-
|
|
4843
|
+
// Skip for global home-dir BMAD installs — only inject into project-local BMAD
|
|
4844
|
+
if (!bmadDetection.isGlobal) {
|
|
4845
|
+
await processBmadTtsInjections(bmadDetection.bmadPath, targetDir);
|
|
4846
|
+
}
|
|
4846
4847
|
|
|
4847
4848
|
// Create default voice assignments if they don't exist
|
|
4848
4849
|
await createDefaultBmadVoiceAssignmentsProactive(targetDir);
|
|
4849
4850
|
|
|
4850
4851
|
// Prompt user to inject TTS into BMAD agents (or auto-inject with --yes flag)
|
|
4851
|
-
|
|
4852
|
+
// Skip injection prompt for global BMAD — modifying shared ~/.bmad files from a project install is wrong
|
|
4853
|
+
let enableTtsInjection = bmadDetection.isGlobal ? false : options.yes;
|
|
4852
4854
|
|
|
4853
4855
|
if (!options.yes) {
|
|
4854
4856
|
console.log(''); // Add spacing
|
|
@@ -5047,7 +5049,7 @@ async function updateCommandFiles(targetDir, spinner) {
|
|
|
5047
5049
|
* on every `npx agentvibes update` regardless of target directory.
|
|
5048
5050
|
*/
|
|
5049
5051
|
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'];
|
|
5052
|
+
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', 'tts-watcher.ps1'];
|
|
5051
5053
|
|
|
5052
5054
|
/**
|
|
5053
5055
|
* Update critical hooks in the global ~/.claude/hooks/ directory if it exists.
|
|
@@ -5094,6 +5096,59 @@ async function updateGlobalHooks(srcHooksDir, homeDirOverride) {
|
|
|
5094
5096
|
return updated;
|
|
5095
5097
|
}
|
|
5096
5098
|
|
|
5099
|
+
/**
|
|
5100
|
+
* Restart the AgentVibes TTS queue watcher on Windows after an update.
|
|
5101
|
+
* Only runs if the watcher is already installed (~/.agentvibes/tts-watcher.ps1 exists),
|
|
5102
|
+
* meaning the user previously ran setup-ssh-receiver.ps1. Silently skips for users
|
|
5103
|
+
* who don't use the SSH remote receiver.
|
|
5104
|
+
* @param {string} [homeDirOverride] - Override home dir (for testing only)
|
|
5105
|
+
* @returns {Promise<boolean>} true if watcher was restarted, false if skipped
|
|
5106
|
+
*/
|
|
5107
|
+
async function restartWatcherIfInstalled(homeDirOverride) {
|
|
5108
|
+
if (!isNativeWindows()) return false;
|
|
5109
|
+
|
|
5110
|
+
const homeDir = homeDirOverride || os.homedir();
|
|
5111
|
+
const watcherDest = path.join(homeDir, '.agentvibes', 'tts-watcher.ps1');
|
|
5112
|
+
const vbsLauncher = path.join(homeDir, '.agentvibes', 'start-watcher.vbs');
|
|
5113
|
+
|
|
5114
|
+
// Only act if the user has the SSH receiver set up
|
|
5115
|
+
try {
|
|
5116
|
+
await fs.access(watcherDest);
|
|
5117
|
+
} catch {
|
|
5118
|
+
return false;
|
|
5119
|
+
}
|
|
5120
|
+
|
|
5121
|
+
const { spawnSync, spawn } = require('child_process');
|
|
5122
|
+
|
|
5123
|
+
// Kill old watcher — use array args to avoid quoting issues
|
|
5124
|
+
spawnSync('powershell.exe', [
|
|
5125
|
+
'-NoProfile', '-Command',
|
|
5126
|
+
'Get-CimInstance Win32_Process | Where-Object { $_.CommandLine -like \'*tts-watcher.ps1*\' } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }'
|
|
5127
|
+
], { stdio: 'ignore', timeout: 8000 });
|
|
5128
|
+
|
|
5129
|
+
// Copy updated watcher from global hooks to the deployed location
|
|
5130
|
+
const watcherSrc = path.join(homeDir, '.claude', 'hooks-windows', 'tts-watcher.ps1');
|
|
5131
|
+
try {
|
|
5132
|
+
await fs.copyFile(watcherSrc, watcherDest);
|
|
5133
|
+
} catch {
|
|
5134
|
+
// src may not exist on a fresh install path — skip copy, the file was already
|
|
5135
|
+
// put there by updateGlobalHooks() earlier in the same run
|
|
5136
|
+
}
|
|
5137
|
+
|
|
5138
|
+
// Restart via VBS launcher (hidden, no console flash) or fall back to direct spawn
|
|
5139
|
+
try {
|
|
5140
|
+
await fs.access(vbsLauncher);
|
|
5141
|
+
spawnSync('wscript.exe', [vbsLauncher], { stdio: 'ignore' });
|
|
5142
|
+
} catch {
|
|
5143
|
+
const ps = spawn('powershell.exe', [
|
|
5144
|
+
'-NoProfile', '-ExecutionPolicy', 'Bypass', '-WindowStyle', 'Hidden', '-File', watcherDest
|
|
5145
|
+
], { detached: true, stdio: 'ignore' });
|
|
5146
|
+
ps.unref();
|
|
5147
|
+
}
|
|
5148
|
+
|
|
5149
|
+
return true;
|
|
5150
|
+
}
|
|
5151
|
+
|
|
5097
5152
|
/**
|
|
5098
5153
|
* Perform all update operations
|
|
5099
5154
|
* @param {string} targetDir - Target installation directory
|
|
@@ -5120,6 +5175,14 @@ async function performUpdateOperations(targetDir, spinner) {
|
|
|
5120
5175
|
console.log(chalk.green(`✓ Updated ${globalHooksUpdated} critical scripts in ~/.claude/hooks/`));
|
|
5121
5176
|
}
|
|
5122
5177
|
|
|
5178
|
+
// On Windows: restart the TTS queue watcher if it was previously installed via
|
|
5179
|
+
// setup-ssh-receiver.ps1. This propagates hook updates without requiring the
|
|
5180
|
+
// user to manually run update-watcher.ps1 after every `npx agentvibes update`.
|
|
5181
|
+
const watcherRestarted = await restartWatcherIfInstalled();
|
|
5182
|
+
if (watcherRestarted) {
|
|
5183
|
+
console.log(chalk.green('✓ TTS watcher restarted with updated scripts'));
|
|
5184
|
+
}
|
|
5185
|
+
|
|
5123
5186
|
// Update personalities
|
|
5124
5187
|
spinner.text = 'Updating personality templates...';
|
|
5125
5188
|
const srcPersonalitiesDir = path.join(__dirname, '..', '.claude', 'personalities');
|
|
@@ -109,9 +109,17 @@ export function isSingleVoiceProvider(provider) {
|
|
|
109
109
|
*/
|
|
110
110
|
export function parseBmadManifest(projectRoot) {
|
|
111
111
|
const safeRoot = path.resolve(projectRoot ?? process.cwd());
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
112
|
+
// Check project-local first, then home dir (global BMAD install)
|
|
113
|
+
const roots = [safeRoot];
|
|
114
|
+
const homeDir = os.homedir();
|
|
115
|
+
if (safeRoot !== homeDir) roots.push(homeDir);
|
|
116
|
+
|
|
117
|
+
let manifestPath = null;
|
|
118
|
+
for (const root of roots) {
|
|
119
|
+
const candidate = path.resolve(root, '_bmad', '_config', 'agent-manifest.csv');
|
|
120
|
+
if (fs.existsSync(candidate)) { manifestPath = candidate; break; }
|
|
121
|
+
}
|
|
122
|
+
if (!manifestPath) return [];
|
|
115
123
|
|
|
116
124
|
try {
|
|
117
125
|
const raw = fs.readFileSync(manifestPath, 'utf8');
|
|
@@ -196,11 +204,32 @@ export function scanBmadAgents(projectRoot) {
|
|
|
196
204
|
const fromManifest = parseBmadManifest(projectRoot);
|
|
197
205
|
if (fromManifest.length > 0) return fromManifest;
|
|
198
206
|
|
|
199
|
-
// Fallback: directory scan
|
|
207
|
+
// Fallback: directory scan — check project-local then home dir
|
|
200
208
|
const safeRoot = path.resolve(projectRoot ?? process.cwd());
|
|
209
|
+
const homeDir2 = os.homedir();
|
|
210
|
+
|
|
211
|
+
// v6.6+: agents under .claude/skills/*/agents/ — collect all such dirs
|
|
212
|
+
const skillsAgentDirs = [];
|
|
213
|
+
for (const root of (safeRoot !== homeDir2 ? [safeRoot, homeDir2] : [safeRoot])) {
|
|
214
|
+
const skillsDir = path.resolve(root, '.claude', 'skills');
|
|
215
|
+
if (fs.existsSync(skillsDir)) {
|
|
216
|
+
try {
|
|
217
|
+
for (const skill of fs.readdirSync(skillsDir)) {
|
|
218
|
+
const agentsDir = path.resolve(skillsDir, skill, 'agents');
|
|
219
|
+
if (fs.existsSync(agentsDir)) skillsAgentDirs.push(agentsDir);
|
|
220
|
+
}
|
|
221
|
+
} catch { /* skip */ }
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
201
225
|
const candidateDirs = [
|
|
202
226
|
path.resolve(safeRoot, '_bmad', 'bmm', 'agents'),
|
|
203
227
|
path.resolve(safeRoot, '.bmad', 'agents'),
|
|
228
|
+
...(safeRoot !== homeDir2 ? [
|
|
229
|
+
path.resolve(homeDir2, '_bmad', 'bmm', 'agents'),
|
|
230
|
+
path.resolve(homeDir2, '.bmad', 'agents'),
|
|
231
|
+
] : []),
|
|
232
|
+
...skillsAgentDirs,
|
|
204
233
|
];
|
|
205
234
|
|
|
206
235
|
for (const dir of candidateDirs) {
|
|
@@ -232,15 +261,33 @@ export function scanBmadAgents(projectRoot) {
|
|
|
232
261
|
*/
|
|
233
262
|
export function isBmadDetected(projectRoot) {
|
|
234
263
|
const safeRoot = path.resolve(projectRoot ?? process.cwd());
|
|
235
|
-
const
|
|
236
|
-
if (fs.existsSync(manifestPath)) return true;
|
|
264
|
+
const homeDir = os.homedir();
|
|
237
265
|
|
|
238
|
-
//
|
|
239
|
-
const
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
266
|
+
// Check project-local first, then home-dir (BMAD can be installed globally at ~/_bmad)
|
|
267
|
+
const roots = safeRoot !== homeDir ? [safeRoot, homeDir] : [safeRoot];
|
|
268
|
+
|
|
269
|
+
for (const root of roots) {
|
|
270
|
+
// v6.x: agent-manifest.csv; v6.6+: manifest.yaml only (no agent-manifest.csv)
|
|
271
|
+
if (fs.existsSync(path.resolve(root, '_bmad', '_config', 'agent-manifest.csv'))) return true;
|
|
272
|
+
if (fs.existsSync(path.resolve(root, '_bmad', '_config', 'manifest.yaml'))) return true;
|
|
273
|
+
|
|
274
|
+
const dirs = [
|
|
275
|
+
path.resolve(root, '_bmad', 'bmm', 'agents'),
|
|
276
|
+
path.resolve(root, '.bmad', 'agents'),
|
|
277
|
+
];
|
|
278
|
+
if (dirs.some(d => fs.existsSync(d))) return true;
|
|
279
|
+
|
|
280
|
+
// v6.6+: agents live under .claude/skills/*/agents/
|
|
281
|
+
const skillsDir = path.resolve(root, '.claude', 'skills');
|
|
282
|
+
if (fs.existsSync(skillsDir)) {
|
|
283
|
+
try {
|
|
284
|
+
const skills = fs.readdirSync(skillsDir);
|
|
285
|
+
if (skills.some(s => fs.existsSync(path.resolve(skillsDir, s, 'agents')))) return true;
|
|
286
|
+
} catch { /* skip */ }
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
return false;
|
|
244
291
|
}
|
|
245
292
|
|
|
246
293
|
// ---------------------------------------------------------------------------
|