Skip to content

Instantly share code, notes, and snippets.

@leodutra
Last active June 21, 2026 09:26
Show Gist options
  • Select an option

  • Save leodutra/a0923f416b7cd19369d2fed207c179ac to your computer and use it in GitHub Desktop.

Select an option

Save leodutra/a0923f416b7cd19369d2fed207c179ac to your computer and use it in GitHub Desktop.
Install Fabric AI on Arch Linux
# ------------------------------------------------------------
# Helpers
# ------------------------------------------------------------
zshrc_append() {
# Append a line to ~/.zshrc only if it isn't already there.
local line="$1"
grep -qxF "$line" ~/.zshrc 2>/dev/null || echo "$line" >> ~/.zshrc
}
# ------------------------------------------------------------
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 \
cmake \
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
zshrc_append 'source ~/.config/zsh/aliases/fabric-ai-zsh-aliases.zsh'
# Fabric Setup
fabric --setup
# Reload zsh config
source ~/.zshrc
# =============================================================================
# Fabric AI
# =============================================================================
# Main Fabric command.
alias fabric=fabric-ai
# 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 Utilities
# =============================================================================
# Returns clipboard contents (Wayland first, X11 fallback).
p() {
wl-paste --primary 2>/dev/null || xclip -selection clipboard -o
}
# =============================================================================
# Web Utilities
# =============================================================================
# Fetch a URL, extract the main readable content, and convert to Markdown.
#
# Usage:
# html https://example.com
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.cpp transcription helper
# =============================================================================
# Usage:
# whisper <url-or-file>
#
# Supports local audio/video files and YouTube URLs.
#
# Environment:
# WHISPER_MODEL model name (default: large-v2)
# WHISPER_MODEL_FILE explicit ggml path (default: derived from WHISPER_MODEL)
# WHISPER_CPP_DIR whisper.cpp root (default: ~/whisper.cpp)
# WHISPER_CPP_BIN whisper-cli path (default: <dir>/build/bin/whisper-cli)
# WHISPER_LANG spoken language (default: auto — set "pt"/"en"/... to force)
# WHISPER_THREADS thread count (default: nproc)
# WHISPER_VAD enable Silero VAD (0/1, default 1; needs model present)
# WHISPER_VAD_MODEL Silero VAD ggml path (default: <dir>/models/ggml-silero-v6.2.0.bin)
# WHISPER_SUPPRESS_NST suppress (applause)/(music) tokens (0/1, default 0)
# WHISPER_MAX_LEN max line length (default: 0 = off; cosmetic line-wrap only)
# WHISPER_EXTRA_ARGS extra flags string (passthrough, e.g. "--prompt 'tech jargon'")
# WHISPER_QUIET silence stderr (0/1)
# WHISPER_DEBUG print resolved config (0/1)
#
# Note: whisper.cpp defaults -l to "en", NOT auto-detect. This wrapper defaults to
# "auto" so non-English audio isn't silently transcribed as English (the
# "(speaking in foreign language)" loop). Force WHISPER_LANG when you know the
# language and want to avoid mis-detection on silent/music intros.
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 TRANSCRIBE_LANG="${WHISPER_LANG:-auto}" # NOT `LANG` — that shadows the locale env var
local THREADS="${WHISPER_THREADS:-$(nproc)}"
local MAX_LEN="${WHISPER_MAX_LEN:-0}"
local VAD_MODEL="${WHISPER_VAD_MODEL:-$WHISPER_CPP_DIR/models/ggml-silero-v6.2.0.bin}"
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
}
command -v ffmpeg >/dev/null 2>&1 || {
echo "ffmpeg not found in PATH" >&2
return 1
}
if [[ "$input" =~ ^https?:// ]]; then
command -v yt-dlp >/dev/null 2>&1 || {
echo "yt-dlp not found in PATH (required for URLs)" >&2
return 1
}
elif [[ ! -f "$input" ]]; then
echo "File not found: $input" >&2
return 2
fi
[[ "${WHISPER_DEBUG:-0}" == 1 ]] && {
local vad_state="off"
[[ "${WHISPER_VAD:-1}" == 1 && -f "$VAD_MODEL" ]] && vad_state="on ($VAD_MODEL)"
echo "whisper: model=$MODEL_FILE lang=$TRANSCRIBE_LANG threads=$THREADS vad=$vad_state max_len=$MAX_LEN" >&2
}
(
set -o pipefail
[[ "$quiet" == 1 ]] && exec 2>/dev/null
local tmpwav
tmpwav=$(mktemp --suffix=.wav) || exit 1
trap 'rm -f "$tmpwav"' EXIT
# 16 kHz mono PCM s16le — the format whisper-cli requires
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 args=(
-m "$MODEL_FILE"
-f "$tmpwav"
-l "$TRANSCRIBE_LANG" # the one real fix: don't let it silently fall back to "en"
-t "$THREADS"
-nt -np
)
# opt-in hardening
[[ "${WHISPER_SUPPRESS_NST:-0}" == 1 ]] && args+=( --suppress-nst )
[[ "${WHISPER_VAD:-1}" == 1 && -f "$VAD_MODEL" ]] && args+=( --vad --vad-model "$VAD_MODEL" )
[[ "$MAX_LEN" != "0" ]] && args+=( --max-len "$MAX_LEN" --split-on-word )
# passthrough — quote-aware via xargs, no eval (no injection / no broken quoting).
# Prefer a real array if you embed odd characters: WHISPER_EXTRA_ARGS_ARR=(--prompt "x y")
if [[ -n "${WHISPER_EXTRA_ARGS:-}" ]]; then
local extra=()
mapfile -t extra < <(printf '%s' "$WHISPER_EXTRA_ARGS" | xargs printf '%s\n')
args+=( "${extra[@]}" )
fi
[[ -n "${WHISPER_EXTRA_ARGS_ARR:-}" ]] && args+=( "${WHISPER_EXTRA_ARGS_ARR[@]}" )
"$WHISPER_BIN" "${args[@]}"
)
}
# =============================================================================
# YouTube Helpers
# =============================================================================
# Extract transcript using Fabric.
#
# Usage:
# yt <youtube-url>
# yt -t <youtube-url>
#
# Options:
# -t, --timestamps
# Include timestamps in transcript output.
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
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment