agentvibes 5.0.0 → 5.1.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.
package/src/installer.js CHANGED
@@ -2437,7 +2437,10 @@ async function collectConfiguration(options = {}) {
2437
2437
  { name: '🌺 Hawaiian Slack Key Guitar ' + chalk.gray('[SPACE to preview]'), value: 'agent_vibes_hawaiian_slack_key_guitar_v2_loop.mp3' },
2438
2438
  { name: '🏜️ Arabic Oud (Middle Eastern) ' + chalk.gray('[SPACE to preview]'), value: 'agent_vibes_arabic_v2_loop.mp3' },
2439
2439
  { name: '🪘 Gnawa Ambient (North African) ' + chalk.gray('[SPACE to preview]'), value: 'agent_vibes_ganawa_ambient_v2_loop.mp3' },
2440
- { name: '🥁 Tabla Dream Pop (Indian percussion) ' + chalk.gray('[SPACE to preview]'), value: 'agent_vibes_tabla_dream_pop_v1_loop.mp3' }
2440
+ { name: '🥁 Tabla Dream Pop (Indian percussion) ' + chalk.gray('[SPACE to preview]'), value: 'agent_vibes_tabla_dream_pop_v1_loop.mp3' },
2441
+ { name: '🎤 Late Night Hip Hop Groove ' + chalk.gray('[SPACE to preview]'), value: 'Late Night Hip Hop Groove.mp3' },
2442
+ { name: '🌃 Drifting Down the Hall (90s Vibes) ' + chalk.gray('[SPACE to preview]'), value: 'Drifting Down the Hall.mp3' },
2443
+ { name: '🎩 Midnight Charleston Stomp (Swing) ' + chalk.gray('[SPACE to preview]'), value: 'Midnight Charleston Stomp.mp3' }
2441
2444
  ];
2442
2445
 
2443
2446
  // Add custom tracks separator and options if any exist
@@ -3582,7 +3585,6 @@ async function copyPluginFiles(targetDir, spinner) {
3582
3585
  pluginFiles.push(file);
3583
3586
  const destPath = path.join(destPluginsDir, file);
3584
3587
  await fs.copyFile(srcPath, destPath);
3585
- console.log(chalk.gray(` ✓ ${file}`));
3586
3588
  }
3587
3589
  }
3588
3590
  spinner.succeed(chalk.green('Installed BMAD plugin files!\n'));
@@ -3616,7 +3618,6 @@ async function copyBmadConfigFiles(targetDir, spinner) {
3616
3618
  await fs.access(srcPath);
3617
3619
  const destPath = path.join(destBmadDir, bmadVoicesFile);
3618
3620
  await fs.copyFile(srcPath, destPath);
3619
- console.log(chalk.gray(` ✓ ${bmadVoicesFile}`));
3620
3621
  fileCount++;
3621
3622
  spinner.succeed(chalk.green('Installed BMAD config files!\n'));
3622
3623
  } catch (error) {
@@ -3705,7 +3706,10 @@ async function copyBackgroundMusicFiles(targetDir, spinner) {
3705
3706
  'agentvibes_funk_loop.mp3': '🕺',
3706
3707
  'agentvibes_reggae_loop.mp3': '🌴',
3707
3708
  'agentvibes_blues_loop.mp3': '🎸',
3708
- 'agentvibes_classical_loop.mp3': '🎻'
3709
+ 'agentvibes_classical_loop.mp3': '🎻',
3710
+ 'Late Night Hip Hop Groove.mp3': '🎤',
3711
+ 'Drifting Down the Hall.mp3': '🌃',
3712
+ 'Midnight Charleston Stomp.mp3': '🎩'
3709
3713
  };
3710
3714
 
3711
3715
  const tracks = musicFiles.map(track => ({
@@ -3784,10 +3788,6 @@ async function copyConfigFiles(targetDir, spinner) {
3784
3788
 
3785
3789
  if (copiedFiles.length > 0) {
3786
3790
  spinner.succeed(chalk.green(`Installed ${copiedFiles.length} config file${copiedFiles.length === 1 ? '' : 's'}!\n`));
3787
- copiedFiles.forEach(file => {
3788
- console.log(chalk.gray(` ✓ ${file}`));
3789
- });
3790
- console.log(''); // Add blank line for spacing
3791
3791
  } else {
3792
3792
  spinner.info(chalk.gray('Config files already exist, skipping\n'));
3793
3793
  }
@@ -139,6 +139,85 @@ export async function removeClaudeMcp(targetDir) {
139
139
  return { success: true };
140
140
  }
141
141
 
142
+ /**
143
+ * Full uninstall: remove MCP entry + all AgentVibes files from the project.
144
+ * Does NOT touch user's own .claude/ settings (settings.json, CLAUDE.md etc.).
145
+ */
146
+ export async function uninstallClaude(targetDir) {
147
+ const removed = [];
148
+
149
+ // 1. Remove MCP entry
150
+ await removeClaudeMcp(targetDir);
151
+ removed.push('.mcp.json (agentvibes entry)');
152
+
153
+ // 2. Remove AgentVibes directories
154
+ const dirs = [
155
+ ['.claude', 'commands', 'agent-vibes'],
156
+ ['.claude', 'hooks'],
157
+ ['.claude', 'hooks-windows'],
158
+ ['.claude', 'personalities'],
159
+ ['.claude', 'output-styles'],
160
+ ['.claude', 'plugins'],
161
+ ['.claude', 'audio'],
162
+ ['.claude', 'config'],
163
+ ['.agentvibes'],
164
+ ];
165
+
166
+ for (const parts of dirs) {
167
+ const dirPath = path.join(targetDir, ...parts);
168
+ try {
169
+ await fs.rm(dirPath, { recursive: true, force: true });
170
+ removed.push(parts.join('/'));
171
+ } catch { /* doesn't exist */ }
172
+ }
173
+
174
+ // 3. Remove AgentVibes config files from .claude/
175
+ const configFiles = [
176
+ 'tts-voice.txt', 'tts-provider.txt', 'tts-personality.txt',
177
+ 'tts-verbosity.txt', 'tts-translate.txt', 'tts-target-voice.txt',
178
+ 'tts-target-language.txt', 'tts-language.txt', 'tts-speech-rate.txt',
179
+ 'tts-target-speech-rate.txt', 'piper-speech-rate.txt',
180
+ 'piper-target-speech-rate.txt', 'personalities.json',
181
+ 'github-star-reminder.txt', 'piper-voices-dir.txt',
182
+ 'verbosity.txt', 'personality.txt', 'intro-text.txt',
183
+ 'reverb-level.txt', 'background-music-enabled.txt',
184
+ 'background-music-volume.txt',
185
+ ];
186
+
187
+ for (const file of configFiles) {
188
+ try {
189
+ await fs.unlink(path.join(targetDir, '.claude', file));
190
+ } catch { /* doesn't exist */ }
191
+ }
192
+
193
+ // 4. Remove settings.json hook entries if present
194
+ const settingsPath = path.join(targetDir, '.claude', 'settings.json');
195
+ try {
196
+ const content = await fs.readFile(settingsPath, 'utf8');
197
+ const settings = JSON.parse(content);
198
+ let changed = false;
199
+ if (settings.hooks) {
200
+ for (const hookKey of Object.keys(settings.hooks)) {
201
+ const hooks = settings.hooks[hookKey];
202
+ if (Array.isArray(hooks)) {
203
+ const filtered = hooks.filter(h =>
204
+ !(h.command && (h.command.includes('agentvibes') || h.command.includes('play-tts') || h.command.includes('bmad-speak'))));
205
+ if (filtered.length !== hooks.length) {
206
+ settings.hooks[hookKey] = filtered;
207
+ changed = true;
208
+ }
209
+ }
210
+ }
211
+ }
212
+ if (changed) {
213
+ await fs.writeFile(settingsPath, JSON.stringify(settings, null, 2) + '\n');
214
+ removed.push('.claude/settings.json (hooks cleaned)');
215
+ }
216
+ } catch { /* no settings or parse error */ }
217
+
218
+ return { success: true, removed };
219
+ }
220
+
142
221
  // ── Copilot install/remove ──────────────────────────────────────────────────
143
222
 
144
223
  export async function installCopilotMcp(targetDir) {