PAI — USB Flashing Guide¶
Overview¶
PAI is a bootable Debian 12 live USB with Sway, Ollama, and a local Chat UI. This document covers every method for getting the PAI ISO onto a USB drive — from the simplest to the most automated.
Table of Contents¶
- Browser-Based Flashing — Why It Doesn't Work (Yet)
- Option 1: Stream Directly from Cloud to USB
- Option 2: Download ISO + Flash Manually
- Option 3: One-Command Auto-Flasher Script
- Option 4: GitHub Releases + Landing Page
- Option 5: Rufus (Windows)
- Platform-Specific Instructions
- Safety Warnings
- Architecture Notes
Browser-Based Flashing¶
The Dream¶
A website where users plug in a USB drive, click "Flash", and PAI writes directly to the drive — no downloads, no tools, no terminal.
Why It's Not Possible Today¶
WebUSB API (supported in Chrome/Edge) allows websites to communicate with USB devices, but it cannot write to USB mass storage devices. The operating system kernel maintains exclusive control over mass storage block devices, preventing any browser API from accessing raw blocks.
| Technology | Can Flash USB? | Why / Why Not |
|---|---|---|
| WebUSB API | No | OS kernel claims mass storage devices exclusively. Works for specialized devices (Arduino, etc.) but not bulk storage. |
| Web Serial API | No | Designed for serial devices (COM ports), not USB drives. |
| File System Access API | No | Can read/write files on the user's filesystem, but cannot write raw blocks to a device. |
| Chrome Extensions | Partially | Google's Chromebook Recovery Utility does this as a Chrome extension — but it uses native messaging and platform-specific binaries under the hood. Not a pure web solution. |
The Fundamental Limitation¶
USB mass storage devices are claimed by the OS kernel the moment they're plugged in. The kernel mounts a filesystem driver on top of the raw block device, and no browser sandbox can bypass this. Writing an ISO requires raw block-level access (/dev/sdX on Linux, \\.\PhysicalDriveN on Windows), which is a privileged operation that browsers intentionally cannot perform.
What We Can Do Instead¶
Build a web-based experience that gets as close as possible: - Auto-detect the user's OS - Provide a copy-paste one-liner or a tiny downloadable flasher - Host the ISO on a CDN/GitHub Releases for fast delivery
Option 1: Stream Directly from Cloud to USB¶
No ISO file touches your local disk. The ISO streams over HTTPS directly into the USB block device.
Prerequisites¶
- A running PAI server (Codespace, VPS, or local) serving the ISO over HTTP
- Terminal access on the machine with the USB drive
Setup — Start the ISO Server¶
On the machine hosting the ISO:
Or, if using GitHub Releases:
Flash — Linux¶
# Identify your USB device
lsblk
# Stream and flash (replace /dev/sdX with your USB device)
curl -L https://YOUR-ISO-URL/live-image-amd64.hybrid.iso | sudo dd of=/dev/sdX bs=4M status=progress
sync
Flash — macOS¶
# Identify your USB device
diskutil list
# Unmount it first
diskutil unmountDisk /dev/diskN
# Stream and flash (use rdiskN for raw speed)
curl -L https://YOUR-ISO-URL/live-image-amd64.hybrid.iso | sudo dd of=/dev/rdiskN bs=4m
sync
Flash — Windows (PowerShell as Admin)¶
# Find your USB disk number
Get-Disk
# Stream directly
curl.exe -L "https://YOUR-ISO-URL/live-image-amd64.hybrid.iso" -o \\.\PhysicalDriveX
Note: On Windows, this method is less reliable. Option 2 or 5 (Rufus) is recommended for Windows users.
Option 2: Download ISO + Flash Manually¶
The traditional approach. Download the ISO, then write it to USB.
Download¶
From GitHub Releases (when available):
From a Codespace:
# Inside the Codespace, start a file server:
cd /workspaces/addie/pai-minimal/output && python3 -m http.server 8888
# Then open the forwarded port URL in your browser (VS Code Ports tab)
# and click the ISO filename to download
Flash — Linux¶
# Identify USB device
lsblk
# Write ISO (replace /dev/sdX)
sudo dd if=pai.iso of=/dev/sdX bs=4M status=progress
sync
Flash — macOS¶
Flash — Windows¶
Use Rufus, Etcher, or the dd equivalent in WSL.
Option 3: One-Command Auto-Flasher Script¶
A single curl | bash command that downloads the ISO, detects USB drives, lets the user pick one, and flashes it.
Usage¶
Or from GitHub:
What the Script Does¶
- Detects the OS (Linux/macOS)
- Lists available removable USB drives
- Prompts the user to select a drive
- Confirms the selection (shows drive size/model as a safety check)
- Downloads the latest ISO from GitHub Releases
- Writes it to the selected drive with
dd - Runs
syncto ensure all data is flushed
See scripts/flash.sh for the implementation.
Security Notes¶
- The script requires
sudobecause writing to block devices is a privileged operation - Users should always inspect scripts before piping to bash:
curl -fsSL https://pai.direct/flash | less - The script only writes to the user-selected device — it never auto-detects and flashes without confirmation
Option 4: GitHub Releases + Landing Page¶
The most scalable distribution method. No server required.
GitHub Releases¶
- Upload the ISO as a release asset on nirholas/pai
- GitHub hosts files up to 2GB for free per release
- Gives users a permanent, versioned download URL:
Landing Page (GitHub Pages / Vercel / Netlify)¶
A simple website at pai.direct (or similar) that:
- Auto-detects the visitor's OS via
navigator.userAgent - Shows the appropriate instructions:
- Linux: One-liner
curl | ddcommand, pre-filled with the download URL - macOS: Same, with macOS-specific device paths (
/dev/rdiskN) - Windows: Download button + link to Rufus with step-by-step guide
- Provides the auto-flasher script as a second option
- Shows system requirements: 2GB+ USB drive, x86_64 machine
Landing Page Mockup¶
┌─────────────────────────────────────────────┐
│ │
│ 🔒 PAI │
│ Private AI on a bootable USB drive │
│ │
│ ┌─────────────────────────────────────┐ │
│ │ We detected you're on: Linux │ │
│ │ │ │
│ │ One-command flash: │ │
│ │ ┌─────────────────────────────────┐ │ │
│ │ │ curl -fsSL https://pai.direct/ │ │ │
│ │ │ flash | sudo bash │ │ │
│ │ └──────────────────────── [Copy]──┘ │ │
│ │ │ │
│ │ Or download the ISO (912 MB): │ │
│ │ [ Download PAI ] │ │
│ └─────────────────────────────────────┘ │
│ │
│ Requirements: 2GB+ USB · x86_64 PC │
│ Source: github.com/nirholas/pai │
│ │
└─────────────────────────────────────────────┘
Option 5: Rufus (Windows)¶
Rufus is the standard Windows USB flasher. It's free, open-source, and works with any ISO.
Steps¶
- Download Rufus from rufus.ie (or
winget install Rufus.Rufus) - Download the PAI ISO from GitHub Releases
- Open Rufus
- Device: Select your USB drive
- Boot selection: Click "SELECT" → choose the PAI ISO
- Partition scheme: GPT (for UEFI) or MBR (for legacy BIOS)
- Click START
- Wait for completion, then boot from the USB
Rufus Portable¶
Rufus also comes as a portable .exe — no installation needed. Users can download it alongside the ISO and run it directly.
Platform-Specific Instructions¶
Linux¶
# 1. Identify your USB drive
lsblk -d -o NAME,SIZE,MODEL,TRAN | grep usb
# 2. Unmount if mounted
sudo umount /dev/sdX*
# 3. Flash (choose one):
# Option A: Download then flash
curl -LO https://github.com/nirholas/pai/releases/latest/download/pai.iso
sudo dd if=pai.iso of=/dev/sdX bs=4M status=progress && sync
# Option B: Stream directly (no local file)
curl -L https://github.com/nirholas/pai/releases/latest/download/pai.iso | sudo dd of=/dev/sdX bs=4M status=progress && sync
# Option C: Auto-flasher
curl -fsSL https://raw.githubusercontent.com/nirholas/pai/main/scripts/flash.sh | sudo bash
macOS¶
# 1. Identify your USB drive
diskutil list
# 2. Unmount
diskutil unmountDisk /dev/diskN
# 3. Flash (use rdiskN for 10-20x faster writes)
curl -L https://github.com/nirholas/pai/releases/latest/download/pai.iso | sudo dd of=/dev/rdiskN bs=4m && sync
# 4. Eject
diskutil eject /dev/diskN
Windows¶
- Download the PAI ISO
- Download Rufus
- Run Rufus → Select USB → Select ISO → Start
- Reboot and select USB from boot menu (usually F12/F2/DEL at startup)
Chromebook (via Linux/Crostini)¶
# Enable Linux (Settings → Advanced → Developers → Linux → Turn On)
# Then use the Linux terminal:
curl -fsSL https://raw.githubusercontent.com/nirholas/pai/main/scripts/flash.sh | sudo bash
Safety Warnings¶
⚠️ dd will destroy all data on the target device. There is no undo.
Before flashing:
1. Back up any important data on the USB drive
2. Triple-check the device name — dd to the wrong device will erase that disk (including your OS drive)
3. Verify device size — your USB drive should match the expected size in lsblk/diskutil
4. Unmount the device before writing — do NOT write to a mounted device
5. Use sync after dd to ensure all data is flushed before removing the drive
How to Identify Your USB Drive¶
| OS | Command | What to Look For |
|---|---|---|
| Linux | lsblk -d -o NAME,SIZE,MODEL,TRAN |
TRAN column shows usb |
| macOS | diskutil list |
(external, physical) label |
| Windows | Get-Disk |
Bus Type: USB |
Architecture Notes¶
Why a Hybrid ISO?¶
The PAI ISO is built as a hybrid ISO (live-image-amd64.hybrid.iso), meaning it can be:
- Burned to a DVD/CD (standard ISO 9660)
- Written to a USB drive (raw dd — contains a valid MBR/GPT partition table)
- Booted in a VM (attach as virtual optical drive)
This is handled automatically by live-build with the --binary-image iso-hybrid setting.
Why Not Use Etcher/Ventoy/etc.?¶
You can! PAI works with any ISO-to-USB tool:
- Etcher — GUI, cross-platform, open-source
- Ventoy — multi-ISO USB, just copy the ISO file
- USBImager — minimal GUI, 300KB
- dd — no install needed, available on every Unix system
We recommend dd or the auto-flasher script because they require zero additional software.
ISO Size¶
| Build | Size | Packages |
|---|---|---|
| Minimal | ~912 MB | ~20 packages (Sway, Firefox, Ollama, networking) |
| Full | ~4-6 GB | 100+ packages (Tor, crypto wallets, dev tools, media) |
The minimal build fits on any USB drive 2GB or larger. The full build requires a 64GB+ disk to build and 8GB+ USB to flash.