822 lines
23 KiB
Text
822 lines
23 KiB
Text
# ~/dotfiles/aliases.sh
|
|
|
|
# ---- PAI Commands -----
|
|
alias cmd='bun ~/.claude/commands/cmd.md'
|
|
alias freq='~/.claude/skills/frequency-therapy/tools/freq'
|
|
|
|
# ---- Fabric -----
|
|
|
|
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
|
|
}
|
|
|
|
# Fabric pattern aliases removed - now using lazy loading in ~/.zshenv
|
|
# (command_not_found_handler automatically detects fabric patterns)
|
|
|
|
# ----------------------------
|
|
# Sudo Wrapper with PATH Preservation
|
|
# ----------------------------
|
|
|
|
# Preserve PATH when using sudo with user-installed tools
|
|
# Usage: S uv pip install something --system (capital S)
|
|
alias S='sudo env PATH="$PATH"'
|
|
|
|
# ----------------------------
|
|
# Python Package Managers Quick Reference
|
|
# ----------------------------
|
|
# pip/pip3/uv → Venv-focused (use for projects)
|
|
# pipx → CLI tools (use for global tools like yt-dlp, black, ruff)
|
|
# S uv → System install with PATH preserved (only when pipx won't work)
|
|
|
|
# Pipx management aliases
|
|
alias U='pipx upgrade-all' # Update all pipx packages
|
|
alias P='pipx list' # List pipx packages
|
|
|
|
# --- GUI Applications (background + disown) ---
|
|
alias nemo='nemo . > /dev/null 2>&1 & disown'
|
|
alias hugo-serve='hugo server --bind 0.0.0.0 --baseURL http://localhost:1313 -D > /dev/null 2>&1 & disown'
|
|
|
|
# --- OpenCode ---
|
|
|
|
ide() {
|
|
local project="${1:-$(pwd)}" # directory to open, pwd if not specified
|
|
local editor="${2:-hx}" # default helix
|
|
local win_name="ide"
|
|
|
|
if [[ -n "$TMUX" ]]; then
|
|
tmux new-window -n "$win_name" -c "$project"
|
|
|
|
# Left pane: opencode
|
|
tmux select-pane -t 0
|
|
tmux send-keys "opencode" C-m
|
|
|
|
# Split right: right side gets 75%, left remains 25%
|
|
tmux split-window -h -p 75 -c "$project" # pane 1 (right)
|
|
tmux send-keys "$editor \"$project\"" C-m
|
|
|
|
# Now on right side, split horizontally for bottom editor (~25%)
|
|
tmux select-pane -t 1
|
|
|
|
# Bottom-right: editor
|
|
tmux select-pane -t 2
|
|
tmux split-window -v -p 25 -c "$project" # pane 2 (bottom-right)
|
|
|
|
# Focus back on top-right (main terminal)
|
|
tmux select-pane -t 1
|
|
else
|
|
tmux new-session -s "$win_name" -n main -d -c "$project"
|
|
tmux split-window -h -p 75 -c "$project"
|
|
tmux select-pane -t 0
|
|
tmux send-keys "opencode" C-m
|
|
tmux select-pane -t 1
|
|
tmux split-window -v -p 25 -c "$project"
|
|
tmux select-pane -t 2
|
|
tmux send-keys "$editor \"$project\"" C-m
|
|
tmux select-pane -t 1
|
|
tmux attach -t "$win_name"
|
|
fi
|
|
}
|
|
|
|
|
|
# TMUX-RECON Aliases
|
|
|
|
# ----------------------------
|
|
# Clipboard (Wayland-first, fallback to X11)
|
|
# ----------------------------
|
|
|
|
if command -v wl-copy &> /dev/null && [[ -n "$WAYLAND_DISPLAY" ]]; then
|
|
# Wayland - use wl-clipboard
|
|
alias pbcopy='wl-copy'
|
|
alias pbpaste='wl-paste'
|
|
elif command -v xsel &> /dev/null; then
|
|
alias pbcopy='xsel --input --clipboard'
|
|
alias pbpaste='xsel --output --clipboard'
|
|
elif command -v xclip &> /dev/null; then
|
|
alias pbcopy='xclip -selection clipboard'
|
|
alias pbpaste='xclip -selection clipboard -o'
|
|
fi
|
|
|
|
|
|
# ----------------------------
|
|
# Basic Shortcuts
|
|
# ----------------------------
|
|
|
|
alias a='~/arsenal/run -t'
|
|
alias any='~/AnythingLLMDesktop/start'
|
|
alias c='clear'
|
|
alias ..='cd ..'
|
|
alias ...='cd ../..'
|
|
alias ....='cd ../../..'
|
|
cpy() {
|
|
cat "$1" | pbcopy
|
|
}
|
|
alias d='docker'
|
|
alias dc='docker compose'
|
|
# alias h='history'
|
|
alias f='fabric'
|
|
#f() {
|
|
# fd "$1" -exec bat {} +
|
|
#}
|
|
alias i='sudo apt install'
|
|
alias j='journalctl -f'
|
|
# Note: jj is now a script in ~/scripts/ (upgraded from alias)
|
|
# For quick clipboard pretty-print, still use: pbpaste | jq . | pbcopy
|
|
alias jjj='pbpaste | jq .' # Quick view (no copy back)
|
|
alias kill='kill $(ps aux | fzf | awk '\''{print $2}'\'')'
|
|
# alias k9='kill -9 **'
|
|
alias nano='hx'
|
|
alias nf='fzf -m --preview="bat --color=always --style=numbers --line-range:300 {}" --bind "enter:become(hx {+})"'
|
|
alias oc='opencode'
|
|
alias p='parallel'
|
|
|
|
alias rec='meeting-record' # Override for transcription
|
|
alias rec-audio='parecord --device=alsa_output.pci-0000_00_1f.3.analog-stereo.monitor \
|
|
--file-format=wav ~/recordings/meeting-$(date +%Y%m%d-%H%M%S).wav'
|
|
alias rm='rm -I'
|
|
|
|
if [[ -n "$ZSH_VERSION" ]]; then
|
|
alias s='source ~/.zshrc' # zshrc already sources ~/.aliases and ~/.exports
|
|
elif [[ -n "$BASH_VERSION" ]]; then
|
|
alias s='source ~/.bashrc' # bashrc already sources ~/.aliases
|
|
fi
|
|
|
|
alias sa='source ~/.aliases'
|
|
alias snaabu="sudo /home/$USER/.pdtm/go/bin/naabu"
|
|
|
|
alias ta='tmux attach -t'
|
|
alias trim="awk '{\$1=\$1;print}'"
|
|
alias up='sudo apt update && sudo apt upgrade -y'
|
|
alias v='fd --type f --hidden --exclude .git | fzf-tmux -p --reverse | xargs hx'
|
|
alias vp='fd --type f --hidden --exclude .git | fzf --preview "bat {} --color=always --style=numbers" | xargs hx'
|
|
alias vv='hx $(fzf --preview="bat {} --color=always")'
|
|
alias gr='glow $(fzf --preview="bat {} --color=always")'
|
|
alias xx='exit'
|
|
alias eixt='exit'
|
|
alias yy='yazi'
|
|
|
|
|
|
# --------------------------------------
|
|
# Navigation
|
|
# --------------------------------------
|
|
|
|
# alias ..='cd ..'
|
|
# alias ...='cd ../..'
|
|
# alias cdf='cd $(fd -t d | fzf)'
|
|
# alias cdi='zoxide query -i'
|
|
|
|
function take {
|
|
mkdir -p "$1"
|
|
cd "$1" || exit
|
|
}
|
|
|
|
# ----------------------------
|
|
# File & Disk Utilities
|
|
# ----------------------------
|
|
|
|
# Unalias potential conflicts
|
|
unalias batclip 2>/dev/null
|
|
unalias dl 2>/dev/null
|
|
|
|
batclip() {
|
|
bat "$1" | xclip
|
|
}
|
|
# alias du='dust'
|
|
alias dfh='gdu -dn'
|
|
dl() {
|
|
yt-dlp -f best "$1"
|
|
}
|
|
|
|
if [[ -n "$ZSH_VERSION" ]]; then
|
|
alias reload='source ~/.zshrc'
|
|
elif [[ -n "$BASH_VERSION" ]]; then
|
|
alias reload='source ~/.bashrc'
|
|
fi
|
|
|
|
|
|
tailb() {
|
|
tail -f "$1" | bat --paging=never -l log
|
|
}
|
|
|
|
|
|
# --------------------------------------
|
|
# Search / Fuzzy Finder
|
|
# --------------------------------------
|
|
|
|
# alias f='fd -H -I -t f'
|
|
# f() { cd "$(find . -type d | fzf)" }
|
|
alias fzf="fzf --preview 'bat --color=always {}'"
|
|
# alias fzf="fzf --height 40% --layout reverse --border --preview 'bat --color=always {}' --preview-window '~3'"
|
|
alias ff='find * -type f | fzf --preview "bat --color=always {}"'
|
|
# alias fd='fdfind' # Debian compatibility
|
|
|
|
# Press F1 to open the file with less without leaving fzf
|
|
# Press CTRL-Y to copy the line to clipboard and aborts fzf (requires pbcopy)
|
|
alias fo="fzf --bind 'f1:execute(less -f {}),ctrl-y:execute-silent(echo {} | pbcopy)+abort'"
|
|
|
|
alias psf="ps -ef |
|
|
fzf --bind 'ctrl-r:reload(ps -ef)' \
|
|
--header 'Press CTRL-R to reload' --header-lines=1 \
|
|
--height=50% --layout=reverse"
|
|
|
|
# List all commands or search through them
|
|
if [[ -n "$ZSH_VERSION" ]]; then
|
|
alias findcmd='print -l ${(k)commands} | fzf --prompt="Search command: "'
|
|
elif [[ -n "$BASH_VERSION" ]]; then
|
|
alias findcmd='compgen -c | sort -u | fzf --prompt="Search command: "'
|
|
fi
|
|
|
|
# alias findcmd='compgen -c | sort -u | fzf --prompt="Search command: "'
|
|
# alias allcmds='compgen -c | sort -u | fzf'
|
|
|
|
|
|
# ----------------------------
|
|
# Taskwarrior
|
|
# ----------------------------
|
|
|
|
alias t='task'
|
|
alias tl='task list'
|
|
alias twa='task add'
|
|
# tm() {
|
|
# task modify
|
|
# }
|
|
# Commented out: conflicts with TabMan alias at line 731
|
|
# Use 'task modify' directly or create 'tmod' alias if needed
|
|
alias tb='task burndown.daily'
|
|
|
|
# ----------------------------
|
|
# Miscellaneous
|
|
# ----------------------------
|
|
|
|
# Note: note() is now a script in ~/scripts/ (upgraded from function)
|
|
# Old notes are still in ~/drafts.txt if you need them
|
|
|
|
help() {
|
|
if builtin help "$1" &>/dev/null; then
|
|
builtin help "$1" | bat --plain
|
|
else
|
|
"$@" --help 2>&1 | bat --plain
|
|
fi
|
|
}
|
|
|
|
mdstrip() {
|
|
sed -i 's/\\n/\n/g' "$1"
|
|
}
|
|
|
|
|
|
# help() {
|
|
# "$@" --help 2>&1 | bat --plain --language=txt
|
|
# }
|
|
|
|
# alias shelp='builtin help | bat --plain --language=help'
|
|
|
|
# alias bathelp='bat --plain --language=help'
|
|
# help() {
|
|
# "$@" --help 2>&1 | bathelp
|
|
# }
|
|
|
|
# ----------------------------
|
|
# Conditional Fallbacks
|
|
# ----------------------------
|
|
|
|
# Debian-specific fix for fd
|
|
if ! command -v fd &> /dev/null && command -v fdfind &> /dev/null; then
|
|
alias fd='fdfind'
|
|
fi
|
|
|
|
# if command -v bat &> /dev/null; then
|
|
# alias cat="bat"
|
|
# elif command -v batcat &> /dev/null; then
|
|
# alias cat="batcat"
|
|
# fi
|
|
|
|
alias l='eza -lah --icons'
|
|
alias sl='eza'
|
|
|
|
if command -v exa &> /dev/null; then
|
|
alias ls='exa'
|
|
# alias l='exa -l'
|
|
alias lsl='exa --icons'
|
|
alias ll='exa -lah --icons'
|
|
alias lt='exa -lah --tree --level=3 --icons'
|
|
fi
|
|
|
|
if command -v eza &> /dev/null; then
|
|
alias lg='eza -lah --icons --git -a'
|
|
# Newest files first (like ls -ltr but reversed to show newest at bottom)
|
|
alias ltr='eza --color=always -lrsnew'
|
|
alias snew='eza --color=always -lrsnew | head -20' # Newest 20 files
|
|
alias lnew='eza --color=always -lsnew | tail -20' # Newest 20 at bottom
|
|
fi
|
|
|
|
# Fallbacks if neither exa nor eza are found
|
|
if ! command -v exa &> /dev/null && ! command -v eza &> /dev/null; then
|
|
alias ls='ls --color=auto'
|
|
alias ll='ls -lah'
|
|
alias la='ls -A'
|
|
fi
|
|
|
|
if command -v rg &> /dev/null; then
|
|
alias rg='rg --smart-case'
|
|
alias rgl='rg --files | fzf --preview "bat --color=always {}"'
|
|
fi
|
|
|
|
if command -v ag &> /dev/null; then
|
|
alias ags='ag --smart-case'
|
|
alias agf='ag -l | fzf --preview "bat --color=always {}"'
|
|
fi
|
|
|
|
# Smart history with atuin (fallback to fzf if not available)
|
|
if command -v atuin &> /dev/null; then
|
|
alias h='atuin search --interactive'
|
|
else
|
|
alias h='history | fzf --preview "echo {}" --preview-window="up:3:wrap"'
|
|
fi
|
|
|
|
# Python as 'py' and pip
|
|
alias py='python3'
|
|
alias pip='python3 -m pip'
|
|
alias serve='python3 -m http.server 80'
|
|
|
|
# --------------------------------------
|
|
# Networking & System Info
|
|
# --------------------------------------
|
|
|
|
alias xh='xh --style auto'
|
|
# Note: myip is now a script in ~/scripts/ (upgraded from alias)
|
|
alias localip="ip a | grep inet"
|
|
|
|
if command -v mtr &> /dev/null; then
|
|
alias ping='mtr'
|
|
else
|
|
unalias ping
|
|
fi
|
|
|
|
alias net='bandwhich'
|
|
alias sniff='sudo tcpdump -i any -n'
|
|
# Note: ports is now a script in ~/scripts/ (upgraded from alias)
|
|
alias psnet='sudo netstat -tulnp'
|
|
alias fire='sudo ufw status verbose'
|
|
alias logs='sudo tail -f /var/log/syslog'
|
|
alias chkports='sudo lsof -i -P -n | less'
|
|
|
|
# unalias zi
|
|
|
|
# GIT ALIASES -----------------------------------------------------------------
|
|
alias gc='git commit'
|
|
alias gco='git checkout'
|
|
alias ga='git add'
|
|
alias gst='git rev-parse --git-dir > /dev/null 2>&1 && git status || eza'
|
|
alias grv='git remote -v'
|
|
|
|
|
|
copy-line() {
|
|
rg --line-number . | fzf --delimiter ':' --preview 'bat --color=always --highlight-line {2} {1}' | awk -F ':' '{print "+"$2" "$1}'
|
|
}
|
|
|
|
open-at-line() {
|
|
hx $(rg --line-number . | fzf --delimiter ':' --preview 'bat --color=always --highlight-line {2} {1}' | awk -F ':' '{print "+"$2" "$1}')
|
|
}
|
|
|
|
# PAI Context Manager
|
|
alias cm="~/.claude/commands/context-manager.sh"
|
|
alias cms="~/.claude/commands/context-manager.sh search"
|
|
alias cmr="~/.claude/commands/context-manager.sh recent"
|
|
alias cmn="~/.claude/commands/context-manager.sh new"
|
|
alias cmt="~/.claude/commands/context-manager.sh tree"
|
|
|
|
# Enhanced fzf file operations with better previews
|
|
alias fzfg='rg --line-number --color=always . | fzf --ansi --delimiter ":" --preview "bat --color=always --highlight-line {2} {1}" --bind "enter:execute(hx +{2} {1})"'
|
|
alias fzfd='fd --type d | fzf --preview "eza --tree --level=2 --color=always {} 2>/dev/null || tree -L 2 -C {}"'
|
|
|
|
# Better process management
|
|
alias psg='ps aux | fzf --header-lines=1 --preview "echo {}" --preview-window=up:1'
|
|
|
|
# Enhanced git fzf integration
|
|
alias gfzf='git log --oneline --color=always | fzf --ansi --preview "git show --color=always {1}" --bind "enter:execute(git show {1} | less -R)"'
|
|
|
|
# --------------------------------------
|
|
# N8N API Helper
|
|
# --------------------------------------
|
|
# Requires N8N_API_KEY and N8N_BASE_URL in ~/.env
|
|
n8n_api() {
|
|
source ~/.env
|
|
local endpoint="${1:-/workflows}"
|
|
shift
|
|
curl -s -H "X-N8N-API-KEY: ${N8N_API_KEY}" \
|
|
"${N8N_BASE_URL}/api/v1${endpoint}" \
|
|
"$@"
|
|
}
|
|
|
|
# --------------------------------------
|
|
# Baserow API Helper
|
|
# --------------------------------------
|
|
# Requires BASEROW_API_KEY and BASEROW_TABLE_ID in ~/.env
|
|
# Baserow is on localhost:3000 via SSH tunnel
|
|
baserow_api() {
|
|
source ~/.env
|
|
local endpoint="${1:-database/rows/table/${BASEROW_CONTACTS_TABLE_ID}/}"
|
|
if [ $# -gt 0 ]; then
|
|
shift
|
|
fi
|
|
curl -s -H "Authorization: Token ${BASEROW_API_KEY}" \
|
|
"http://baserow:3000/api/${endpoint}" \
|
|
"$@"
|
|
}
|
|
alias docker-compose="docker compose"
|
|
|
|
# ----------------------------
|
|
# Manual Redshift Control (Nuclear Option - 2025-10-16)
|
|
# ----------------------------
|
|
alias night='redshift -O 2600 -P && echo "🌙 Night mode activated (2600K)"'
|
|
alias day='redshift -x && echo "☀️ Day mode activated (reset to default)"'
|
|
alias evening='redshift -O 3500 -P && echo "🌅 Evening mode activated (3500K)"'
|
|
|
|
# WhisperTux quick launch aliases
|
|
alias wt='systemctl --user start whispertux'
|
|
alias wtr='systemctl --user restart whispertux'
|
|
alias wt-stop='systemctl --user stop whispertux'
|
|
alias wt-status='systemctl --user status whispertux'
|
|
alias wt-log='journalctl --user -u whispertux -f'
|
|
alias reload='source ~/.zshrc && echo "✅ Shell reloaded - WhisperTux aliases active"'
|
|
|
|
# ----------------------------
|
|
# Evan Hahn Inspired Utilities (Tier 1)
|
|
# ----------------------------
|
|
# Source: https://evanhahn.com/scripts-i-wrote-that-i-use-all-the-time/
|
|
|
|
# Copy current directory to clipboard (strips trailing newline)
|
|
cpwd() {
|
|
pwd | tr -d '\n' | pbcopy
|
|
}
|
|
|
|
# ISO date format for filename prefixes (2025-10-28)
|
|
hoy() {
|
|
echo -n "$(date '+%Y-%m-%d')"
|
|
}
|
|
|
|
# Text case conversion
|
|
alias uppered='tr "[:lower:]" "[:upper:]"'
|
|
alias lowered='tr "[:upper:]" "[:lower:]"'
|
|
|
|
# Print specific line from stdin (usage: cat file | line 10)
|
|
line() {
|
|
sed -n "${1}p"
|
|
}
|
|
|
|
# Jump to temporary directory
|
|
tempe() {
|
|
cd "$(mktemp -d)"
|
|
}
|
|
|
|
# True background execution (suppress ALL output)
|
|
bb() {
|
|
nohup "$@" >/dev/null 2>&1 &
|
|
}
|
|
|
|
# Note: running() is now a script in ~/scripts/ with PID highlighting
|
|
|
|
# Quick scratch buffer in editor (temp file)
|
|
scratch() {
|
|
"${EDITOR:-vim}" "$(mktemp)"
|
|
}
|
|
|
|
# Note: tryna and trynafail are now scripts in ~/scripts/
|
|
|
|
# ----------------------------
|
|
# Claude Code Hook Management
|
|
# ----------------------------
|
|
|
|
# Fix Claude Code hooks when they stop firing
|
|
# Touches all hook files to force file watcher reload
|
|
# Usage: fix-hooks (then wait 60s before sending next message)
|
|
alias fix-hooks='cd ~/.claude && touch settings.json hooks/*.ts && echo "✅ Hooks refreshed - wait 60-90 seconds before next message"'
|
|
|
|
# ----------------------------
|
|
# Column Formatting Function Family
|
|
# ----------------------------
|
|
|
|
# col - Column formatter with custom delimiter (supports files and stdin)
|
|
# Usage: col <file> [delimiter]
|
|
# cat file | col [delimiter]
|
|
# Default delimiter is whitespace
|
|
# Examples:
|
|
# col file.txt # Default whitespace delimiter
|
|
# col file.csv ',' # CSV with comma delimiter
|
|
# col file.tsv $'\t' # TSV with tab delimiter
|
|
# cat file.csv | col ',' # Piped input
|
|
col() {
|
|
local delim="${2:- }"
|
|
|
|
if [[ $# -eq 0 ]] || [[ "$1" == "-" ]]; then
|
|
# Read from stdin
|
|
column -t -s "$delim"
|
|
else
|
|
# Read from file
|
|
local file="$1"
|
|
if [[ ! -f "$file" ]]; then
|
|
echo "Error: File '$file' not found" >&2
|
|
return 1
|
|
fi
|
|
column -t -s "$delim" < "$file"
|
|
fi
|
|
}
|
|
|
|
# colp - Explicit piped version (alias for clarity)
|
|
# Usage: cat file.csv | colp ','
|
|
colp() {
|
|
local delim="${1:- }"
|
|
column -t -s "$delim"
|
|
}
|
|
|
|
colah() { cola "$1" | sed '1s/^/\x1b[1;36m/; 1s/$/\x1b[0m/'; }
|
|
|
|
# cola - Auto-detect delimiter (CSV/TSV/space)
|
|
# Usage: cola <file>
|
|
# Automatically detects comma, tab, or space delimiters
|
|
cola() {
|
|
if [[ $# -eq 0 ]]; then
|
|
echo "Usage: cola <file>" >&2
|
|
return 1
|
|
fi
|
|
|
|
local file="$1"
|
|
if [[ ! -f "$file" ]]; then
|
|
echo "Error: File '$file' not found" >&2
|
|
return 1
|
|
fi
|
|
|
|
# Detect delimiter by sampling first line
|
|
local first_line=$(head -n1 "$file")
|
|
local delim
|
|
|
|
if [[ "$first_line" =~ $'\t' ]]; then
|
|
delim=$'\t'
|
|
echo "# Auto-detected: TSV (tab-delimited)" >&2
|
|
elif [[ "$first_line" =~ , ]]; then
|
|
delim=','
|
|
echo "# Auto-detected: CSV (comma-delimited)" >&2
|
|
else
|
|
delim=' '
|
|
echo "# Auto-detected: Space-delimited" >&2
|
|
fi
|
|
|
|
column -t -s "$delim" < "$file"
|
|
}
|
|
|
|
# colh - Column formatter with highlighted header row
|
|
# Usage: colh <file> [delimiter]
|
|
# First row is displayed in bold cyan
|
|
colh() {
|
|
if [[ $# -eq 0 ]]; then
|
|
echo "Usage: colh <file> [delimiter]" >&2
|
|
return 1
|
|
fi
|
|
|
|
local file="$1"
|
|
local delim="${2:- }"
|
|
|
|
if [[ ! -f "$file" ]]; then
|
|
echo "Error: File '$file' not found" >&2
|
|
return 1
|
|
fi
|
|
|
|
{
|
|
# Header in bold cyan
|
|
head -n1 "$file" | column -t -s "$delim" | sed 's/^/\x1b[1;36m/' | sed 's/$/\x1b[0m/'
|
|
# Rest of file normal
|
|
tail -n+2 "$file" | column -t -s "$delim"
|
|
}
|
|
}
|
|
|
|
# coln - Column formatter with numbered rows
|
|
# Usage: coln <file> [delimiter]
|
|
# Adds line numbers like cat -n
|
|
coln() {
|
|
if [[ $# -eq 0 ]]; then
|
|
echo "Usage: coln <file> [delimiter]" >&2
|
|
return 1
|
|
fi
|
|
|
|
local file="$1"
|
|
local delim="${2:- }"
|
|
|
|
if [[ ! -f "$file" ]]; then
|
|
echo "Error: File '$file' not found" >&2
|
|
return 1
|
|
fi
|
|
|
|
column -t -s "$delim" < "$file" | nl -w3 -s' '
|
|
}
|
|
|
|
# Bonus: CSV/TSV converters
|
|
csv2tsv() {
|
|
if [[ $# -eq 0 ]]; then
|
|
echo "Usage: csv2tsv <file>" >&2
|
|
return 1
|
|
fi
|
|
sed 's/,/\t/g' "$1"
|
|
}
|
|
|
|
tsv2csv() {
|
|
if [[ $# -eq 0 ]]; then
|
|
echo "Usage: tsv2csv <file>" >&2
|
|
return 1
|
|
fi
|
|
sed 's/\t/,/g' "$1"
|
|
}
|
|
|
|
# colj - Convert CSV to JSON array (first row = keys)
|
|
colj() {
|
|
local input
|
|
if [[ $# -eq 0 ]] || [[ "$1" == "-" ]]; then
|
|
input=$(cat)
|
|
else
|
|
[[ -f "$1" ]] || { echo "Error: File '$1' not found" >&2; return 1; }
|
|
input=$(cat "$1")
|
|
fi
|
|
|
|
# Use Python for reliable CSV parsing (handles quoted fields with commas)
|
|
echo "$input" | python3 -c '
|
|
import csv, json, sys
|
|
reader = csv.DictReader(sys.stdin)
|
|
print(json.dumps([row for row in reader], indent=2))
|
|
'
|
|
}
|
|
|
|
# ----------------------------
|
|
# Reconnaissance & Pentesting Aliases
|
|
# ----------------------------
|
|
|
|
# Note: recon, web-recon, and wes are now scripts in ~/scripts/pentesting/
|
|
# Access them directly: recon, web-recon, wes
|
|
|
|
# Web reconnaissance alias (alternative name)
|
|
discover() {
|
|
web-recon "$1"
|
|
}
|
|
|
|
# enum4linux-ng docker wrapper
|
|
e4l() {
|
|
docker run --rm -t enum4linux-ng -A -C "$1"
|
|
}
|
|
|
|
# Naabu + nmap combo (uses pscan if available)
|
|
gomap() {
|
|
if command -v pscan &>/dev/null; then
|
|
pscan "$1" -v
|
|
elif command -v naabu &>/dev/null; then
|
|
naabu -host "$1" -nmap-cli "nmap $2"
|
|
else
|
|
echo "Install naabu or use pscan script"
|
|
fi
|
|
}
|
|
|
|
# Metasploit multi-handler
|
|
msfl() {
|
|
if [ ! -f "$HOME/scripts/multi_handler.rc" ]; then
|
|
echo -e "\033[0;33m⚠\033[0m multi_handler.rc not found"
|
|
echo "Create it at: ~/scripts/multi_handler.rc"
|
|
return 1
|
|
fi
|
|
msfconsole -r "$HOME/scripts/multi_handler.rc"
|
|
}
|
|
|
|
# ================================================================
|
|
# System Backup Workflow
|
|
# ================================================================
|
|
# Full system backup to encrypted volume before major OS changes
|
|
#
|
|
# Usage:
|
|
# 1. Mount encrypted volume:
|
|
# sudo veracrypt -t <vault-path> /mnt/veracrypt1
|
|
# 2. Run backup:
|
|
# run-backup
|
|
# 3. Unmount when complete:
|
|
# sudo veracrypt -t -d /mnt/veracrypt1
|
|
#
|
|
# Notes:
|
|
# - Uses encrypted storage (VeraCrypt) for data at rest
|
|
# - Backup script is in ~/.claude/context/personal/scripts/
|
|
# - Logs to /var/log/system-backup.log
|
|
# - For low /tmp space, set TMPDIR before mounting:
|
|
# mkdir -p /path/to/temp && sudo env TMPDIR=/path/to/temp veracrypt -t ...
|
|
# ================================================================
|
|
|
|
alias run-backup='sudo ~/.claude/context/personal/scripts/full-system-backup.sh /mnt/backup-vault'
|
|
|
|
# ================================================================
|
|
# ProtonVPN Automation - Quick Reference & Documentation
|
|
#
|
|
# Created: 2025-11-08
|
|
#
|
|
# Quick reference for VPN server curation and automation system.
|
|
# See full docs: ~/.claude/skills/app-troubleshooting/SKILL.md (lines 2130-2369)
|
|
#
|
|
# Common commands:
|
|
# proton-connect-colorado - Connect to random top-quality server
|
|
# test-vpn-quality - Test current connection quality
|
|
# proton-rank-servers 20 - View top 20 servers by quality
|
|
# proton-discover-servers 1 50 - Discover new servers
|
|
# ================================================================
|
|
|
|
alias vpn-help='bat ~/.local/share/doc/protonvpn-automation-quickref.md 2>/dev/null || cat ~/.local/share/doc/protonvpn-automation-quickref.md'
|
|
|
|
# Kill stale ProtonVPN connections (fixes zombie openvpn after Plasma partial shutdown)
|
|
vpn-kill() {
|
|
nmcli connection show --active | grep -i proton | while read -r line; do
|
|
name=$(echo "$line" | awk '{print $1" "$2}')
|
|
nmcli connection down "$name" 2>/dev/null && echo "Disconnected: $name"
|
|
done
|
|
}
|
|
|
|
|
|
# TabMan - Browser tab manager
|
|
alias tabman="bun ~/github/tabman/index.ts"
|
|
alias tm="bun ~/github/tabman/index.ts"
|
|
|
|
# Port reference quick access
|
|
alias lp='cat ~/.claude/context/infrastructure/ports-reference.md | less'
|
|
|
|
# Reddit video downloader for Redlib
|
|
alias reddit-dl="bun /home/e/opt/redlib/reddit-dl.ts"
|
|
|
|
alias inotify-check='echo "Instances: $(find /proc/*/fd -lname "anon_inode:inotify" 2>/dev/null | wc -l) / $(cat /proc/sys/fs/inotify/max_user_instances)"'
|
|
|
|
# SimpleX Bot - E2EE automation
|
|
alias sbot='~/opt/simplex-bot/simplex'
|
|
|
|
# ----------------------------
|
|
# GPG Encryption Helpers
|
|
# ----------------------------
|
|
# Simple file encryption/decryption using your default GPG key
|
|
# Usage: gpg-encrypt notes.md → creates notes.md.gpg
|
|
# gpg-decrypt notes.md.gpg → creates notes.md
|
|
|
|
gpg-encrypt() {
|
|
local file="$1"
|
|
if [[ -z "$file" ]]; then
|
|
echo "Usage: gpg-encrypt <file>" >&2
|
|
return 1
|
|
fi
|
|
if [[ ! -f "$file" ]]; then
|
|
echo "Error: File '$file' not found" >&2
|
|
return 1
|
|
fi
|
|
gpg --output "${file}.gpg" --encrypt --default-recipient-self "$file" \
|
|
&& echo "✅ Encrypted: ${file}.gpg"
|
|
}
|
|
|
|
gpg-decrypt() {
|
|
local file="$1"
|
|
if [[ -z "$file" ]]; then
|
|
echo "Usage: gpg-decrypt <file.gpg>" >&2
|
|
return 1
|
|
fi
|
|
if [[ ! -f "$file" ]]; then
|
|
echo "Error: File '$file' not found" >&2
|
|
return 1
|
|
fi
|
|
local output="${file%.gpg}"
|
|
if [[ "$output" == "$file" ]]; then
|
|
output="${file}.decrypted"
|
|
fi
|
|
gpg --decrypt "$file" > "$output" \
|
|
&& echo "✅ Decrypted: $output"
|
|
}
|
|
|
|
# Standard Notes (AppImage in Downloads)
|
|
alias standard-notes='/home/$USER/Downloads/standard-notes-3.201.2-linux-x86_64.AppImage'
|
|
|
|
alias dailies='~/.claude/context/personal/scripts/daily-reminders.sh'
|
|
|
|
# ---- Meshtastic -----
|
|
mesh-nodes() {
|
|
for port in /dev/ttyUSB*; do
|
|
[ -e "$port" ] || continue
|
|
echo "=== $port ==="
|
|
timeout 5 meshtastic --port "$port" --info 2>&1 | grep -iE "Owner|Short Name|Role|Hardware" || echo "No Meshtastic device"
|
|
done
|
|
}
|
|
|
|
mesh-send() {
|
|
local port="${1:-/dev/ttyUSB0}"
|
|
shift
|
|
meshtastic --port "$port" --sendtext "$*"
|
|
}
|
|
|
|
mesh-listen() {
|
|
local port="${1:-/dev/ttyUSB0}"
|
|
meshtastic --port "$port" --listen
|
|
}
|