agentvibes 5.6.0 → 5.6.2

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 +58 -8
  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 +15 -2
  15. package/RELEASE_NOTES.md +64 -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,194 +1,194 @@
1
- #!/usr/bin/env node
2
- /**
3
- * AgentVibes List Formatter
4
- *
5
- * Beautiful multi-column boxen displays for voices and personalities
6
- * Inspired by BMAD-METHOD's installer UX
7
- */
8
-
9
- import chalk from 'chalk';
10
- import boxen from 'boxen';
11
-
12
- /**
13
- * Format items into multi-column layout
14
- * @param {Array} items - Array of strings or objects with {name, description, current}
15
- * @param {Object} options - Formatting options
16
- * @returns {string} Formatted multi-column text
17
- */
18
- export function formatColumns(items, options = {}) {
19
- const {
20
- columns = 2,
21
- columnWidth = 35,
22
- highlightChar = '▶',
23
- indent = ' '
24
- } = options;
25
-
26
- const rows = [];
27
- const itemsPerRow = columns;
28
-
29
- for (let i = 0; i < items.length; i += itemsPerRow) {
30
- const rowItems = items.slice(i, i + itemsPerRow);
31
- const row = rowItems.map((item, idx) => {
32
- const isObject = typeof item === 'object';
33
- const name = isObject ? item.name : item;
34
- const desc = isObject ? item.description : '';
35
- const isCurrent = isObject ? item.current : false;
36
-
37
- // Format item
38
- let formatted = isCurrent ? `${highlightChar} ${name}` : ` ${name}`;
39
-
40
- if (desc) {
41
- formatted = chalk.cyan(formatted) + chalk.gray(` ${desc}`);
42
- } else if (isCurrent) {
43
- formatted = chalk.cyan(formatted);
44
- }
45
-
46
- // Pad to column width (accounting for ANSI codes)
47
- const plainLength = (isCurrent ? `${highlightChar} ${name}` : ` ${name}`).length + (desc ? ` ${desc}`.length : 0);
48
- const padding = Math.max(0, columnWidth - plainLength);
49
-
50
- return formatted + ' '.repeat(padding);
51
- });
52
-
53
- rows.push(indent + row.join(' '));
54
- }
55
-
56
- return rows.join('\n');
57
- }
58
-
59
- /**
60
- * Format voices list with boxen
61
- * @param {Array} voices - Array of voice objects {name, lang, current}
62
- * @param {Object} options - Display options
63
- * @returns {string} Formatted boxen output
64
- */
65
- export function formatVoicesList(voices, options = {}) {
66
- const {
67
- provider = 'Piper TTS',
68
- title = '🎤 Available Voices',
69
- columns = 2,
70
- showUsage = true
71
- } = options;
72
-
73
- if (voices.length === 0) {
74
- const content = chalk.yellow('No voices found') + '\n\n' +
75
- chalk.gray('Download voices with:\n') +
76
- chalk.cyan(' /agent-vibes:provider download <voice-name>');
77
-
78
- return boxen(content, {
79
- padding: 1,
80
- margin: 1,
81
- borderStyle: 'round',
82
- borderColor: 'yellow',
83
- title: chalk.bold(title),
84
- titleAlignment: 'center'
85
- });
86
- }
87
-
88
- // Format voices
89
- const formattedItems = voices.map(v => ({
90
- name: v.name,
91
- description: v.lang || '',
92
- current: v.current || false
93
- }));
94
-
95
- let content = chalk.bold(`${provider}\n\n`);
96
- content += formatColumns(formattedItems, { columns });
97
-
98
- if (showUsage) {
99
- content += '\n\n' + chalk.gray('─'.repeat(60)) + '\n';
100
- content += chalk.dim('Switch voice: ') + chalk.cyan('/agent-vibes:switch <voice-name>') + '\n';
101
- content += chalk.dim('Preview voice: ') + chalk.cyan('/agent-vibes:preview <voice-name>');
102
- }
103
-
104
- return boxen(content, {
105
- padding: 1,
106
- margin: 1,
107
- borderStyle: 'round',
108
- borderColor: 'cyan',
109
- title: chalk.bold(title),
110
- titleAlignment: 'center'
111
- });
112
- }
113
-
114
- /**
115
- * Format personalities list with boxen
116
- * @param {Array} personalities - Array of personality objects {name, description, current}
117
- * @param {Object} options - Display options
118
- * @returns {string} Formatted boxen output
119
- */
120
- export function formatPersonalitiesList(personalities, options = {}) {
121
- const {
122
- title = '🎭 Available Personalities',
123
- columns = 2,
124
- showUsage = true
125
- } = options;
126
-
127
- if (personalities.length === 0) {
128
- const content = chalk.yellow('No personalities found') + '\n\n' +
129
- chalk.gray('Add a personality with:\n') +
130
- chalk.cyan(' /agent-vibes:personality add <name>');
131
-
132
- return boxen(content, {
133
- padding: 1,
134
- margin: 1,
135
- borderStyle: 'round',
136
- borderColor: 'yellow',
137
- title: chalk.bold(title),
138
- titleAlignment: 'center'
139
- });
140
- }
141
-
142
- let content = formatColumns(personalities, { columns, columnWidth: 40 });
143
-
144
- if (showUsage) {
145
- content += '\n\n' + chalk.gray('─'.repeat(60)) + '\n';
146
- content += chalk.dim('Set personality: ') + chalk.cyan('/agent-vibes:personality <name>') + '\n';
147
- content += chalk.dim('Add personality: ') + chalk.cyan('/agent-vibes:personality add <name>') + '\n';
148
- content += chalk.dim('Edit personality: ') + chalk.cyan('/agent-vibes:personality edit <name>');
149
- }
150
-
151
- return boxen(content, {
152
- padding: 1,
153
- margin: 1,
154
- borderStyle: 'round',
155
- borderColor: 'magenta',
156
- title: chalk.bold(title),
157
- titleAlignment: 'center'
158
- });
159
- }
160
-
161
- /**
162
- * Format generic list with boxen
163
- * @param {Array} items - Array of items (strings or objects)
164
- * @param {Object} options - Display options
165
- * @returns {string} Formatted boxen output
166
- */
167
- export function formatList(items, options = {}) {
168
- const {
169
- title = 'Items',
170
- icon = '📋',
171
- columns = 2,
172
- borderColor = 'blue',
173
- showCount = true
174
- } = options;
175
-
176
- const titleText = icon ? `${icon} ${title}` : title;
177
- const countText = showCount ? chalk.gray(` (${items.length})`) : '';
178
-
179
- let content = '';
180
- if (showCount) {
181
- content = chalk.bold(`Total: ${items.length} items\n\n`);
182
- }
183
-
184
- content += formatColumns(items, { columns });
185
-
186
- return boxen(content, {
187
- padding: 1,
188
- margin: 1,
189
- borderStyle: 'round',
190
- borderColor,
191
- title: chalk.bold(titleText) + countText,
192
- titleAlignment: 'center'
193
- });
194
- }
1
+ #!/usr/bin/env node
2
+ /**
3
+ * AgentVibes List Formatter
4
+ *
5
+ * Beautiful multi-column boxen displays for voices and personalities
6
+ * Inspired by BMAD-METHOD's installer UX
7
+ */
8
+
9
+ import chalk from 'chalk';
10
+ import boxen from 'boxen';
11
+
12
+ /**
13
+ * Format items into multi-column layout
14
+ * @param {Array} items - Array of strings or objects with {name, description, current}
15
+ * @param {Object} options - Formatting options
16
+ * @returns {string} Formatted multi-column text
17
+ */
18
+ export function formatColumns(items, options = {}) {
19
+ const {
20
+ columns = 2,
21
+ columnWidth = 35,
22
+ highlightChar = '▶',
23
+ indent = ' '
24
+ } = options;
25
+
26
+ const rows = [];
27
+ const itemsPerRow = columns;
28
+
29
+ for (let i = 0; i < items.length; i += itemsPerRow) {
30
+ const rowItems = items.slice(i, i + itemsPerRow);
31
+ const row = rowItems.map((item, idx) => {
32
+ const isObject = typeof item === 'object';
33
+ const name = isObject ? item.name : item;
34
+ const desc = isObject ? item.description : '';
35
+ const isCurrent = isObject ? item.current : false;
36
+
37
+ // Format item
38
+ let formatted = isCurrent ? `${highlightChar} ${name}` : ` ${name}`;
39
+
40
+ if (desc) {
41
+ formatted = chalk.cyan(formatted) + chalk.gray(` ${desc}`);
42
+ } else if (isCurrent) {
43
+ formatted = chalk.cyan(formatted);
44
+ }
45
+
46
+ // Pad to column width (accounting for ANSI codes)
47
+ const plainLength = (isCurrent ? `${highlightChar} ${name}` : ` ${name}`).length + (desc ? ` ${desc}`.length : 0);
48
+ const padding = Math.max(0, columnWidth - plainLength);
49
+
50
+ return formatted + ' '.repeat(padding);
51
+ });
52
+
53
+ rows.push(indent + row.join(' '));
54
+ }
55
+
56
+ return rows.join('\n');
57
+ }
58
+
59
+ /**
60
+ * Format voices list with boxen
61
+ * @param {Array} voices - Array of voice objects {name, lang, current}
62
+ * @param {Object} options - Display options
63
+ * @returns {string} Formatted boxen output
64
+ */
65
+ export function formatVoicesList(voices, options = {}) {
66
+ const {
67
+ provider = 'Piper TTS',
68
+ title = '🎤 Available Voices',
69
+ columns = 2,
70
+ showUsage = true
71
+ } = options;
72
+
73
+ if (voices.length === 0) {
74
+ const content = chalk.yellow('No voices found') + '\n\n' +
75
+ chalk.gray('Download voices with:\n') +
76
+ chalk.cyan(' /agent-vibes:provider download <voice-name>');
77
+
78
+ return boxen(content, {
79
+ padding: 1,
80
+ margin: 1,
81
+ borderStyle: 'round',
82
+ borderColor: 'yellow',
83
+ title: chalk.bold(title),
84
+ titleAlignment: 'center'
85
+ });
86
+ }
87
+
88
+ // Format voices
89
+ const formattedItems = voices.map(v => ({
90
+ name: v.name,
91
+ description: v.lang || '',
92
+ current: v.current || false
93
+ }));
94
+
95
+ let content = chalk.bold(`${provider}\n\n`);
96
+ content += formatColumns(formattedItems, { columns });
97
+
98
+ if (showUsage) {
99
+ content += '\n\n' + chalk.gray('─'.repeat(60)) + '\n';
100
+ content += chalk.dim('Switch voice: ') + chalk.cyan('/agent-vibes:switch <voice-name>') + '\n';
101
+ content += chalk.dim('Preview voice: ') + chalk.cyan('/agent-vibes:preview <voice-name>');
102
+ }
103
+
104
+ return boxen(content, {
105
+ padding: 1,
106
+ margin: 1,
107
+ borderStyle: 'round',
108
+ borderColor: 'cyan',
109
+ title: chalk.bold(title),
110
+ titleAlignment: 'center'
111
+ });
112
+ }
113
+
114
+ /**
115
+ * Format personalities list with boxen
116
+ * @param {Array} personalities - Array of personality objects {name, description, current}
117
+ * @param {Object} options - Display options
118
+ * @returns {string} Formatted boxen output
119
+ */
120
+ export function formatPersonalitiesList(personalities, options = {}) {
121
+ const {
122
+ title = '🎭 Available Personalities',
123
+ columns = 2,
124
+ showUsage = true
125
+ } = options;
126
+
127
+ if (personalities.length === 0) {
128
+ const content = chalk.yellow('No personalities found') + '\n\n' +
129
+ chalk.gray('Add a personality with:\n') +
130
+ chalk.cyan(' /agent-vibes:personality add <name>');
131
+
132
+ return boxen(content, {
133
+ padding: 1,
134
+ margin: 1,
135
+ borderStyle: 'round',
136
+ borderColor: 'yellow',
137
+ title: chalk.bold(title),
138
+ titleAlignment: 'center'
139
+ });
140
+ }
141
+
142
+ let content = formatColumns(personalities, { columns, columnWidth: 40 });
143
+
144
+ if (showUsage) {
145
+ content += '\n\n' + chalk.gray('─'.repeat(60)) + '\n';
146
+ content += chalk.dim('Set personality: ') + chalk.cyan('/agent-vibes:personality <name>') + '\n';
147
+ content += chalk.dim('Add personality: ') + chalk.cyan('/agent-vibes:personality add <name>') + '\n';
148
+ content += chalk.dim('Edit personality: ') + chalk.cyan('/agent-vibes:personality edit <name>');
149
+ }
150
+
151
+ return boxen(content, {
152
+ padding: 1,
153
+ margin: 1,
154
+ borderStyle: 'round',
155
+ borderColor: 'magenta',
156
+ title: chalk.bold(title),
157
+ titleAlignment: 'center'
158
+ });
159
+ }
160
+
161
+ /**
162
+ * Format generic list with boxen
163
+ * @param {Array} items - Array of items (strings or objects)
164
+ * @param {Object} options - Display options
165
+ * @returns {string} Formatted boxen output
166
+ */
167
+ export function formatList(items, options = {}) {
168
+ const {
169
+ title = 'Items',
170
+ icon = '📋',
171
+ columns = 2,
172
+ borderColor = 'blue',
173
+ showCount = true
174
+ } = options;
175
+
176
+ const titleText = icon ? `${icon} ${title}` : title;
177
+ const countText = showCount ? chalk.gray(` (${items.length})`) : '';
178
+
179
+ let content = '';
180
+ if (showCount) {
181
+ content = chalk.bold(`Total: ${items.length} items\n\n`);
182
+ }
183
+
184
+ content += formatColumns(items, { columns });
185
+
186
+ return boxen(content, {
187
+ padding: 1,
188
+ margin: 1,
189
+ borderStyle: 'round',
190
+ borderColor,
191
+ title: chalk.bold(titleText) + countText,
192
+ titleAlignment: 'center'
193
+ });
194
+ }