agentvibes 5.6.0 → 5.6.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 (101) hide show
  1. package/.agentvibes/config.json +3 -38
  2. package/.claude/config/audio-effects.cfg +1 -1
  3. package/.claude/config/background-music-enabled.txt +1 -1
  4. package/.claude/config/background-music-position.txt +6 -6
  5. package/.claude/github-star-reminder.txt +1 -1
  6. package/.claude/hooks/play-tts-ssh-remote.sh +119 -42
  7. package/.claude/hooks/play-tts-windows-receiver.sh +31 -0
  8. package/.claude/hooks/stop.sh +2 -27
  9. package/.claude/hooks-windows/play-tts-windows-sapi.ps1 +108 -108
  10. package/.claude/hooks-windows/play-tts.ps1 +23 -7
  11. package/.claude/piper-voices-dir.txt +1 -1
  12. package/.clawdbot/skill/README.md +326 -0
  13. package/.mcp.json +17 -27
  14. package/README.md +11 -2
  15. package/RELEASE_NOTES.md +38 -0
  16. package/bin/agent-vibes +39 -39
  17. package/package.json +1 -1
  18. package/src/bmad-detector.js +71 -71
  19. package/src/cli/list-personalities.js +110 -110
  20. package/src/cli/list-voices.js +114 -114
  21. package/src/commands/bmad-voices.js +394 -394
  22. package/src/commands/install-mcp.js +476 -476
  23. package/src/console/brand-colors.js +13 -13
  24. package/src/console/constants/personalities.js +44 -44
  25. package/src/console/modals/modal-overlay.js +247 -247
  26. package/src/console/navigation.js +5 -1
  27. package/src/console/tabs/agents-tab.js +5 -5
  28. package/src/console/tabs/help-tab.js +314 -314
  29. package/src/console/tabs/readme-tab.js +272 -272
  30. package/src/console/tabs/setup-tab.js +32 -17
  31. package/src/console/tabs/voices-tab.js +2 -2
  32. package/src/console/widgets/destroy-list.js +25 -25
  33. package/src/console/widgets/notice.js +55 -55
  34. package/src/console/widgets/personality-picker.js +213 -213
  35. package/src/console/widgets/reverb-picker.js +97 -97
  36. package/src/console/widgets/track-picker.js +1 -1
  37. package/src/i18n/de.js +202 -202
  38. package/src/i18n/es.js +202 -202
  39. package/src/i18n/fr.js +202 -202
  40. package/src/i18n/hi.js +202 -202
  41. package/src/i18n/ja.js +202 -202
  42. package/src/i18n/ko.js +202 -202
  43. package/src/i18n/pt.js +202 -202
  44. package/src/i18n/strings.js +54 -54
  45. package/src/i18n/zh-CN.js +202 -202
  46. package/src/installer/language-screen.js +31 -31
  47. package/src/installer/music-file-input.js +304 -304
  48. package/src/services/agent-voice-store.js +420 -423
  49. package/src/services/config-service.js +264 -264
  50. package/src/services/language-service.js +47 -47
  51. package/src/services/llm-provider-service.js +11 -4
  52. package/src/services/navigation-service.js +34 -10
  53. package/src/services/provider-service.js +143 -143
  54. package/src/utils/audio-duration-validator.js +298 -298
  55. package/src/utils/audio-format-validator.js +277 -277
  56. package/src/utils/dependency-checker.js +469 -469
  57. package/src/utils/file-ownership-verifier.js +358 -358
  58. package/src/utils/list-formatter.js +194 -194
  59. package/src/utils/music-file-validator.js +285 -285
  60. package/src/utils/preview-list-prompt.js +136 -136
  61. package/src/utils/secure-music-storage.js +412 -412
  62. package/.agentvibes/LITE-MODE.md +0 -236
  63. package/.agentvibes/README.md +0 -136
  64. package/.agentvibes/backup/session-start-tts.sh.20251210_212814 +0 -141
  65. package/.agentvibes/backups/agents/analyst_20260204_144958.md +0 -78
  66. package/.agentvibes/backups/agents/architect_20260204_144958.md +0 -72
  67. package/.agentvibes/backups/agents/dev_20260204_144958.md +0 -74
  68. package/.agentvibes/backups/agents/pm_20260204_144958.md +0 -72
  69. package/.agentvibes/backups/agents/quick-flow-solo-dev_20260204_144958.md +0 -64
  70. package/.agentvibes/backups/agents/sm_20260204_144958.md +0 -87
  71. package/.agentvibes/backups/agents/tea_20260204_144958.md +0 -79
  72. package/.agentvibes/backups/agents/tech-writer_20260204_144958.md +0 -82
  73. package/.agentvibes/backups/agents/ux-designer_20260204_144958.md +0 -80
  74. package/.agentvibes/config/README-personality-defaults.md +0 -162
  75. package/.agentvibes/config/agentvibes.json +0 -1
  76. package/.agentvibes/config/mode.txt +0 -1
  77. package/.agentvibes/config/personality-voice-defaults.default.json +0 -21
  78. package/.agentvibes/config/save-audio.txt +0 -1
  79. package/.agentvibes/config/voice-metadata.json +0 -160
  80. package/.agentvibes/hooks/help.sh +0 -191
  81. package/.agentvibes/hooks/post-tool-use-lite.sh +0 -111
  82. package/.agentvibes/hooks/save-audio-manager.sh +0 -162
  83. package/.agentvibes/hooks/session-start-full-optimized.sh +0 -102
  84. package/.agentvibes/hooks/session-start-full.sh +0 -142
  85. package/.agentvibes/hooks/session-start-lite-v2.sh +0 -34
  86. package/.agentvibes/hooks/session-start-lite.sh +0 -29
  87. package/.agentvibes/hooks/stop-lite.sh +0 -115
  88. package/.agentvibes/hooks/switch-mode.sh +0 -215
  89. package/.agentvibes/output-styles/audio-summary.md +0 -30
  90. package/.claude/audio/voice-samples/piper/alan.wav +0 -0
  91. package/.claude/audio/voice-samples/piper/amy.wav +0 -0
  92. package/.claude/audio/voice-samples/piper/charlotte.wav +0 -0
  93. package/.claude/audio/voice-samples/piper/joe.wav +0 -0
  94. package/.claude/audio/voice-samples/piper/john.wav +0 -0
  95. package/.claude/audio/voice-samples/piper/katherine.wav +0 -0
  96. package/.claude/audio/voice-samples/piper/kristin.wav +0 -0
  97. package/.claude/audio/voice-samples/piper/linda.wav +0 -0
  98. package/.claude/audio/voice-samples/piper/marcus.wav +0 -0
  99. package/.claude/audio/voice-samples/piper/ryan.wav +0 -0
  100. package/.claude/hooks/post-response.sh +0 -41
  101. package/bin/ensure-soprano-running.sh +0 -43
@@ -1,110 +1,110 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Personality List Display - Beautiful multi-column personality listing
4
- * Called by personality-manager.sh to display personalities with boxen formatting
5
- */
6
-
7
- import { formatPersonalitiesList } from '../utils/list-formatter.js';
8
- import fs from 'fs';
9
- import path from 'path';
10
- import os from 'os';
11
-
12
- /**
13
- * Get personality description from markdown file
14
- */
15
- function getPersonalityDescription(filePath) {
16
- try {
17
- const content = fs.readFileSync(filePath, 'utf8');
18
-
19
- // Try to extract description from frontmatter or first paragraph
20
- const descMatch = content.match(/description:\s*(.+)/i);
21
- if (descMatch) {
22
- return descMatch[1].trim();
23
- }
24
-
25
- // Try to get first line after frontmatter
26
- const lines = content.split('\n');
27
- let inFrontmatter = false;
28
- let frontmatterCount = 0;
29
-
30
- for (const line of lines) {
31
- if (line.trim() === '---') {
32
- frontmatterCount++;
33
- inFrontmatter = frontmatterCount === 1;
34
- continue;
35
- }
36
-
37
- if (!inFrontmatter && frontmatterCount >= 2 && line.trim()) {
38
- // First non-empty line after frontmatter
39
- return line.trim().replace(/^#+\s*/, '').substring(0, 50);
40
- }
41
- }
42
-
43
- return '';
44
- } catch (error) {
45
- return '';
46
- }
47
- }
48
-
49
- /**
50
- * Get all personalities from directory
51
- */
52
- function getPersonalities(personalitiesDir, currentPersonality) {
53
- const personalities = [];
54
-
55
- if (!fs.existsSync(personalitiesDir)) {
56
- return personalities;
57
- }
58
-
59
- const files = fs.readdirSync(personalitiesDir);
60
- for (const file of files) {
61
- if (file.endsWith('.md')) {
62
- const name = path.basename(file, '.md');
63
- const filePath = path.join(personalitiesDir, file);
64
- const description = getPersonalityDescription(filePath);
65
-
66
- personalities.push({
67
- name,
68
- description,
69
- current: name === currentPersonality
70
- });
71
- }
72
- }
73
-
74
- // Add special 'random' option
75
- personalities.push({
76
- name: 'random',
77
- description: 'Picks randomly each time',
78
- current: currentPersonality === 'random'
79
- });
80
-
81
- return personalities.sort((a, b) => {
82
- // Keep 'random' at the end
83
- if (a.name === 'random') return 1;
84
- if (b.name === 'random') return -1;
85
- return a.name.localeCompare(b.name);
86
- });
87
- }
88
-
89
- /**
90
- * Main function
91
- */
92
- function main() {
93
- const args = process.argv.slice(2);
94
-
95
- // Parse arguments
96
- const personalitiesDir = args[0] || path.join(os.homedir(), '.claude', 'personalities');
97
- const currentPersonality = args[1] || 'normal';
98
-
99
- const personalities = getPersonalities(personalitiesDir, currentPersonality);
100
-
101
- // Display with boxen
102
- const output = formatPersonalitiesList(personalities, {
103
- columns: 2,
104
- showUsage: true
105
- });
106
-
107
- console.log(output);
108
- }
109
-
110
- main();
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Personality List Display - Beautiful multi-column personality listing
4
+ * Called by personality-manager.sh to display personalities with boxen formatting
5
+ */
6
+
7
+ import { formatPersonalitiesList } from '../utils/list-formatter.js';
8
+ import fs from 'fs';
9
+ import path from 'path';
10
+ import os from 'os';
11
+
12
+ /**
13
+ * Get personality description from markdown file
14
+ */
15
+ function getPersonalityDescription(filePath) {
16
+ try {
17
+ const content = fs.readFileSync(filePath, 'utf8');
18
+
19
+ // Try to extract description from frontmatter or first paragraph
20
+ const descMatch = content.match(/description:\s*(.+)/i);
21
+ if (descMatch) {
22
+ return descMatch[1].trim();
23
+ }
24
+
25
+ // Try to get first line after frontmatter
26
+ const lines = content.split('\n');
27
+ let inFrontmatter = false;
28
+ let frontmatterCount = 0;
29
+
30
+ for (const line of lines) {
31
+ if (line.trim() === '---') {
32
+ frontmatterCount++;
33
+ inFrontmatter = frontmatterCount === 1;
34
+ continue;
35
+ }
36
+
37
+ if (!inFrontmatter && frontmatterCount >= 2 && line.trim()) {
38
+ // First non-empty line after frontmatter
39
+ return line.trim().replace(/^#+\s*/, '').substring(0, 50);
40
+ }
41
+ }
42
+
43
+ return '';
44
+ } catch (error) {
45
+ return '';
46
+ }
47
+ }
48
+
49
+ /**
50
+ * Get all personalities from directory
51
+ */
52
+ function getPersonalities(personalitiesDir, currentPersonality) {
53
+ const personalities = [];
54
+
55
+ if (!fs.existsSync(personalitiesDir)) {
56
+ return personalities;
57
+ }
58
+
59
+ const files = fs.readdirSync(personalitiesDir);
60
+ for (const file of files) {
61
+ if (file.endsWith('.md')) {
62
+ const name = path.basename(file, '.md');
63
+ const filePath = path.join(personalitiesDir, file);
64
+ const description = getPersonalityDescription(filePath);
65
+
66
+ personalities.push({
67
+ name,
68
+ description,
69
+ current: name === currentPersonality
70
+ });
71
+ }
72
+ }
73
+
74
+ // Add special 'random' option
75
+ personalities.push({
76
+ name: 'random',
77
+ description: 'Picks randomly each time',
78
+ current: currentPersonality === 'random'
79
+ });
80
+
81
+ return personalities.sort((a, b) => {
82
+ // Keep 'random' at the end
83
+ if (a.name === 'random') return 1;
84
+ if (b.name === 'random') return -1;
85
+ return a.name.localeCompare(b.name);
86
+ });
87
+ }
88
+
89
+ /**
90
+ * Main function
91
+ */
92
+ function main() {
93
+ const args = process.argv.slice(2);
94
+
95
+ // Parse arguments
96
+ const personalitiesDir = args[0] || path.join(os.homedir(), '.claude', 'personalities');
97
+ const currentPersonality = args[1] || 'normal';
98
+
99
+ const personalities = getPersonalities(personalitiesDir, currentPersonality);
100
+
101
+ // Display with boxen
102
+ const output = formatPersonalitiesList(personalities, {
103
+ columns: 2,
104
+ showUsage: true
105
+ });
106
+
107
+ console.log(output);
108
+ }
109
+
110
+ main();
@@ -1,114 +1,114 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Voice List Display - Beautiful multi-column voice listing
4
- * Called by voice-manager.sh to display voices with boxen formatting
5
- */
6
-
7
- import { formatVoicesList } from '../utils/list-formatter.js';
8
- import fs from 'fs';
9
- import path from 'path';
10
- import { execFileSync } from 'child_process';
11
- import os from 'os';
12
-
13
- /**
14
- * Get Piper voices from voice directory
15
- */
16
- function getPiperVoices(voiceDir, currentVoice) {
17
- const voices = [];
18
-
19
- if (!fs.existsSync(voiceDir)) {
20
- return voices;
21
- }
22
-
23
- const files = fs.readdirSync(voiceDir);
24
- for (const file of files) {
25
- if (file.endsWith('.onnx')) {
26
- const voiceName = path.basename(file, '.onnx');
27
- voices.push({
28
- name: voiceName,
29
- lang: extractLanguage(voiceName),
30
- current: voiceName === currentVoice
31
- });
32
- }
33
- }
34
-
35
- return voices.sort((a, b) => a.name.localeCompare(b.name));
36
- }
37
-
38
- /**
39
- * Get macOS voices using say -v ?
40
- */
41
- function getMacOSVoices(currentVoice) {
42
- const voices = [];
43
-
44
- if (os.platform() !== 'darwin') {
45
- return voices;
46
- }
47
-
48
- try {
49
- const output = execFileSync('say', ['-v', '?'], { encoding: 'utf8' }); // NOSONAR - Safe: checking macOS say voices from system PATH
50
- const lines = output.split('\n');
51
-
52
- for (const line of lines) {
53
- if (!line.trim()) continue;
54
-
55
- const parts = line.trim().split(/\s+/);
56
- if (parts.length >= 2) {
57
- const voiceName = parts[0];
58
- const lang = parts[1];
59
-
60
- voices.push({
61
- name: voiceName,
62
- lang,
63
- current: voiceName === currentVoice
64
- });
65
- }
66
- }
67
- } catch (error) {
68
- // say command failed
69
- }
70
-
71
- return voices;
72
- }
73
-
74
- /**
75
- * Extract language code from voice name
76
- */
77
- function extractLanguage(voiceName) {
78
- const match = voiceName.match(/^([a-z]{2}_[A-Z]{2})/);
79
- return match ? match[1] : '';
80
- }
81
-
82
- /**
83
- * Main function
84
- */
85
- function main() {
86
- const args = process.argv.slice(2);
87
-
88
- // Parse arguments
89
- const provider = args[0] || 'piper';
90
- const currentVoice = args[1] || '';
91
- const voiceDir = args[2] || '';
92
-
93
- let voices = [];
94
- let providerName = 'Piper TTS';
95
-
96
- if (provider === 'piper') {
97
- voices = getPiperVoices(voiceDir, currentVoice);
98
- providerName = 'Piper TTS';
99
- } else if (provider === 'macos') {
100
- voices = getMacOSVoices(currentVoice);
101
- providerName = 'macOS TTS';
102
- }
103
-
104
- // Display with boxen
105
- const output = formatVoicesList(voices, {
106
- provider: providerName,
107
- columns: 2,
108
- showUsage: true
109
- });
110
-
111
- console.log(output);
112
- }
113
-
114
- main();
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Voice List Display - Beautiful multi-column voice listing
4
+ * Called by voice-manager.sh to display voices with boxen formatting
5
+ */
6
+
7
+ import { formatVoicesList } from '../utils/list-formatter.js';
8
+ import fs from 'fs';
9
+ import path from 'path';
10
+ import { execFileSync } from 'child_process';
11
+ import os from 'os';
12
+
13
+ /**
14
+ * Get Piper voices from voice directory
15
+ */
16
+ function getPiperVoices(voiceDir, currentVoice) {
17
+ const voices = [];
18
+
19
+ if (!fs.existsSync(voiceDir)) {
20
+ return voices;
21
+ }
22
+
23
+ const files = fs.readdirSync(voiceDir);
24
+ for (const file of files) {
25
+ if (file.endsWith('.onnx')) {
26
+ const voiceName = path.basename(file, '.onnx');
27
+ voices.push({
28
+ name: voiceName,
29
+ lang: extractLanguage(voiceName),
30
+ current: voiceName === currentVoice
31
+ });
32
+ }
33
+ }
34
+
35
+ return voices.sort((a, b) => a.name.localeCompare(b.name));
36
+ }
37
+
38
+ /**
39
+ * Get macOS voices using say -v ?
40
+ */
41
+ function getMacOSVoices(currentVoice) {
42
+ const voices = [];
43
+
44
+ if (os.platform() !== 'darwin') {
45
+ return voices;
46
+ }
47
+
48
+ try {
49
+ const output = execFileSync('say', ['-v', '?'], { encoding: 'utf8' }); // NOSONAR - Safe: checking macOS say voices from system PATH
50
+ const lines = output.split('\n');
51
+
52
+ for (const line of lines) {
53
+ if (!line.trim()) continue;
54
+
55
+ const parts = line.trim().split(/\s+/);
56
+ if (parts.length >= 2) {
57
+ const voiceName = parts[0];
58
+ const lang = parts[1];
59
+
60
+ voices.push({
61
+ name: voiceName,
62
+ lang,
63
+ current: voiceName === currentVoice
64
+ });
65
+ }
66
+ }
67
+ } catch (error) {
68
+ // say command failed
69
+ }
70
+
71
+ return voices;
72
+ }
73
+
74
+ /**
75
+ * Extract language code from voice name
76
+ */
77
+ function extractLanguage(voiceName) {
78
+ const match = voiceName.match(/^([a-z]{2}_[A-Z]{2})/);
79
+ return match ? match[1] : '';
80
+ }
81
+
82
+ /**
83
+ * Main function
84
+ */
85
+ function main() {
86
+ const args = process.argv.slice(2);
87
+
88
+ // Parse arguments
89
+ const provider = args[0] || 'piper';
90
+ const currentVoice = args[1] || '';
91
+ const voiceDir = args[2] || '';
92
+
93
+ let voices = [];
94
+ let providerName = 'Piper TTS';
95
+
96
+ if (provider === 'piper') {
97
+ voices = getPiperVoices(voiceDir, currentVoice);
98
+ providerName = 'Piper TTS';
99
+ } else if (provider === 'macos') {
100
+ voices = getMacOSVoices(currentVoice);
101
+ providerName = 'macOS TTS';
102
+ }
103
+
104
+ // Display with boxen
105
+ const output = formatVoicesList(voices, {
106
+ provider: providerName,
107
+ columns: 2,
108
+ showUsage: true
109
+ });
110
+
111
+ console.log(output);
112
+ }
113
+
114
+ main();