agentvibes 2.0.6 → 2.0.8

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 (159) hide show
  1. package/.claude/commands/agent-vibes/preview.md +5 -4
  2. package/.claude/commands/agent-vibes/whoami.md +2 -2
  3. package/.claude/hooks/check-output-style.sh +60 -0
  4. package/.claude/hooks/language-manager.sh +50 -48
  5. package/.claude/hooks/personality-manager.sh +34 -2
  6. package/.claude/hooks/play-tts-piper.sh +27 -9
  7. package/.claude/hooks/play-tts.sh +29 -127
  8. package/.claude/hooks/provider-commands.sh +41 -2
  9. package/.claude/hooks/voice-manager.sh +85 -36
  10. package/.claude/personalities/angry.md +2 -1
  11. package/.claude/personalities/annoying.md +2 -1
  12. package/.claude/personalities/crass.md +2 -1
  13. package/.claude/personalities/dramatic.md +2 -1
  14. package/.claude/personalities/dry-humor.md +2 -1
  15. package/.claude/personalities/flirty.md +2 -1
  16. package/.claude/personalities/funny.md +2 -1
  17. package/.claude/personalities/grandpa.md +2 -1
  18. package/.claude/personalities/millennial.md +2 -1
  19. package/.claude/personalities/moody.md +2 -1
  20. package/.claude/personalities/normal.md +2 -1
  21. package/.claude/personalities/pirate.md +2 -1
  22. package/.claude/personalities/poetic.md +2 -1
  23. package/.claude/personalities/professional.md +2 -1
  24. package/.claude/personalities/robot.md +2 -1
  25. package/.claude/personalities/sarcastic.md +2 -1
  26. package/.claude/personalities/sassy.md +2 -1
  27. package/.claude/personalities/surfer-dude.md +2 -1
  28. package/.claude/personalities/zen.md +2 -1
  29. package/.claude/piper-voices-dir.txt +1 -0
  30. package/README.md +2 -2
  31. package/RELEASE_NOTES.md +277 -0
  32. package/agentvibes.org/.claude/commands/agent-vibes/add.md +21 -0
  33. package/agentvibes.org/.claude/commands/agent-vibes/agent-vibes.md +68 -0
  34. package/agentvibes.org/.claude/commands/agent-vibes/commands.json +53 -0
  35. package/agentvibes.org/.claude/commands/agent-vibes/get.md +9 -0
  36. package/agentvibes.org/.claude/commands/agent-vibes/list.md +13 -0
  37. package/agentvibes.org/.claude/commands/agent-vibes/personality.md +79 -0
  38. package/agentvibes.org/.claude/commands/agent-vibes/preview.md +16 -0
  39. package/agentvibes.org/.claude/commands/agent-vibes/provider.md +54 -0
  40. package/agentvibes.org/.claude/commands/agent-vibes/replay.md +19 -0
  41. package/agentvibes.org/.claude/commands/agent-vibes/sample.md +12 -0
  42. package/agentvibes.org/.claude/commands/agent-vibes/sentiment.md +52 -0
  43. package/agentvibes.org/.claude/commands/agent-vibes/set-language.md +47 -0
  44. package/agentvibes.org/.claude/commands/agent-vibes/set-pretext.md +65 -0
  45. package/agentvibes.org/.claude/commands/agent-vibes/switch.md +53 -0
  46. package/agentvibes.org/.claude/commands/agent-vibes/update.md +20 -0
  47. package/agentvibes.org/.claude/commands/agent-vibes/version.md +10 -0
  48. package/agentvibes.org/.claude/commands/agent-vibes/whoami.md +7 -0
  49. package/agentvibes.org/.claude/hooks/bmad-voice-manager.sh +278 -0
  50. package/agentvibes.org/.claude/hooks/language-manager.sh +190 -0
  51. package/agentvibes.org/.claude/hooks/personality-manager.sh +279 -0
  52. package/agentvibes.org/.claude/hooks/piper-download-voices.sh +133 -0
  53. package/agentvibes.org/.claude/hooks/piper-voice-manager.sh +227 -0
  54. package/agentvibes.org/.claude/hooks/play-tts-elevenlabs.sh +201 -0
  55. package/agentvibes.org/.claude/hooks/play-tts-piper.sh +175 -0
  56. package/agentvibes.org/.claude/hooks/play-tts.sh +138 -0
  57. package/agentvibes.org/.claude/hooks/provider-commands.sh +374 -0
  58. package/agentvibes.org/.claude/hooks/provider-manager.sh +196 -0
  59. package/agentvibes.org/.claude/hooks/sentiment-manager.sh +163 -0
  60. package/agentvibes.org/.claude/hooks/voice-manager.sh +349 -0
  61. package/agentvibes.org/.claude/hooks/voices-config.sh +33 -0
  62. package/agentvibes.org/.claude/journal/2025-10-07.html +373 -0
  63. package/agentvibes.org/.claude/journal/index.html +91 -0
  64. package/agentvibes.org/.claude/output-styles/agent-vibes.md +203 -0
  65. package/agentvibes.org/.claude/personalities/angry.md +16 -0
  66. package/agentvibes.org/.claude/personalities/annoying.md +16 -0
  67. package/agentvibes.org/.claude/personalities/crass.md +16 -0
  68. package/agentvibes.org/.claude/personalities/dramatic.md +16 -0
  69. package/agentvibes.org/.claude/personalities/dry-humor.md +52 -0
  70. package/agentvibes.org/.claude/personalities/flirty.md +22 -0
  71. package/agentvibes.org/.claude/personalities/funny.md +16 -0
  72. package/agentvibes.org/.claude/personalities/grandpa.md +34 -0
  73. package/agentvibes.org/.claude/personalities/millennial.md +16 -0
  74. package/agentvibes.org/.claude/personalities/moody.md +16 -0
  75. package/agentvibes.org/.claude/personalities/normal.md +18 -0
  76. package/agentvibes.org/.claude/personalities/pirate.md +16 -0
  77. package/agentvibes.org/.claude/personalities/poetic.md +16 -0
  78. package/agentvibes.org/.claude/personalities/professional.md +16 -0
  79. package/agentvibes.org/.claude/personalities/robot.md +16 -0
  80. package/agentvibes.org/.claude/personalities/sarcastic.md +40 -0
  81. package/agentvibes.org/.claude/personalities/sassy.md +16 -0
  82. package/agentvibes.org/.claude/personalities/surfer-dude.md +16 -0
  83. package/agentvibes.org/.claude/personalities/zen.md +16 -0
  84. package/agentvibes.org/.mcp-minimal.json +60 -0
  85. package/agentvibes.org/CHANGELOG.md +56 -0
  86. package/agentvibes.org/README.md +93 -0
  87. package/agentvibes.org/app/(auth)/layout.tsx +15 -0
  88. package/agentvibes.org/app/(auth)/reset-password/page.tsx +45 -0
  89. package/agentvibes.org/app/(auth)/signin/page.tsx +82 -0
  90. package/agentvibes.org/app/(auth)/signup/page.tsx +104 -0
  91. package/agentvibes.org/app/(default)/layout.tsx +31 -0
  92. package/agentvibes.org/app/(default)/page.tsx +20 -0
  93. package/agentvibes.org/app/api/hello/route.ts +3 -0
  94. package/agentvibes.org/app/css/additional-styles/theme.css +82 -0
  95. package/agentvibes.org/app/css/additional-styles/utility-patterns.css +55 -0
  96. package/agentvibes.org/app/css/style.css +100 -0
  97. package/agentvibes.org/app/layout.tsx +63 -0
  98. package/agentvibes.org/components/cta.tsx +58 -0
  99. package/agentvibes.org/components/features.tsx +256 -0
  100. package/agentvibes.org/components/hero-home.tsx +133 -0
  101. package/agentvibes.org/components/modal-video.tsx +137 -0
  102. package/agentvibes.org/components/page-illustration.tsx +55 -0
  103. package/agentvibes.org/components/spotlight.tsx +77 -0
  104. package/agentvibes.org/components/testimonials.tsx +282 -0
  105. package/agentvibes.org/components/ui/footer.tsx +82 -0
  106. package/agentvibes.org/components/ui/header.tsx +53 -0
  107. package/agentvibes.org/components/ui/logo.tsx +10 -0
  108. package/agentvibes.org/components/workflows.tsx +176 -0
  109. package/agentvibes.org/next.config.js +4 -0
  110. package/agentvibes.org/package-lock.json +1974 -0
  111. package/agentvibes.org/package.json +30 -0
  112. package/agentvibes.org/pnpm-lock.yaml +1141 -0
  113. package/agentvibes.org/postcss.config.js +5 -0
  114. package/agentvibes.org/public/audio/02-sarcastic.mp3 +0 -0
  115. package/agentvibes.org/public/audio/03-angry.mp3 +0 -0
  116. package/agentvibes.org/public/audio/04-grandpa.mp3 +0 -0
  117. package/agentvibes.org/public/audio/05-sarcastic-example2.mp3 +0 -0
  118. package/agentvibes.org/public/audio/french-rachel.mp3 +0 -0
  119. package/agentvibes.org/public/audio/spanish-antoni.mp3 +0 -0
  120. package/agentvibes.org/public/favicon.ico +0 -0
  121. package/agentvibes.org/public/fonts/nacelle-italic.woff2 +0 -0
  122. package/agentvibes.org/public/fonts/nacelle-regular.woff2 +0 -0
  123. package/agentvibes.org/public/fonts/nacelle-semibold.woff2 +0 -0
  124. package/agentvibes.org/public/fonts/nacelle-semibolditalic.woff2 +0 -0
  125. package/agentvibes.org/public/images/blurred-shape-gray.svg +1 -0
  126. package/agentvibes.org/public/images/blurred-shape.svg +1 -0
  127. package/agentvibes.org/public/images/client-logo-01.svg +1 -0
  128. package/agentvibes.org/public/images/client-logo-02.svg +1 -0
  129. package/agentvibes.org/public/images/client-logo-03.svg +1 -0
  130. package/agentvibes.org/public/images/client-logo-04.svg +1 -0
  131. package/agentvibes.org/public/images/client-logo-05.svg +1 -0
  132. package/agentvibes.org/public/images/client-logo-06.svg +1 -0
  133. package/agentvibes.org/public/images/client-logo-07.svg +1 -0
  134. package/agentvibes.org/public/images/client-logo-08.svg +1 -0
  135. package/agentvibes.org/public/images/client-logo-09.svg +1 -0
  136. package/agentvibes.org/public/images/features.png +0 -0
  137. package/agentvibes.org/public/images/footer-illustration.svg +1 -0
  138. package/agentvibes.org/public/images/hero-image-01.jpg +0 -0
  139. package/agentvibes.org/public/images/logo.svg +1 -0
  140. package/agentvibes.org/public/images/page-illustration.svg +1 -0
  141. package/agentvibes.org/public/images/secondary-illustration.svg +1 -0
  142. package/agentvibes.org/public/images/testimonial-01.jpg +0 -0
  143. package/agentvibes.org/public/images/testimonial-02.jpg +0 -0
  144. package/agentvibes.org/public/images/testimonial-03.jpg +0 -0
  145. package/agentvibes.org/public/images/testimonial-04.jpg +0 -0
  146. package/agentvibes.org/public/images/testimonial-05.jpg +0 -0
  147. package/agentvibes.org/public/images/testimonial-06.jpg +0 -0
  148. package/agentvibes.org/public/images/testimonial-07.jpg +0 -0
  149. package/agentvibes.org/public/images/testimonial-08.jpg +0 -0
  150. package/agentvibes.org/public/images/testimonial-09.jpg +0 -0
  151. package/agentvibes.org/public/images/workflow-01.png +0 -0
  152. package/agentvibes.org/public/images/workflow-02.png +0 -0
  153. package/agentvibes.org/public/images/workflow-03.png +0 -0
  154. package/agentvibes.org/public/videos/video.mp4 +0 -0
  155. package/agentvibes.org/tsconfig.json +28 -0
  156. package/agentvibes.org/utils/useMasonry.tsx +67 -0
  157. package/agentvibes.org/utils/useMousePosition.tsx +27 -0
  158. package/package.json +1 -1
  159. package/src/installer.js +145 -171
package/src/installer.js CHANGED
@@ -70,7 +70,7 @@ async function install(options = {}) {
70
70
  const currentDir = process.env.INIT_CWD || process.cwd();
71
71
 
72
72
  console.log(chalk.cyan('\n📍 Installation Details:'));
73
- console.log(chalk.gray(` Current directory: ${currentDir}`));
73
+ console.log(chalk.gray(` Install location: ${currentDir}/.claude/`));
74
74
  console.log(chalk.gray(` Package version: ${VERSION}`));
75
75
 
76
76
  // Show latest release notes from git log
@@ -97,6 +97,7 @@ async function install(options = {}) {
97
97
  // Provider selection prompt
98
98
  let selectedProvider = 'piper';
99
99
  let elevenLabsKey = process.env.ELEVENLABS_API_KEY;
100
+ let piperVoicesPath = null;
100
101
 
101
102
  if (!options.yes) {
102
103
  console.log(chalk.cyan('🎭 Choose Your TTS Provider:\n'));
@@ -123,7 +124,6 @@ async function install(options = {}) {
123
124
  selectedProvider = provider;
124
125
 
125
126
  // If Piper selected, ask for voice storage location
126
- let piperVoicesPath = null;
127
127
  if (selectedProvider === 'piper') {
128
128
  const homeDir = process.env.HOME || process.env.USERPROFILE;
129
129
  const defaultPiperPath = path.join(homeDir, '.claude', 'piper-voices');
@@ -284,34 +284,34 @@ async function install(options = {}) {
284
284
  }
285
285
  }
286
286
 
287
- // Ask for installation directory
288
- let targetDir = options.directory || currentDir;
287
+ // Use current directory for installation (where installer was run)
288
+ const targetDir = options.directory || currentDir;
289
289
 
290
+ // Explain why installing in .claude/ and confirm
290
291
  if (!options.yes) {
291
- console.log(chalk.cyan('\n📂 AgentVibes Installation Location:\n'));
292
- console.log(chalk.gray(' AgentVibes will be installed in the .claude/ subdirectory'));
293
- console.log(chalk.gray(' of your chosen location.\n'));
294
-
295
- const { installDir } = await inquirer.prompt([
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([
296
301
  {
297
- type: 'input',
298
- name: 'installDir',
299
- message: 'Where should AgentVibes be installed?',
300
- default: currentDir,
301
- validate: (input) => {
302
- if (!input || input.trim() === '') {
303
- return 'Please provide a valid directory path';
304
- }
305
- return true;
306
- },
302
+ type: 'confirm',
303
+ name: 'confirmLocation',
304
+ message: `Install AgentVibes in ${targetDir}/.claude/ ?`,
305
+ default: true,
307
306
  },
308
307
  ]);
309
308
 
310
- targetDir = installDir;
311
- console.log(chalk.green(`✓ AgentVibes will be installed in: ${targetDir}/.claude/`));
309
+ if (!confirmLocation) {
310
+ console.log(chalk.red('\n❌ Installation cancelled.\n'));
311
+ process.exit(0);
312
+ }
312
313
  }
313
314
 
314
- // Show installation summary
315
315
  console.log(chalk.cyan('\n📦 What will be installed:'));
316
316
  console.log(chalk.gray(` • 16 slash commands → ${targetDir}/.claude/commands/agent-vibes/`));
317
317
  console.log(chalk.gray(` • Multi-provider TTS system (ElevenLabs + Piper TTS) → ${targetDir}/.claude/hooks/`));
@@ -322,13 +322,13 @@ async function install(options = {}) {
322
322
  console.log(chalk.gray(` • 30+ language support with native voices`));
323
323
  console.log(chalk.gray(` • BMAD integration for multi-agent sessions\n`));
324
324
 
325
- // Confirmation prompt (unless --yes flag is used)
325
+ // Final confirmation prompt (unless --yes flag is used)
326
326
  if (!options.yes) {
327
327
  const { confirm } = await inquirer.prompt([
328
328
  {
329
329
  type: 'confirm',
330
330
  name: 'confirm',
331
- message: chalk.yellow(`Install AgentVibes with ${selectedProvider === 'elevenlabs' ? 'ElevenLabs' : 'Piper TTS'} in ${targetDir}/.claude/ ?`),
331
+ message: chalk.yellow(`Proceed with installation using ${selectedProvider === 'elevenlabs' ? 'ElevenLabs' : 'Piper TTS'}?`),
332
332
  default: true,
333
333
  },
334
334
  ]);
@@ -727,84 +727,10 @@ program
727
727
  );
728
728
 
729
729
  console.log(chalk.cyan('📍 Update Details:'));
730
- console.log(chalk.white(` Current directory: ${currentDir}`));
731
- console.log(chalk.white(` Update location: ${targetDir}/.claude/ (project-local)`));
732
- console.log(chalk.white(` Package version: ${version}\n`));
733
-
734
- // Check if already installed
735
- const commandsDir = path.join(targetDir, '.claude', 'commands', 'agent-vibes');
736
- let isInstalled = false;
737
- try {
738
- await fs.access(commandsDir);
739
- isInstalled = true;
740
- } catch {}
741
-
742
- if (!isInstalled) {
743
- console.log(chalk.red('❌ AgentVibes is not installed in this directory.'));
744
- console.log(chalk.gray(' Run: node src/installer.js install\n'));
745
- process.exit(1);
746
- }
730
+ console.log(chalk.gray(` Update location: ${targetDir}/.claude/`));
731
+ console.log(chalk.gray(` Package version: ${version}`));
747
732
 
748
- // Show latest release notes from RELEASE_NOTES.md
749
- try {
750
- const releaseNotesPath = path.join(__dirname, '..', 'RELEASE_NOTES.md');
751
- const releaseNotes = await fs.readFile(releaseNotesPath, 'utf8');
752
-
753
- // Extract latest release summary
754
- const lines = releaseNotes.split('\n');
755
-
756
- // Find the first release version header
757
- const versionIndex = lines.findIndex(line => line.match(/^## 📦 v\d+\.\d+\.\d+/));
758
-
759
- if (versionIndex >= 0) {
760
- // Extract version
761
- const versionMatch = lines[versionIndex].match(/v(\d+\.\d+\.\d+)/);
762
- const version = versionMatch ? versionMatch[1] : 'unknown';
763
-
764
- // Find the AI Summary section
765
- const summaryIndex = lines.findIndex((line, idx) =>
766
- idx > versionIndex && line.includes('### 🤖 AI Summary')
767
- );
768
-
769
- if (summaryIndex >= 0) {
770
- console.log(chalk.cyan(`📰 Latest Release (v${version}):\n`));
771
-
772
- // Extract summary text (lines between AI Summary and next ###)
773
- let summaryText = '';
774
- for (let i = summaryIndex + 1; i < lines.length; i++) {
775
- const line = lines[i];
776
- if (line.startsWith('###') || line.startsWith('##')) break;
777
- if (line.trim()) {
778
- summaryText += line.trim() + ' ';
779
- }
780
- }
781
-
782
- // Wrap text at ~80 chars for better readability
783
- const words = summaryText.split(' ');
784
- let currentLine = '';
785
- const wrappedLines = [];
786
-
787
- words.forEach(word => {
788
- if ((currentLine + word).length > 80) {
789
- wrappedLines.push(currentLine.trim());
790
- currentLine = word + ' ';
791
- } else {
792
- currentLine += word + ' ';
793
- }
794
- });
795
- if (currentLine.trim()) wrappedLines.push(currentLine.trim());
796
-
797
- wrappedLines.forEach(line => {
798
- console.log(chalk.white(` ${line}`));
799
- });
800
- console.log();
801
- }
802
- }
803
- } catch {
804
- // Release notes not available - no problem
805
- }
806
-
807
- // Show latest commit messages
733
+ // Show latest release notes from git log
808
734
  try {
809
735
  const { execSync } = await import('node:child_process');
810
736
  const gitLog = execSync(
@@ -813,55 +739,33 @@ program
813
739
  ).trim();
814
740
 
815
741
  if (gitLog) {
816
- console.log(chalk.cyan('📝 Latest Commit Messages:\n'));
742
+ console.log(chalk.cyan('\n📰 Latest Release Notes:'));
817
743
  const commits = gitLog.split('\n');
818
744
  commits.forEach(commit => {
819
745
  const [hash, ...messageParts] = commit.split(' ');
820
746
  const message = messageParts.join(' ');
821
747
  console.log(chalk.gray(` ${hash}`) + ' ' + chalk.white(message));
822
748
  });
823
- console.log();
824
749
  }
825
750
  } catch (error) {
826
- // Git not available - try RELEASE_NOTES.md fallback
827
- try {
828
- const releaseNotesPath = path.join(__dirname, '..', 'RELEASE_NOTES.md');
829
- const releaseNotes = await fs.readFile(releaseNotesPath, 'utf8');
830
-
831
- // Extract commits from "Recent Commits" section
832
- const lines = releaseNotes.split('\n');
833
- const commitsIndex = lines.findIndex(line => line.includes('## 📝 Recent Commits'));
834
-
835
- if (commitsIndex >= 0) {
836
- console.log(chalk.cyan('📝 Latest Commit Messages:\n'));
837
-
838
- // Find the code block with commits (between ``` markers)
839
- let inCodeBlock = false;
840
- for (let i = commitsIndex + 1; i < lines.length; i++) {
841
- const line = lines[i];
751
+ // Git not available or not a git repo - skip release notes
752
+ }
842
753
 
843
- if (line.trim() === '```') {
844
- if (inCodeBlock) break; // End of code block
845
- inCodeBlock = true;
846
- continue;
847
- }
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 {}
848
761
 
849
- if (inCodeBlock && line.trim()) {
850
- // Parse commit line: "hash message"
851
- const match = line.match(/^([a-f0-9]+)\s+(.+)$/);
852
- if (match) {
853
- const [, hash, message] = match;
854
- console.log(chalk.gray(` ${hash}`) + ' ' + chalk.white(message));
855
- }
856
- }
857
- }
858
- console.log();
859
- }
860
- } catch {
861
- // No release notes available
862
- }
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);
863
766
  }
864
767
 
768
+
865
769
  console.log(chalk.cyan('📦 What will be updated:'));
866
770
  console.log(chalk.gray(' • Slash commands (keep your customizations)'));
867
771
  console.log(chalk.gray(' • TTS scripts'));
@@ -911,11 +815,20 @@ program
911
815
  spinner.text = 'Updating TTS scripts...';
912
816
  const srcHooksDir = path.join(__dirname, '..', '.claude', 'hooks');
913
817
  const allHookFiles = await fs.readdir(srcHooksDir);
914
- // Only copy AgentVibes-related scripts, exclude project-specific files
915
- const hookFiles = allHookFiles.filter(file =>
916
- !file.includes('prepare-release') &&
917
- !file.startsWith('.')
918
- );
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
+ }
919
832
 
920
833
  for (const file of hookFiles) {
921
834
  const srcPath = path.join(srcHooksDir, file);
@@ -928,12 +841,20 @@ program
928
841
  // Update personalities (only add new ones, don't overwrite existing)
929
842
  spinner.text = 'Updating personality templates...';
930
843
  const srcPersonalitiesDir = path.join(__dirname, '..', '.claude', 'personalities');
931
- const srcPersonalityFiles = await fs.readdir(srcPersonalitiesDir);
844
+ const allPersonalityFiles = await fs.readdir(srcPersonalitiesDir);
932
845
  let newPersonalities = 0;
933
846
  let updatedPersonalities = 0;
934
847
 
935
- for (const file of srcPersonalityFiles) {
848
+ // Filter to only .md files, skip directories
849
+ for (const file of allPersonalityFiles) {
936
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
+
937
858
  const destPath = path.join(personalitiesDir, file);
938
859
 
939
860
  try {
@@ -966,44 +887,53 @@ program
966
887
  console.log(chalk.cyan('📦 Update Summary:'));
967
888
  console.log(chalk.white(` • ${commandFiles.length} commands updated`));
968
889
  console.log(chalk.white(` • ${hookFiles.length} TTS scripts updated`));
969
- console.log(chalk.white(` • ${srcPersonalityFiles.length} personality templates (${newPersonalities} new, ${updatedPersonalities} updated)`));
890
+ console.log(chalk.white(` • ${newPersonalities + updatedPersonalities} personality templates (${newPersonalities} new, ${updatedPersonalities} updated)`));
970
891
  console.log(chalk.white(` • ${outputStyleFiles.length} output styles updated\n`));
971
892
 
972
- // 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)
973
894
  try {
974
- const releaseNotesPath = path.join(__dirname, '..', 'RELEASE_NOTES.md');
975
- const releaseNotes = await fs.readFile(releaseNotesPath, 'utf8');
976
-
977
- // Extract latest release summary
978
- 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;
979
899
 
980
- // Find the first release version header
981
- const versionIndex = lines.findIndex(line => line.match(/^## 📦 v\d+\.\d+\.\d+/));
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
+ }
982
908
 
983
- if (versionIndex >= 0) {
984
- // Extract version
985
- const versionMatch = lines[versionIndex].match(/v(\d+\.\d+\.\d+)/);
986
- const version = versionMatch ? versionMatch[1] : 'unknown';
909
+ const lines = releaseNotes.split('\n');
987
910
 
988
- // Find the AI Summary section
989
- const summaryIndex = lines.findIndex((line, idx) =>
990
- idx > versionIndex && line.includes('### 🤖 AI Summary')
991
- );
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`));
992
915
 
993
- if (summaryIndex >= 0) {
994
- console.log(chalk.cyan(`📰 Latest Release (v${version}):\n`));
916
+ // Find content after "## 🚀 Major Features" line
917
+ let summaryText = '';
918
+ let foundMajorFeatures = false;
995
919
 
996
- // Extract summary text (lines between AI Summary and next ###)
997
- let summaryText = '';
998
- for (let i = summaryIndex + 1; i < lines.length; i++) {
999
- const line = lines[i];
1000
- if (line.startsWith('###') || line.startsWith('##')) break;
1001
- if (line.trim()) {
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')) {
1002
930
  summaryText += line.trim() + ' ';
1003
931
  }
1004
932
  }
933
+ }
1005
934
 
1006
- // Wrap text at ~80 chars for better readability
935
+ // Wrap text at ~80 chars
936
+ if (summaryText) {
1007
937
  const words = summaryText.split(' ');
1008
938
  let currentLine = '';
1009
939
  const wrappedLines = [];
@@ -1023,6 +953,50 @@ program
1023
953
  });
1024
954
  console.log();
1025
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
+ }
1026
1000
  }
1027
1001
  } catch {
1028
1002
  // Release notes not available - no problem