Here's a complete, self-contained deployment guide you can reuse on any Debian-based machine (Pop!_OS, Ubuntu, Debian + GNOME). It's written so you can copy the whole thing to a USB or just follow it step by step.

---

# Voice Commander — Desktop Launcher Deployment Guide

**Target:** Debian-based Linux with a GNOME-style desktop (Pop!_OS 22.04, Ubuntu, Debian)
**What you get:** A double-clickable desktop icon (Tux penguin) that starts the Voice Commander server and opens it in your default browser.

---

## 1. Prerequisites

Before deploying the launcher, confirm:

- [ ] Voice Commander project exists at `~/voice-commander/` (`app.py`, `start.sh`, `static/tux.svg`)
- [ ] `./start.sh` runs the server successfully from a terminal (verify once before creating the launcher)
- [ ] A web browser is installed (Brave, Firefox, Chromium, or Chrome)
- [ ] The Tux icon file exists: `~/voice-commander/static/tux.svg`

> **Note:** On machines where the project folder has a different name (e.g. `~/Voice Commander`), adjust the paths in Steps 2–3 or rename the folder first:
> ```bash
> mv ~/"Voice Commander" ~/voice-commander
> ```

---

## 2. Files You're Creating

| File | Purpose |
|---|---|
| `~/.local/share/icons/voice-commander.svg` | Tux icon, visible to the system |
| `~/voice-commander/launch-voice-commander.sh` | Wrapper: starts server, waits, opens browser |
| `~/.local/share/applications/voice-commander.desktop` | Launcher registered in the app menu |
| `~/Desktop/voice-commander.desktop` | The desktop shortcut itself |

---

## 3. Deployment Steps

Run each block in a terminal on the target machine.

### Step 3.1 — Install the Tux icon

```bash
mkdir -p ~/.local/share/icons
cp ~/voice-commander/static/tux.svg ~/.local/share/icons/voice-commander.svg
```

### Step 3.2 — Create the launcher wrapper script

This script does the real work: it detects an already-running server (no duplicate instances, no "port in use" errors), starts the server, waits until it actually responds, then opens the browser.

```bash
cat > ~/voice-commander/launch-voice-commander.sh << 'EOF'
#!/bin/bash
# Voice Commander launcher: starts server, opens browser, keeps terminal for logs

PROJECT_DIR="$HOME/voice-commander"
URL="http://localhost:5123"
cd "$PROJECT_DIR" || exit 1

# 1) Already running? Just open the browser and bail.
if curl -s -o /dev/null --max-time 2 "$URL"; then
    echo "Voice Commander is already running at $URL"
    xdg-open "$URL" >/dev/null 2>&1 || \
        brave-browser --new-window "$URL" >/dev/null 2>&1 || \
        brave --new-window "$URL" >/dev/null 2>&1 || \
        google-chrome --new-window "$URL" >/dev/null 2>&1 || \
        firefox --new-window "$URL" >/dev/null 2>&1 &
    sleep 2
    exit 0
fi

# 2) Start the server in the background
./start.sh &
SERVER_PID=$!

# 3) Wait until the server responds (max ~15s)
for i in $(seq 1 30); do
    if curl -s -o /dev/null --max-time 1 "$URL"; then
        break
    fi
    sleep 0.5
done

# 4) Open the browser (fallback chain: default → brave → chrome → firefox)
xdg-open "$URL" >/dev/null 2>&1 || \
    brave-browser --new-window "$URL" >/dev/null 2>&1 || \
    brave --new-window "$URL" >/dev/null 2>&1 || \
    google-chrome --new-window "$URL" >/dev/null 2>&1 || \
    firefox --new-window "$URL" >/dev/null 2>&1 &

# 5) Keep the terminal open for logs / Ctrl+C to stop
wait $SERVER_PID
EOF

chmod +x ~/voice-commander/launch-voice-commander.sh
```

### Step 3.3 — Create the desktop entry

> ⚠️ **Critical:** Use the literal username (e.g. `/home/pop/...`), **not** `$USER`. Desktop entries don't expand shell variables. The `Exec=` line must contain **no** shell metacharacters (`&`, `;`, `$`, quotes) — that's why all logic lives in the wrapper script.

```bash
mkdir -p ~/.local/share/applications
U=$(whoami)
cat > ~/.local/share/applications/voice-commander.desktop << EOF
[Desktop Entry]
Type=Application
Name=Voice Commander
Comment=Voice-controlled desktop task runner
Exec=/home/$U/voice-commander/launch-voice-commander.sh
Icon=voice-commander
Terminal=true
Categories=Utility;
StartupNotify=false
EOF

chmod +x ~/.local/share/applications/voice-commander.desktop
```

### Step 3.4 — Drop a copy on the Desktop & refresh

```bash
cp ~/.local/share/applications/voice-commander.desktop ~/Desktop/
update-desktop-database ~/.local/share/applications 2>/dev/null
touch ~/.local/share/icons/voice-commander.svg
gtk-update-icon-cache ~/.local/share/icons/ 2>/dev/null
```

### Step 3.5 — Trust & launch

1. On the Desktop, double-click **Voice Commander**.
2. The first time, Pop!_OS/GNOME shows **"Untrusted application launcher"** → click **Allow Launching** (or right-click → *Allow Launching*).
3. A terminal opens, the server starts (you'll see the 🐧 banner), and after ~2–3 seconds your browser opens at `http://localhost:5123`.

**From the app menu instead:** press **Super**, type "Voice Commander", click the penguin entry.

---

## 4. First-Run Verification Checklist

- [ ] Terminal window shows the Voice Commander banner (whisper binary + model found)
- [ ] Browser opens `http://localhost:5123` automatically
- [ ] Page loads with gray background, Tux logo, red Record button, turquoise task buttons
- [ ] Double-clicking the icon **again** while running → just reopens the browser (no second server, no port error)

---

## 5. Customization Options

### Option A — Silent background launch (no terminal window)

Change `Terminal=true` → `Terminal=false` in both `.desktop` files, and change step 2 of the wrapper to:

```bash
nohup ./start.sh > /tmp/voice-commander.log 2>&1 &
SERVER_PID=$!
```

Stop the server later with:

```bash
fuser -k 5123/tcp
```

### Option B — Different default browser

The wrapper tries `xdg-open` first (respects your system default), then Brave, then Chrome, then Firefox. To force a specific browser, remove the others from the chain or set your system default:

```bash
xdg-settings set default-web-browser brave-browser.desktop
```

### Option C — Auto-start on login (systemd user service)

```bash
mkdir -p ~/.config/systemd/user
cat > ~/.config/systemd/user/voice-commander.service << 'EOF'
[Unit]
Description=Voice Commander web server
After=network.target

[Service]
ExecStart=/home/USERNAME/voice-commander/start.sh
Restart=on-failure
WorkingDirectory=/home/USERNAME/voice-commander

[Install]
WantedBy=default.target
EOF
# Replace USERNAME above, then:
systemctl --user daemon-reload
systemctl --user enable --now voice-commander.service
```

The server then starts at login (no terminal); keep the desktop icon for quickly opening the browser, or pair it with the wrapper's already-running detection.

---

## 6. Troubleshooting

| Symptom | Cause / Fix |
|---|---|
| "Untrusted application launcher" | Normal on first run → click **Allow Launching** |
| Icon shows as generic gear/blank | Re-run Step 3.4 (`gtk-update-icon-cache`); verify `~/.local/share/icons/voice-commander.svg` exists |
| Click does nothing / no browser opens | Rebuild `.desktop` with literal username in `Exec=` (no `$USER`, no `&&`); confirm wrapper is executable (`ls -l launch-voice-commander.sh`) |
| Terminal opens but browser doesn't | Server took >15s to start (slow first boot of whisper). Run `./start.sh` manually to see errors; or increase the `seq 1 30` wait loop |
| "Port 5123 is already in use" | A previous instance is still running → `fuser -k 5123/tcp`, or just let the wrapper detect it and reopen the browser |
| Browser opens but page won't load | Server not up yet — reload the page; check the terminal window for the Flask banner |
| Works from terminal but not from icon | The `.desktop` file is untrusted/stale → re-copy it (Step 3.4) and **Allow Launching** again |
| Folder named `Voice Commander` (space) | Rename to `voice-commander` or update every path in the guide |

---

## 7. Portable Version (for new machines)

To deploy on another Debian-based machine, carry these two files:

1. `launch-voice-commander.sh` (from `~/voice-commander/`)
2. `voice-commander.desktop` (from `~/.local/share/applications/`)

On the new machine:

```bash
# Adjust for the new username!
NEWUSER=$(whoami)

mkdir -p ~/.local/share/icons ~/.local/share/applications
cp /media/$USER/USB/voice-commander.desktop ~/.local/share/applications/
cp ~/voice-commander/static/tux.svg ~/.local/share/icons/voice-commander.svg
cp /media/$USER/USB/launch-voice-commander.sh ~/voice-commander/

# Fix the username inside the .desktop file if it differs
sed -i "s|/home/[^/]*/voice-commander|/home/$NEWUSER/voice-commander|" \
    ~/.local/share/applications/voice-commander.desktop

chmod +x ~/voice-commander/launch-voice-commander.sh
cp ~/.local/share/applications/voice-commander.desktop ~/Desktop/
update-desktop-database ~/.local/share/applications 2>/dev/null
```

---

Want me to save this guide as a note in your knowledge base so you can pull it up anytime (and for future machine installs)? Or would you prefer it written to a `LAUNCHER-GUIDE.md` file inside the project folder alongside the README?
