agentvibes 5.10.1 → 5.11.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.
- package/.agentvibes/config.json +15 -1
- package/.agentvibes/install-manifest.json +342 -0
- package/.claude/audio/ui/CREDITS.txt +16 -0
- package/.claude/audio/ui/bling-success.wav +0 -0
- package/.claude/commands/agent-vibes/receiver.md +64 -0
- package/.claude/commands/agent-vibes-bmad-voices.md +117 -117
- package/.claude/commands/agent-vibes-rdp.md +24 -24
- package/.claude/config/audio-effects.cfg +5 -4
- package/.claude/config/audio-effects.cfg.sample +52 -52
- package/.claude/config/background-music-enabled.txt +1 -1
- package/.claude/config/background-music-position.txt +27 -0
- package/.claude/config/background-music-volume.txt +1 -0
- package/.claude/config/background-music.cfg +1 -0
- package/.claude/config/background-music.txt +1 -0
- package/.claude/config/language.txt +1 -0
- package/.claude/config/personality.txt +1 -0
- package/.claude/config/reverb-level.txt +1 -0
- package/.claude/config/tts-speech-rate.txt +1 -0
- package/.claude/config/tts-verbosity.txt +1 -0
- package/.claude/docs/TERMUX_SETUP.md +408 -408
- package/.claude/github-star-reminder.txt +1 -1
- package/.claude/hooks/audio-cache-utils.sh +0 -0
- package/.claude/hooks/audio-processor.sh +57 -18
- package/.claude/hooks/background-music-manager.sh +0 -0
- package/.claude/hooks/bmad-party-speak.sh +0 -0
- package/.claude/hooks/bmad-speak-enhanced.sh +0 -0
- package/.claude/hooks/bmad-speak.sh +0 -0
- package/.claude/hooks/bmad-tts-injector.sh +0 -0
- package/.claude/hooks/bmad-voice-manager.sh +0 -0
- package/.claude/hooks/clawdbot-receiver-SECURE.sh +0 -0
- package/.claude/hooks/clawdbot-receiver.sh +0 -0
- package/.claude/hooks/clean-audio-cache.sh +0 -0
- package/.claude/hooks/cleanup-cache.sh +0 -0
- package/.claude/hooks/configure-rdp-mode.sh +0 -0
- package/.claude/hooks/download-extra-voices.sh +0 -0
- package/.claude/hooks/effects-manager.sh +0 -0
- package/.claude/hooks/github-star-reminder.sh +0 -0
- package/.claude/hooks/kokoro-installer.sh +117 -0
- package/.claude/hooks/kokoro-server.py +219 -0
- package/.claude/hooks/kokoro-tts.py +141 -0
- package/.claude/hooks/language-manager.sh +0 -0
- package/.claude/hooks/learn-manager.sh +0 -0
- package/.claude/hooks/macos-voice-manager.sh +0 -0
- package/.claude/hooks/migrate-background-music.sh +0 -0
- package/.claude/hooks/migrate-to-agentvibes.sh +0 -0
- package/.claude/hooks/optimize-background-music.sh +0 -0
- package/.claude/hooks/path-resolver.sh +0 -0
- package/.claude/hooks/personality-manager.sh +0 -0
- package/.claude/hooks/piper-download-voices.sh +39 -16
- package/.claude/hooks/piper-installer.sh +11 -6
- package/.claude/hooks/piper-multispeaker-registry.sh +0 -0
- package/.claude/hooks/piper-voice-manager.sh +6 -6
- package/.claude/hooks/play-tts-agentvibes-receiver-for-voiceless-connections.sh +3 -1
- package/.claude/hooks/play-tts-agentvibes-receiver.sh +1 -0
- package/.claude/hooks/play-tts-elevenlabs.sh +360 -0
- package/.claude/hooks/play-tts-enhanced.sh +0 -0
- package/.claude/hooks/play-tts-kokoro.sh +127 -0
- package/.claude/hooks/play-tts-macos.sh +0 -0
- package/.claude/hooks/play-tts-piper.sh +0 -0
- package/.claude/hooks/play-tts-soprano.sh +0 -0
- package/.claude/hooks/play-tts-ssh-remote.sh +9 -2
- package/.claude/hooks/play-tts-termux-ssh.sh +3 -1
- package/.claude/hooks/play-tts-windows-receiver.sh +0 -0
- package/.claude/hooks/play-tts.sh +78 -2
- package/.claude/hooks/prepare-release.sh +0 -0
- package/.claude/hooks/provider-commands.sh +71 -22
- package/.claude/hooks/provider-manager.sh +15 -7
- package/.claude/hooks/replay-target-audio.sh +0 -0
- package/.claude/hooks/requirements.txt +6 -6
- package/.claude/hooks/sentiment-manager.sh +0 -0
- package/.claude/hooks/session-start-tts.sh +0 -0
- package/.claude/hooks/soprano-gradio-synth.py +139 -139
- package/.claude/hooks/speed-manager.sh +0 -0
- package/.claude/hooks/stop-tts.sh +0 -0
- package/.claude/hooks/termux-installer.sh +0 -0
- package/.claude/hooks/translate-manager.sh +0 -0
- package/.claude/hooks/translator.py +237 -237
- package/.claude/hooks/tts-queue-worker.sh +0 -0
- package/.claude/hooks/tts-queue.sh +0 -0
- package/.claude/hooks/verbosity-manager.sh +0 -0
- package/.claude/hooks/voice-manager.sh +0 -0
- package/.claude/hooks-windows/audio-cache-utils.ps1.user.bak +119 -0
- package/.claude/hooks-windows/kokoro-server.py +219 -0
- package/.claude/hooks-windows/kokoro-tts.py +107 -0
- package/.claude/hooks-windows/play-tts-kokoro.ps1 +191 -0
- package/.claude/hooks-windows/play-tts.ps1 +29 -1
- package/.claude/hooks-windows/soprano-gradio-synth.py +153 -153
- package/.claude/hooks-windows/soprano-gradio-synth.py.user.bak +153 -0
- package/.claude/piper-voices-dir.txt +1 -0
- package/.claude/verbosity.txt +1 -1
- package/.clawdbot/README.md +105 -105
- package/.mcp.json +6 -19
- package/README.md +127 -2116
- package/RELEASE_NOTES.md +73 -0
- package/WINDOWS-SETUP.md +208 -208
- package/bin/agent-vibes +39 -39
- package/bin/agentvibes-voice-browser.js +0 -0
- package/bin/agentvibes.js +0 -0
- package/bin/mcp-server.js +121 -121
- package/bin/mcp-server.sh +0 -0
- package/bin/test-bmad-pr +78 -78
- package/mcp-server/QUICK_START.md +203 -203
- package/mcp-server/README.md +345 -345
- package/mcp-server/WINDOWS_SETUP.md +0 -0
- package/mcp-server/examples/claude_desktop_config.json +11 -11
- package/mcp-server/examples/claude_desktop_config_piper.json +9 -9
- package/mcp-server/examples/custom_instructions.md +169 -169
- package/mcp-server/install-deps.js +0 -0
- package/mcp-server/server.py +1807 -1807
- package/mcp-server/test_server.py +0 -0
- package/package.json +4 -3
- package/src/cli/list-personalities.js +110 -110
- package/src/cli/list-voices.js +114 -114
- package/src/commands/bmad-voices.js +394 -394
- package/src/commands/install-mcp.js +3 -3
- package/src/console/app.js +25 -9
- package/src/console/audio-env.js +85 -1
- package/src/console/brand-colors.js +13 -13
- package/src/console/constants/personalities.js +44 -44
- package/src/console/navigation.js +4 -0
- package/src/console/tabs/agents-tab.js +12 -6
- package/src/console/tabs/help-tab.js +314 -314
- package/src/console/tabs/music-tab.js +7 -25
- package/src/console/tabs/readme-tab.js +272 -272
- package/src/console/tabs/setup-tab.js +1704 -120
- package/src/console/tabs/voices-tab.js +72 -88
- package/src/console/widgets/destroy-list.js +25 -25
- package/src/console/widgets/format-utils.js +14 -2
- package/src/console/widgets/help-bar.js +55 -0
- package/src/console/widgets/notice.js +55 -55
- package/src/console/widgets/reverb-picker.js +429 -41
- package/src/console/widgets/track-picker.js +60 -51
- package/src/i18n/de.js +2 -1
- package/src/i18n/en.js +1 -0
- package/src/i18n/es.js +2 -1
- package/src/i18n/fr.js +2 -1
- package/src/i18n/hi.js +2 -1
- package/src/i18n/ja.js +2 -1
- package/src/i18n/ko.js +2 -1
- package/src/i18n/pt.js +2 -1
- package/src/i18n/strings.js +9 -9
- package/src/i18n/zh-CN.js +2 -1
- package/src/installer/language-screen.js +31 -31
- package/src/installer/music-file-input.js +304 -304
- package/src/installer.js +95 -7
- package/src/services/config-service.js +264 -264
- package/src/services/language-service.js +47 -47
- package/src/services/provider-service.js +35 -0
- package/src/services/provider-voice-catalog.js +126 -0
- package/src/services/tts-engine-service.js +51 -2
- package/src/utils/audio-duration-validator.js +53 -10
- package/src/utils/audio-format-validator.js +277 -277
- package/src/utils/dependency-checker.js +469 -469
- package/src/utils/file-ownership-verifier.js +358 -358
- package/src/utils/music-file-validator.js +285 -285
- package/src/utils/preview-list-prompt.js +144 -136
- package/src/utils/provider-validator.js +70 -0
- package/src/utils/secure-music-storage.js +412 -412
- package/templates/agentvibes-receiver.sh +235 -231
- package/templates/audio/welcome-music.mp3 +0 -0
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
|
|
9
9
|
import fs from 'node:fs';
|
|
10
10
|
import path from 'node:path';
|
|
11
|
-
import { spawn } from 'node:child_process';
|
|
12
11
|
import { destroyList } from './destroy-list.js';
|
|
13
12
|
import { BRAND_PINK } from '../brand-colors.js';
|
|
13
|
+
import { renderHelpBar, selectorTitle } from './help-bar.js';
|
|
14
14
|
import { formatTrackName } from './format-utils.js';
|
|
15
|
-
import { buildAudioEnv,
|
|
15
|
+
import { buildAudioEnv, spawnMp3Player } from '../audio-env.js';
|
|
16
16
|
|
|
17
17
|
const IS_TEST = process.env.AGENTVIBES_TEST_MODE === 'true';
|
|
18
18
|
let blessed;
|
|
@@ -22,7 +22,6 @@ if (!IS_TEST) {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
const _modalTitle = (text) => ` {${BRAND_PINK}-fg}${text}{/${BRAND_PINK}-fg} `;
|
|
25
|
-
const _hintLabel = '{#455a64-fg}[Space] Preview [Enter] Select [Esc] Cancel{/#455a64-fg}';
|
|
26
25
|
|
|
27
26
|
/**
|
|
28
27
|
* Open a small volume input modal (0–100).
|
|
@@ -172,16 +171,46 @@ export function openTrackPicker(screen, currentTrack, currentVolume, onSelect, o
|
|
|
172
171
|
);
|
|
173
172
|
const currentIdx = tracks.findIndex(t => t.file === currentTrack);
|
|
174
173
|
|
|
175
|
-
|
|
176
|
-
|
|
174
|
+
// Standardized chrome: bordered box titled "Music Track Selector", a pinned
|
|
175
|
+
// (non-scrolling) help bar at the top, and the track list filling the rest.
|
|
176
|
+
const TITLE = selectorTitle('Music Track');
|
|
177
|
+
const HELP = renderHelpBar([
|
|
178
|
+
{ key: 'Space', label: 'preview' },
|
|
179
|
+
{ key: 'Enter', label: 'select' },
|
|
180
|
+
{ key: 'Esc', label: 'cancel' },
|
|
181
|
+
]);
|
|
182
|
+
|
|
183
|
+
const boxHeight = Math.min(tracks.length + 5, Math.floor(screen.rows * 0.7));
|
|
184
|
+
const box = blessed.box({
|
|
177
185
|
parent: screen,
|
|
178
186
|
top: 'center',
|
|
179
187
|
left: 'center',
|
|
180
188
|
width: 54,
|
|
181
|
-
height:
|
|
189
|
+
height: boxHeight,
|
|
182
190
|
border: { type: 'line' },
|
|
183
191
|
tags: true,
|
|
184
|
-
label:
|
|
192
|
+
label: TITLE,
|
|
193
|
+
style: { border: { fg: COLORS.btnFocus } },
|
|
194
|
+
});
|
|
195
|
+
box.setFront();
|
|
196
|
+
|
|
197
|
+
blessed.text({
|
|
198
|
+
parent: box,
|
|
199
|
+
top: 0,
|
|
200
|
+
left: 1,
|
|
201
|
+
right: 1,
|
|
202
|
+
height: 1,
|
|
203
|
+
tags: true,
|
|
204
|
+
content: HELP,
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
const list = blessed.list({
|
|
208
|
+
parent: box,
|
|
209
|
+
top: 1,
|
|
210
|
+
left: 0,
|
|
211
|
+
right: 0,
|
|
212
|
+
bottom: 0,
|
|
213
|
+
tags: true,
|
|
185
214
|
items,
|
|
186
215
|
keys: true,
|
|
187
216
|
vi: false,
|
|
@@ -189,50 +218,29 @@ export function openTrackPicker(screen, currentTrack, currentVolume, onSelect, o
|
|
|
189
218
|
scrollable: true,
|
|
190
219
|
scrollbar: { ch: '│', track: { bg: '#1e2a3a' }, style: { fg: COLORS.btnFocus } },
|
|
191
220
|
style: {
|
|
192
|
-
border: { fg: COLORS.btnFocus },
|
|
193
221
|
selected: { bg: COLORS.btnFocus, fg: COLORS.btnFocusFg, bold: true },
|
|
194
222
|
item: { fg: '#e3f2fd' },
|
|
195
223
|
},
|
|
196
224
|
});
|
|
197
225
|
|
|
198
|
-
//
|
|
199
|
-
function
|
|
200
|
-
|
|
201
|
-
// Use _ prefix convention for bottom border content (blessed doesn't have setFooter)
|
|
202
|
-
list._label2 && list._label2.destroy();
|
|
203
|
-
list._label2 = blessed.text({
|
|
204
|
-
parent: list,
|
|
205
|
-
bottom: -1,
|
|
206
|
-
left: 1,
|
|
207
|
-
width: 50,
|
|
208
|
-
height: 1,
|
|
209
|
-
tags: true,
|
|
210
|
-
content: text,
|
|
211
|
-
style: { fg: '#e3f2fd' },
|
|
212
|
-
});
|
|
226
|
+
// Transient preview/error status shows in the title area; idle restores the title.
|
|
227
|
+
function _setStatus(text) {
|
|
228
|
+
box.setLabel(text || TITLE);
|
|
213
229
|
screen.render();
|
|
214
230
|
}
|
|
215
231
|
|
|
216
|
-
_setHint(_hintLabel);
|
|
217
|
-
|
|
218
232
|
if (currentIdx >= 0) list.select(currentIdx);
|
|
219
233
|
list.focus();
|
|
220
234
|
screen.render();
|
|
221
235
|
|
|
222
236
|
// Preview playback state
|
|
223
237
|
const _spawnEnv = buildAudioEnv();
|
|
224
|
-
const _mp3Player = detectMp3Player(_spawnEnv);
|
|
225
238
|
let _previewProc = null;
|
|
226
239
|
let _previewTrackId = null;
|
|
227
240
|
|
|
228
241
|
function _killPreview() {
|
|
229
242
|
if (_previewProc) {
|
|
230
|
-
|
|
231
|
-
if (_isWin) {
|
|
232
|
-
try { _previewProc.kill(); } catch {}
|
|
233
|
-
} else {
|
|
234
|
-
try { process.kill(-_previewProc.pid, 'SIGTERM'); } catch {}
|
|
235
|
-
}
|
|
243
|
+
_previewProc.kill();
|
|
236
244
|
_previewProc = null;
|
|
237
245
|
}
|
|
238
246
|
_previewTrackId = null;
|
|
@@ -242,7 +250,7 @@ export function openTrackPicker(screen, currentTrack, currentVolume, onSelect, o
|
|
|
242
250
|
// Toggle off if same track
|
|
243
251
|
if (_previewTrackId === trackFile) {
|
|
244
252
|
_killPreview();
|
|
245
|
-
|
|
253
|
+
_setStatus();
|
|
246
254
|
return;
|
|
247
255
|
}
|
|
248
256
|
|
|
@@ -252,31 +260,34 @@ export function openTrackPicker(screen, currentTrack, currentVolume, onSelect, o
|
|
|
252
260
|
const safeBase = path.resolve(tracksDir);
|
|
253
261
|
if (!trackPath.startsWith(safeBase + path.sep) && trackPath !== safeBase) return;
|
|
254
262
|
|
|
255
|
-
if (!
|
|
256
|
-
|
|
257
|
-
setTimeout(() => {
|
|
258
|
-
_setHint(_hintLabel);
|
|
259
|
-
}, 3000);
|
|
263
|
+
if (!fs.existsSync(trackPath)) {
|
|
264
|
+
_setStatus(' {red-fg}Track file missing{/red-fg} ');
|
|
265
|
+
setTimeout(() => { _setStatus(); }, 3000);
|
|
260
266
|
return;
|
|
261
267
|
}
|
|
262
268
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
269
|
+
const proc = spawnMp3Player(trackPath, _spawnEnv);
|
|
270
|
+
if (!proc) {
|
|
271
|
+
_setStatus(' {red-fg}No MP3 player found{/red-fg} ');
|
|
272
|
+
setTimeout(() => { _setStatus(); }, 3000);
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
_previewProc = proc;
|
|
266
277
|
_previewTrackId = trackFile;
|
|
267
278
|
|
|
268
279
|
const label = tracks.find(t => t.file === trackFile)?.label ?? trackFile;
|
|
269
|
-
|
|
280
|
+
_setStatus(` {bright-cyan-fg}♪ ${label} (Space to stop){/bright-cyan-fg} `);
|
|
270
281
|
|
|
271
|
-
|
|
282
|
+
proc.on('exit', () => {
|
|
272
283
|
if (_previewTrackId === trackFile) {
|
|
273
284
|
_previewTrackId = null;
|
|
274
285
|
_previewProc = null;
|
|
275
|
-
|
|
286
|
+
_setStatus();
|
|
276
287
|
}
|
|
277
288
|
});
|
|
278
289
|
|
|
279
|
-
|
|
290
|
+
proc.on('error', () => {
|
|
280
291
|
_previewTrackId = null;
|
|
281
292
|
_previewProc = null;
|
|
282
293
|
});
|
|
@@ -284,12 +295,11 @@ export function openTrackPicker(screen, currentTrack, currentVolume, onSelect, o
|
|
|
284
295
|
|
|
285
296
|
function _close(callback) {
|
|
286
297
|
_killPreview();
|
|
287
|
-
if (list._label2) list._label2.destroy();
|
|
288
298
|
if (callback) {
|
|
289
299
|
callback();
|
|
290
|
-
destroyList(
|
|
300
|
+
destroyList(box, screen, onClose);
|
|
291
301
|
} else {
|
|
292
|
-
destroyList(
|
|
302
|
+
destroyList(box, screen, onClose);
|
|
293
303
|
}
|
|
294
304
|
}
|
|
295
305
|
|
|
@@ -304,15 +314,14 @@ export function openTrackPicker(screen, currentTrack, currentVolume, onSelect, o
|
|
|
304
314
|
const selected = tracks[list.selected];
|
|
305
315
|
if (!selected) return;
|
|
306
316
|
_killPreview();
|
|
307
|
-
if (list._label2) list._label2.destroy();
|
|
308
317
|
if (options.skipVolume) {
|
|
309
|
-
destroyList(
|
|
318
|
+
destroyList(box, screen, null);
|
|
310
319
|
setTimeout(() => {
|
|
311
320
|
onSelect(selected.file);
|
|
312
321
|
if (onClose) onClose();
|
|
313
322
|
}, 0);
|
|
314
323
|
} else {
|
|
315
|
-
destroyList(
|
|
324
|
+
destroyList(box, screen, null);
|
|
316
325
|
openVolumeInput(screen, currentVolume ?? 20, (volume) => {
|
|
317
326
|
onSelect(selected.file, volume);
|
|
318
327
|
}, onClose);
|
package/src/i18n/de.js
CHANGED
|
@@ -143,6 +143,7 @@ export default {
|
|
|
143
143
|
voicesSwitchBtn: "[Stimme wechseln]",
|
|
144
144
|
voicesFavoriteBtn: "[★ Favorit]",
|
|
145
145
|
voicesDownloadBtn: "[Stimme herunterladen]",
|
|
146
|
+
voicesInstallAllBtn: "[BMAD-Stimmen installieren]",
|
|
146
147
|
voicesRowHintInstalled: "[Space] Vorschau [Enter] Auswählen [*] Favorit",
|
|
147
148
|
voicesRowHintUninstalled: "[Enter] Herunterladen und installieren",
|
|
148
149
|
musicRowHint: "[Space] Abspielen [Enter] Auswählen [*] Favorit",
|
|
@@ -200,4 +201,4 @@ export default {
|
|
|
200
201
|
readmeNotFound: "*(Keine README.md im aktuellen Verzeichnis gefunden)*",
|
|
201
202
|
bmadFooterNobmad: "[Tab] Tab wechseln [Q] Beenden",
|
|
202
203
|
bmadFooterBmad: "[↑↓/jk] Navigieren [Space] Vorschau [Enter] Konfigurieren [A] Auto-zuweisen [B] Stapel [X] Zurücksetzen [Q] Beenden",
|
|
203
|
-
};
|
|
204
|
+
};
|
package/src/i18n/en.js
CHANGED
|
@@ -143,6 +143,7 @@ export default {
|
|
|
143
143
|
voicesSwitchBtn: "[Switch Voice]",
|
|
144
144
|
voicesFavoriteBtn: "[+ Thumbs Up]",
|
|
145
145
|
voicesDownloadBtn: "[Download Voice]",
|
|
146
|
+
voicesInstallAllBtn: "[Install BMAD Voices]",
|
|
146
147
|
voicesRowHintInstalled: "[Space] Preview [Enter] Select [+/*] Up [-] Down",
|
|
147
148
|
voicesRowHintUninstalled: "[Enter] Download & Install",
|
|
148
149
|
musicRowHint: "[Space] Play [Enter] Select [+/*] Favorite",
|
package/src/i18n/es.js
CHANGED
|
@@ -143,6 +143,7 @@ export default {
|
|
|
143
143
|
voicesSwitchBtn: "[Cambiar Voz]",
|
|
144
144
|
voicesFavoriteBtn: "[★ Favorito]",
|
|
145
145
|
voicesDownloadBtn: "[Descargar Voz]",
|
|
146
|
+
voicesInstallAllBtn: "[Instalar Voces BMAD]",
|
|
146
147
|
voicesRowHintInstalled: "[Space] Vista previa [Enter] Seleccionar [*] Favorito",
|
|
147
148
|
voicesRowHintUninstalled: "[Enter] Descargar e instalar",
|
|
148
149
|
musicRowHint: "[Space] Reproducir [Enter] Seleccionar [*] Favorito",
|
|
@@ -200,4 +201,4 @@ export default {
|
|
|
200
201
|
readmeNotFound: "*(No se encontró README.md en el directorio actual)*",
|
|
201
202
|
bmadFooterNobmad: "[Tab] Cambiar Pestaña [Q] Salir",
|
|
202
203
|
bmadFooterBmad: "[↑↓/jk] Navegar [Space] Previsualizar [Enter] Configurar [A] Auto-asignar [B] Masivo [X] Restablecer [Q] Salir",
|
|
203
|
-
};
|
|
204
|
+
};
|
package/src/i18n/fr.js
CHANGED
|
@@ -143,6 +143,7 @@ export default {
|
|
|
143
143
|
voicesSwitchBtn: "[Changer la voix]",
|
|
144
144
|
voicesFavoriteBtn: "[★ Favori]",
|
|
145
145
|
voicesDownloadBtn: "[Télécharger la voix]",
|
|
146
|
+
voicesInstallAllBtn: "[Installer les voix BMAD]",
|
|
146
147
|
voicesRowHintInstalled: "[Space] Aperçu [Enter] Sélectionner [*] Favori",
|
|
147
148
|
voicesRowHintUninstalled: "[Enter] Télécharger et installer",
|
|
148
149
|
musicRowHint: "[Space] Lire [Enter] Sélectionner [*] Favori",
|
|
@@ -200,4 +201,4 @@ export default {
|
|
|
200
201
|
readmeNotFound: "*(Aucun README.md trouvé dans le répertoire actuel)*",
|
|
201
202
|
bmadFooterNobmad: "[Tab] Changer d'onglet [Q] Quitter",
|
|
202
203
|
bmadFooterBmad: "[↑↓/jk] Naviguer [Space] Aperçu [Enter] Configurer [A] Auto-assigner [B] Lot [X] Réinitialiser [Q] Quitter",
|
|
203
|
-
};
|
|
204
|
+
};
|
package/src/i18n/hi.js
CHANGED
|
@@ -143,6 +143,7 @@ export default {
|
|
|
143
143
|
voicesSwitchBtn: "[आवाज़ बदलें]",
|
|
144
144
|
voicesFavoriteBtn: "[★ पसंदीदा]",
|
|
145
145
|
voicesDownloadBtn: "[आवाज़ डाउनलोड]",
|
|
146
|
+
voicesInstallAllBtn: "[BMAD आवाज़ें इंस्टॉल करें]",
|
|
146
147
|
voicesRowHintInstalled: "[Space] पूर्वावलोकन [Enter] चुनें [*] पसंदीदा",
|
|
147
148
|
voicesRowHintUninstalled: "[Enter] डाउनलोड और इंस्टॉल करें",
|
|
148
149
|
musicRowHint: "[Space] चलाएं [Enter] चुनें [*] पसंदीदा",
|
|
@@ -200,4 +201,4 @@ export default {
|
|
|
200
201
|
readmeNotFound: "*(वर्तमान निर्देशिका में README.md नहीं मिला)*",
|
|
201
202
|
bmadFooterNobmad: "[Tab] टैब बदलें [Q] बाहर",
|
|
202
203
|
bmadFooterBmad: "[↑↓/jk] नेविगेट [Space] प्रीव्यू [Enter] कॉन्फ़िगर [A] ऑटो-असाइन [B] बल्क [X] रीसेट [Q] बाहर",
|
|
203
|
-
};
|
|
204
|
+
};
|
package/src/i18n/ja.js
CHANGED
|
@@ -143,6 +143,7 @@ export default {
|
|
|
143
143
|
voicesSwitchBtn: "[音声切り替え]",
|
|
144
144
|
voicesFavoriteBtn: "[★ お気に入り]",
|
|
145
145
|
voicesDownloadBtn: "[音声ダウンロード]",
|
|
146
|
+
voicesInstallAllBtn: "[BMADボイスをインストール]",
|
|
146
147
|
voicesRowHintInstalled: "[Space] プレビュー [Enter] 選択 [*] お気に入り",
|
|
147
148
|
voicesRowHintUninstalled: "[Enter] ダウンロードしてインストール",
|
|
148
149
|
musicRowHint: "[Space] 再生 [Enter] 選択 [*] お気に入り",
|
|
@@ -200,4 +201,4 @@ export default {
|
|
|
200
201
|
readmeNotFound: "*(現在のディレクトリにREADME.mdが見つかりません)*",
|
|
201
202
|
bmadFooterNobmad: "[Tab] タブ切替 [Q] 終了",
|
|
202
203
|
bmadFooterBmad: "[↑↓/jk] 移動 [Space] プレビュー [Enter] 設定 [A] 自動割当 [B] 一括 [X] リセット [Q] 終了",
|
|
203
|
-
};
|
|
204
|
+
};
|
package/src/i18n/ko.js
CHANGED
|
@@ -143,6 +143,7 @@ export default {
|
|
|
143
143
|
voicesSwitchBtn: "[음성 전환]",
|
|
144
144
|
voicesFavoriteBtn: "[★ 즐겨찾기]",
|
|
145
145
|
voicesDownloadBtn: "[음성 다운로드]",
|
|
146
|
+
voicesInstallAllBtn: "[BMAD 음성 설치]",
|
|
146
147
|
voicesRowHintInstalled: "[Space] 미리보기 [Enter] 선택 [*] 즐겨찾기",
|
|
147
148
|
voicesRowHintUninstalled: "[Enter] 다운로드 및 설치",
|
|
148
149
|
musicRowHint: "[Space] 재생 [Enter] 선택 [*] 즐겨찾기",
|
|
@@ -200,4 +201,4 @@ export default {
|
|
|
200
201
|
readmeNotFound: "*(현재 디렉토리에서 README.md를 찾을 수 없습니다)*",
|
|
201
202
|
bmadFooterNobmad: "[Tab] 탭 전환 [Q] 나가기",
|
|
202
203
|
bmadFooterBmad: "[↑↓/jk] 탐색 [Space] 미리보기 [Enter] 설정 [A] 자동배정 [B] 일괄 [X] 초기화 [Q] 나가기",
|
|
203
|
-
};
|
|
204
|
+
};
|
package/src/i18n/pt.js
CHANGED
|
@@ -143,6 +143,7 @@ export default {
|
|
|
143
143
|
voicesSwitchBtn: "[Trocar Voz]",
|
|
144
144
|
voicesFavoriteBtn: "[★ Favorito]",
|
|
145
145
|
voicesDownloadBtn: "[Baixar Voz]",
|
|
146
|
+
voicesInstallAllBtn: "[Instalar Vozes BMAD]",
|
|
146
147
|
voicesRowHintInstalled: "[Space] Visualizar [Enter] Selecionar [*] Favorito",
|
|
147
148
|
voicesRowHintUninstalled: "[Enter] Baixar e instalar",
|
|
148
149
|
musicRowHint: "[Space] Reproduzir [Enter] Selecionar [*] Favorito",
|
|
@@ -200,4 +201,4 @@ export default {
|
|
|
200
201
|
readmeNotFound: "*(Nenhum README.md encontrado no diretório atual)*",
|
|
201
202
|
bmadFooterNobmad: "[Tab] Mudar Aba [Q] Sair",
|
|
202
203
|
bmadFooterBmad: "[↑↓/jk] Navegar [Space] Visualizar [Enter] Configurar [A] Auto-atribuir [B] Lote [X] Redefinir [Q] Sair",
|
|
203
|
-
};
|
|
204
|
+
};
|
package/src/i18n/strings.js
CHANGED
|
@@ -42,13 +42,13 @@ export function t(lang, key) {
|
|
|
42
42
|
* Each entry has: value (language code), name (display label for inquirer)
|
|
43
43
|
*/
|
|
44
44
|
export const SUPPORTED_LANGUAGES = [
|
|
45
|
-
{ value: 'en', name: '
|
|
46
|
-
{ value: 'es', name: '
|
|
47
|
-
{ value: 'fr', name: '
|
|
48
|
-
{ value: 'de', name: '
|
|
49
|
-
{ value: 'pt', name: '
|
|
50
|
-
{ value: 'ja', name: '
|
|
51
|
-
{ value: 'hi', name: '
|
|
52
|
-
{ value: 'zh-CN', name: '
|
|
53
|
-
{ value: 'ko', name: '
|
|
45
|
+
{ value: 'en', name: '[EN] English' },
|
|
46
|
+
{ value: 'es', name: '[ES] Español (Spanish)' },
|
|
47
|
+
{ value: 'fr', name: '[FR] Français (French)' },
|
|
48
|
+
{ value: 'de', name: '[DE] Deutsch (German)' },
|
|
49
|
+
{ value: 'pt', name: '[PT] Português (Portuguese)' },
|
|
50
|
+
{ value: 'ja', name: '[JA] 日本語 (Japanese)' },
|
|
51
|
+
{ value: 'hi', name: '[HI] हिन्दी (Hindi)' },
|
|
52
|
+
{ value: 'zh-CN', name: '[ZH] 中文 (Chinese Simplified)' },
|
|
53
|
+
{ value: 'ko', name: '[KO] 한국어 (Korean)' },
|
|
54
54
|
];
|
package/src/i18n/zh-CN.js
CHANGED
|
@@ -143,6 +143,7 @@ export default {
|
|
|
143
143
|
voicesSwitchBtn: "[切换语音]",
|
|
144
144
|
voicesFavoriteBtn: "[★ 收藏]",
|
|
145
145
|
voicesDownloadBtn: "[下载语音]",
|
|
146
|
+
voicesInstallAllBtn: "[安装BMAD语音]",
|
|
146
147
|
voicesRowHintInstalled: "[Space] 预览 [Enter] 选择 [*] 收藏",
|
|
147
148
|
voicesRowHintUninstalled: "[Enter] 下载并安装",
|
|
148
149
|
musicRowHint: "[Space] 播放 [Enter] 选择 [*] 收藏",
|
|
@@ -200,4 +201,4 @@ export default {
|
|
|
200
201
|
readmeNotFound: "*(当前目录中未找到README.md)*",
|
|
201
202
|
bmadFooterNobmad: "[Tab] 切换标签 [Q] 退出",
|
|
202
203
|
bmadFooterBmad: "[↑↓/jk] 导航 [Space] 预览 [Enter] 配置 [A] 自动分配 [B] 批量 [X] 重置 [Q] 退出",
|
|
203
|
-
};
|
|
204
|
+
};
|
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* File: src/installer/language-screen.js
|
|
3
|
-
*
|
|
4
|
-
* Language selection screen for the AgentVibes installer TUI.
|
|
5
|
-
* Presents a list of supported languages and returns the selected code.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import inquirer from 'inquirer';
|
|
9
|
-
import { t, SUPPORTED_LANGUAGES } from '../i18n/strings.js';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Show the language selection screen and return the chosen language code.
|
|
13
|
-
*
|
|
14
|
-
* @param {string} [currentLang='en'] - Currently active language code (used as default)
|
|
15
|
-
* @returns {Promise<string>} The selected language code (e.g. 'es', 'zh-CN')
|
|
16
|
-
*/
|
|
17
|
-
export async function selectLanguage(currentLang = 'en') {
|
|
18
|
-
const { lang } = await inquirer.prompt([{
|
|
19
|
-
type: 'list',
|
|
20
|
-
name: 'lang',
|
|
21
|
-
message: '🌐 Select Language / Seleccionar Idioma / Choisir la langue / Sprache wählen / Selecionar Idioma / 言語を選択 / भाषा चुनें / 选择语言 / 언어 선택',
|
|
22
|
-
default: currentLang,
|
|
23
|
-
choices: SUPPORTED_LANGUAGES
|
|
24
|
-
}]);
|
|
25
|
-
|
|
26
|
-
console.clear();
|
|
27
|
-
const chosenName = SUPPORTED_LANGUAGES.find(l => l.value === lang)?.name ?? lang;
|
|
28
|
-
console.log(`\u2713 ${t(lang, 'languageApplied')}: ${chosenName}\n`);
|
|
29
|
-
|
|
30
|
-
return lang;
|
|
31
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* File: src/installer/language-screen.js
|
|
3
|
+
*
|
|
4
|
+
* Language selection screen for the AgentVibes installer TUI.
|
|
5
|
+
* Presents a list of supported languages and returns the selected code.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import inquirer from 'inquirer';
|
|
9
|
+
import { t, SUPPORTED_LANGUAGES } from '../i18n/strings.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Show the language selection screen and return the chosen language code.
|
|
13
|
+
*
|
|
14
|
+
* @param {string} [currentLang='en'] - Currently active language code (used as default)
|
|
15
|
+
* @returns {Promise<string>} The selected language code (e.g. 'es', 'zh-CN')
|
|
16
|
+
*/
|
|
17
|
+
export async function selectLanguage(currentLang = 'en') {
|
|
18
|
+
const { lang } = await inquirer.prompt([{
|
|
19
|
+
type: 'list',
|
|
20
|
+
name: 'lang',
|
|
21
|
+
message: '🌐 Select Language / Seleccionar Idioma / Choisir la langue / Sprache wählen / Selecionar Idioma / 言語を選択 / भाषा चुनें / 选择语言 / 언어 선택',
|
|
22
|
+
default: currentLang,
|
|
23
|
+
choices: SUPPORTED_LANGUAGES
|
|
24
|
+
}]);
|
|
25
|
+
|
|
26
|
+
console.clear();
|
|
27
|
+
const chosenName = SUPPORTED_LANGUAGES.find(l => l.value === lang)?.name ?? lang;
|
|
28
|
+
console.log(`\u2713 ${t(lang, 'languageApplied')}: ${chosenName}\n`);
|
|
29
|
+
|
|
30
|
+
return lang;
|
|
31
|
+
}
|