agentvibes 5.6.9 → 5.7.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 (99) hide show
  1. package/.agentvibes/config.json +3 -38
  2. package/.claude/commands/agent-vibes/provider.md +0 -0
  3. package/.claude/config/audio-effects.cfg +1 -1
  4. package/.claude/config/background-music-position.txt +6 -8
  5. package/.claude/config/reverb-level.txt +0 -0
  6. package/.claude/github-star-reminder.txt +1 -1
  7. package/.claude/hooks/bmad-tts-injector.sh +49 -21
  8. package/.claude/hooks/migrate-to-agentvibes.sh +24 -16
  9. package/.claude/hooks/personality-manager.sh +15 -2
  10. package/.claude/hooks/play-tts.sh +6 -0
  11. package/.claude/hooks/provider-commands.sh +16 -4
  12. package/.claude/hooks/provider-manager.sh +38 -0
  13. package/.claude/hooks/stop.sh +2 -27
  14. package/.claude/hooks/voice-manager.sh +50 -2
  15. package/.claude/hooks-windows/play-tts.ps1 +34 -1
  16. package/.claude/hooks-windows/tts-watcher.ps1 +122 -0
  17. package/.claude/piper-voices-dir.txt +1 -1
  18. package/.mcp.json +13 -33
  19. package/README.md +6 -8
  20. package/RELEASE_NOTES.md +32 -0
  21. package/bin/agent-vibes +39 -39
  22. package/package.json +1 -1
  23. package/src/bmad-detector.js +85 -71
  24. package/src/cli/list-personalities.js +110 -110
  25. package/src/cli/list-voices.js +114 -114
  26. package/src/commands/bmad-voices.js +394 -394
  27. package/src/commands/install-mcp.js +476 -476
  28. package/src/console/brand-colors.js +13 -13
  29. package/src/console/constants/personalities.js +44 -44
  30. package/src/console/tabs/help-tab.js +314 -314
  31. package/src/console/tabs/readme-tab.js +272 -272
  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/i18n/de.js +202 -202
  36. package/src/i18n/es.js +202 -202
  37. package/src/i18n/fr.js +202 -202
  38. package/src/i18n/hi.js +202 -202
  39. package/src/i18n/ja.js +202 -202
  40. package/src/i18n/ko.js +202 -202
  41. package/src/i18n/pt.js +202 -202
  42. package/src/i18n/strings.js +54 -54
  43. package/src/i18n/zh-CN.js +202 -202
  44. package/src/installer/language-screen.js +31 -31
  45. package/src/installer/music-file-input.js +304 -304
  46. package/src/installer.js +330 -64
  47. package/src/services/agent-voice-store.js +59 -12
  48. package/src/services/config-service.js +264 -264
  49. package/src/services/language-service.js +47 -47
  50. package/src/services/llm-provider-service.js +57 -12
  51. package/src/services/provider-service.js +143 -143
  52. package/src/utils/audio-duration-validator.js +298 -298
  53. package/src/utils/audio-format-validator.js +277 -277
  54. package/src/utils/dependency-checker.js +469 -469
  55. package/src/utils/file-ownership-verifier.js +358 -358
  56. package/src/utils/list-formatter.js +194 -194
  57. package/src/utils/music-file-validator.js +285 -285
  58. package/src/utils/preview-list-prompt.js +136 -136
  59. package/src/utils/secure-music-storage.js +412 -412
  60. package/.agentvibes/LITE-MODE.md +0 -236
  61. package/.agentvibes/README.md +0 -136
  62. package/.agentvibes/backup/session-start-tts.sh.20251210_212814 +0 -141
  63. package/.agentvibes/backups/agents/analyst_20260204_144958.md +0 -78
  64. package/.agentvibes/backups/agents/architect_20260204_144958.md +0 -72
  65. package/.agentvibes/backups/agents/dev_20260204_144958.md +0 -74
  66. package/.agentvibes/backups/agents/pm_20260204_144958.md +0 -72
  67. package/.agentvibes/backups/agents/quick-flow-solo-dev_20260204_144958.md +0 -64
  68. package/.agentvibes/backups/agents/sm_20260204_144958.md +0 -87
  69. package/.agentvibes/backups/agents/tea_20260204_144958.md +0 -79
  70. package/.agentvibes/backups/agents/tech-writer_20260204_144958.md +0 -82
  71. package/.agentvibes/backups/agents/ux-designer_20260204_144958.md +0 -80
  72. package/.agentvibes/config/README-personality-defaults.md +0 -162
  73. package/.agentvibes/config/agentvibes.json +0 -1
  74. package/.agentvibes/config/mode.txt +0 -1
  75. package/.agentvibes/config/personality-voice-defaults.default.json +0 -21
  76. package/.agentvibes/config/save-audio.txt +0 -1
  77. package/.agentvibes/config/voice-metadata.json +0 -160
  78. package/.agentvibes/hooks/help.sh +0 -191
  79. package/.agentvibes/hooks/post-tool-use-lite.sh +0 -111
  80. package/.agentvibes/hooks/save-audio-manager.sh +0 -162
  81. package/.agentvibes/hooks/session-start-full-optimized.sh +0 -102
  82. package/.agentvibes/hooks/session-start-full.sh +0 -142
  83. package/.agentvibes/hooks/session-start-lite-v2.sh +0 -34
  84. package/.agentvibes/hooks/session-start-lite.sh +0 -29
  85. package/.agentvibes/hooks/stop-lite.sh +0 -115
  86. package/.agentvibes/hooks/switch-mode.sh +0 -215
  87. package/.agentvibes/output-styles/audio-summary.md +0 -30
  88. package/.claude/audio/voice-samples/piper/alan.wav +0 -0
  89. package/.claude/audio/voice-samples/piper/amy.wav +0 -0
  90. package/.claude/audio/voice-samples/piper/charlotte.wav +0 -0
  91. package/.claude/audio/voice-samples/piper/joe.wav +0 -0
  92. package/.claude/audio/voice-samples/piper/john.wav +0 -0
  93. package/.claude/audio/voice-samples/piper/katherine.wav +0 -0
  94. package/.claude/audio/voice-samples/piper/kristin.wav +0 -0
  95. package/.claude/audio/voice-samples/piper/linda.wav +0 -0
  96. package/.claude/audio/voice-samples/piper/marcus.wav +0 -0
  97. package/.claude/audio/voice-samples/piper/ryan.wav +0 -0
  98. package/.claude/hooks/post-response.sh +0 -41
  99. 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
+ }