agentvibes 4.2.0 → 4.4.0
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/bmad/bmad-voices.md +69 -69
- package/.agentvibes/config.json +12 -0
- package/.claude/activation-instructions +54 -54
- package/.claude/audio/tracks/README.md +52 -52
- package/.claude/commands/agent-vibes/add.md +21 -21
- package/.claude/commands/agent-vibes/agent-vibes.md +101 -101
- package/.claude/commands/agent-vibes/agent.md +79 -79
- package/.claude/commands/agent-vibes/background-music.md +111 -111
- package/.claude/commands/agent-vibes/bmad.md +198 -198
- package/.claude/commands/agent-vibes/clean.md +18 -18
- package/.claude/commands/agent-vibes/cleanup.md +18 -18
- package/.claude/commands/agent-vibes/commands.json +145 -145
- package/.claude/commands/agent-vibes/effects.md +97 -97
- package/.claude/commands/agent-vibes/get.md +9 -9
- package/.claude/commands/agent-vibes/hide.md +91 -91
- package/.claude/commands/agent-vibes/language.md +23 -23
- package/.claude/commands/agent-vibes/learn.md +67 -67
- package/.claude/commands/agent-vibes/list.md +13 -13
- package/.claude/commands/agent-vibes/mute.md +37 -37
- package/.claude/commands/agent-vibes/preview.md +17 -17
- package/.claude/commands/agent-vibes/provider.md +68 -68
- package/.claude/commands/agent-vibes/replay-target.md +14 -14
- package/.claude/commands/agent-vibes/sample.md +12 -12
- package/.claude/commands/agent-vibes/set-favorite-voice.md +84 -84
- package/.claude/commands/agent-vibes/set-pretext.md +65 -65
- package/.claude/commands/agent-vibes/set-speed.md +41 -41
- package/.claude/commands/agent-vibes/show.md +84 -84
- package/.claude/commands/agent-vibes/switch.md +87 -87
- package/.claude/commands/agent-vibes/target-voice.md +26 -26
- package/.claude/commands/agent-vibes/target.md +30 -30
- package/.claude/commands/agent-vibes/translate.md +68 -68
- package/.claude/commands/agent-vibes/unmute.md +45 -45
- package/.claude/commands/agent-vibes/verbosity.md +89 -89
- package/.claude/commands/agent-vibes/whoami.md +7 -7
- package/.claude/commands/agent-vibes-bmad-voices.md +117 -117
- package/.claude/commands/agent-vibes-rdp.md +24 -24
- package/.claude/config/agentvibes.json +1 -0
- package/.claude/config/audio-effects.cfg +2 -2
- package/.claude/config/audio-effects.cfg.sample +52 -52
- package/.claude/config/background-music-volume.txt +1 -0
- package/.claude/config/intro-text.txt +1 -0
- package/.claude/config/piper-speech-rate.txt +4 -0
- package/.claude/config/piper-target-speech-rate.txt +1 -0
- package/.claude/config/reverb-level.txt +1 -0
- package/.claude/config/tts-speech-rate.txt +4 -0
- package/.claude/config/tts-target-speech-rate.txt +1 -0
- package/.claude/docs/TERMUX_SETUP.md +408 -408
- package/.claude/github-star-reminder.txt +1 -1
- package/.claude/hooks/README-TTS-QUEUE.md +135 -135
- package/.claude/hooks/audio-cache-utils.sh +246 -246
- package/.claude/hooks/audio-processor.sh +433 -433
- package/.claude/hooks/background-music-manager.sh +404 -404
- package/.claude/hooks/bmad-speak-enhanced.sh +165 -165
- package/.claude/hooks/bmad-speak.sh +269 -269
- package/.claude/hooks/bmad-tts-injector.sh +568 -568
- package/.claude/hooks/bmad-voice-manager.sh +928 -928
- package/.claude/hooks/clawdbot-receiver-SECURE.sh +129 -129
- package/.claude/hooks/clawdbot-receiver.sh +107 -107
- package/.claude/hooks/clean-audio-cache.sh +22 -22
- package/.claude/hooks/cleanup-cache.sh +106 -106
- package/.claude/hooks/configure-rdp-mode.sh +137 -137
- package/.claude/hooks/download-extra-voices.sh +244 -244
- package/.claude/hooks/effects-manager.sh +268 -268
- package/.claude/hooks/github-star-reminder.sh +154 -154
- package/.claude/hooks/language-manager.sh +362 -362
- package/.claude/hooks/learn-manager.sh +492 -492
- package/.claude/hooks/macos-voice-manager.sh +205 -205
- package/.claude/hooks/migrate-background-music.sh +125 -125
- package/.claude/hooks/migrate-to-agentvibes.sh +161 -161
- package/.claude/hooks/optimize-background-music.sh +87 -87
- package/.claude/hooks/path-resolver.sh +60 -60
- package/.claude/hooks/personality-manager.sh +448 -448
- package/.claude/hooks/piper-download-voices.sh +225 -225
- package/.claude/hooks/piper-installer.sh +292 -292
- package/.claude/hooks/piper-multispeaker-registry.sh +171 -171
- package/.claude/hooks/piper-voice-manager.sh +24 -3
- package/.claude/hooks/play-tts-agentvibes-receiver-for-voiceless-connections.sh +90 -90
- package/.claude/hooks/play-tts-enhanced.sh +105 -105
- package/.claude/hooks/play-tts-macos.sh +368 -368
- package/.claude/hooks/play-tts-piper.sh +679 -679
- package/.claude/hooks/play-tts-soprano.sh +356 -356
- package/.claude/hooks/play-tts-ssh-remote.sh +167 -167
- package/.claude/hooks/play-tts-termux-ssh.sh +169 -169
- package/.claude/hooks/play-tts.sh +301 -301
- package/.claude/hooks/prepare-release.sh +54 -54
- package/.claude/hooks/provider-commands.sh +617 -617
- package/.claude/hooks/provider-manager.sh +399 -399
- package/.claude/hooks/replay-target-audio.sh +95 -95
- package/.claude/hooks/requirements.txt +6 -6
- package/.claude/hooks/sentiment-manager.sh +201 -201
- package/.claude/hooks/session-start-tts.sh +81 -81
- package/.claude/hooks/soprano-gradio-synth.py +139 -139
- package/.claude/hooks/speed-manager.sh +291 -291
- package/.claude/hooks/stop-tts.sh +84 -84
- package/.claude/hooks/termux-installer.sh +261 -261
- package/.claude/hooks/translate-manager.sh +341 -341
- package/.claude/hooks/translator.py +237 -237
- package/.claude/hooks/tts-queue-worker.sh +145 -145
- package/.claude/hooks/tts-queue.sh +165 -165
- package/.claude/hooks/verbosity-manager.sh +178 -178
- package/.claude/hooks/voice-manager.sh +548 -548
- package/.claude/hooks-windows/audio-cache-utils.ps1 +119 -119
- package/.claude/hooks-windows/background-music-manager.ps1 +348 -0
- package/.claude/hooks-windows/clean-audio-cache.ps1 +53 -0
- package/.claude/hooks-windows/download-extra-voices.ps1 +185 -0
- package/.claude/hooks-windows/effects-manager.ps1 +294 -0
- package/.claude/hooks-windows/language-manager.ps1 +193 -0
- package/.claude/hooks-windows/learn-manager.ps1 +241 -0
- package/.claude/hooks-windows/personality-manager.ps1 +266 -0
- package/.claude/hooks-windows/play-tts-piper.ps1 +209 -0
- package/.claude/hooks-windows/play-tts-sapi.ps1 +108 -0
- package/.claude/hooks-windows/play-tts-soprano.ps1 +159 -158
- package/.claude/hooks-windows/play-tts-windows-piper.ps1 +50 -5
- package/.claude/hooks-windows/play-tts-windows-sapi.ps1 +108 -108
- package/.claude/hooks-windows/play-tts.ps1 +344 -266
- package/.claude/hooks-windows/provider-manager.ps1 +29 -10
- package/.claude/hooks-windows/session-start-tts.ps1 +124 -124
- package/.claude/hooks-windows/soprano-gradio-synth.py +153 -153
- package/.claude/hooks-windows/speed-manager.ps1 +166 -0
- package/.claude/hooks-windows/verbosity-manager.ps1 +119 -0
- package/.claude/hooks-windows/voice-manager-windows.ps1 +92 -8
- package/.claude/output-styles/agent-vibes.md +202 -202
- package/.claude/personalities/angry.md +14 -14
- package/.claude/personalities/annoying.md +14 -14
- package/.claude/personalities/crass.md +14 -14
- package/.claude/personalities/dramatic.md +14 -14
- package/.claude/personalities/dry-humor.md +50 -50
- package/.claude/personalities/flirty.md +20 -20
- package/.claude/personalities/funny.md +14 -14
- package/.claude/personalities/grandpa.md +32 -32
- package/.claude/personalities/millennial.md +14 -14
- package/.claude/personalities/moody.md +14 -14
- package/.claude/personalities/normal.md +16 -16
- package/.claude/personalities/pirate.md +14 -14
- package/.claude/personalities/poetic.md +14 -14
- package/.claude/personalities/professional.md +14 -14
- package/.claude/personalities/rapper.md +55 -55
- package/.claude/personalities/robot.md +14 -14
- package/.claude/personalities/sarcastic.md +38 -38
- package/.claude/personalities/sassy.md +14 -14
- package/.claude/personalities/surfer-dude.md +14 -14
- package/.claude/personalities/zen.md +14 -14
- package/.claude/settings.json +15 -15
- package/.claude/verbosity.txt +1 -1
- package/.clawdbot/README.md +105 -105
- package/.clawdbot/skill/SKILL.md +241 -241
- package/.mcp.json +12 -0
- package/CLAUDE.md +170 -170
- package/README.md +2029 -2007
- package/RELEASE_NOTES.md +1310 -1203
- package/WINDOWS-SETUP.md +208 -208
- package/bin/agent-vibes +39 -39
- package/bin/agentvibes-voice-browser.js +1840 -1840
- package/bin/agentvibes.js +48 -2
- package/bin/mcp-server.js +121 -121
- package/bin/mcp-server.sh +206 -206
- 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 +260 -260
- package/mcp-server/docs/troubleshooting-audio.md +313 -313
- 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 +130 -130
- package/mcp-server/pyproject.toml +52 -52
- package/mcp-server/requirements.txt +2 -2
- package/mcp-server/server.py +1465 -1453
- package/mcp-server/test_server.py +395 -395
- package/mcp-server/test_windows_script_parity.py +336 -0
- package/package.json +110 -110
- package/setup-windows.ps1 +815 -815
- package/src/bmad-detector.js +71 -71
- 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 +476 -476
- package/src/console/app.js +824 -824
- package/src/console/audio-env.js +20 -1
- package/src/console/brand-colors.js +13 -13
- package/src/console/constants/personalities.js +44 -44
- package/src/console/footer-config.js +50 -50
- package/src/console/modals/modal-overlay.js +247 -247
- package/src/console/navigation.js +62 -62
- package/src/console/tabs/agents-tab.js +1684 -1516
- package/src/console/tabs/help-tab.js +261 -261
- package/src/console/tabs/install-tab.js +1007 -991
- package/src/console/tabs/music-tab.js +22 -8
- package/src/console/tabs/placeholder-tab.js +53 -53
- package/src/console/tabs/readme-tab.js +267 -267
- package/src/console/tabs/receiver-tab.js +1472 -1212
- package/src/console/tabs/settings-tab.js +152 -79
- package/src/console/tabs/voices-tab.js +100 -21
- package/src/console/widgets/destroy-list.js +25 -25
- package/src/console/widgets/format-utils.js +89 -89
- package/src/console/widgets/notice.js +55 -55
- package/src/console/widgets/personality-picker.js +185 -185
- package/src/console/widgets/reverb-picker.js +94 -94
- package/src/console/widgets/track-picker.js +285 -285
- package/src/installer/music-file-input.js +304 -304
- package/src/installer.js +5882 -5829
- package/src/services/agent-voice-store.js +423 -423
- package/src/services/config-service.js +264 -264
- package/src/services/navigation-service.js +123 -123
- package/src/services/provider-service.js +132 -132
- package/src/services/verbosity-service.js +157 -157
- package/src/utils/audio-duration-validator.js +298 -298
- package/src/utils/audio-format-validator.js +277 -277
- package/src/utils/dependency-checker.js +469 -466
- package/src/utils/file-ownership-verifier.js +358 -358
- package/src/utils/list-formatter.js +194 -194
- package/src/utils/music-file-validator.js +285 -285
- package/src/utils/preview-list-prompt.js +136 -136
- package/src/utils/provider-validator.js +96 -12
- package/src/utils/secure-music-storage.js +412 -412
- package/templates/agentvibes-receiver.sh +482 -482
- package/templates/audio/welcome-music.mp3 +0 -0
- package/voice-assignments.json +8244 -8244
- package/.claude/config/background-music-position.txt +0 -1
|
@@ -1,466 +1,469 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* AgentVibes Dependency Checker
|
|
4
|
-
*
|
|
5
|
-
* Checks for required and optional system dependencies
|
|
6
|
-
* Displays missing dependencies with platform-specific install commands
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { execFileSync } from 'child_process';
|
|
10
|
-
import os from 'os';
|
|
11
|
-
import chalk from 'chalk';
|
|
12
|
-
import boxen from 'boxen';
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Check if a command exists in the system
|
|
16
|
-
*/
|
|
17
|
-
function commandExists(command) {
|
|
18
|
-
try {
|
|
19
|
-
// Try --version first (most common)
|
|
20
|
-
execFileSync(command, ['--version'], { stdio: 'pipe' });
|
|
21
|
-
return true;
|
|
22
|
-
} catch {
|
|
23
|
-
// Some commands like ffmpeg use -version (single dash)
|
|
24
|
-
try {
|
|
25
|
-
execFileSync(command, ['-version'], { stdio: 'pipe' });
|
|
26
|
-
return true;
|
|
27
|
-
} catch {
|
|
28
|
-
return false;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Check bash version (macOS specific requirement)
|
|
35
|
-
*/
|
|
36
|
-
function checkBashVersion() {
|
|
37
|
-
try {
|
|
38
|
-
const version = execFileSync('bash', ['--version'], { encoding: 'utf8' }); // NOSONAR - Safe: checking bash version from system PATH
|
|
39
|
-
const match = version.match(/version (\d+)\.(\d+)/);
|
|
40
|
-
if (match) {
|
|
41
|
-
const major = parseInt(match[1]);
|
|
42
|
-
return { installed: true, version: `${major}.${match[2]}`, isModern: major >= 5 };
|
|
43
|
-
}
|
|
44
|
-
return { installed: true, version: 'unknown', isModern: false };
|
|
45
|
-
} catch {
|
|
46
|
-
return { installed: false, version: null, isModern: false };
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Check Python version
|
|
52
|
-
*/
|
|
53
|
-
function checkPythonVersion() {
|
|
54
|
-
const commands = ['python3', 'python', 'py'];
|
|
55
|
-
|
|
56
|
-
for (const cmd of commands) {
|
|
57
|
-
try {
|
|
58
|
-
const version = execFileSync(cmd, ['--version'], { encoding: 'utf8', stdio: 'pipe' });
|
|
59
|
-
const match = version.match(/Python (\d+)\.(\d+)/);
|
|
60
|
-
if (match) {
|
|
61
|
-
const major = parseInt(match[1]);
|
|
62
|
-
const minor = parseInt(match[2]);
|
|
63
|
-
const versionStr = `${major}.${minor}`;
|
|
64
|
-
const isCompatible = major === 3 && minor >= 10;
|
|
65
|
-
return { installed: true, command: cmd, version: versionStr, isCompatible };
|
|
66
|
-
}
|
|
67
|
-
} catch {
|
|
68
|
-
continue;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return { installed: false, command: null, version: null, isCompatible: false };
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Check Node.js version
|
|
77
|
-
*/
|
|
78
|
-
function checkNodeVersion() {
|
|
79
|
-
try {
|
|
80
|
-
const version = process.version;
|
|
81
|
-
const match = version.match(/v(\d+)\.(\d+)/);
|
|
82
|
-
if (match) {
|
|
83
|
-
const major = parseInt(match[1]);
|
|
84
|
-
const versionStr = `${major}.${match[2]}`;
|
|
85
|
-
const isCompatible = major >= 16;
|
|
86
|
-
return { installed: true, version: versionStr, isCompatible };
|
|
87
|
-
}
|
|
88
|
-
return { installed: true, version: 'unknown', isCompatible: false };
|
|
89
|
-
} catch {
|
|
90
|
-
return { installed: false, version: null, isCompatible: false };
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Check for audio players (Linux/WSL)
|
|
96
|
-
*/
|
|
97
|
-
function checkAudioPlayers() {
|
|
98
|
-
const players = ['paplay', 'aplay', 'mpg123', 'mpv'];
|
|
99
|
-
const found = [];
|
|
100
|
-
|
|
101
|
-
for (const player of players) {
|
|
102
|
-
if (commandExists(player)) {
|
|
103
|
-
found.push(player);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
return { hasAny: found.length > 0, players: found };
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Get platform-specific install commands for missing dependencies
|
|
112
|
-
*/
|
|
113
|
-
/**
|
|
114
|
-
* Build homebrew package list for macOS
|
|
115
|
-
* @param {Object} missing - Missing dependencies
|
|
116
|
-
* @returns {string[]} Homebrew packages to install
|
|
117
|
-
*/
|
|
118
|
-
function buildBrewPackages(missing) {
|
|
119
|
-
const packages = [];
|
|
120
|
-
const packageMap = {
|
|
121
|
-
bash: 'bash',
|
|
122
|
-
sox: 'sox',
|
|
123
|
-
ffmpeg: 'ffmpeg',
|
|
124
|
-
pipx: 'pipx',
|
|
125
|
-
flock: 'util-linux',
|
|
126
|
-
curl: 'curl',
|
|
127
|
-
bc: 'bc'
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
for (const [key, pkg] of Object.entries(packageMap)) {
|
|
131
|
-
if (missing[key]) {
|
|
132
|
-
packages.push(pkg);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
return packages;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Build Linux package lists for different package managers
|
|
141
|
-
* @param {Object} missing - Missing dependencies
|
|
142
|
-
* @returns {Object} Package lists for apt, dnf, and pacman
|
|
143
|
-
*/
|
|
144
|
-
function buildLinuxPackages(missing) {
|
|
145
|
-
const apt = [];
|
|
146
|
-
const dnf = [];
|
|
147
|
-
const pacman = [];
|
|
148
|
-
|
|
149
|
-
const packageMap = {
|
|
150
|
-
sox: { apt: 'sox libsox-fmt-mp3', dnf: 'sox', pacman: 'sox' },
|
|
151
|
-
ffmpeg: { apt: 'ffmpeg', dnf: 'ffmpeg', pacman: 'ffmpeg' },
|
|
152
|
-
python: { apt: 'python3-pip', dnf: 'python3-pip', pacman: 'python-pip' },
|
|
153
|
-
pipx: { apt: 'pipx', dnf: 'pipx', pacman: 'python-pipx' },
|
|
154
|
-
audioPlayer: { apt: 'pulseaudio-utils', dnf: 'pulseaudio-utils', pacman: 'libpulse' },
|
|
155
|
-
flock: { apt: 'util-linux', dnf: 'util-linux', pacman: 'util-linux' },
|
|
156
|
-
curl: { apt: 'curl', dnf: 'curl', pacman: 'curl' },
|
|
157
|
-
bc: { apt: 'bc', dnf: 'bc', pacman: 'bc' }
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
for (const [key, packages] of Object.entries(packageMap)) {
|
|
161
|
-
if (missing[key]) {
|
|
162
|
-
apt.push(packages.apt);
|
|
163
|
-
dnf.push(packages.dnf);
|
|
164
|
-
pacman.push(packages.pacman);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
return { apt, dnf, pacman };
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Generate macOS installation commands
|
|
173
|
-
* @param {Object} missing - Missing dependencies
|
|
174
|
-
* @returns {Array} Installation command objects
|
|
175
|
-
*/
|
|
176
|
-
function getMacOSCommands(missing) {
|
|
177
|
-
const commands = [];
|
|
178
|
-
const brewPackages = buildBrewPackages(missing);
|
|
179
|
-
|
|
180
|
-
if (brewPackages.length > 0) {
|
|
181
|
-
commands.push({
|
|
182
|
-
label: 'macOS (Homebrew)',
|
|
183
|
-
command: `brew install ${brewPackages.join(' ')}`
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
if (missing.python) {
|
|
188
|
-
commands.push({
|
|
189
|
-
label: 'Python 3.10+',
|
|
190
|
-
command: 'brew install python@3.11'
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
return commands;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Generate Linux installation commands
|
|
199
|
-
* @param {Object} missing - Missing dependencies
|
|
200
|
-
* @returns {Array} Installation command objects
|
|
201
|
-
*/
|
|
202
|
-
function getLinuxCommands(missing) {
|
|
203
|
-
const commands = [];
|
|
204
|
-
const packages = buildLinuxPackages(missing);
|
|
205
|
-
|
|
206
|
-
if (packages.apt.length > 0) {
|
|
207
|
-
commands.push({
|
|
208
|
-
label: 'Ubuntu/Debian',
|
|
209
|
-
command: `sudo apt-get update && sudo apt-get install -y ${packages.apt.join(' ')}`
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
if (packages.dnf.length > 0) {
|
|
214
|
-
commands.push({
|
|
215
|
-
label: 'Fedora/RHEL',
|
|
216
|
-
command: `sudo dnf install -y ${packages.dnf.join(' ')}`
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
if (packages.pacman.length > 0) {
|
|
221
|
-
commands.push({
|
|
222
|
-
label: 'Arch Linux',
|
|
223
|
-
command: `sudo pacman -S ${packages.pacman.join(' ')}`
|
|
224
|
-
});
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
return commands;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
export function getInstallCommands(missing, platform) {
|
|
231
|
-
if (platform === 'darwin') {
|
|
232
|
-
return getMacOSCommands(missing);
|
|
233
|
-
} else if (platform === 'linux' || platform === 'wsl') {
|
|
234
|
-
return getLinuxCommands(missing);
|
|
235
|
-
} else if (platform === 'win32') {
|
|
236
|
-
return [{
|
|
237
|
-
label: 'Windows (Native)',
|
|
238
|
-
command: 'npx agentvibes install',
|
|
239
|
-
note: 'Windows Piper and SAPI providers are supported natively'
|
|
240
|
-
}];
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
return [];
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* Main dependency check function
|
|
248
|
-
*/
|
|
249
|
-
export function checkDependencies(options = {}) {
|
|
250
|
-
const platform = os.platform();
|
|
251
|
-
const isMac = platform === 'darwin';
|
|
252
|
-
const isWindows = platform === 'win32';
|
|
253
|
-
const isLinux = !isMac && !isWindows;
|
|
254
|
-
|
|
255
|
-
const results = {
|
|
256
|
-
core: {},
|
|
257
|
-
optional: {},
|
|
258
|
-
missing: {},
|
|
259
|
-
warnings: []
|
|
260
|
-
};
|
|
261
|
-
|
|
262
|
-
// Core requirements
|
|
263
|
-
const nodeCheck = checkNodeVersion();
|
|
264
|
-
results.core.node = nodeCheck;
|
|
265
|
-
if (!nodeCheck.isCompatible) {
|
|
266
|
-
results.missing.node = true;
|
|
267
|
-
results.warnings.push(`Node.js ${nodeCheck.version || 'not found'} - requires ≥16.0`);
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
const pythonCheck = checkPythonVersion();
|
|
271
|
-
results.core.python = pythonCheck;
|
|
272
|
-
if (!pythonCheck.isCompatible) {
|
|
273
|
-
results.missing.python = true;
|
|
274
|
-
results.warnings.push(`Python ${pythonCheck.version || 'not found'} - requires ≥3.10`);
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
// macOS-specific: bash 5.x requirement
|
|
278
|
-
if (isMac) {
|
|
279
|
-
const bashCheck = checkBashVersion();
|
|
280
|
-
results.core.bash = bashCheck;
|
|
281
|
-
if (!bashCheck.isModern) {
|
|
282
|
-
results.missing.bash = true;
|
|
283
|
-
results.warnings.push(`Bash ${bashCheck.version || 'not found'} - macOS requires ≥5.0`);
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
// Optional tools
|
|
288
|
-
if (!isWindows) {
|
|
289
|
-
results.optional.sox = commandExists('sox');
|
|
290
|
-
if (!results.optional.sox) {
|
|
291
|
-
results.missing.sox = true;
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
*
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
});
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* AgentVibes Dependency Checker
|
|
4
|
+
*
|
|
5
|
+
* Checks for required and optional system dependencies
|
|
6
|
+
* Displays missing dependencies with platform-specific install commands
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { execFileSync } from 'child_process';
|
|
10
|
+
import os from 'os';
|
|
11
|
+
import chalk from 'chalk';
|
|
12
|
+
import boxen from 'boxen';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Check if a command exists in the system
|
|
16
|
+
*/
|
|
17
|
+
function commandExists(command) {
|
|
18
|
+
try {
|
|
19
|
+
// Try --version first (most common)
|
|
20
|
+
execFileSync(command, ['--version'], { stdio: 'pipe' });
|
|
21
|
+
return true;
|
|
22
|
+
} catch {
|
|
23
|
+
// Some commands like ffmpeg use -version (single dash)
|
|
24
|
+
try {
|
|
25
|
+
execFileSync(command, ['-version'], { stdio: 'pipe' });
|
|
26
|
+
return true;
|
|
27
|
+
} catch {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Check bash version (macOS specific requirement)
|
|
35
|
+
*/
|
|
36
|
+
function checkBashVersion() {
|
|
37
|
+
try {
|
|
38
|
+
const version = execFileSync('bash', ['--version'], { encoding: 'utf8' }); // NOSONAR - Safe: checking bash version from system PATH
|
|
39
|
+
const match = version.match(/version (\d+)\.(\d+)/);
|
|
40
|
+
if (match) {
|
|
41
|
+
const major = parseInt(match[1]);
|
|
42
|
+
return { installed: true, version: `${major}.${match[2]}`, isModern: major >= 5 };
|
|
43
|
+
}
|
|
44
|
+
return { installed: true, version: 'unknown', isModern: false };
|
|
45
|
+
} catch {
|
|
46
|
+
return { installed: false, version: null, isModern: false };
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Check Python version
|
|
52
|
+
*/
|
|
53
|
+
function checkPythonVersion() {
|
|
54
|
+
const commands = ['python3', 'python', 'py'];
|
|
55
|
+
|
|
56
|
+
for (const cmd of commands) {
|
|
57
|
+
try {
|
|
58
|
+
const version = execFileSync(cmd, ['--version'], { encoding: 'utf8', stdio: 'pipe' });
|
|
59
|
+
const match = version.match(/Python (\d+)\.(\d+)/);
|
|
60
|
+
if (match) {
|
|
61
|
+
const major = parseInt(match[1]);
|
|
62
|
+
const minor = parseInt(match[2]);
|
|
63
|
+
const versionStr = `${major}.${minor}`;
|
|
64
|
+
const isCompatible = major === 3 && minor >= 10;
|
|
65
|
+
return { installed: true, command: cmd, version: versionStr, isCompatible };
|
|
66
|
+
}
|
|
67
|
+
} catch {
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return { installed: false, command: null, version: null, isCompatible: false };
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Check Node.js version
|
|
77
|
+
*/
|
|
78
|
+
function checkNodeVersion() {
|
|
79
|
+
try {
|
|
80
|
+
const version = process.version;
|
|
81
|
+
const match = version.match(/v(\d+)\.(\d+)/);
|
|
82
|
+
if (match) {
|
|
83
|
+
const major = parseInt(match[1]);
|
|
84
|
+
const versionStr = `${major}.${match[2]}`;
|
|
85
|
+
const isCompatible = major >= 16;
|
|
86
|
+
return { installed: true, version: versionStr, isCompatible };
|
|
87
|
+
}
|
|
88
|
+
return { installed: true, version: 'unknown', isCompatible: false };
|
|
89
|
+
} catch {
|
|
90
|
+
return { installed: false, version: null, isCompatible: false };
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Check for audio players (Linux/WSL)
|
|
96
|
+
*/
|
|
97
|
+
function checkAudioPlayers() {
|
|
98
|
+
const players = ['paplay', 'aplay', 'mpg123', 'mpv'];
|
|
99
|
+
const found = [];
|
|
100
|
+
|
|
101
|
+
for (const player of players) {
|
|
102
|
+
if (commandExists(player)) {
|
|
103
|
+
found.push(player);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return { hasAny: found.length > 0, players: found };
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Get platform-specific install commands for missing dependencies
|
|
112
|
+
*/
|
|
113
|
+
/**
|
|
114
|
+
* Build homebrew package list for macOS
|
|
115
|
+
* @param {Object} missing - Missing dependencies
|
|
116
|
+
* @returns {string[]} Homebrew packages to install
|
|
117
|
+
*/
|
|
118
|
+
function buildBrewPackages(missing) {
|
|
119
|
+
const packages = [];
|
|
120
|
+
const packageMap = {
|
|
121
|
+
bash: 'bash',
|
|
122
|
+
sox: 'sox',
|
|
123
|
+
ffmpeg: 'ffmpeg',
|
|
124
|
+
pipx: 'pipx',
|
|
125
|
+
flock: 'util-linux',
|
|
126
|
+
curl: 'curl',
|
|
127
|
+
bc: 'bc'
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
for (const [key, pkg] of Object.entries(packageMap)) {
|
|
131
|
+
if (missing[key]) {
|
|
132
|
+
packages.push(pkg);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return packages;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Build Linux package lists for different package managers
|
|
141
|
+
* @param {Object} missing - Missing dependencies
|
|
142
|
+
* @returns {Object} Package lists for apt, dnf, and pacman
|
|
143
|
+
*/
|
|
144
|
+
function buildLinuxPackages(missing) {
|
|
145
|
+
const apt = [];
|
|
146
|
+
const dnf = [];
|
|
147
|
+
const pacman = [];
|
|
148
|
+
|
|
149
|
+
const packageMap = {
|
|
150
|
+
sox: { apt: 'sox libsox-fmt-mp3', dnf: 'sox', pacman: 'sox' },
|
|
151
|
+
ffmpeg: { apt: 'ffmpeg', dnf: 'ffmpeg', pacman: 'ffmpeg' },
|
|
152
|
+
python: { apt: 'python3-pip', dnf: 'python3-pip', pacman: 'python-pip' },
|
|
153
|
+
pipx: { apt: 'pipx', dnf: 'pipx', pacman: 'python-pipx' },
|
|
154
|
+
audioPlayer: { apt: 'pulseaudio-utils', dnf: 'pulseaudio-utils', pacman: 'libpulse' },
|
|
155
|
+
flock: { apt: 'util-linux', dnf: 'util-linux', pacman: 'util-linux' },
|
|
156
|
+
curl: { apt: 'curl', dnf: 'curl', pacman: 'curl' },
|
|
157
|
+
bc: { apt: 'bc', dnf: 'bc', pacman: 'bc' }
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
for (const [key, packages] of Object.entries(packageMap)) {
|
|
161
|
+
if (missing[key]) {
|
|
162
|
+
apt.push(packages.apt);
|
|
163
|
+
dnf.push(packages.dnf);
|
|
164
|
+
pacman.push(packages.pacman);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return { apt, dnf, pacman };
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Generate macOS installation commands
|
|
173
|
+
* @param {Object} missing - Missing dependencies
|
|
174
|
+
* @returns {Array} Installation command objects
|
|
175
|
+
*/
|
|
176
|
+
function getMacOSCommands(missing) {
|
|
177
|
+
const commands = [];
|
|
178
|
+
const brewPackages = buildBrewPackages(missing);
|
|
179
|
+
|
|
180
|
+
if (brewPackages.length > 0) {
|
|
181
|
+
commands.push({
|
|
182
|
+
label: 'macOS (Homebrew)',
|
|
183
|
+
command: `brew install ${brewPackages.join(' ')}`
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (missing.python) {
|
|
188
|
+
commands.push({
|
|
189
|
+
label: 'Python 3.10+',
|
|
190
|
+
command: 'brew install python@3.11'
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return commands;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Generate Linux installation commands
|
|
199
|
+
* @param {Object} missing - Missing dependencies
|
|
200
|
+
* @returns {Array} Installation command objects
|
|
201
|
+
*/
|
|
202
|
+
function getLinuxCommands(missing) {
|
|
203
|
+
const commands = [];
|
|
204
|
+
const packages = buildLinuxPackages(missing);
|
|
205
|
+
|
|
206
|
+
if (packages.apt.length > 0) {
|
|
207
|
+
commands.push({
|
|
208
|
+
label: 'Ubuntu/Debian',
|
|
209
|
+
command: `sudo apt-get update && sudo apt-get install -y ${packages.apt.join(' ')}`
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (packages.dnf.length > 0) {
|
|
214
|
+
commands.push({
|
|
215
|
+
label: 'Fedora/RHEL',
|
|
216
|
+
command: `sudo dnf install -y ${packages.dnf.join(' ')}`
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (packages.pacman.length > 0) {
|
|
221
|
+
commands.push({
|
|
222
|
+
label: 'Arch Linux',
|
|
223
|
+
command: `sudo pacman -S ${packages.pacman.join(' ')}`
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return commands;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export function getInstallCommands(missing, platform) {
|
|
231
|
+
if (platform === 'darwin') {
|
|
232
|
+
return getMacOSCommands(missing);
|
|
233
|
+
} else if (platform === 'linux' || platform === 'wsl') {
|
|
234
|
+
return getLinuxCommands(missing);
|
|
235
|
+
} else if (platform === 'win32') {
|
|
236
|
+
return [{
|
|
237
|
+
label: 'Windows (Native)',
|
|
238
|
+
command: 'npx agentvibes install',
|
|
239
|
+
note: 'Windows Piper and SAPI providers are supported natively'
|
|
240
|
+
}];
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return [];
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Main dependency check function
|
|
248
|
+
*/
|
|
249
|
+
export function checkDependencies(options = {}) {
|
|
250
|
+
const platform = os.platform();
|
|
251
|
+
const isMac = platform === 'darwin';
|
|
252
|
+
const isWindows = platform === 'win32';
|
|
253
|
+
const isLinux = !isMac && !isWindows;
|
|
254
|
+
|
|
255
|
+
const results = {
|
|
256
|
+
core: {},
|
|
257
|
+
optional: {},
|
|
258
|
+
missing: {},
|
|
259
|
+
warnings: []
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
// Core requirements
|
|
263
|
+
const nodeCheck = checkNodeVersion();
|
|
264
|
+
results.core.node = nodeCheck;
|
|
265
|
+
if (!nodeCheck.isCompatible) {
|
|
266
|
+
results.missing.node = true;
|
|
267
|
+
results.warnings.push(`Node.js ${nodeCheck.version || 'not found'} - requires ≥16.0`);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const pythonCheck = checkPythonVersion();
|
|
271
|
+
results.core.python = pythonCheck;
|
|
272
|
+
if (!pythonCheck.isCompatible) {
|
|
273
|
+
results.missing.python = true;
|
|
274
|
+
results.warnings.push(`Python ${pythonCheck.version || 'not found'} - requires ≥3.10`);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// macOS-specific: bash 5.x requirement
|
|
278
|
+
if (isMac) {
|
|
279
|
+
const bashCheck = checkBashVersion();
|
|
280
|
+
results.core.bash = bashCheck;
|
|
281
|
+
if (!bashCheck.isModern) {
|
|
282
|
+
results.missing.bash = true;
|
|
283
|
+
results.warnings.push(`Bash ${bashCheck.version || 'not found'} - macOS requires ≥5.0`);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Optional tools
|
|
288
|
+
if (!isWindows) {
|
|
289
|
+
results.optional.sox = commandExists('sox');
|
|
290
|
+
if (!results.optional.sox) {
|
|
291
|
+
results.missing.sox = true;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// ffmpeg is needed on ALL platforms for background music mixing
|
|
296
|
+
{
|
|
297
|
+
results.optional.ffmpeg = commandExists('ffmpeg');
|
|
298
|
+
if (!results.optional.ffmpeg) {
|
|
299
|
+
results.missing.ffmpeg = true;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
results.optional.pipx = commandExists('pipx');
|
|
303
|
+
if (!results.optional.pipx) {
|
|
304
|
+
results.missing.pipx = true;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Check for flock (used for TTS queue file locking)
|
|
308
|
+
results.optional.flock = commandExists('flock');
|
|
309
|
+
if (!results.optional.flock) {
|
|
310
|
+
results.missing.flock = true;
|
|
311
|
+
results.warnings.push('flock command not found (required for TTS queue file locking)');
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// Check for curl (used for downloading Piper TTS and voices)
|
|
315
|
+
results.optional.curl = commandExists('curl');
|
|
316
|
+
if (!results.optional.curl) {
|
|
317
|
+
results.missing.curl = true;
|
|
318
|
+
results.warnings.push('curl command not found (required for downloading Piper TTS)');
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Check for bc (used for audio processing calculations)
|
|
322
|
+
results.optional.bc = commandExists('bc');
|
|
323
|
+
if (!results.optional.bc) {
|
|
324
|
+
results.missing.bc = true;
|
|
325
|
+
results.warnings.push('bc command not found (used for audio processing calculations)');
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// Audio player check (Linux/WSL only)
|
|
329
|
+
if (isLinux || process.env.WSL_DISTRO_NAME) {
|
|
330
|
+
const audioCheck = checkAudioPlayers();
|
|
331
|
+
results.optional.audioPlayer = audioCheck.hasAny;
|
|
332
|
+
if (!audioCheck.hasAny) {
|
|
333
|
+
results.missing.audioPlayer = true;
|
|
334
|
+
results.warnings.push('No audio player found (paplay, aplay, mpg123, or mpv)');
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
return results;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Build list of missing core dependencies
|
|
344
|
+
* @param {Object} missing - Missing dependencies object
|
|
345
|
+
* @param {Object} results - Full check results
|
|
346
|
+
* @returns {string[]} List of missing core dependencies
|
|
347
|
+
*/
|
|
348
|
+
function buildCoreMissingList(missing, results) {
|
|
349
|
+
const list = [];
|
|
350
|
+
const coreMap = {
|
|
351
|
+
node: { label: 'Node.js ≥16.0', key: 'node' },
|
|
352
|
+
python: { label: 'Python ≥3.10', key: 'python' },
|
|
353
|
+
bash: { label: 'Bash ≥5.0', key: 'bash' }
|
|
354
|
+
};
|
|
355
|
+
|
|
356
|
+
for (const [dep, { label, key }] of Object.entries(coreMap)) {
|
|
357
|
+
if (missing[dep]) {
|
|
358
|
+
const version = results.core[key]?.version;
|
|
359
|
+
list.push(`• ${label} ${version ? `(found: ${version})` : ''}`);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
return list;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* Build list of missing optional dependencies
|
|
368
|
+
* @param {Object} missing - Missing dependencies object
|
|
369
|
+
* @returns {string[]} List of missing optional dependencies
|
|
370
|
+
*/
|
|
371
|
+
function buildOptionalMissingList(missing) {
|
|
372
|
+
const optionalMap = {
|
|
373
|
+
curl: '• curl (downloading Piper TTS and voices)',
|
|
374
|
+
sox: '• sox (background music mixing, audio effects)',
|
|
375
|
+
ffmpeg: '• ffmpeg (audio processing, RDP optimization)',
|
|
376
|
+
bc: '• bc (audio processing calculations)',
|
|
377
|
+
pipx: '• pipx (Piper TTS installation)',
|
|
378
|
+
flock: '• flock (TTS queue file locking)',
|
|
379
|
+
audioPlayer: '• paplay/aplay (audio playback)'
|
|
380
|
+
};
|
|
381
|
+
|
|
382
|
+
const list = [];
|
|
383
|
+
for (const [dep, description] of Object.entries(optionalMap)) {
|
|
384
|
+
if (missing[dep]) {
|
|
385
|
+
list.push(description);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
return list;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Format install commands section
|
|
394
|
+
* @param {Array} commands - Install commands
|
|
395
|
+
* @returns {string} Formatted commands section
|
|
396
|
+
*/
|
|
397
|
+
function formatInstallCommands(commands) {
|
|
398
|
+
if (commands.length === 0) {
|
|
399
|
+
return '';
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
let section = chalk.cyan.bold('Installation Commands:\n\n');
|
|
403
|
+
commands.forEach(({ label, command, note }) => {
|
|
404
|
+
section += chalk.cyan(`${label}:\n`);
|
|
405
|
+
section += chalk.white(` ${command}\n`);
|
|
406
|
+
if (note) {
|
|
407
|
+
section += chalk.gray(` ${note}\n`);
|
|
408
|
+
}
|
|
409
|
+
section += '\n';
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
return section;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Display missing dependencies in a formatted box
|
|
417
|
+
*/
|
|
418
|
+
export function displayMissingDependencies(results) {
|
|
419
|
+
const platform = os.platform();
|
|
420
|
+
const missing = results.missing;
|
|
421
|
+
const hasMissing = Object.keys(missing).length > 0;
|
|
422
|
+
|
|
423
|
+
if (!hasMissing) {
|
|
424
|
+
return false; // No missing dependencies
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
let content = chalk.bold.yellow('⚠️ Missing Dependencies Detected\n\n');
|
|
428
|
+
|
|
429
|
+
// Core requirements
|
|
430
|
+
const coreMissing = buildCoreMissingList(missing, results);
|
|
431
|
+
if (coreMissing.length > 0) {
|
|
432
|
+
content += chalk.red('Required:\n');
|
|
433
|
+
content += coreMissing.map(item => chalk.red(item)).join('\n') + '\n\n';
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
// Optional tools
|
|
437
|
+
const optionalMissing = buildOptionalMissingList(missing);
|
|
438
|
+
if (optionalMissing.length > 0) {
|
|
439
|
+
content += chalk.yellow('Optional (recommended):\n');
|
|
440
|
+
content += optionalMissing.map(item => chalk.yellow(item)).join('\n') + '\n\n';
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// Install commands
|
|
444
|
+
const commands = getInstallCommands(missing, platform);
|
|
445
|
+
content += formatInstallCommands(commands);
|
|
446
|
+
|
|
447
|
+
// Impact notice
|
|
448
|
+
if (optionalMissing.length > 0 && coreMissing.length === 0) {
|
|
449
|
+
content += chalk.gray('Note: TTS will still work without optional tools,\n');
|
|
450
|
+
content += chalk.gray('but some features will be disabled.\n');
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
console.log(boxen(content, {
|
|
454
|
+
padding: 1,
|
|
455
|
+
margin: 1,
|
|
456
|
+
borderStyle: 'round',
|
|
457
|
+
borderColor: coreMissing.length > 0 ? 'red' : 'yellow'
|
|
458
|
+
}));
|
|
459
|
+
|
|
460
|
+
return hasMissing;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* Check and display dependencies (convenience function)
|
|
465
|
+
*/
|
|
466
|
+
export function checkAndDisplay() {
|
|
467
|
+
const results = checkDependencies();
|
|
468
|
+
return displayMissingDependencies(results);
|
|
469
|
+
}
|