agentvibes 2.0.5 → 2.0.7
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/.claude/commands/agent-vibes/preview.md +5 -4
- package/.claude/hooks/language-manager.sh +50 -48
- package/.claude/hooks/piper-voice-manager.sh +37 -4
- package/.claude/hooks/play-tts-piper.sh +1 -1
- package/.claude/hooks/play-tts.sh +29 -127
- package/.claude/hooks/provider-commands.sh +41 -2
- package/.claude/piper-voices-dir.txt +1 -0
- package/README.md +2 -2
- package/RELEASE_NOTES.md +202 -0
- package/package.json +1 -1
- package/src/installer.js +367 -170
- package/agentvibes.org/.claude/commands/agent-vibes/add.md +0 -21
- package/agentvibes.org/.claude/commands/agent-vibes/agent-vibes.md +0 -68
- package/agentvibes.org/.claude/commands/agent-vibes/commands.json +0 -53
- package/agentvibes.org/.claude/commands/agent-vibes/get.md +0 -9
- package/agentvibes.org/.claude/commands/agent-vibes/list.md +0 -13
- package/agentvibes.org/.claude/commands/agent-vibes/personality.md +0 -79
- package/agentvibes.org/.claude/commands/agent-vibes/preview.md +0 -16
- package/agentvibes.org/.claude/commands/agent-vibes/provider.md +0 -54
- package/agentvibes.org/.claude/commands/agent-vibes/replay.md +0 -19
- package/agentvibes.org/.claude/commands/agent-vibes/sample.md +0 -12
- package/agentvibes.org/.claude/commands/agent-vibes/sentiment.md +0 -52
- package/agentvibes.org/.claude/commands/agent-vibes/set-language.md +0 -47
- package/agentvibes.org/.claude/commands/agent-vibes/set-pretext.md +0 -65
- package/agentvibes.org/.claude/commands/agent-vibes/switch.md +0 -53
- package/agentvibes.org/.claude/commands/agent-vibes/update.md +0 -20
- package/agentvibes.org/.claude/commands/agent-vibes/version.md +0 -10
- package/agentvibes.org/.claude/commands/agent-vibes/whoami.md +0 -7
- package/agentvibes.org/.claude/journal/2025-10-07.html +0 -373
- package/agentvibes.org/.claude/journal/index.html +0 -91
- package/agentvibes.org/.mcp-minimal.json +0 -60
- package/agentvibes.org/CHANGELOG.md +0 -56
- package/agentvibes.org/README.md +0 -93
- package/agentvibes.org/app/(auth)/layout.tsx +0 -15
- package/agentvibes.org/app/(auth)/reset-password/page.tsx +0 -45
- package/agentvibes.org/app/(auth)/signin/page.tsx +0 -82
- package/agentvibes.org/app/(auth)/signup/page.tsx +0 -104
- package/agentvibes.org/app/(default)/layout.tsx +0 -31
- package/agentvibes.org/app/(default)/page.tsx +0 -20
- package/agentvibes.org/app/api/hello/route.ts +0 -3
- package/agentvibes.org/app/css/additional-styles/theme.css +0 -82
- package/agentvibes.org/app/css/additional-styles/utility-patterns.css +0 -55
- package/agentvibes.org/app/css/style.css +0 -100
- package/agentvibes.org/app/layout.tsx +0 -63
- package/agentvibes.org/components/cta.tsx +0 -58
- package/agentvibes.org/components/features.tsx +0 -256
- package/agentvibes.org/components/hero-home.tsx +0 -133
- package/agentvibes.org/components/modal-video.tsx +0 -137
- package/agentvibes.org/components/page-illustration.tsx +0 -55
- package/agentvibes.org/components/spotlight.tsx +0 -77
- package/agentvibes.org/components/testimonials.tsx +0 -282
- package/agentvibes.org/components/ui/footer.tsx +0 -82
- package/agentvibes.org/components/ui/header.tsx +0 -53
- package/agentvibes.org/components/ui/logo.tsx +0 -10
- package/agentvibes.org/components/workflows.tsx +0 -176
- package/agentvibes.org/next.config.js +0 -4
- package/agentvibes.org/package-lock.json +0 -1974
- package/agentvibes.org/package.json +0 -30
- package/agentvibes.org/pnpm-lock.yaml +0 -1141
- package/agentvibes.org/postcss.config.js +0 -5
- package/agentvibes.org/public/audio/02-sarcastic.mp3 +0 -0
- package/agentvibes.org/public/audio/03-angry.mp3 +0 -0
- package/agentvibes.org/public/audio/04-grandpa.mp3 +0 -0
- package/agentvibes.org/public/audio/05-sarcastic-example2.mp3 +0 -0
- package/agentvibes.org/public/audio/french-rachel.mp3 +0 -0
- package/agentvibes.org/public/audio/spanish-antoni.mp3 +0 -0
- package/agentvibes.org/public/favicon.ico +0 -0
- package/agentvibes.org/public/fonts/nacelle-italic.woff2 +0 -0
- package/agentvibes.org/public/fonts/nacelle-regular.woff2 +0 -0
- package/agentvibes.org/public/fonts/nacelle-semibold.woff2 +0 -0
- package/agentvibes.org/public/fonts/nacelle-semibolditalic.woff2 +0 -0
- package/agentvibes.org/public/images/blurred-shape-gray.svg +0 -1
- package/agentvibes.org/public/images/blurred-shape.svg +0 -1
- package/agentvibes.org/public/images/client-logo-01.svg +0 -1
- package/agentvibes.org/public/images/client-logo-02.svg +0 -1
- package/agentvibes.org/public/images/client-logo-03.svg +0 -1
- package/agentvibes.org/public/images/client-logo-04.svg +0 -1
- package/agentvibes.org/public/images/client-logo-05.svg +0 -1
- package/agentvibes.org/public/images/client-logo-06.svg +0 -1
- package/agentvibes.org/public/images/client-logo-07.svg +0 -1
- package/agentvibes.org/public/images/client-logo-08.svg +0 -1
- package/agentvibes.org/public/images/client-logo-09.svg +0 -1
- package/agentvibes.org/public/images/features.png +0 -0
- package/agentvibes.org/public/images/footer-illustration.svg +0 -1
- package/agentvibes.org/public/images/hero-image-01.jpg +0 -0
- package/agentvibes.org/public/images/logo.svg +0 -1
- package/agentvibes.org/public/images/page-illustration.svg +0 -1
- package/agentvibes.org/public/images/secondary-illustration.svg +0 -1
- package/agentvibes.org/public/images/testimonial-01.jpg +0 -0
- package/agentvibes.org/public/images/testimonial-02.jpg +0 -0
- package/agentvibes.org/public/images/testimonial-03.jpg +0 -0
- package/agentvibes.org/public/images/testimonial-04.jpg +0 -0
- package/agentvibes.org/public/images/testimonial-05.jpg +0 -0
- package/agentvibes.org/public/images/testimonial-06.jpg +0 -0
- package/agentvibes.org/public/images/testimonial-07.jpg +0 -0
- package/agentvibes.org/public/images/testimonial-08.jpg +0 -0
- package/agentvibes.org/public/images/testimonial-09.jpg +0 -0
- package/agentvibes.org/public/images/workflow-01.png +0 -0
- package/agentvibes.org/public/images/workflow-02.png +0 -0
- package/agentvibes.org/public/images/workflow-03.png +0 -0
- package/agentvibes.org/public/videos/video.mp4 +0 -0
- package/agentvibes.org/tsconfig.json +0 -28
- package/agentvibes.org/utils/useMasonry.tsx +0 -67
- package/agentvibes.org/utils/useMousePosition.tsx +0 -27
package/src/installer.js
CHANGED
|
@@ -68,11 +68,9 @@ async function install(options = {}) {
|
|
|
68
68
|
// When running via npx, process.cwd() returns the npm cache directory
|
|
69
69
|
// Use INIT_CWD (set by npm/npx) to get the actual user's working directory
|
|
70
70
|
const currentDir = process.env.INIT_CWD || process.cwd();
|
|
71
|
-
const targetDir = options.directory || currentDir;
|
|
72
71
|
|
|
73
72
|
console.log(chalk.cyan('\n📍 Installation Details:'));
|
|
74
|
-
console.log(chalk.gray(`
|
|
75
|
-
console.log(chalk.gray(` Install location: ${targetDir}/.claude/ (project-local)`));
|
|
73
|
+
console.log(chalk.gray(` Install location: ${currentDir}/.claude/`));
|
|
76
74
|
console.log(chalk.gray(` Package version: ${VERSION}`));
|
|
77
75
|
|
|
78
76
|
// Show latest release notes from git log
|
|
@@ -96,6 +94,224 @@ async function install(options = {}) {
|
|
|
96
94
|
// Git not available or not a git repo - skip release notes
|
|
97
95
|
}
|
|
98
96
|
|
|
97
|
+
// Provider selection prompt
|
|
98
|
+
let selectedProvider = 'piper';
|
|
99
|
+
let elevenLabsKey = process.env.ELEVENLABS_API_KEY;
|
|
100
|
+
let piperVoicesPath = null;
|
|
101
|
+
|
|
102
|
+
if (!options.yes) {
|
|
103
|
+
console.log(chalk.cyan('🎭 Choose Your TTS Provider:\n'));
|
|
104
|
+
|
|
105
|
+
const { provider } = await inquirer.prompt([
|
|
106
|
+
{
|
|
107
|
+
type: 'list',
|
|
108
|
+
name: 'provider',
|
|
109
|
+
message: 'Which TTS provider would you like to use?',
|
|
110
|
+
choices: [
|
|
111
|
+
{
|
|
112
|
+
name: chalk.green('🆓 Piper TTS (Free, Offline)') + chalk.gray(' - 50+ neural voices, no API key needed'),
|
|
113
|
+
value: 'piper',
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
name: chalk.cyan('🎤 ElevenLabs (Premium)') + chalk.gray(' - 150+ AI voices, requires API key'),
|
|
117
|
+
value: 'elevenlabs',
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
default: 'piper',
|
|
121
|
+
},
|
|
122
|
+
]);
|
|
123
|
+
|
|
124
|
+
selectedProvider = provider;
|
|
125
|
+
|
|
126
|
+
// If Piper selected, ask for voice storage location
|
|
127
|
+
if (selectedProvider === 'piper') {
|
|
128
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE;
|
|
129
|
+
const defaultPiperPath = path.join(homeDir, '.claude', 'piper-voices');
|
|
130
|
+
|
|
131
|
+
console.log(chalk.cyan('\n📁 Piper Voice Storage Location:\n'));
|
|
132
|
+
console.log(chalk.gray(' Piper voice models are ~25MB each. They can be stored globally'));
|
|
133
|
+
console.log(chalk.gray(' to be shared across all your projects, or locally per project.\n'));
|
|
134
|
+
|
|
135
|
+
const { piperPath } = await inquirer.prompt([
|
|
136
|
+
{
|
|
137
|
+
type: 'input',
|
|
138
|
+
name: 'piperPath',
|
|
139
|
+
message: 'Where should Piper voice models be downloaded?',
|
|
140
|
+
default: defaultPiperPath,
|
|
141
|
+
validate: (input) => {
|
|
142
|
+
if (!input || input.trim() === '') {
|
|
143
|
+
return 'Please provide a valid path';
|
|
144
|
+
}
|
|
145
|
+
return true;
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
]);
|
|
149
|
+
|
|
150
|
+
piperVoicesPath = piperPath;
|
|
151
|
+
console.log(chalk.green(`✓ Piper voices will be stored in: ${piperVoicesPath}`));
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// If ElevenLabs selected, handle API key
|
|
155
|
+
if (selectedProvider === 'elevenlabs') {
|
|
156
|
+
if (elevenLabsKey) {
|
|
157
|
+
console.log(chalk.green(`\n✓ ElevenLabs API key detected from environment`));
|
|
158
|
+
console.log(chalk.gray(` Key: ${elevenLabsKey.substring(0, 10)}...`));
|
|
159
|
+
|
|
160
|
+
const { useExisting } = await inquirer.prompt([
|
|
161
|
+
{
|
|
162
|
+
type: 'confirm',
|
|
163
|
+
name: 'useExisting',
|
|
164
|
+
message: 'Use this existing API key?',
|
|
165
|
+
default: true,
|
|
166
|
+
},
|
|
167
|
+
]);
|
|
168
|
+
|
|
169
|
+
if (!useExisting) {
|
|
170
|
+
elevenLabsKey = null;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (!elevenLabsKey) {
|
|
175
|
+
console.log(chalk.yellow('\n⚠️ ElevenLabs API Key Required'));
|
|
176
|
+
console.log(chalk.gray(' Get your free API key at: https://elevenlabs.io'));
|
|
177
|
+
console.log(chalk.gray(' Free tier: 10,000 characters/month\n'));
|
|
178
|
+
|
|
179
|
+
const { setupMethod } = await inquirer.prompt([
|
|
180
|
+
{
|
|
181
|
+
type: 'list',
|
|
182
|
+
name: 'setupMethod',
|
|
183
|
+
message: 'How would you like to set up your API key?',
|
|
184
|
+
choices: [
|
|
185
|
+
{
|
|
186
|
+
name: 'Add to shell config (recommended)',
|
|
187
|
+
value: 'shell',
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
name: 'Enter manually (I\'ll set it up myself later)',
|
|
191
|
+
value: 'manual',
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
name: 'Skip (use Piper TTS instead)',
|
|
195
|
+
value: 'skip',
|
|
196
|
+
},
|
|
197
|
+
],
|
|
198
|
+
},
|
|
199
|
+
]);
|
|
200
|
+
|
|
201
|
+
if (setupMethod === 'skip') {
|
|
202
|
+
console.log(chalk.yellow('\n→ Switching to Piper TTS (free option)\n'));
|
|
203
|
+
selectedProvider = 'piper';
|
|
204
|
+
} else if (setupMethod === 'manual') {
|
|
205
|
+
const { apiKey } = await inquirer.prompt([
|
|
206
|
+
{
|
|
207
|
+
type: 'input',
|
|
208
|
+
name: 'apiKey',
|
|
209
|
+
message: 'Enter your ElevenLabs API key:',
|
|
210
|
+
validate: (input) => input.length > 0 || 'API key cannot be empty',
|
|
211
|
+
},
|
|
212
|
+
]);
|
|
213
|
+
elevenLabsKey = apiKey;
|
|
214
|
+
console.log(chalk.yellow('\n⚠️ Remember to add this to your environment variables later:'));
|
|
215
|
+
console.log(chalk.gray(` export ELEVENLABS_API_KEY="${apiKey}"\n`));
|
|
216
|
+
} else if (setupMethod === 'shell') {
|
|
217
|
+
const { apiKey } = await inquirer.prompt([
|
|
218
|
+
{
|
|
219
|
+
type: 'input',
|
|
220
|
+
name: 'apiKey',
|
|
221
|
+
message: 'Enter your ElevenLabs API key:',
|
|
222
|
+
validate: (input) => input.length > 0 || 'API key cannot be empty',
|
|
223
|
+
},
|
|
224
|
+
]);
|
|
225
|
+
elevenLabsKey = apiKey;
|
|
226
|
+
|
|
227
|
+
// Detect shell
|
|
228
|
+
const shell = process.env.SHELL || '';
|
|
229
|
+
let shellConfig = '';
|
|
230
|
+
let shellName = '';
|
|
231
|
+
|
|
232
|
+
if (shell.includes('zsh')) {
|
|
233
|
+
shellConfig = path.join(process.env.HOME, '.zshrc');
|
|
234
|
+
shellName = 'zsh';
|
|
235
|
+
} else if (shell.includes('bash')) {
|
|
236
|
+
shellConfig = path.join(process.env.HOME, '.bashrc');
|
|
237
|
+
shellName = 'bash';
|
|
238
|
+
} else {
|
|
239
|
+
console.log(chalk.yellow('\n⚠️ Could not detect shell type'));
|
|
240
|
+
console.log(chalk.gray(' Please add manually to your shell config:'));
|
|
241
|
+
console.log(chalk.gray(` export ELEVENLABS_API_KEY="${apiKey}"\n`));
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if (shellConfig && shellName) {
|
|
245
|
+
console.log(chalk.cyan(`\n🐚 Detected shell: ${shellName}`));
|
|
246
|
+
console.log(chalk.gray(` Config file: ${shellConfig}`));
|
|
247
|
+
|
|
248
|
+
const { confirmShell } = await inquirer.prompt([
|
|
249
|
+
{
|
|
250
|
+
type: 'confirm',
|
|
251
|
+
name: 'confirmShell',
|
|
252
|
+
message: `Add ELEVENLABS_API_KEY to ${shellConfig}?`,
|
|
253
|
+
default: true,
|
|
254
|
+
},
|
|
255
|
+
]);
|
|
256
|
+
|
|
257
|
+
if (confirmShell) {
|
|
258
|
+
try {
|
|
259
|
+
const configContent = `\n# ElevenLabs API Key for AgentVibes\nexport ELEVENLABS_API_KEY="${apiKey}"\n`;
|
|
260
|
+
await fs.appendFile(shellConfig, configContent);
|
|
261
|
+
console.log(chalk.green(`\n✓ API key added to ${shellConfig}`));
|
|
262
|
+
console.log(chalk.yellow(' Run this to use immediately: ') + chalk.cyan(`source ${shellConfig}`));
|
|
263
|
+
} catch (error) {
|
|
264
|
+
console.log(chalk.red(`\n✗ Failed to write to ${shellConfig}`));
|
|
265
|
+
console.log(chalk.gray(' Please add manually:'));
|
|
266
|
+
console.log(chalk.gray(` export ELEVENLABS_API_KEY="${apiKey}"\n`));
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
console.log(''); // Spacing
|
|
275
|
+
} else {
|
|
276
|
+
console.log(chalk.green('✓ Auto-confirmed (--yes flag)'));
|
|
277
|
+
// Auto-detect provider based on API key
|
|
278
|
+
if (elevenLabsKey) {
|
|
279
|
+
selectedProvider = 'elevenlabs';
|
|
280
|
+
console.log(chalk.green('✓ Using ElevenLabs (API key detected)\n'));
|
|
281
|
+
} else {
|
|
282
|
+
selectedProvider = 'piper';
|
|
283
|
+
console.log(chalk.green('✓ Using Piper TTS (free option)\n'));
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Use current directory for installation (where installer was run)
|
|
288
|
+
const targetDir = options.directory || currentDir;
|
|
289
|
+
|
|
290
|
+
// Explain why installing in .claude/ and confirm
|
|
291
|
+
if (!options.yes) {
|
|
292
|
+
console.log(chalk.cyan('\n📂 Installation Location:\n'));
|
|
293
|
+
console.log(chalk.white(' AgentVibes will be installed in:'));
|
|
294
|
+
console.log(chalk.yellow(` ${targetDir}/.claude/\n`));
|
|
295
|
+
console.log(chalk.gray(' Why .claude/?'));
|
|
296
|
+
console.log(chalk.gray(' • Claude Code automatically discovers tools in .claude/ directories'));
|
|
297
|
+
console.log(chalk.gray(' • This makes slash commands and TTS features immediately available'));
|
|
298
|
+
console.log(chalk.gray(' • Project-specific installation keeps your setup isolated\n'));
|
|
299
|
+
|
|
300
|
+
const { confirmLocation } = await inquirer.prompt([
|
|
301
|
+
{
|
|
302
|
+
type: 'confirm',
|
|
303
|
+
name: 'confirmLocation',
|
|
304
|
+
message: `Install AgentVibes in ${targetDir}/.claude/ ?`,
|
|
305
|
+
default: true,
|
|
306
|
+
},
|
|
307
|
+
]);
|
|
308
|
+
|
|
309
|
+
if (!confirmLocation) {
|
|
310
|
+
console.log(chalk.red('\n❌ Installation cancelled.\n'));
|
|
311
|
+
process.exit(0);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
99
315
|
console.log(chalk.cyan('\n📦 What will be installed:'));
|
|
100
316
|
console.log(chalk.gray(` • 16 slash commands → ${targetDir}/.claude/commands/agent-vibes/`));
|
|
101
317
|
console.log(chalk.gray(` • Multi-provider TTS system (ElevenLabs + Piper TTS) → ${targetDir}/.claude/hooks/`));
|
|
@@ -106,13 +322,13 @@ async function install(options = {}) {
|
|
|
106
322
|
console.log(chalk.gray(` • 30+ language support with native voices`));
|
|
107
323
|
console.log(chalk.gray(` • BMAD integration for multi-agent sessions\n`));
|
|
108
324
|
|
|
109
|
-
//
|
|
325
|
+
// Final confirmation prompt (unless --yes flag is used)
|
|
110
326
|
if (!options.yes) {
|
|
111
327
|
const { confirm } = await inquirer.prompt([
|
|
112
328
|
{
|
|
113
329
|
type: 'confirm',
|
|
114
330
|
name: 'confirm',
|
|
115
|
-
message: chalk.yellow(`
|
|
331
|
+
message: chalk.yellow(`Proceed with installation using ${selectedProvider === 'elevenlabs' ? 'ElevenLabs' : 'Piper TTS'}?`),
|
|
116
332
|
default: true,
|
|
117
333
|
},
|
|
118
334
|
]);
|
|
@@ -121,8 +337,6 @@ async function install(options = {}) {
|
|
|
121
337
|
console.log(chalk.red('\n❌ Installation cancelled.\n'));
|
|
122
338
|
process.exit(0);
|
|
123
339
|
}
|
|
124
|
-
} else {
|
|
125
|
-
console.log(chalk.green('✓ Auto-confirmed (--yes flag)\n'));
|
|
126
340
|
}
|
|
127
341
|
|
|
128
342
|
console.log(''); // Add spacing
|
|
@@ -258,24 +472,19 @@ async function install(options = {}) {
|
|
|
258
472
|
}
|
|
259
473
|
spinner.succeed(chalk.green('Installed output styles!\n'));
|
|
260
474
|
|
|
261
|
-
//
|
|
262
|
-
spinner.start('
|
|
263
|
-
const
|
|
475
|
+
// Save provider selection
|
|
476
|
+
spinner.start('Saving provider configuration...');
|
|
477
|
+
const providerConfigPath = path.join(claudeDir, 'tts-provider.txt');
|
|
478
|
+
await fs.writeFile(providerConfigPath, selectedProvider);
|
|
264
479
|
|
|
265
|
-
if
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
console.log(chalk.white(' 2. Sign up or log in (free tier available)'));
|
|
270
|
-
console.log(chalk.white(' 3. Copy your API key from the profile section'));
|
|
271
|
-
console.log(chalk.white(' 4. Set it in your shell profile:\n'));
|
|
272
|
-
console.log(chalk.cyan(' export ELEVENLABS_API_KEY="your-key-here"'));
|
|
273
|
-
console.log(chalk.gray('\n Add this to ~/.bashrc or ~/.zshrc to make it permanent\n'));
|
|
274
|
-
} else {
|
|
275
|
-
spinner.succeed(chalk.green('ElevenLabs API key found!'));
|
|
276
|
-
console.log(chalk.gray(` Key: ${apiKey.substring(0, 10)}...\n`));
|
|
480
|
+
// Save Piper voices directory if Piper is selected
|
|
481
|
+
if (selectedProvider === 'piper' && piperVoicesPath) {
|
|
482
|
+
const piperConfigPath = path.join(claudeDir, 'piper-voices-dir.txt');
|
|
483
|
+
await fs.writeFile(piperConfigPath, piperVoicesPath);
|
|
277
484
|
}
|
|
278
485
|
|
|
486
|
+
spinner.succeed(chalk.green(`Provider set to: ${selectedProvider === 'elevenlabs' ? 'ElevenLabs' : 'Piper TTS'}\n`));
|
|
487
|
+
|
|
279
488
|
// List what was installed
|
|
280
489
|
console.log(chalk.cyan('📦 Installation Summary:'));
|
|
281
490
|
console.log(chalk.white(` • ${commandFiles.length} slash commands installed`));
|
|
@@ -283,7 +492,21 @@ async function install(options = {}) {
|
|
|
283
492
|
console.log(chalk.white(` • ${personalityFiles.length} personality templates installed`));
|
|
284
493
|
console.log(chalk.white(` • ${outputStyleFiles.length} output styles installed`));
|
|
285
494
|
console.log(chalk.white(` • Voice manager ready`));
|
|
286
|
-
|
|
495
|
+
|
|
496
|
+
if (selectedProvider === 'elevenlabs') {
|
|
497
|
+
console.log(chalk.white(` • 27+ ElevenLabs AI voices available`));
|
|
498
|
+
console.log(chalk.white(` • 30+ languages supported`));
|
|
499
|
+
if (elevenLabsKey) {
|
|
500
|
+
console.log(chalk.green(` • ElevenLabs API key configured ✓`));
|
|
501
|
+
} else {
|
|
502
|
+
console.log(chalk.yellow(` • ElevenLabs API key: Set manually later`));
|
|
503
|
+
}
|
|
504
|
+
} else {
|
|
505
|
+
console.log(chalk.white(` • 50+ Piper neural voices available (free!)`));
|
|
506
|
+
console.log(chalk.white(` • 18 languages supported`));
|
|
507
|
+
console.log(chalk.green(` • No API key needed ✓`));
|
|
508
|
+
}
|
|
509
|
+
console.log('');
|
|
287
510
|
|
|
288
511
|
// Show recent changes from git log or RELEASE_NOTES.md
|
|
289
512
|
try {
|
|
@@ -504,84 +727,10 @@ program
|
|
|
504
727
|
);
|
|
505
728
|
|
|
506
729
|
console.log(chalk.cyan('📍 Update Details:'));
|
|
507
|
-
console.log(chalk.
|
|
508
|
-
console.log(chalk.
|
|
509
|
-
console.log(chalk.white(` Package version: ${version}\n`));
|
|
510
|
-
|
|
511
|
-
// Check if already installed
|
|
512
|
-
const commandsDir = path.join(targetDir, '.claude', 'commands', 'agent-vibes');
|
|
513
|
-
let isInstalled = false;
|
|
514
|
-
try {
|
|
515
|
-
await fs.access(commandsDir);
|
|
516
|
-
isInstalled = true;
|
|
517
|
-
} catch {}
|
|
518
|
-
|
|
519
|
-
if (!isInstalled) {
|
|
520
|
-
console.log(chalk.red('❌ AgentVibes is not installed in this directory.'));
|
|
521
|
-
console.log(chalk.gray(' Run: node src/installer.js install\n'));
|
|
522
|
-
process.exit(1);
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
// Show latest release notes from RELEASE_NOTES.md
|
|
526
|
-
try {
|
|
527
|
-
const releaseNotesPath = path.join(__dirname, '..', 'RELEASE_NOTES.md');
|
|
528
|
-
const releaseNotes = await fs.readFile(releaseNotesPath, 'utf8');
|
|
529
|
-
|
|
530
|
-
// Extract latest release summary
|
|
531
|
-
const lines = releaseNotes.split('\n');
|
|
532
|
-
|
|
533
|
-
// Find the first release version header
|
|
534
|
-
const versionIndex = lines.findIndex(line => line.match(/^## 📦 v\d+\.\d+\.\d+/));
|
|
535
|
-
|
|
536
|
-
if (versionIndex >= 0) {
|
|
537
|
-
// Extract version
|
|
538
|
-
const versionMatch = lines[versionIndex].match(/v(\d+\.\d+\.\d+)/);
|
|
539
|
-
const version = versionMatch ? versionMatch[1] : 'unknown';
|
|
540
|
-
|
|
541
|
-
// Find the AI Summary section
|
|
542
|
-
const summaryIndex = lines.findIndex((line, idx) =>
|
|
543
|
-
idx > versionIndex && line.includes('### 🤖 AI Summary')
|
|
544
|
-
);
|
|
545
|
-
|
|
546
|
-
if (summaryIndex >= 0) {
|
|
547
|
-
console.log(chalk.cyan(`📰 Latest Release (v${version}):\n`));
|
|
548
|
-
|
|
549
|
-
// Extract summary text (lines between AI Summary and next ###)
|
|
550
|
-
let summaryText = '';
|
|
551
|
-
for (let i = summaryIndex + 1; i < lines.length; i++) {
|
|
552
|
-
const line = lines[i];
|
|
553
|
-
if (line.startsWith('###') || line.startsWith('##')) break;
|
|
554
|
-
if (line.trim()) {
|
|
555
|
-
summaryText += line.trim() + ' ';
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
// Wrap text at ~80 chars for better readability
|
|
560
|
-
const words = summaryText.split(' ');
|
|
561
|
-
let currentLine = '';
|
|
562
|
-
const wrappedLines = [];
|
|
563
|
-
|
|
564
|
-
words.forEach(word => {
|
|
565
|
-
if ((currentLine + word).length > 80) {
|
|
566
|
-
wrappedLines.push(currentLine.trim());
|
|
567
|
-
currentLine = word + ' ';
|
|
568
|
-
} else {
|
|
569
|
-
currentLine += word + ' ';
|
|
570
|
-
}
|
|
571
|
-
});
|
|
572
|
-
if (currentLine.trim()) wrappedLines.push(currentLine.trim());
|
|
730
|
+
console.log(chalk.gray(` Update location: ${targetDir}/.claude/`));
|
|
731
|
+
console.log(chalk.gray(` Package version: ${version}`));
|
|
573
732
|
|
|
574
|
-
|
|
575
|
-
console.log(chalk.white(` ${line}`));
|
|
576
|
-
});
|
|
577
|
-
console.log();
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
} catch {
|
|
581
|
-
// Release notes not available - no problem
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
// Show latest commit messages
|
|
733
|
+
// Show latest release notes from git log
|
|
585
734
|
try {
|
|
586
735
|
const { execSync } = await import('node:child_process');
|
|
587
736
|
const gitLog = execSync(
|
|
@@ -590,55 +739,33 @@ program
|
|
|
590
739
|
).trim();
|
|
591
740
|
|
|
592
741
|
if (gitLog) {
|
|
593
|
-
console.log(chalk.cyan('
|
|
742
|
+
console.log(chalk.cyan('\n📰 Latest Release Notes:'));
|
|
594
743
|
const commits = gitLog.split('\n');
|
|
595
744
|
commits.forEach(commit => {
|
|
596
745
|
const [hash, ...messageParts] = commit.split(' ');
|
|
597
746
|
const message = messageParts.join(' ');
|
|
598
747
|
console.log(chalk.gray(` ${hash}`) + ' ' + chalk.white(message));
|
|
599
748
|
});
|
|
600
|
-
console.log();
|
|
601
749
|
}
|
|
602
750
|
} catch (error) {
|
|
603
|
-
// Git not available -
|
|
604
|
-
|
|
605
|
-
const releaseNotesPath = path.join(__dirname, '..', 'RELEASE_NOTES.md');
|
|
606
|
-
const releaseNotes = await fs.readFile(releaseNotesPath, 'utf8');
|
|
607
|
-
|
|
608
|
-
// Extract commits from "Recent Commits" section
|
|
609
|
-
const lines = releaseNotes.split('\n');
|
|
610
|
-
const commitsIndex = lines.findIndex(line => line.includes('## 📝 Recent Commits'));
|
|
611
|
-
|
|
612
|
-
if (commitsIndex >= 0) {
|
|
613
|
-
console.log(chalk.cyan('📝 Latest Commit Messages:\n'));
|
|
614
|
-
|
|
615
|
-
// Find the code block with commits (between ``` markers)
|
|
616
|
-
let inCodeBlock = false;
|
|
617
|
-
for (let i = commitsIndex + 1; i < lines.length; i++) {
|
|
618
|
-
const line = lines[i];
|
|
751
|
+
// Git not available or not a git repo - skip release notes
|
|
752
|
+
}
|
|
619
753
|
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
754
|
+
// Check if already installed
|
|
755
|
+
const commandsDir = path.join(targetDir, '.claude', 'commands', 'agent-vibes');
|
|
756
|
+
let isInstalled = false;
|
|
757
|
+
try {
|
|
758
|
+
await fs.access(commandsDir);
|
|
759
|
+
isInstalled = true;
|
|
760
|
+
} catch {}
|
|
625
761
|
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
const [, hash, message] = match;
|
|
631
|
-
console.log(chalk.gray(` ${hash}`) + ' ' + chalk.white(message));
|
|
632
|
-
}
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
console.log();
|
|
636
|
-
}
|
|
637
|
-
} catch {
|
|
638
|
-
// No release notes available
|
|
639
|
-
}
|
|
762
|
+
if (!isInstalled) {
|
|
763
|
+
console.log(chalk.red('\n❌ AgentVibes is not installed in this directory.'));
|
|
764
|
+
console.log(chalk.gray(' Run: npx agentvibes install\n'));
|
|
765
|
+
process.exit(1);
|
|
640
766
|
}
|
|
641
767
|
|
|
768
|
+
|
|
642
769
|
console.log(chalk.cyan('📦 What will be updated:'));
|
|
643
770
|
console.log(chalk.gray(' • Slash commands (keep your customizations)'));
|
|
644
771
|
console.log(chalk.gray(' • TTS scripts'));
|
|
@@ -688,11 +815,20 @@ program
|
|
|
688
815
|
spinner.text = 'Updating TTS scripts...';
|
|
689
816
|
const srcHooksDir = path.join(__dirname, '..', '.claude', 'hooks');
|
|
690
817
|
const allHookFiles = await fs.readdir(srcHooksDir);
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
818
|
+
|
|
819
|
+
// Filter to only include files (not directories) and exclude project-specific files
|
|
820
|
+
const hookFiles = [];
|
|
821
|
+
for (const file of allHookFiles) {
|
|
822
|
+
const srcPath = path.join(srcHooksDir, file);
|
|
823
|
+
const stat = await fs.stat(srcPath);
|
|
824
|
+
|
|
825
|
+
if (stat.isFile() &&
|
|
826
|
+
file.endsWith('.sh') &&
|
|
827
|
+
!file.includes('prepare-release') &&
|
|
828
|
+
!file.startsWith('.')) {
|
|
829
|
+
hookFiles.push(file);
|
|
830
|
+
}
|
|
831
|
+
}
|
|
696
832
|
|
|
697
833
|
for (const file of hookFiles) {
|
|
698
834
|
const srcPath = path.join(srcHooksDir, file);
|
|
@@ -705,12 +841,20 @@ program
|
|
|
705
841
|
// Update personalities (only add new ones, don't overwrite existing)
|
|
706
842
|
spinner.text = 'Updating personality templates...';
|
|
707
843
|
const srcPersonalitiesDir = path.join(__dirname, '..', '.claude', 'personalities');
|
|
708
|
-
const
|
|
844
|
+
const allPersonalityFiles = await fs.readdir(srcPersonalitiesDir);
|
|
709
845
|
let newPersonalities = 0;
|
|
710
846
|
let updatedPersonalities = 0;
|
|
711
847
|
|
|
712
|
-
|
|
848
|
+
// Filter to only .md files, skip directories
|
|
849
|
+
for (const file of allPersonalityFiles) {
|
|
713
850
|
const srcPath = path.join(srcPersonalitiesDir, file);
|
|
851
|
+
const stat = await fs.stat(srcPath);
|
|
852
|
+
|
|
853
|
+
// Only copy .md files, skip directories
|
|
854
|
+
if (!stat.isFile() || !file.endsWith('.md')) {
|
|
855
|
+
continue;
|
|
856
|
+
}
|
|
857
|
+
|
|
714
858
|
const destPath = path.join(personalitiesDir, file);
|
|
715
859
|
|
|
716
860
|
try {
|
|
@@ -743,44 +887,53 @@ program
|
|
|
743
887
|
console.log(chalk.cyan('📦 Update Summary:'));
|
|
744
888
|
console.log(chalk.white(` • ${commandFiles.length} commands updated`));
|
|
745
889
|
console.log(chalk.white(` • ${hookFiles.length} TTS scripts updated`));
|
|
746
|
-
console.log(chalk.white(` • ${
|
|
890
|
+
console.log(chalk.white(` • ${newPersonalities + updatedPersonalities} personality templates (${newPersonalities} new, ${updatedPersonalities} updated)`));
|
|
747
891
|
console.log(chalk.white(` • ${outputStyleFiles.length} output styles updated\n`));
|
|
748
892
|
|
|
749
|
-
// Show latest release notes from RELEASE_NOTES.md
|
|
893
|
+
// Show latest release notes from RELEASE_NOTES_V2.md (v2.0+) or RELEASE_NOTES.md (legacy)
|
|
750
894
|
try {
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
const lines = releaseNotes.split('\n');
|
|
895
|
+
// Try v2.0 format first
|
|
896
|
+
let releaseNotesPath = path.join(__dirname, '..', 'RELEASE_NOTES_V2.md');
|
|
897
|
+
let releaseNotes;
|
|
898
|
+
let isV2Format = true;
|
|
756
899
|
|
|
757
|
-
|
|
758
|
-
|
|
900
|
+
try {
|
|
901
|
+
releaseNotes = await fs.readFile(releaseNotesPath, 'utf8');
|
|
902
|
+
} catch {
|
|
903
|
+
// Fallback to legacy format
|
|
904
|
+
releaseNotesPath = path.join(__dirname, '..', 'RELEASE_NOTES.md');
|
|
905
|
+
releaseNotes = await fs.readFile(releaseNotesPath, 'utf8');
|
|
906
|
+
isV2Format = false;
|
|
907
|
+
}
|
|
759
908
|
|
|
760
|
-
|
|
761
|
-
// Extract version
|
|
762
|
-
const versionMatch = lines[versionIndex].match(/v(\d+\.\d+\.\d+)/);
|
|
763
|
-
const version = versionMatch ? versionMatch[1] : 'unknown';
|
|
909
|
+
const lines = releaseNotes.split('\n');
|
|
764
910
|
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
);
|
|
911
|
+
if (isV2Format) {
|
|
912
|
+
// v2.0 format - extract summary from top of file
|
|
913
|
+
const packageVersion = packageJson.version;
|
|
914
|
+
console.log(chalk.cyan(`📰 Latest Release (v${packageVersion}):\n`));
|
|
769
915
|
|
|
770
|
-
|
|
771
|
-
|
|
916
|
+
// Find content after "## 🚀 Major Features" line
|
|
917
|
+
let summaryText = '';
|
|
918
|
+
let foundMajorFeatures = false;
|
|
772
919
|
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
920
|
+
for (const line of lines) {
|
|
921
|
+
if (line.includes('## 🚀 Major Features')) {
|
|
922
|
+
foundMajorFeatures = true;
|
|
923
|
+
continue;
|
|
924
|
+
}
|
|
925
|
+
if (foundMajorFeatures) {
|
|
926
|
+
// Stop at next major heading or after 200 chars
|
|
927
|
+
if (line.startsWith('##') && !line.includes('Major Features')) break;
|
|
928
|
+
if (summaryText.length > 200) break;
|
|
929
|
+
if (line.trim() && !line.startsWith('#') && !line.startsWith('**Release Date')) {
|
|
779
930
|
summaryText += line.trim() + ' ';
|
|
780
931
|
}
|
|
781
932
|
}
|
|
933
|
+
}
|
|
782
934
|
|
|
783
|
-
|
|
935
|
+
// Wrap text at ~80 chars
|
|
936
|
+
if (summaryText) {
|
|
784
937
|
const words = summaryText.split(' ');
|
|
785
938
|
let currentLine = '';
|
|
786
939
|
const wrappedLines = [];
|
|
@@ -800,6 +953,50 @@ program
|
|
|
800
953
|
});
|
|
801
954
|
console.log();
|
|
802
955
|
}
|
|
956
|
+
} else {
|
|
957
|
+
// Legacy format (v1.x)
|
|
958
|
+
const versionIndex = lines.findIndex(line => line.match(/^## 📦 v\d+\.\d+\.\d+/));
|
|
959
|
+
|
|
960
|
+
if (versionIndex >= 0) {
|
|
961
|
+
const versionMatch = lines[versionIndex].match(/v(\d+\.\d+\.\d+)/);
|
|
962
|
+
const version = versionMatch ? versionMatch[1] : 'unknown';
|
|
963
|
+
|
|
964
|
+
const summaryIndex = lines.findIndex((line, idx) =>
|
|
965
|
+
idx > versionIndex && line.includes('### 🤖 AI Summary')
|
|
966
|
+
);
|
|
967
|
+
|
|
968
|
+
if (summaryIndex >= 0) {
|
|
969
|
+
console.log(chalk.cyan(`📰 Latest Release (v${version}):\n`));
|
|
970
|
+
|
|
971
|
+
let summaryText = '';
|
|
972
|
+
for (let i = summaryIndex + 1; i < lines.length; i++) {
|
|
973
|
+
const line = lines[i];
|
|
974
|
+
if (line.startsWith('###') || line.startsWith('##')) break;
|
|
975
|
+
if (line.trim()) {
|
|
976
|
+
summaryText += line.trim() + ' ';
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
const words = summaryText.split(' ');
|
|
981
|
+
let currentLine = '';
|
|
982
|
+
const wrappedLines = [];
|
|
983
|
+
|
|
984
|
+
words.forEach(word => {
|
|
985
|
+
if ((currentLine + word).length > 80) {
|
|
986
|
+
wrappedLines.push(currentLine.trim());
|
|
987
|
+
currentLine = word + ' ';
|
|
988
|
+
} else {
|
|
989
|
+
currentLine += word + ' ';
|
|
990
|
+
}
|
|
991
|
+
});
|
|
992
|
+
if (currentLine.trim()) wrappedLines.push(currentLine.trim());
|
|
993
|
+
|
|
994
|
+
wrappedLines.forEach(line => {
|
|
995
|
+
console.log(chalk.white(` ${line}`));
|
|
996
|
+
});
|
|
997
|
+
console.log();
|
|
998
|
+
}
|
|
999
|
+
}
|
|
803
1000
|
}
|
|
804
1001
|
} catch {
|
|
805
1002
|
// Release notes not available - no problem
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Add a new custom ElevenLabs TTS voice
|
|
3
|
-
argument-hint: <voice_name> <voice_id>
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
Add a new custom ElevenLabs TTS voice to your voice library.
|
|
7
|
-
|
|
8
|
-
Usage:
|
|
9
|
-
- `/agent-vibes:add "My Custom Voice" abc123xyz456789`
|
|
10
|
-
- `/agent-vibes:add Narrator KTPVrSVAEUSJRClDzBw7`
|
|
11
|
-
|
|
12
|
-
The voice ID should be a 15-30 character alphanumeric string from your ElevenLabs account.
|
|
13
|
-
|
|
14
|
-
To find your voice IDs:
|
|
15
|
-
1. Go to https://elevenlabs.io/app/voice-library
|
|
16
|
-
2. Click on a voice
|
|
17
|
-
3. Copy the voice ID from the URL or settings
|
|
18
|
-
|
|
19
|
-
After adding, you can switch to it with `/agent-vibes:switch "Voice Name"`
|
|
20
|
-
|
|
21
|
-
!bash .claude/hooks/voice-manager.sh add $ARGUMENTS
|