Last active
May 13, 2026 01:38
-
-
Save leodutra/a0923f416b7cd19369d2fed207c179ac to your computer and use it in GitHub Desktop.
Install Fabric AI on Arch Linux
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| sudo pacman -S --needed base-devel git pkgconf cmake make gcc | |
| # Install Paru | |
| if ! command -v paru >/dev/null 2>&1; then | |
| git clone https://aur.archlinux.org/paru.git | |
| cd paru || exit | |
| makepkg -si | |
| fi | |
| # Install Fabric AI + dependencies | |
| paru -S --needed --noconfirm \ | |
| fabric-ai \ | |
| ffmpeg \ | |
| python \ | |
| python-html2text \ | |
| python-readability-lxml \ | |
| python-requests \ | |
| xclip \ | |
| yt-dlp | |
| # Install Whisper.cpp | |
| cd $HOME | |
| git clone https://github.com/ggml-org/whisper.cpp.git | |
| cd whisper.cpp | |
| sh ./models/download-ggml-model.sh large-v2 | |
| # build the project | |
| cmake -B build -DGGML_CUDA=1 -DCMAKE_CUDA_ARCHITECTURES="86" -D WHISPER_FFMPEG=yes | |
| cmake --build build -j --config Release | |
| cd $HOME | |
| # Install Fabric completions | |
| curl -fsSL https://raw.githubusercontent.com/danielmiessler/Fabric/refs/heads/main/completions/setup-completions.sh | sh | |
| cat << 'EOF' >> ~/.zshrc | |
| # Fabric AI | |
| alias fabric=fabric-ai | |
| # Fabric pattern aliases | |
| # Creates aliases for all Fabric patterns so they can be invoked directly | |
| for pattern_file in $HOME/.config/fabric/patterns/*; do | |
| pattern_name="$(basename "$pattern_file")" | |
| alias_name="${FABRIC_ALIAS_PREFIX:-}${pattern_name}" | |
| alias_command="alias $alias_name='fabric --pattern $pattern_name'" | |
| eval "$alias_command" | |
| done | |
| # Clipboard helper | |
| # Returns clipboard contents (Wayland first, X11 fallback) | |
| p() { | |
| wl-paste --primary 2>/dev/null || xclip -selection clipboard -o | |
| } | |
| # HTML → Markdown extractor | |
| # Fetches a URL, extracts the main readable content, converts to markdown | |
| html() { | |
| python - "$1" <<'PY' | |
| import sys, requests | |
| from readability import Document | |
| import html2text | |
| url = sys.argv[1] | |
| html = requests.get(url).text | |
| doc = Document(html) | |
| print(html2text.html2text(doc.summary())) | |
| PY | |
| } | |
| # Whisper transcription via whisper.cpp (pipe-friendly) | |
| # Env: | |
| # WHISPER_MODEL model name (default: large-v2) | |
| # WHISPER_MODEL_FILE full path override | |
| # WHISPER_CPP_DIR whisper.cpp checkout (default: ~/whisper.cpp) | |
| # WHISPER_CPP_BIN whisper-cli binary path override | |
| # WHISPER_THREADS thread count (default: nproc) | |
| # WHISPER_BEAM_SIZE beam search width (default: 5) | |
| # WHISPER_BEST_OF candidate samples (default: 5) | |
| # WHISPER_TEMP sampling temperature (default: 0.0) | |
| # WHISPER_ENTROPY entropy threshold (default: 2.0) | |
| # WHISPER_MAX_LEN max segment length (default: 60) | |
| # WHISPER_SPLIT_WORD split on word rather than token (default: 1) | |
| # WHISPER_QUIET=1 suppress all stderr noise (incl. yt-dlp, ffmpeg, whisper-cli) | |
| # WHISPER_DEBUG=1 print resolved config to stderr | |
| whisper() { | |
| local input="$1" | |
| local model="${WHISPER_MODEL:-large-v2}" | |
| local WHISPER_CPP_DIR="${WHISPER_CPP_DIR:-$HOME/whisper.cpp}" | |
| local WHISPER_BIN="${WHISPER_CPP_BIN:-$WHISPER_CPP_DIR/build/bin/whisper-cli}" | |
| local MODEL_FILE="${WHISPER_MODEL_FILE:-$WHISPER_CPP_DIR/models/ggml-${model}.bin}" | |
| local THREADS="${WHISPER_THREADS:-$(nproc)}" | |
| local BEAM_SIZE="${WHISPER_BEAM_SIZE:-5}" | |
| local BEST_OF="${WHISPER_BEST_OF:-5}" | |
| local TEMP="${WHISPER_TEMP:-0.0}" | |
| local ENTROPY="${WHISPER_ENTROPY:-2.0}" | |
| local MAX_LEN="${WHISPER_MAX_LEN:-60}" | |
| local SPLIT_WORD="${WHISPER_SPLIT_WORD:-1}" | |
| local quiet="${WHISPER_QUIET:-0}" | |
| [[ -z "$input" ]] && { | |
| echo "Usage: whisper <url-or-file>" >&2 | |
| return 1 | |
| } | |
| [[ ! -x "$WHISPER_BIN" ]] && { | |
| echo "whisper-cli not found at $WHISPER_BIN" >&2 | |
| echo "Build: cmake -B build -DGGML_CUDA=1 && cmake --build build -j --config Release" >&2 | |
| return 1 | |
| } | |
| [[ ! -f "$MODEL_FILE" ]] && { | |
| echo "Model not found: $MODEL_FILE" >&2 | |
| echo "Download: $WHISPER_CPP_DIR/models/download-ggml-model.sh $model" >&2 | |
| return 1 | |
| } | |
| if [[ ! "$input" =~ ^https?:// ]] && [[ ! -f "$input" ]]; then | |
| echo "File not found: $input" >&2 | |
| return 2 | |
| fi | |
| [[ "${WHISPER_DEBUG:-0}" == 1 ]] && \ | |
| echo "whisper: model=$MODEL_FILE threads=$THREADS beam=$BEAM_SIZE best_of=$BEST_OF temp=$TEMP entropy=$ENTROPY max_len=$MAX_LEN" >&2 | |
| # Subshell scopes pipefail, EXIT trap, and tmpwav cleanup — | |
| # caller's shell state is never mutated. | |
| ( | |
| set -o pipefail | |
| [[ "$quiet" == 1 ]] && exec 2>/dev/null | |
| local tmpwav | |
| tmpwav=$(mktemp --suffix=.wav) || exit 1 | |
| trap 'rm -f "$tmpwav"' EXIT | |
| # whisper.cpp needs 16-bit 16kHz mono WAV | |
| if [[ "$input" =~ ^https?:// ]]; then | |
| yt-dlp -f bestaudio -o - "$input" \ | |
| | ffmpeg -loglevel error -i pipe:0 -ar 16000 -ac 1 -c:a pcm_s16le -y "$tmpwav" </dev/null \ | |
| || { echo "Audio prep failed" >&2; exit 3; } | |
| else | |
| ffmpeg -loglevel error -i "$input" -ar 16000 -ac 1 -c:a pcm_s16le -y "$tmpwav" </dev/null \ | |
| || { echo "Audio prep failed" >&2; exit 3; } | |
| fi | |
| local extra_args=() | |
| [[ "$SPLIT_WORD" == "1" ]] && extra_args+=( "--split-on-word" ) | |
| "$WHISPER_BIN" -m "$MODEL_FILE" -f "$tmpwav" \ | |
| -t "$THREADS" -bs "$BEAM_SIZE" -bo "$BEST_OF" \ | |
| --temperature "$TEMP" \ | |
| --entropy-thold "$ENTROPY" \ | |
| --max-len "$MAX_LEN" \ | |
| -nt -np "${extra_args[@]}" | |
| ) | |
| } | |
| # yt function for YouTube transcripts | |
| yt() { | |
| if [ "$#" -eq 0 ] || [ "$#" -gt 2 ]; then | |
| echo "Usage: yt [-t | --timestamps] youtube-link" | |
| echo "Use the '-t' flag to get the transcript with timestamps." | |
| return 1 | |
| fi | |
| transcript_flag="--transcript" | |
| if [ "$1" = "-t" ] || [ "$1" = "--timestamps" ]; then | |
| transcript_flag="--transcript-with-timestamps" | |
| shift | |
| fi | |
| local video_link="$1" | |
| fabric -y "$video_link" $transcript_flag | |
| } | |
| EOF | |
| # Fabric Setup | |
| fabric --setup | |
| # Reload zsh config | |
| source ~/.zshrc |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment