diff --git a/README.md b/README.md index cc2979d..2b40736 100644 --- a/README.md +++ b/README.md @@ -14,14 +14,14 @@ Learn more about the platform in the [AssemblyAI docs](https://www.assemblyai.co ## ⚡ Quickstart -Install on macOS or Linux with Homebrew: +Install on macOS or Linux with one command: ```sh -brew tap assemblyai/cli https://github.com/AssemblyAI/cli -brew trust assemblyai/cli # only needed when HOMEBREW_REQUIRE_TAP_TRUST is set; harmless otherwise -brew install assembly +curl -LsSf https://raw.githubusercontent.com/AssemblyAI/cli/main/install.sh | sh ``` +This installs [uv](https://docs.astral.sh/uv/) if needed, then installs `assembly` as a uv tool. + Sign in (stores your API key in the OS keyring) and run your first transcription: ```sh @@ -29,7 +29,7 @@ assembly login assembly transcribe --sample ``` -That's it. Run `assembly onboard` for a guided tour, or see [Installation](#-installation) for pipx/uv and other options. +That's it. Run `assembly onboard` for a guided tour, or see [Installation](#-installation) for Homebrew, pipx, and other options. ## 🚀 Why the AssemblyAI CLI? @@ -218,7 +218,17 @@ Requires Python 3.12+ (Homebrew brings its own; for pipx/uv see the `--python` h > The `assemblyai-cli` package on PyPI is **not** this project — install with one of the > commands below, not `pip install assemblyai-cli`. -### Homebrew (recommended — macOS / Linux) +### Install script (recommended — macOS / Linux) + +```sh +curl -LsSf https://raw.githubusercontent.com/AssemblyAI/cli/main/install.sh | sh +``` + +The [`install.sh`](install.sh) script bootstraps [uv](https://docs.astral.sh/uv/) if it +isn't already present, then runs `uv tool install` to put `assembly` on your `PATH`. Re-run +it any time to update to the latest version. + +### Homebrew (macOS / Linux) ```sh brew tap assemblyai/cli https://github.com/AssemblyAI/cli @@ -243,12 +253,14 @@ If your default interpreter is older than Python 3.12, add `--python python3.12` System dependencies for the live-audio commands (pipx/uv installs only) Only the live-audio commands need anything extra: `stream`, `dictate`, and `agent` use PortAudio for -microphone capture and [`ffmpeg`](https://ffmpeg.org) on `PATH` to stream non-WAV audio. -Plain `transcribe` uploads your file directly and needs neither. +microphone capture and [`ffmpeg`](https://ffmpeg.org) on `PATH` to stream non-WAV audio; `assembly share` +uses [`cloudflared`](https://github.com/cloudflare/cloudflared) for its public tunnel. +Plain `transcribe` uploads your file directly and needs none of them. The +[`install.sh`](install.sh) script checks for these and prints the right install command when any are missing. - Debian/Ubuntu: `sudo apt-get install libportaudio2 ffmpeg` - Fedora: `sudo dnf install portaudio ffmpeg` -- macOS (Homebrew): `brew install portaudio ffmpeg` +- macOS (Homebrew): `brew install portaudio ffmpeg cloudflared` diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..c884e24 --- /dev/null +++ b/install.sh @@ -0,0 +1,120 @@ +#!/bin/bash + +set -e # Exit on any error + +# Canonical installer for the AssemblyAI CLI (`assembly`). +# Installs the app as a uv tool, bootstrapping uv first if it is missing. + +PACKAGE="git+https://github.com/AssemblyAI/cli.git" +PYTHON_VERSION="3.13" + +# Best-effort check for the PortAudio shared library (no `command` to probe, so +# look via pkg-config, the dynamic linker cache, then well-known lib paths). +has_portaudio() { + if command -v pkg-config >/dev/null 2>&1 && pkg-config --exists portaudio-2.0 2>/dev/null; then + return 0 + fi + local f + case "$(uname -s)" in + Darwin) + for f in /opt/homebrew/lib/libportaudio*.dylib /usr/local/lib/libportaudio*.dylib; do + [ -e "$f" ] && return 0 + done + ;; + Linux) + if command -v ldconfig >/dev/null 2>&1 && ldconfig -p 2>/dev/null | grep -q libportaudio; then + return 0 + fi + for f in /usr/lib/libportaudio.so* /usr/lib/*/libportaudio.so*; do + [ -e "$f" ] && return 0 + done + ;; + esac + return 1 +} + +# Homebrew also pulls in ffmpeg, portaudio, and cloudflared. The uv install does +# not, so detect any that are missing and print how to install them — without +# touching the system or invoking sudo on the user's behalf. +advise_system_deps() { + local missing=() + command -v ffmpeg >/dev/null 2>&1 || missing+=("ffmpeg") + has_portaudio || missing+=("portaudio") + command -v cloudflared >/dev/null 2>&1 || missing+=("cloudflared") + + [ ${#missing[@]} -eq 0 ] && return 0 + + echo "" + echo "Optional system dependencies are missing: ${missing[*]}" + echo "(core 'assembly transcribe' works without them)" + echo " - ffmpeg: decode non-WAV / URL audio" + echo " - portaudio: microphone capture for stream / dictate / agent" + echo " - cloudflared: public tunnel for 'assembly share'" + echo "" + echo "Install them with:" + + # Split into packages a system package manager carries vs. cloudflared, + # which needs Cloudflare's own repo on Linux. + local pkgs=() + local need_cloudflared=0 + local dep + for dep in "${missing[@]}"; do + case "$dep" in + cloudflared) need_cloudflared=1 ;; + *) pkgs+=("$dep") ;; + esac + done + + case "$(uname -s)" in + Darwin) + echo " brew install ${missing[*]}" + ;; + Linux) + if command -v apt-get >/dev/null 2>&1; then + # PortAudio's runtime lib is libportaudio2 on Debian/Ubuntu. + local apt_pkgs=("${pkgs[@]/portaudio/libportaudio2}") + [ ${#apt_pkgs[@]} -gt 0 ] && echo " sudo apt-get install ${apt_pkgs[*]}" + elif command -v dnf >/dev/null 2>&1; then + [ ${#pkgs[@]} -gt 0 ] && echo " sudo dnf install ${pkgs[*]}" + else + [ ${#pkgs[@]} -gt 0 ] && echo " install with your package manager: ${pkgs[*]}" + fi + if [ "$need_cloudflared" -eq 1 ]; then + echo " cloudflared: see https://pkg.cloudflare.com or" + echo " https://github.com/cloudflare/cloudflared/releases" + fi + ;; + *) + echo " ${missing[*]}" + ;; + esac +} + +if ! command -v uv &>/dev/null; then + echo "uv is not installed. Installing..." + curl -LsSf https://astral.sh/uv/install.sh | sh + echo "uv installation complete!" + echo "" + + if [ -x "$HOME/.local/bin/uv" ]; then + "$HOME/.local/bin/uv" tool install -U "$PACKAGE" --python "$PYTHON_VERSION" + else + echo "Please restart your shell and run this script again" + echo "" + exit 0 + fi +else + uv self update + uv tool install -U "$PACKAGE" --python "$PYTHON_VERSION" +fi + +advise_system_deps || true + +echo "" +echo "For help and support, see the AssemblyAI CLI repository" +echo "https://github.com/AssemblyAI/cli" +echo "" +echo "Read the docs at https://www.assemblyai.com/docs" +echo "" +echo "The AssemblyAI CLI is installed!" +echo "Run 'assembly login' to sign in, then 'assembly transcribe --sample' to try it"