- build-unified.sh: master build script (16 hooks, kernel 7.0.0-rc7) - config/package-lists: Debian package selections - assets: Alfred Commander extension tarball - docs: ARM64 investigation, kernel upgrade roadmap
129 lines
4.8 KiB
Bash
129 lines
4.8 KiB
Bash
#!/bin/bash
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# Alfred Linux v2.0-b4 — Voice (Kokoro TTS + Welcome Greeting)
|
|
#
|
|
# Installs Kokoro TTS for offline voice synthesis.
|
|
# Alfred speaks on first boot.
|
|
# BUILD: v2.0-b4 (Voice)
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
set +e # Voice is optional — don't kill the build if TTS install fails
|
|
|
|
echo "[Alfred Linux v2.0-b4] Installing Voice subsystem..."
|
|
|
|
# ── 0. Ensure DNS works inside chroot ──
|
|
if ! getent hosts deb.debian.org &>/dev/null 2>&1; then
|
|
rm -f /etc/resolv.conf 2>/dev/null || true
|
|
printf 'nameserver 9.9.9.9\nnameserver 1.1.1.1\n' > /etc/resolv.conf
|
|
fi
|
|
|
|
# ── 1. Install Python audio dependencies ──
|
|
PYVER=$(python3 --version 2>/dev/null | grep -oP '\d+\.\d+' | head -1)
|
|
apt-get install -y python3-pip "python${PYVER}-venv" espeak-ng sox libsox-fmt-all 2>/dev/null || \
|
|
apt-get install -y python3-pip python3-venv espeak-ng sox libsox-fmt-all 2>/dev/null || true
|
|
|
|
# ── 2. Install Kokoro TTS (CPU-only — no CUDA/NVIDIA bloat) ──
|
|
# Install CPU-only PyTorch FIRST to prevent pulling the full 3.4GB CUDA stack.
|
|
# This keeps the ISO under 4GB (ISO 9660 single-file limit).
|
|
pip3 install --break-system-packages torch --index-url https://download.pytorch.org/whl/cpu 2>/dev/null || true
|
|
pip3 install --break-system-packages kokoro 2>/dev/null || {
|
|
echo "[WARN] kokoro system install failed, trying with venv..."
|
|
python3 -m venv /opt/alfred-voice
|
|
/opt/alfred-voice/bin/pip install torch --index-url https://download.pytorch.org/whl/cpu
|
|
/opt/alfred-voice/bin/pip install kokoro
|
|
ln -sf /opt/alfred-voice/bin/python3 /usr/local/bin/alfred-voice-python
|
|
}
|
|
|
|
# Clean up empty fallback venv dir if system-wide install worked
|
|
if python3 -c "import kokoro" 2>/dev/null && [[ -d /opt/alfred-voice ]] && [[ ! -f /opt/alfred-voice/bin/python3 ]]; then
|
|
rm -rf /opt/alfred-voice
|
|
echo "[Alfred Voice] Kokoro installed system-wide, removed empty venv dir"
|
|
fi
|
|
|
|
# ── 3. Create welcome script ──
|
|
cat > /usr/local/bin/alfred-welcome.sh << 'WELCOME'
|
|
#!/bin/bash
|
|
# Alfred Linux — First Boot Welcome
|
|
# Speaks a greeting via Kokoro TTS on first login
|
|
|
|
if [[ -f "$HOME/.alfred-welcomed" ]]; then
|
|
exit 0
|
|
fi
|
|
|
|
# Try Kokoro TTS first
|
|
VOICE_PYTHON="python3"
|
|
[[ -x /usr/local/bin/alfred-voice-python ]] && VOICE_PYTHON="/usr/local/bin/alfred-voice-python"
|
|
|
|
$VOICE_PYTHON -c "
|
|
try:
|
|
from kokoro import KPipeline
|
|
pipe = KPipeline(lang_code='a')
|
|
generator = pipe('Welcome to Alfred Linux. I am Alfred, your AI companion. Everything here is sovereign. Everything here is yours.', voice='af_heart', speed=1.0)
|
|
import soundfile as sf
|
|
for i, (gs, ps, audio) in enumerate(generator):
|
|
sf.write('/tmp/alfred-welcome.wav', audio, 24000)
|
|
break
|
|
except Exception as e:
|
|
print(f'Kokoro TTS failed: {e}')
|
|
import subprocess
|
|
subprocess.run(['espeak-ng', '-w', '/tmp/alfred-welcome.wav',
|
|
'Welcome to Alfred Linux. I am Alfred, your AI companion.'])
|
|
" 2>/dev/null
|
|
|
|
# Play the audio
|
|
if [[ -f /tmp/alfred-welcome.wav ]]; then
|
|
aplay /tmp/alfred-welcome.wav 2>/dev/null || paplay /tmp/alfred-welcome.wav 2>/dev/null || true
|
|
rm -f /tmp/alfred-welcome.wav
|
|
fi
|
|
|
|
# Mark as welcomed
|
|
touch "$HOME/.alfred-welcomed"
|
|
WELCOME
|
|
chmod +x /usr/local/bin/alfred-welcome.sh
|
|
|
|
# ── 4. XFCE autostart entry ──
|
|
mkdir -p /etc/skel/.config/autostart
|
|
cat > /etc/skel/.config/autostart/alfred-welcome.desktop << 'DESK'
|
|
[Desktop Entry]
|
|
Type=Application
|
|
Name=Alfred Welcome
|
|
Comment=Alfred greets you on first login
|
|
Exec=/usr/local/bin/alfred-welcome.sh
|
|
Hidden=false
|
|
X-GNOME-Autostart-enabled=true
|
|
X-GNOME-Autostart-Delay=3
|
|
DESK
|
|
|
|
# ── 5. Alfred TTS CLI wrapper ──
|
|
cat > /usr/local/bin/alfred-say << 'SAY'
|
|
#!/bin/bash
|
|
# Alfred TTS — speak any text
|
|
# Usage: alfred-say "Hello, Commander"
|
|
|
|
TEXT="${*:-Hello, I am Alfred.}"
|
|
VOICE_PYTHON="python3"
|
|
[[ -x /usr/local/bin/alfred-voice-python ]] && VOICE_PYTHON="/usr/local/bin/alfred-voice-python"
|
|
|
|
$VOICE_PYTHON -c "
|
|
try:
|
|
from kokoro import KPipeline
|
|
pipe = KPipeline(lang_code='a')
|
|
generator = pipe('''$TEXT''', voice='af_heart', speed=1.0)
|
|
import soundfile as sf
|
|
for i, (gs, ps, audio) in enumerate(generator):
|
|
sf.write('/tmp/alfred-tts.wav', audio, 24000)
|
|
break
|
|
except Exception:
|
|
import subprocess
|
|
subprocess.run(['espeak-ng', '-w', '/tmp/alfred-tts.wav', '''$TEXT'''])
|
|
" 2>/dev/null
|
|
|
|
if [[ -f /tmp/alfred-tts.wav ]]; then
|
|
aplay /tmp/alfred-tts.wav 2>/dev/null || paplay /tmp/alfred-tts.wav 2>/dev/null
|
|
rm -f /tmp/alfred-tts.wav
|
|
fi
|
|
SAY
|
|
chmod +x /usr/local/bin/alfred-say
|
|
|
|
echo "[Alfred Linux v2.0-b4] Voice subsystem installed."
|