Skip to content

Instantly share code, notes, and snippets.

@leodutra
Last active May 13, 2026 01:38
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
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