---
description: Build and release LysnrAI desktop app for macOS, Windows, and Linux
---

## Release Desktop App

Build distributable packages of LysnrAI for macOS, Windows, and Linux.

---

## Fresh Mac Setup (from scratch)

Follow these steps on a **new Mac** that has never built this project before.

### 1. Install system tools

```bash
xcode-select --install                          # Xcode Command Line Tools
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"  # Homebrew
brew install python@3.13 portaudio              # Python + audio lib for PyAudio
```

### 2. Clone and set up the project

```bash
git clone https://github.com/saravanakumardb1/learning_voice_ai_agent.git
cd learning_voice_ai_agent
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
```

### 3. Configure Azure credentials

```bash
cp .env ~/.lysnrai/.env     # create config dir + env file
```

Edit `~/.lysnrai/.env` and fill in real values for:

| Variable                  | Where to get it                      |
| ------------------------- | ------------------------------------ |
| `AZURE_SPEECH_KEY`        | Azure Portal → Speech Service → Keys |
| `AZURE_SPEECH_REGION`     | e.g. `eastus`                        |
| `AZURE_OPENAI_ENDPOINT`   | Azure Portal → OpenAI → Endpoint     |
| `AZURE_OPENAI_KEY`        | Azure Portal → OpenAI → Keys         |
| `AZURE_OPENAI_DEPLOYMENT` | e.g. `gpt-4o-mini`                   |

### 4. (Optional) Set up Apple code signing

Only needed if you want to distribute the app to others (notarized).

**a) Create a "Developer ID Application" certificate:**

1. Go to [developer.apple.com/account/resources/certificates](https://developer.apple.com/account/resources/certificates/list)
2. Click **+** → select **Developer ID Application**
3. Create a CSR: open **Keychain Access** → Certificate Assistant → Request a Certificate From a Certificate Authority → Save to Disk
4. Upload the CSR → download the `.cer` → double-click to install in Keychain
5. Verify: `security find-identity -v -p codesigning | grep "Developer ID"`

**b) Generate an app-specific password** (for notarization):

1. Go to [appleid.apple.com](https://appleid.apple.com) → Sign-In and Security → App-Specific Passwords
2. Generate a new password, label it "LysnrAI Notarization"
3. Keep it handy — the codesign script will prompt for it securely (never stored)

---

## Pre-Flight Quality Gate

Run these checks before building any platform to catch issues early.

### 0a. Verify clean working tree

// turbo

```bash
git diff --quiet && git diff --cached --quiet && echo "Clean" || (echo "ERROR: Uncommitted changes — commit or stash first" && exit 1)
```

### 0b. Activate venv + verify deps

// turbo

```bash
source .venv/bin/activate && pip install -e ".[dev]" --quiet
```

### 0c. Lint with ruff

// turbo

```bash
source .venv/bin/activate && python -m ruff check src/ --select E,F,W --no-fix 2>&1 | tail -20
```

### 0d. Run Python tests

```bash
source .venv/bin/activate && python -m pytest tests/ -v --tb=short -q 2>&1 | tail -20
```

### 0e. Verify imports (quick syntax check)

// turbo

```bash
source .venv/bin/activate && python -c "import src.main; print('OK: src.main imports cleanly')"
```

---

## macOS Build + Release

### Step 1 — Build the .app bundle

// turbo

```bash
bash scripts/build.sh
```

**Output:** `dist/LysnrAI.app` (ad-hoc signed, ready for local use)

### Step 2 — (Optional) Code sign + notarize

```bash
export APPLE_DEVELOPER_ID="Developer ID Application: Saravanakumar Dhandapani (748N7QPX7J)"
bash scripts/codesign_macos.sh dist/LysnrAI.app
```

The script interactively prompts for:

- **Apple ID** (default: `saravanakumardb@gmail.com`)
- **Team ID** (default: `748N7QPX7J`)
- **App-specific password** (secure input, not echoed or stored)

### Step 3 — Install locally

```bash
bash scripts/install_macos.sh
```

Installs to `/Applications/LysnrAI.app`, creates `~/.LysnrAI/.env`, and adds `~/Desktop/LysnrAI.command` launcher.

### Step 4 — Package for distribution

```bash
ditto -c -k --keepParent dist/LysnrAI.app dist/LysnrAI-macOS.zip
```

---

## Windows Build + Release

Run these on a Windows machine.

### Step 1 — Build

```powershell
.\scripts\build_windows.ps1                # ZIP only
.\scripts\build_windows.ps1 -Installer     # ZIP + Inno Setup installer
```

**Output:** `dist\LysnrAI-0.1.0-win64.zip` (and optionally `dist\LysnrAI-0.1.0-setup.exe`)

### Step 2 — (Optional) Code sign

```powershell
$env:SIGN_CERT_PATH = "C:\certs\LysnrAI.pfx"
$env:SIGN_CERT_PASS = "your-pfx-password"
.\scripts\codesign_windows.ps1
```

---

## Linux Build + Release

Run these on a Linux machine.

### Step 1 — Build

```bash
bash scripts/build_linux.sh               # tar.gz only
bash scripts/build_linux.sh --appimage    # tar.gz + AppImage
```

**Output:** `dist/LysnrAI-0.1.0-linux-x86_64.tar.gz` (and optionally `.AppImage`)

---

## End-User Setup Guide

Share these instructions with anyone receiving the app.

### macOS

1. Extract `LysnrAI-macOS.zip` and move `LysnrAI.app` to `/Applications/`
2. If not notarized, run: `xattr -cr /Applications/LysnrAI.app`
3. Create `~/.lysnrai/.env` with Azure credentials (see `.env`)
4. Launch via `~/Desktop/LysnrAI.command` (Terminal launcher for Accessibility)
5. Grant microphone access when prompted
6. Dictate: hold **Cmd+Shift+Space**, speak, release to paste

### Windows

1. Extract ZIP or run the installer
2. Copy `.env` → `.env` next to `LysnrAI.exe`, fill in Azure credentials
3. Double-click `LysnrAI.exe` — allow microphone + antivirus if prompted
4. Dictate: hold **Ctrl+Shift+Space**, speak, release to paste
5. App lives in the system tray (bottom-right)

### Linux

1. Extract: `tar xzf LysnrAI-*-linux-x86_64.tar.gz`
2. Install deps: `sudo apt install xdotool xclip libnotify-bin`
3. Copy `.env` → `.env`, fill in Azure credentials
4. Run `./LysnrAI`
5. Dictate: hold **Ctrl+Shift+Space**, speak, release to paste

---

## Reference

### Keyboard Shortcuts

| Action         | Windows / Linux    | macOS                     |
| -------------- | ------------------ | ------------------------- |
| Dictate (hold) | `Ctrl+Shift+Space` | `Cmd+Shift+Space` or `Fn` |
| History        | `Ctrl+Shift+H`     | `Cmd+Shift+H`             |
| Undo paste     | `Ctrl+Shift+Z`     | `Cmd+Shift+Z`             |
| Stats          | `Ctrl+Shift+S`     | `Cmd+Shift+S`             |
| Shortcuts help | `Ctrl+Shift+K`     | `Cmd+Shift+K`             |

### Key Files

| File                           | Purpose                                                |
| ------------------------------ | ------------------------------------------------------ |
| `scripts/build.sh`             | macOS build (PyInstaller + dylibs + Info.plist)        |
| `scripts/build_windows.ps1`    | Windows build (PyInstaller + ZIP + optional installer) |
| `scripts/build_linux.sh`       | Linux build (PyInstaller + tar.gz + optional AppImage) |
| `scripts/codesign_macos.sh`    | macOS code signing + interactive notarization          |
| `scripts/codesign_windows.ps1` | Windows Authenticode signing                           |
| `scripts/install_macos.sh`     | Full macOS install (build + /Applications + launcher)  |
| `.env`                         | Template for Azure credentials                         |

### Troubleshooting

| Problem                          | Fix                                                                            |
| -------------------------------- | ------------------------------------------------------------------------------ |
| macOS "App is damaged"           | Not notarized. Run `xattr -cr /Applications/LysnrAI.app`                       |
| macOS no Accessibility           | Must launch via `.command` file (Terminal inherits Accessibility)              |
| macOS no Developer ID cert       | Create at developer.apple.com → Certificates → + → Developer ID Application    |
| Windows SmartScreen blocks       | Code sign the .exe, or click "More info" → "Run anyway"                        |
| Windows VCRUNTIME140.dll missing | Install [VC++ Redistributable](https://aka.ms/vs/17/release/vc_redist.x64.exe) |
| Linux no system tray             | Install `gnome-shell-extension-appindicator` (GNOME)                           |
| Linux no audio                   | Check PulseAudio/PipeWire is running, mic not muted                            |
| PyInstaller build fails          | Activate `.venv` first: `source .venv/bin/activate && pip install -e ".[dev]"` |
| Ruff lint errors                 | Run `ruff check src/ --fix` to auto-fix, then review                           |
| Tests fail before build          | Fix failing tests first — never ship with red tests                            |
