A new start

This commit is contained in:
2025-10-29 00:06:12 +01:00
commit 665ce57751
42 changed files with 3205 additions and 0 deletions

34
.editorconfig Executable file
View File

@@ -0,0 +1,34 @@
# EditorConfig is awesome: https://editorconfig.org
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
indent_size = 2
# Matches multiple files with brace expansion notation
# Set default charset
[*.{js,py}]
charset = utf-8
# 4 space indentation
[*.py]
indent_style = space
indent_size = 4
# Tab indentation (no size specified)
[Makefile]
indent_style = tab
# Indentation override for all JS under lib directory
[lib/**.js]
indent_style = space
indent_size = 2
# Matches the exact files either package.json or .travis.yml
[{package.json,.travis.yml}]
indent_style = space
indent_size = 2

16
.gitconfig Executable file
View File

@@ -0,0 +1,16 @@
[user]
name = Sebastian Krüger
email = valknar@pivoine.art
[filter "lfs"]
clean = git-lfs clean -- %f
smudge = git-lfs smudge -- %f
process = git-lfs filter-process
required = true
[core]
editor = nano
[init]
defaultBranch = main
[alias]
squash-all = "!f(){ git reset $(git commit-tree \"HEAD^{tree}\" \"$@\");};f"
[push]
autoSetupRemote = true

55
.gitignore vendored Executable file
View File

@@ -0,0 +1,55 @@
# Ignore everything
*
# But not these files.
!CLAUDE.md
!.gitignore
!.gitconfig
!.gitmodules
!README.md
!.editorconfig
!*.env
!.prettierrc
!.prettierignore
!package.json
!pnpm-workspace.yaml
!.nvmrc
!.ruby-version
!.python-version
!.pre-commit-config.yaml
!.rubocop.yml
!requirements.txt
!Gemfile
!ecosystem.config.js
!playbook.yml
!.p10k.zsh
!crates.yml
!flatpaks.yml
!eslint.config.mts
!.zprofile
!.zlogout
!.zlogin
!.zshrc
!.zshenv
!.hushlogin
!.last_pwd
!biome.json
!arty.yml
!/.github/
!/.github/**
!/.init/
!/.init/**
!.vscode/
!.vscode/settings.json
!.vscode/tasks.json
# Ignore so we won't commit these in the allowed dirctories.
.DS_Store
*.log*
*.db*
*.vscdb*
*.sqlite*
*.bnk*

0
.hushlogin Normal file
View File

17
.init/alias.sh Executable file
View File

@@ -0,0 +1,17 @@
#!/bin/bash
alias ri='source ~/.init/init.sh'
# git
alias g0='git add . && git diff --quiet && git diff --cached --quiet'
alias g1='git reset $(git commit-tree "HEAD^{tree}" -m "A new start")'
alias g2='git log --format=%B -n 1 HEAD | head -n 1'
# rsync
alias rs='rsync --rsync-path="sudo rsync" -avzhe ssh'
# serve static files
alias ss='python -m http.server 8000 -d'
# download youtube mp3
alias yt='yt-dlp -x --audio-format mp3'

0
.init/bin/.gitkeep Normal file
View File

View File

@@ -0,0 +1,477 @@
#!/usr/bin/env bash
#############################################################################
# GitHub Artifact Downloader
#
# Download and extract GitHub Actions artifacts with style
#
# Usage:
# artifact_github_download.sh <REPO> [OPTIONS]
#
# Arguments:
# REPO GitHub repository (owner/repo)
#
# Options:
# -n, --name NAME Artifact name to download (preselect)
# -o, --output DIR Output directory (default: current directory)
# -h, --help Show this help message
#
# Examples:
# artifact_github_download.sh valknarness/awesome
# artifact_github_download.sh valknarness/awesome -n awesome-database-latest
# artifact_github_download.sh valknarness/awesome -o ~/downloads
#############################################################################
set -euo pipefail
# ============================================================================
# Color Definitions
# ============================================================================
# Check if terminal supports colors
if [[ -t 1 ]] && command -v tput >/dev/null 2>&1; then
COLORS=$(tput colors 2>/dev/null || echo 0)
if [[ $COLORS -ge 8 ]]; then
# Standard colors
RED=$(tput setaf 1)
GREEN=$(tput setaf 2)
YELLOW=$(tput setaf 3)
BLUE=$(tput setaf 4)
MAGENTA=$(tput setaf 5)
CYAN=$(tput setaf 6)
WHITE=$(tput setaf 7)
# Bright colors
BRIGHT_GREEN=$(tput setaf 10 2>/dev/null || tput setaf 2)
BRIGHT_YELLOW=$(tput setaf 11 2>/dev/null || tput setaf 3)
BRIGHT_BLUE=$(tput setaf 12 2>/dev/null || tput setaf 4)
BRIGHT_MAGENTA=$(tput setaf 13 2>/dev/null || tput setaf 5)
BRIGHT_CYAN=$(tput setaf 14 2>/dev/null || tput setaf 6)
# Text formatting
BOLD=$(tput bold)
DIM=$(tput dim 2>/dev/null || echo "")
RESET=$(tput sgr0)
else
RED="" GREEN="" YELLOW="" BLUE="" MAGENTA="" CYAN="" WHITE=""
BRIGHT_GREEN="" BRIGHT_YELLOW="" BRIGHT_BLUE="" BRIGHT_MAGENTA="" BRIGHT_CYAN=""
BOLD="" DIM="" RESET=""
fi
else
RED="" GREEN="" YELLOW="" BLUE="" MAGENTA="" CYAN="" WHITE=""
BRIGHT_GREEN="" BRIGHT_YELLOW="" BRIGHT_BLUE="" BRIGHT_MAGENTA="" BRIGHT_CYAN=""
BOLD="" DIM="" RESET=""
fi
# ============================================================================
# Logging Functions
# ============================================================================
log_info() {
echo -e "${BRIGHT_BLUE}${BOLD}${RESET} ${CYAN}$*${RESET}" >&2
}
log_success() {
echo -e "${BRIGHT_GREEN}${BOLD}${RESET} ${GREEN}$*${RESET}" >&2
}
log_warning() {
echo -e "${BRIGHT_YELLOW}${BOLD}${RESET} ${YELLOW}$*${RESET}" >&2
}
log_error() {
echo -e "${RED}${BOLD}${RESET} ${RED}$*${RESET}" >&2
}
log_step() {
echo -e "${BRIGHT_MAGENTA}${BOLD}${RESET} ${MAGENTA}$*${RESET}" >&2
}
log_header() {
local text="$*"
local length=${#text}
local line=$(printf '═%.0s' $(seq 1 $length))
echo "" >&2
echo -e "${BRIGHT_CYAN}${BOLD}${line}${RESET}" >&2
echo -e "${BRIGHT_CYAN}${BOLD}${RESET}${BOLD}${WHITE}${text}${RESET}${BRIGHT_CYAN}${BOLD}${RESET}" >&2
echo -e "${BRIGHT_CYAN}${BOLD}${line}${RESET}" >&2
echo "" >&2
}
log_data() {
local label="$1"
local value="$2"
echo -e " ${DIM}${label}:${RESET} ${BOLD}${value}${RESET}" >&2
}
# ============================================================================
# Helper Functions
# ============================================================================
check_dependencies() {
local missing=()
if ! command -v gh &> /dev/null; then
missing+=("gh (GitHub CLI)")
fi
if ! command -v jq &> /dev/null; then
missing+=("jq")
fi
if ! command -v unzip &> /dev/null; then
missing+=("unzip")
fi
if [[ ${#missing[@]} -gt 0 ]]; then
log_error "Missing required dependencies:"
for dep in "${missing[@]}"; do
echo -e " ${RED}${RESET} ${dep}"
done
exit 1
fi
}
check_gh_auth() {
if ! gh auth status &> /dev/null; then
log_error "Not authenticated with GitHub CLI"
log_info "Run: ${BOLD}gh auth login${RESET}"
exit 1
fi
}
show_help() {
cat << EOF
${BOLD}${BRIGHT_CYAN}GitHub Artifact Downloader${RESET}
${BOLD}USAGE:${RESET}
$(basename "$0") ${CYAN}<REPO>${RESET} [${YELLOW}OPTIONS${RESET}]
${BOLD}ARGUMENTS:${RESET}
${CYAN}REPO${RESET} GitHub repository (${DIM}owner/repo${RESET})
${BOLD}OPTIONS:${RESET}
${YELLOW}-n, --name NAME${RESET} Artifact name to download (preselect)
${YELLOW}-o, --output DIR${RESET} Output directory (default: current directory)
${YELLOW}-h, --help${RESET} Show this help message
${BOLD}EXAMPLES:${RESET}
${DIM}# Interactive mode - list and select artifacts${RESET}
$(basename "$0") valknarness/awesome
${DIM}# Preselect artifact by name${RESET}
$(basename "$0") valknarness/awesome -n awesome-database-latest
${DIM}# Download to specific directory${RESET}
$(basename "$0") valknarness/awesome -o ~/downloads
${DIM}# Combine options${RESET}
$(basename "$0") valknarness/awesome -n awesome-database-latest -o ~/downloads
EOF
}
format_size() {
local bytes=$1
if (( bytes < 1024 )); then
echo "${bytes}B"
elif (( bytes < 1048576 )); then
awk "BEGIN {printf \"%.1fKB\", $bytes/1024}"
elif (( bytes < 1073741824 )); then
awk "BEGIN {printf \"%.1fMB\", $bytes/1048576}"
else
awk "BEGIN {printf \"%.2fGB\", $bytes/1073741824}"
fi
}
format_date() {
local iso_date="$1"
if command -v date &> /dev/null; then
if date --version &> /dev/null 2>&1; then
# GNU date
date -d "$iso_date" "+%Y-%m-%d %H:%M:%S" 2>/dev/null || echo "$iso_date"
else
# BSD date (macOS)
date -j -f "%Y-%m-%dT%H:%M:%SZ" "$iso_date" "+%Y-%m-%d %H:%M:%S" 2>/dev/null || echo "$iso_date"
fi
else
echo "$iso_date"
fi
}
# ============================================================================
# Main Functions
# ============================================================================
list_artifacts() {
local repo="$1"
log_step "Fetching artifacts from ${BOLD}${repo}${RESET}..."
# First check if there are any artifacts using gh's built-in jq
local count
count=$(gh api \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
--jq '.artifacts | length' \
"/repos/${repo}/actions/artifacts?per_page=100" 2>/dev/null)
if [[ -z "$count" ]]; then
log_error "Failed to fetch artifacts from repository"
log_info "Please check that:"
echo " • The repository ${BOLD}${repo}${RESET} exists and you have access"
echo " • GitHub Actions is enabled for this repository"
exit 1
fi
if [[ "$count" -eq 0 ]]; then
log_warning "No artifacts found in repository ${BOLD}${repo}${RESET}"
log_info "This repository may not have any workflow runs that produced artifacts"
exit 0
fi
# Now fetch the full JSON response
local artifacts_json
artifacts_json=$(gh api \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"/repos/${repo}/actions/artifacts?per_page=100" 2>/dev/null)
echo "$artifacts_json"
}
select_artifact() {
local artifacts_json="$1"
local preselect_name="$2"
# Parse artifacts
local artifacts
artifacts=$(echo "$artifacts_json" | jq -r '.artifacts[] |
"\(.id)|\(.name)|\(.size_in_bytes)|\(.created_at)|\(.workflow_run.id)"')
# If preselect name is provided, find matching artifact
if [[ -n "$preselect_name" ]]; then
local selected
selected=$(echo "$artifacts" | grep -F "|${preselect_name}|" | head -1)
if [[ -z "$selected" ]]; then
log_error "Artifact '${BOLD}${preselect_name}${RESET}' not found"
log_info "Available artifacts:"
echo "$artifacts" | while IFS='|' read -r id name size created workflow; do
echo " ${CYAN}${RESET} ${name}"
done
exit 1
fi
echo "$selected"
return 0
fi
# Interactive selection
log_info "Available artifacts:"
echo ""
local i=1
local -a artifact_array
while IFS='|' read -r id name size created workflow; do
artifact_array+=("$id|$name|$size|$created|$workflow")
local formatted_size=$(format_size "$size")
local formatted_date=$(format_date "$created")
printf " ${BOLD}${YELLOW}[%2d]${RESET} ${BRIGHT_CYAN}%s${RESET}\n" "$i" "$name"
printf " ${DIM}Size: ${RESET}%s ${DIM}Created: ${RESET}%s\n" "$formatted_size" "$formatted_date"
echo ""
((i++))
done <<< "$artifacts"
# Prompt for selection
local selection
while true; do
echo -n -e "${BRIGHT_MAGENTA}${BOLD}<EFBFBD>${RESET} ${MAGENTA}Select artifact [1-$((i-1))]:${RESET} "
read -r selection
if [[ "$selection" =~ ^[0-9]+$ ]] && [[ "$selection" -ge 1 ]] && [[ "$selection" -lt "$i" ]]; then
break
else
log_warning "Invalid selection. Please enter a number between 1 and $((i-1))"
fi
done
echo "${artifact_array[$((selection-1))]}"
}
download_artifact() {
local repo="$1"
local artifact_id="$2"
local artifact_name="$3"
local output_dir="$4"
log_step "Downloading artifact ${BOLD}${artifact_name}${RESET}..."
# Create output directory if it doesn't exist
mkdir -p "$output_dir"
# Download artifact using gh
local zip_file="${output_dir}/${artifact_name}.zip"
if gh api \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"/repos/${repo}/actions/artifacts/${artifact_id}/zip" \
> "$zip_file" 2>/dev/null; then
log_success "Downloaded to ${BOLD}${zip_file}${RESET}"
echo "$zip_file"
else
log_error "Failed to download artifact"
exit 1
fi
}
extract_artifact() {
local zip_file="$1"
local output_dir="$2"
log_step "Extracting archive..."
# Create extraction directory
local extract_dir="${output_dir}/$(basename "$zip_file" .zip)"
mkdir -p "$extract_dir"
if unzip -q "$zip_file" -d "$extract_dir"; then
log_success "Extracted to ${BOLD}${extract_dir}${RESET}"
# Show extracted files
log_info "Extracted files:"
find "$extract_dir" -type f -exec basename {} \; | while read -r file; do
echo " ${GREEN}${RESET} ${file}"
done
# Remove zip file
rm "$zip_file"
log_info "Cleaned up zip file"
echo "$extract_dir"
else
log_error "Failed to extract archive"
exit 1
fi
}
# ============================================================================
# Main Script
# ============================================================================
main() {
local repo=""
local artifact_name=""
local output_dir="."
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
show_help
exit 0
;;
-n|--name)
artifact_name="$2"
shift 2
;;
-o|--output)
output_dir="$2"
shift 2
;;
-*)
log_error "Unknown option: $1"
echo ""
show_help
exit 1
;;
*)
if [[ -z "$repo" ]]; then
repo="$1"
else
log_error "Unexpected argument: $1"
echo ""
show_help
exit 1
fi
shift
;;
esac
done
# Validate required arguments
if [[ -z "$repo" ]]; then
log_error "Repository argument is required"
echo ""
show_help
exit 1
fi
# Validate repository format
if [[ ! "$repo" =~ ^[^/]+/[^/]+$ ]]; then
log_error "Invalid repository format. Expected: ${BOLD}owner/repo${RESET}"
exit 1
fi
# Show header
log_header "GitHub Artifact Downloader"
# Check dependencies
log_step "Checking dependencies..."
check_dependencies
log_success "All dependencies found"
# Check GitHub authentication
log_step "Checking GitHub authentication..."
check_gh_auth
log_success "Authenticated with GitHub"
echo ""
log_data "Repository" "${BRIGHT_CYAN}${repo}${RESET}"
if [[ -n "$artifact_name" ]]; then
log_data "Artifact" "${BRIGHT_YELLOW}${artifact_name}${RESET}"
fi
log_data "Output" "${BRIGHT_GREEN}${output_dir}${RESET}"
echo ""
# List artifacts
local artifacts_json
artifacts_json=$(list_artifacts "$repo")
# Select artifact
local selected
selected=$(select_artifact "$artifacts_json" "$artifact_name")
IFS='|' read -r artifact_id name size created workflow <<< "$selected"
echo ""
log_info "Selected artifact:"
log_data " Name" "${BRIGHT_CYAN}${name}${RESET}"
log_data " Size" "$(format_size "$size")"
log_data " Created" "$(format_date "$created")"
echo ""
# Download artifact
local zip_file
zip_file=$(download_artifact "$repo" "$artifact_id" "$name" "$output_dir")
# Extract artifact
local extract_dir
extract_dir=$(extract_artifact "$zip_file" "$output_dir")
# Success summary
echo ""
log_header "Download Complete!"
log_data "Location" "${BOLD}${extract_dir}${RESET}"
echo ""
log_success "All done! 🎉"
}
# Run main function
main "$@"

592
.init/bin/mime_mp4_gif.sh Executable file
View File

@@ -0,0 +1,592 @@
#!/usr/bin/env bash
# mime_mp4_gif.sh - Advanced MP4 to Animated GIF converter
# Converts MP4 videos to GIFs with sophisticated keyframe extraction,
# interpolation algorithms, and scheduling distributions
set -euo pipefail
# Default values
KEYFRAMES=10
INPUT_SCHEDULES=1
TRANSITION="linear"
SCHEDULE="uniform"
MAGIC="none"
KEYFRAME_DURATION=100
INPUT_FILE=""
OUTPUT_FILE=""
VERBOSE=false
# Color codes for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Available algorithms
TRANSITIONS=("linear" "sinoid" "cubic" "quadratic" "exponential" "bounce" "elastic")
SCHEDULES=("uniform" "front-load" "back-load" "center-peak" "edge-peak" "fibonacci" "golden-ratio")
MAGICS=("none" "psychedelic" "dither-bloom" "edge-glow" "temporal-blur" "chromatic-shift" "vaporwave")
#############################################################################
# Helper Functions
#############################################################################
print_usage() {
cat << EOF
Usage: $(basename "$0") [OPTIONS] INPUT_FILE [OUTPUT_FILE]
Convert MP4 videos to animated GIFs with advanced frame extraction algorithms.
Arguments:
INPUT_FILE Input MP4 video file (required)
OUTPUT_FILE Output GIF file (optional, defaults to INPUT_FILE.gif)
Options:
-k, --keyframes N Number of keyframes to extract (default: 10)
-d, --keyframe-duration MS Duration of each frame in milliseconds (default: 100)
Valid range: 1-30000 ms
Lower values = faster animation
Higher values = slower animation
-i, --input-schedules N Number of input schedules (default: 1)
1 schedule = entire video duration
N schedules = divide video into N segments
-t, --transition TYPE Interpolation function for frame timing
Available: ${TRANSITIONS[*]}
(default: linear)
-s, --schedule TYPE Algorithm to distribute keyframes across schedules
Available: ${SCHEDULES[*]}
(default: uniform)
-m, --magic TYPE Apply magical effects to the GIF
Available: ${MAGICS[*]}
(default: none)
-v, --verbose Enable verbose output
-h, --help Show this help message
Examples:
# Basic conversion with 15 keyframes
$(basename "$0") -k 15 video.mp4
# Fast animation with 50ms per frame
$(basename "$0") -k 20 -d 50 video.mp4
# Slow animation with 500ms per frame
$(basename "$0") -k 10 -d 500 video.mp4
# Use sinusoidal transition with center-peak distribution
$(basename "$0") -t sinoid -s center-peak -k 20 video.mp4
# Apply psychedelic magic with fibonacci distribution
$(basename "$0") -m psychedelic -s fibonacci -k 13 video.mp4 trippy.gif
# Complex: 3 schedules with cubic interpolation and edge glow
$(basename "$0") -i 3 -t cubic -s front-load -m edge-glow -k 30 video.mp4
EOF
}
log_info() {
echo -e "${BLUE}[INFO]${NC} $*"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $*"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $*"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $*" >&2
}
verbose_log() {
if [[ "$VERBOSE" == "true" ]]; then
log_info "$@"
fi
}
validate_enum() {
local value="$1"
local array_name="$2"
local -n arr=$array_name
for item in "${arr[@]}"; do
if [[ "$value" == "$item" ]]; then
return 0
fi
done
return 1
}
#############################################################################
# Mathematical Functions
#############################################################################
# Calculate transition weight based on interpolation type
# Input: progress (0.0 to 1.0), Returns: weighted value (0.0 to 1.0)
calculate_transition() {
local progress="$1"
local type="$2"
case "$type" in
linear)
echo "$progress"
;;
sinoid)
# Smooth sinusoidal easing
awk -v p="$progress" 'BEGIN { print (1 - cos(p * 3.14159265359)) / 2 }'
;;
cubic)
# Cubic easing in-out
awk -v p="$progress" 'BEGIN {
if (p < 0.5)
print 4 * p * p * p;
else
print 1 - ((-2 * p + 2) ^ 3) / 2;
}'
;;
quadratic)
# Quadratic easing
awk -v p="$progress" 'BEGIN {
if (p < 0.5)
print 2 * p * p;
else
print 1 - ((-2 * p + 2) ^ 2) / 2;
}'
;;
exponential)
# Exponential easing
awk -v p="$progress" 'BEGIN {
if (p == 0) print 0;
else if (p == 1) print 1;
else if (p < 0.5) print (2 ^ (20 * p - 10)) / 2;
else print (2 - (2 ^ (-20 * p + 10))) / 2;
}'
;;
bounce)
# Bouncing effect
awk -v p="$progress" 'BEGIN {
n1 = 7.5625; d1 = 2.75;
x = 1 - p;
if (x < 1/d1) result = n1 * x * x;
else if (x < 2/d1) { x -= 1.5/d1; result = n1 * x * x + 0.75; }
else if (x < 2.5/d1) { x -= 2.25/d1; result = n1 * x * x + 0.9375; }
else { x -= 2.625/d1; result = n1 * x * x + 0.984375; }
print 1 - result;
}'
;;
elastic)
# Elastic spring effect
awk -v p="$progress" 'BEGIN {
c4 = (2 * 3.14159265359) / 3;
if (p == 0) print 0;
else if (p == 1) print 1;
else if (p < 0.5) print -(2 ^ (20 * p - 10) * sin((20 * p - 11.125) * c4)) / 2;
else print (2 ^ (-20 * p + 10) * sin((20 * p - 11.125) * c4)) / 2 + 1;
}'
;;
*)
echo "$progress"
;;
esac
}
# Generate keyframe distribution based on schedule type
generate_schedule_distribution() {
local num_frames="$1"
local schedule_type="$2"
local -n result_array=$3
case "$schedule_type" in
uniform)
for ((i=0; i<num_frames; i++)); do
result_array[$i]=$(awk -v i="$i" -v n="$num_frames" 'BEGIN { print i / (n - 1) }')
done
;;
front-load)
# More frames at the beginning
for ((i=0; i<num_frames; i++)); do
local t=$(awk -v i="$i" -v n="$num_frames" 'BEGIN { print i / (n - 1) }')
result_array[$i]=$(awk -v t="$t" 'BEGIN { print t * t }')
done
;;
back-load)
# More frames at the end
for ((i=0; i<num_frames; i++)); do
local t=$(awk -v i="$i" -v n="$num_frames" 'BEGIN { print i / (n - 1) }')
result_array[$i]=$(awk -v t="$t" 'BEGIN { print 1 - (1 - t) * (1 - t) }')
done
;;
center-peak)
# More frames in the middle
for ((i=0; i<num_frames; i++)); do
local t=$(awk -v i="$i" -v n="$num_frames" 'BEGIN { print i / (n - 1) }')
result_array[$i]=$(awk -v t="$t" 'BEGIN { print 1 - 4 * (t - 0.5) * (t - 0.5) }')
result_array[$i]=$(awk -v val="${result_array[$i]}" -v t="$t" 'BEGIN { print t }')
done
;;
edge-peak)
# More frames at start and end
for ((i=0; i<num_frames; i++)); do
local t=$(awk -v i="$i" -v n="$num_frames" 'BEGIN { print i / (n - 1) }')
result_array[$i]=$(awk -v t="$t" 'BEGIN { print 4 * (t - 0.5) * (t - 0.5) }')
result_array[$i]=$(awk -v val="${result_array[$i]}" -v t="$t" 'BEGIN { print t }')
done
;;
fibonacci)
# Fibonacci sequence distribution
local fib=(1 1)
for ((i=2; i<num_frames; i++)); do
fib[$i]=$((fib[i-1] + fib[i-2]))
done
local sum=0
for val in "${fib[@]}"; do
((sum += val))
done
local cumsum=0
for ((i=0; i<num_frames; i++)); do
((cumsum += fib[i]))
result_array[$i]=$(awk -v c="$cumsum" -v s="$sum" 'BEGIN { print c / s }')
done
;;
golden-ratio)
# Golden ratio distribution
local phi=1.618033988749895
for ((i=0; i<num_frames; i++)); do
result_array[$i]=$(awk -v i="$i" -v n="$num_frames" -v phi="$phi" 'BEGIN {
print ((i * phi) - int(i * phi))
}')
done
# Sort the array for monotonic distribution
IFS=$'\n' result_array=($(sort -n <<<"${result_array[*]}"))
;;
*)
# Default to uniform
for ((i=0; i<num_frames; i++)); do
result_array[$i]=$(awk -v i="$i" -v n="$num_frames" 'BEGIN { print i / (n - 1) }')
done
;;
esac
}
#############################################################################
# Video Processing Functions
#############################################################################
get_video_duration() {
local file="$1"
ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$file"
}
extract_frames() {
local input="$1"
local duration="$2"
local -n ts_ref=$3
local temp_dir="$4"
verbose_log "Extracting ${#ts_ref[@]} frames from video..."
for i in "${!ts_ref[@]}"; do
local time="${ts_ref[$i]}"
verbose_log " Frame $((i+1)): ${time}s"
ffmpeg -v quiet -ss "$time" -i "$input" -vframes 1 \
-vf "scale=480:-1:flags=lanczos" \
"${temp_dir}/frame_$(printf "%04d" "$i").png" 2>/dev/null
done
}
apply_magic_effects() {
local magic_type="$1"
local temp_dir="$2"
if [[ "$magic_type" == "none" ]]; then
return 0
fi
verbose_log "Applying magic effect: $magic_type"
case "$magic_type" in
psychedelic)
for frame in "$temp_dir"/*.png; do
ffmpeg -v quiet -i "$frame" -vf "hue=s=3:h=sin(2*PI*t)*360" \
"${frame}.tmp.png" 2>/dev/null && mv "${frame}.tmp.png" "$frame"
done
;;
dither-bloom)
for frame in "$temp_dir"/*.png; do
ffmpeg -v quiet -i "$frame" -vf "format=gbrp,split[a][b],[a]negate[c],[b][c]blend=all_mode=xor,noise=alls=20:allf=t" \
"${frame}.tmp.png" 2>/dev/null && mv "${frame}.tmp.png" "$frame"
done
;;
edge-glow)
for frame in "$temp_dir"/*.png; do
ffmpeg -v quiet -i "$frame" -vf "edgedetect=low=0.1:high=0.3,negate,hue=s=2" \
"${temp_dir}/edges_$(basename "$frame")"
ffmpeg -v quiet -i "$frame" -i "${temp_dir}/edges_$(basename "$frame")" \
-filter_complex "[0:v][1:v]blend=all_mode=addition:all_opacity=0.5" \
"${frame}.tmp.png" 2>/dev/null && mv "${frame}.tmp.png" "$frame"
rm "${temp_dir}/edges_$(basename "$frame")"
done
;;
temporal-blur)
# Create motion blur effect
local frames=("$temp_dir"/*.png)
for i in "${!frames[@]}"; do
local prev_idx=$((i > 0 ? i - 1 : 0))
local next_idx=$((i < ${#frames[@]} - 1 ? i + 1 : ${#frames[@]} - 1))
ffmpeg -v quiet -i "${frames[$prev_idx]}" -i "${frames[$i]}" -i "${frames[$next_idx]}" \
-filter_complex "[0:v][1:v][2:v]blend=all_mode=average" \
"${frames[$i]}.tmp.png" 2>/dev/null && mv "${frames[$i]}.tmp.png" "${frames[$i]}"
done
;;
chromatic-shift)
for frame in "$temp_dir"/*.png; do
ffmpeg -v quiet -i "$frame" -vf "rgbashift=rh=5:bh=-5" \
"${frame}.tmp.png" 2>/dev/null && mv "${frame}.tmp.png" "$frame"
done
;;
vaporwave)
for frame in "$temp_dir"/*.png; do
ffmpeg -v quiet -i "$frame" -vf "curves=vintage,hue=h=300:s=1.5,eq=saturation=1.5:contrast=1.2" \
"${frame}.tmp.png" 2>/dev/null && mv "${frame}.tmp.png" "$frame"
done
;;
esac
}
create_gif() {
local temp_dir="$1"
local output="$2"
local frame_delay="$3"
verbose_log "Creating animated GIF with ${frame_delay}ms per frame..."
# Convert milliseconds to centiseconds (GIF delay unit)
local delay_cs
delay_cs=$(awk -v ms="$frame_delay" 'BEGIN { print int(ms / 10) }')
# Ensure minimum delay of 1 centisecond
if [[ $delay_cs -lt 1 ]]; then
delay_cs=1
fi
# Calculate input framerate (frames are read at this rate)
# For GIF delay, we want 1000ms / frame_delay fps
local fps
fps=$(awk -v ms="$frame_delay" 'BEGIN { printf "%.2f", 1000.0 / ms }')
verbose_log "Frame delay: ${delay_cs} centiseconds (${frame_delay}ms), FPS: ${fps}"
# Generate palette for better color quality
ffmpeg -v error -pattern_type glob -i "${temp_dir}/frame_*.png" \
-vf "scale=480:-1:flags=lanczos,palettegen=stats_mode=diff" \
-y "${temp_dir}/palette.png"
# Create GIF using palette with specified frame delay
ffmpeg -v error -framerate "$fps" -pattern_type glob -i "${temp_dir}/frame_*.png" -i "${temp_dir}/palette.png" \
-filter_complex "[0:v]scale=480:-1:flags=lanczos[scaled];[scaled][1:v]paletteuse=dither=bayer:bayer_scale=5" \
-gifflags +transdiff -y "$output"
}
#############################################################################
# Main Processing
#############################################################################
process_video() {
local input="$INPUT_FILE"
local output="$OUTPUT_FILE"
# Validate input file
if [[ ! -f "$input" ]]; then
log_error "Input file not found: $input"
exit 1
fi
# Get video duration
local duration
duration=$(get_video_duration "$input")
verbose_log "Video duration: ${duration}s"
# Calculate schedule duration
local schedule_duration
schedule_duration=$(awk -v d="$duration" -v s="$INPUT_SCHEDULES" 'BEGIN { print d / s }')
verbose_log "Schedule duration: ${schedule_duration}s (${INPUT_SCHEDULES} schedule(s))"
# Generate frame distribution
local -a distribution
generate_schedule_distribution "$KEYFRAMES" "$SCHEDULE" distribution
verbose_log "Using schedule: $SCHEDULE"
verbose_log "Using transition: $TRANSITION"
# Calculate actual timestamps with transition function
local -a timestamps
for i in "${!distribution[@]}"; do
local base_time="${distribution[$i]}"
local weighted_time
weighted_time=$(calculate_transition "$base_time" "$TRANSITION")
# Map to video duration considering input schedules
local actual_time
actual_time=$(awk -v w="$weighted_time" -v d="$duration" 'BEGIN { print w * d }')
# Ensure we don't exceed video duration
timestamps[$i]=$(awk -v t="$actual_time" -v d="$duration" 'BEGIN {
if (t > d) print d;
else print t;
}')
done
# Create temporary directory
local temp_dir
temp_dir=$(mktemp -d)
trap "rm -rf '$temp_dir'" EXIT
# Extract frames
extract_frames "$input" "$duration" timestamps "$temp_dir"
# Apply magic effects
apply_magic_effects "$MAGIC" "$temp_dir"
# Create GIF with specified frame duration
create_gif "$temp_dir" "$output" "$KEYFRAME_DURATION"
log_success "GIF created successfully: $output"
# Show file size
local size
size=$(du -h "$output" | cut -f1)
log_info "Output size: $size"
}
#############################################################################
# Command Line Parsing
#############################################################################
parse_arguments() {
while [[ $# -gt 0 ]]; do
case "$1" in
-k|--keyframes)
KEYFRAMES="$2"
shift 2
;;
-d|--keyframe-duration)
KEYFRAME_DURATION="$2"
shift 2
;;
-i|--input-schedules)
INPUT_SCHEDULES="$2"
shift 2
;;
-t|--transition)
TRANSITION="$2"
if ! validate_enum "$TRANSITION" TRANSITIONS; then
log_error "Invalid transition type: $TRANSITION"
log_error "Available: ${TRANSITIONS[*]}"
exit 1
fi
shift 2
;;
-s|--schedule)
SCHEDULE="$2"
if ! validate_enum "$SCHEDULE" SCHEDULES; then
log_error "Invalid schedule type: $SCHEDULE"
log_error "Available: ${SCHEDULES[*]}"
exit 1
fi
shift 2
;;
-m|--magic)
MAGIC="$2"
if ! validate_enum "$MAGIC" MAGICS; then
log_error "Invalid magic type: $MAGIC"
log_error "Available: ${MAGICS[*]}"
exit 1
fi
shift 2
;;
-v|--verbose)
VERBOSE=true
shift
;;
-h|--help)
print_usage
exit 0
;;
-*)
log_error "Unknown option: $1"
print_usage
exit 1
;;
*)
if [[ -z "$INPUT_FILE" ]]; then
INPUT_FILE="$1"
elif [[ -z "$OUTPUT_FILE" ]]; then
OUTPUT_FILE="$1"
else
log_error "Too many arguments"
print_usage
exit 1
fi
shift
;;
esac
done
# Validate required arguments
if [[ -z "$INPUT_FILE" ]]; then
log_error "Input file is required"
print_usage
exit 1
fi
# Set default output file
if [[ -z "$OUTPUT_FILE" ]]; then
OUTPUT_FILE="${INPUT_FILE%.*}.gif"
fi
# Validate numeric arguments
if ! [[ "$KEYFRAMES" =~ ^[0-9]+$ ]] || [[ "$KEYFRAMES" -lt 2 ]]; then
log_error "Keyframes must be a positive integer >= 2"
exit 1
fi
if ! [[ "$KEYFRAME_DURATION" =~ ^[0-9]+$ ]] || [[ "$KEYFRAME_DURATION" -lt 1 ]] || [[ "$KEYFRAME_DURATION" -gt 30000 ]]; then
log_error "Keyframe duration must be an integer between 1 and 30000 milliseconds"
exit 1
fi
if ! [[ "$INPUT_SCHEDULES" =~ ^[0-9]+$ ]] || [[ "$INPUT_SCHEDULES" -lt 1 ]]; then
log_error "Input schedules must be a positive integer >= 1"
exit 1
fi
}
#############################################################################
# Entry Point
#############################################################################
main() {
parse_arguments "$@"
log_info "Starting MP4 to GIF conversion..."
log_info "Configuration:"
log_info " Input: $INPUT_FILE"
log_info " Output: $OUTPUT_FILE"
log_info " Keyframes: $KEYFRAMES"
log_info " Frame Duration: ${KEYFRAME_DURATION}ms"
log_info " Schedules: $INPUT_SCHEDULES"
log_info " Transition: $TRANSITION"
log_info " Schedule: $SCHEDULE"
log_info " Magic: $MAGIC"
process_video
}
# Run main function
main "$@"

13
.init/eval.sh Executable file
View File

@@ -0,0 +1,13 @@
#!/bin/bash
if command -v oh-my-posh 2>&1 >/dev/null; then
eval "$(! oh-my-posh init zsh --config=~/worker.omp.json)"
fi
if command -v rbenv 2>&1 >/dev/null; then
eval "$(rbenv init - --no-rehash zsh)"
fi
if command -v pyenv 2>&1 >/dev/null; then
eval "$(pyenv init --path)"
fi

5
.init/export.sh Executable file
View File

@@ -0,0 +1,5 @@
#!/bin/bash
export NVM_DIR="$HOME/.nvm"
export REPOS_DIR="$HOME/repos"
export CHORE_CHORE="chore: chore"

116
.init/functions.sh Executable file
View File

@@ -0,0 +1,116 @@
#!/bin/bash
is_ssh() {
IS_SSH=$(cat /proc/$PPID/status | head -1 | cut -f2)
if [ "$_IS_SSH" = "sshd-session" ]; then
return 1
else
return 0
fi
}
_home_push() {
git add -A
git commit -m "${1:-$CHORE_CHORE}"
git push $2 $3
}
_home_pull() {
[ -n $(is_ssh) ] && git checkout $HOME/.last_pwd
git stash
git pull $1 $2
git stash pop
}
_site_deploy_jekyll() {
cd "$HOME/repos/$1"
rm -rf _site
JEKYLL_ENV=production bundle exec jekyll build
rsync -avzhe ssh _site/ "pi@hive:$DOCKER_STORAGE_DIR/staticwebserver/hosts/$1/" --delete
cd -
}
_site_deploy_nuxt() {
cd "$HOME/repos/$1"
rm -rf .output
npm run generate
rsync -avzhe ssh .output/public/ "pi@hive:$DOCKER_STORAGE_DIR/staticwebserver/hosts/$1/" --delete
cd -
}
_site_deploy_static() {
cd "$HOME/repos/$1"
rsync -avzhe ssh src/ "pi@hive:$DOCKER_STORAGE_DIR/staticwebserver/hosts/$1/" --delete
cd -
}
_site_run_jekyll() {
cd "$HOME/repos/$1"
bundle exec jekyll serve --livereload
cd -
}
_site_run_nuxt() {
cd "$HOME/repos/$1"
npm run dev
cd -
}
_site_run_static() {
cd "$HOME/repos/$1"
python -m http.server 8000 -d src
cd -
}
batch_file_sequence() {
a=0
for i in *.$2; do
new=$(printf "$1-%03d.$2" "$a")
mv -i -- "$i" "$new"
let a="$a+1"
done
}
batch_image_webp() {
find . -type f -regex ".*\.\(jpg\|jpeg\|png\)" -exec mogrify -format webp {} \; -print
find . -type f -regex ".*\.\(jpg\|jpeg\|png\)" -exec rm {} \; -print
}
batch_video_x264() {
find . -type f -regex ".*\.\(mp4\)" -exec ffmpeg -i {} -vcodec libx264 -crf 24 "{}.mp4" \; -print
find . -type f -regex ".+mp4\.mp4" -exec python3 -c "import os;os.rename('{}', '{}'[:-4])" \; -print
}
_image_description() {
identify -verbose $1 | grep ImageDescription | sed "s/ exif:ImageDescription: //"
}
_image_optimize() {
i_x4 && cp -rf x4/* . && i_x05 && cp -rf x05/* . && _file_sequence $1 webp && mv $1-000.webp $1.webp
_image_description *.png
rm -rf *.png x4 x05
}
_video_optimize() {
filename=$(basename -- "$1")
extension="${filename##*.}"
filename="${filename%.*}"
ffmpeg -y -i $1 -vf "setpts=1.25*PTS" -r 24 "$filename.mp4"
}
function _over_subdirs {
_PWD=$PWD
. $PWD/.env
for D in $(find . -mindepth 1 -maxdepth 1 -type d); do
cd "$D" && $1
cd $_PWD
done
}
_join_by() {
local d=${1-} f=${2-}
if shift 2; then
printf %s "$f" "${@/#/$d}"
fi
}

0
.init/hooks/.gitkeep Normal file
View File

41
.init/init.sh Executable file
View File

@@ -0,0 +1,41 @@
#!/bin/bash
if [ -f "$HOME/.init/path.sh" ] ; then
. "$HOME/.init/path.sh"
fi
if [ -f "$HOME/.init/export.sh" ] ; then
. "$HOME/.init/export.sh"
fi
if [ -f "$HOME/.init/alias.sh" ] ; then
. "$HOME/.init/alias.sh"
fi
if [ -f "$HOME/.init/source.sh" ] ; then
. "$HOME/.init/source.sh"
fi
if [ -f "$HOME/.init/functions.sh" ] ; then
. "$HOME/.init/functions.sh"
fi
if [ -f "$HOME/.init/links.sh" ] ; then
. "$HOME/.init/links.sh"
fi
if [ -f "$HOME/.init/source.sh" ] ; then
. "$HOME/.init/source.sh"
fi
if [ -f "$HOME/.init/eval.sh" ] ; then
. "$HOME/.init/eval.sh"
fi
if [ -f "$HOME/.init/trap.sh" ] ; then
. "$HOME/.init/trap.sh"
fi
if [ -f "$HOME/.init/start.sh" ] ; then
. "$HOME/.init/start.sh"
fi

1
.init/links.sh Executable file
View File

@@ -0,0 +1 @@
#!/bin/bash

66
.init/path.sh Executable file
View File

@@ -0,0 +1,66 @@
#!/bin/bash
if [ -d "$HOME/bin" ]; then
export PATH="$HOME/bin:$PATH"
fi
if [ -d "$HOME/.local/bin" ]; then
export PATH="$HOME/.local/bin:$PATH"
fi
if [ -d "$HOME/.rvm/bin" ]; then
export PATH="$HOME/.rvm/bin:$PATH"
fi
if [ -d "$HOME/repos/flutter/bin" ]; then
export PATH="$HOME/repos/flutter/bin:$PATH"
fi
if [ -d "$HOME/.rbenv/bin" ]; then
export PATH="$PATH:$HOME/.rbenv/bin"
fi
if [ -d "$HOME/.pyenv/bin" ]; then
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
fi
if [ -d "$HOME/.cargo/bin" ]; then
export PATH="$PATH:$HOME/.cargo/bin"
fi
if [ -d "/opt/Upscayl/resources/bin" ]; then
export PATH="$PATH:/opt/Upscayl/resources/bin"
fi
if [ -d "/usr/local/go/bin" ]; then
export PATH="$PATH:/usr/local/go/bin"
fi
if [ -d "$HOME/go/bin" ]; then
export PATH="$PATH:$HOME/go/bin"
fi
if [ -d "$HOME/node_modules/.bin" ]; then
export PATH="$PATH:$HOME/node_modules/.bin"
fi
if [ -d "$HOME/miniconda3/bin" ]; then
export PATH="$PATH:$HOME/miniconda3/bin"
fi
if [ -d "$HOME/.local/share/flatpak/exports/share" ] ; then
export XDG_DATA_DIRS="$XDG_DATA_DIRS:$HOME/.local/share/flatpak/exports/share"
fi
if [ -d "/var/lib/flatpak/exports/share" ] ; then
export XDG_DATA_DIRS="$XDG_DATA_DIRS:/var/lib/flatpak/exports/share"
fi
if [ -d "$HOME/.init/bin" ] ; then
export PATH="$PATH:$HOME/.init/bin"
fi
if [ -d "$HOME/Projects/kompose" ] ; then
export PATH="$PATH:$HOME/Projects/kompose"
fi

28
.init/source.sh Executable file
View File

@@ -0,0 +1,28 @@
#!/bin/bash
if [ -n "$BASH_VERSION" ]; then
# include .bashrc if it exists
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi
if [ -s "$NVM_DIR/nvm.sh" ] ; then
. "$NVM_DIR/nvm.sh"
fi
if [ -s "$NVM_DIR/bash_completion" ] ; then
. "$NVM_DIR/bash_completion"
fi
if [ -s "$HOME/.rvm/scripts/rvm" ] ; then
. "$HOME/.rvm/scripts/rvm"
fi
if [ -s "$HOME/.cargo/env" ] ; then
. "$HOME/.cargo/env"
fi
# if [ -s "$HOME/.gvm/scripts/gvm" ]; then
# . "$HOME/.gvm/scripts/gvm"
# fi

26
.init/start.sh Executable file
View File

@@ -0,0 +1,26 @@
#!/bin/bash
ssh-add &>/dev/null
# SSH_ENV="$HOME/.ssh/agent-environment"
# function start_agent {
# echo "Initialising new SSH agent..."
# /usr/bin/ssh-agent | sed 's/^echo/#echo/' >"$SSH_ENV"
# echo succeeded
# chmod 600 "$SSH_ENV"
# . "$SSH_ENV" >/dev/null
# /usr/bin/ssh-add;
# }
# # Source SSH settings, if applicable
# if [ -f "$SSH_ENV" ]; then
# . "$SSH_ENV" >/dev/null
# #ps $SSH_AGENT_PID doesn't work under Cygwin
# ps -ef | grep $SSH_AGENT_PID | grep ssh-agent$ >/dev/null || {
# start_agent
# }
# else
# start_agent
# fi

13
.init/trap.sh Executable file
View File

@@ -0,0 +1,13 @@
#!/bin/bash
TRAPINT() {
}
TRAPQUIT() {
}
TRAPTERM() {
}
TRAPEXIT() {
}

1
.last_pwd Normal file
View File

@@ -0,0 +1 @@
repos/sexy.pivoine.art

1
.nvmrc Normal file
View File

@@ -0,0 +1 @@
v20.19.1

193
.p10k.zsh Normal file
View File

@@ -0,0 +1,193 @@
# Generated by Powerlevel10k configuration wizard on 2025-09-04 at 02:33 CEST.
# Based on romkatv/powerlevel10k/config/p10k-pure.zsh, checksum 07533.
# Wizard options: nerdfont-v3 + powerline, small icons, pure, snazzy, 24h time, 1 line,
# compact, instant_prompt=verbose.
# Type `p10k configure` to generate another config.
#
# Config file for Powerlevel10k with the style of Pure (https://github.com/sindresorhus/pure).
#
# Differences from Pure:
#
# - Git:
# - `@c4d3ec2c` instead of something like `v1.4.0~11` when in detached HEAD state.
# - No automatic `git fetch` (the same as in Pure with `PURE_GIT_PULL=0`).
#
# Apart from the differences listed above, the replication of Pure prompt is exact. This includes
# even the questionable parts. For example, just like in Pure, there is no indication of Git status
# being stale; prompt symbol is the same in command, visual and overwrite vi modes; when prompt
# doesn't fit on one line, it wraps around with no attempt to shorten it.
#
# If you like the general style of Pure but not particularly attached to all its quirks, type
# `p10k configure` and pick "Lean" style. This will give you slick minimalist prompt while taking
# advantage of Powerlevel10k features that aren't present in Pure.
# Temporarily change options.
'builtin' 'local' '-a' 'p10k_config_opts'
[[ ! -o 'aliases' ]] || p10k_config_opts+=('aliases')
[[ ! -o 'sh_glob' ]] || p10k_config_opts+=('sh_glob')
[[ ! -o 'no_brace_expand' ]] || p10k_config_opts+=('no_brace_expand')
'builtin' 'setopt' 'no_aliases' 'no_sh_glob' 'brace_expand'
() {
emulate -L zsh -o extended_glob
# Unset all configuration options.
unset -m '(POWERLEVEL9K_*|DEFAULT_USER)~POWERLEVEL9K_GITSTATUS_DIR'
# Zsh >= 5.1 is required.
[[ $ZSH_VERSION == (5.<1->*|<6->.*) ]] || return
# Prompt colors.
local grey='242'
local red='#FF5C57'
local yellow='#F3F99D'
local blue='#57C7FF'
local magenta='#FF6AC1'
local cyan='#9AEDFE'
local white='#F1F1F0'
# Left prompt segments.
typeset -g POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(
context # user@host
dir # current directory
vcs # git status
command_execution_time # previous command duration
# virtualenv # python virtual environment
prompt_char # prompt symbol
)
# Right prompt segments.
typeset -g POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=(
# command_execution_time # previous command duration
# virtualenv # python virtual environment
# context # user@host
time # current time
)
# Basic style options that define the overall prompt look.
typeset -g POWERLEVEL9K_BACKGROUND= # transparent background
typeset -g POWERLEVEL9K_{LEFT,RIGHT}_{LEFT,RIGHT}_WHITESPACE= # no surrounding whitespace
typeset -g POWERLEVEL9K_{LEFT,RIGHT}_SUBSEGMENT_SEPARATOR=' ' # separate segments with a space
typeset -g POWERLEVEL9K_{LEFT,RIGHT}_SEGMENT_SEPARATOR= # no end-of-line symbol
typeset -g POWERLEVEL9K_VISUAL_IDENTIFIER_EXPANSION= # no segment icons
# Add an empty line before each prompt except the first. This doesn't emulate the bug
# in Pure that makes prompt drift down whenever you use the Alt-C binding from fzf or similar.
typeset -g POWERLEVEL9K_PROMPT_ADD_NEWLINE=false
# Magenta prompt symbol if the last command succeeded.
typeset -g POWERLEVEL9K_PROMPT_CHAR_OK_{VIINS,VICMD,VIVIS}_FOREGROUND=$magenta
# Red prompt symbol if the last command failed.
typeset -g POWERLEVEL9K_PROMPT_CHAR_ERROR_{VIINS,VICMD,VIVIS}_FOREGROUND=$red
# Default prompt symbol.
typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIINS_CONTENT_EXPANSION=''
# Prompt symbol in command vi mode.
typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VICMD_CONTENT_EXPANSION=''
# Prompt symbol in visual vi mode is the same as in command mode.
typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIVIS_CONTENT_EXPANSION=''
# Prompt symbol in overwrite vi mode is the same as in command mode.
typeset -g POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE=false
# Grey Python Virtual Environment.
typeset -g POWERLEVEL9K_VIRTUALENV_FOREGROUND=$grey
# Don't show Python version.
typeset -g POWERLEVEL9K_VIRTUALENV_SHOW_PYTHON_VERSION=false
typeset -g POWERLEVEL9K_VIRTUALENV_{LEFT,RIGHT}_DELIMITER=
# Blue current directory.
typeset -g POWERLEVEL9K_DIR_FOREGROUND=$blue
# Context format when root: user@host. The first part white, the rest grey.
typeset -g POWERLEVEL9K_CONTEXT_ROOT_TEMPLATE="%F{$white}%n%f%F{$grey}@%m%f"
# Context format when not root: user@host. The whole thing grey.
typeset -g POWERLEVEL9K_CONTEXT_TEMPLATE="%F{$grey}%n@%m%f"
# Don't show context unless root or in SSH.
typeset -g POWERLEVEL9K_CONTEXT_{DEFAULT,SUDO}_CONTENT_EXPANSION=
# Show previous command duration only if it's >= 5s.
typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_THRESHOLD=5
# Don't show fractional seconds. Thus, 7s rather than 7.3s.
typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_PRECISION=0
# Duration format: 1d 2h 3m 4s.
typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FORMAT='d h m s'
# Yellow previous command duration.
typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FOREGROUND=$yellow
# Grey Git prompt. This makes stale prompts indistinguishable from up-to-date ones.
typeset -g POWERLEVEL9K_VCS_FOREGROUND=$grey
# Disable async loading indicator to make directories that aren't Git repositories
# indistinguishable from large Git repositories without known state.
typeset -g POWERLEVEL9K_VCS_LOADING_TEXT=
# Don't wait for Git status even for a millisecond, so that prompt always updates
# asynchronously when Git state changes.
typeset -g POWERLEVEL9K_VCS_MAX_SYNC_LATENCY_SECONDS=0
# Cyan ahead/behind arrows.
typeset -g POWERLEVEL9K_VCS_{INCOMING,OUTGOING}_CHANGESFORMAT_FOREGROUND=$cyan
# Don't show remote branch, current tag or stashes.
typeset -g POWERLEVEL9K_VCS_GIT_HOOKS=(vcs-detect-changes git-untracked git-aheadbehind)
# Don't show the branch icon.
typeset -g POWERLEVEL9K_VCS_BRANCH_ICON=
# When in detached HEAD state, show @commit where branch normally goes.
typeset -g POWERLEVEL9K_VCS_COMMIT_ICON='@'
# Don't show staged, unstaged, untracked indicators.
typeset -g POWERLEVEL9K_VCS_{STAGED,UNSTAGED,UNTRACKED}_ICON=
# Show '*' when there are staged, unstaged or untracked files.
typeset -g POWERLEVEL9K_VCS_DIRTY_ICON='*'
# Show '⇣' if local branch is behind remote.
typeset -g POWERLEVEL9K_VCS_INCOMING_CHANGES_ICON=':⇣'
# Show '⇡' if local branch is ahead of remote.
typeset -g POWERLEVEL9K_VCS_OUTGOING_CHANGES_ICON=':⇡'
# Don't show the number of commits next to the ahead/behind arrows.
typeset -g POWERLEVEL9K_VCS_{COMMITS_AHEAD,COMMITS_BEHIND}_MAX_NUM=1
# Remove space between '⇣' and '⇡' and all trailing spaces.
typeset -g POWERLEVEL9K_VCS_CONTENT_EXPANSION='${${${P9K_CONTENT/⇣* :⇡/⇣⇡}// }//:/ }'
# Grey current time.
typeset -g POWERLEVEL9K_TIME_FOREGROUND=$grey
# Format for the current time: 09:51:02. See `man 3 strftime`.
typeset -g POWERLEVEL9K_TIME_FORMAT='%D{%H:%M:%S}'
# If set to true, time will update when you hit enter. This way prompts for the past
# commands will contain the start times of their commands rather than the end times of
# their preceding commands.
typeset -g POWERLEVEL9K_TIME_UPDATE_ON_COMMAND=false
# Transient prompt works similarly to the builtin transient_rprompt option. It trims down prompt
# when accepting a command line. Supported values:
#
# - off: Don't change prompt when accepting a command line.
# - always: Trim down prompt when accepting a command line.
# - same-dir: Trim down prompt when accepting a command line unless this is the first command
# typed after changing current working directory.
typeset -g POWERLEVEL9K_TRANSIENT_PROMPT=off
# Instant prompt mode.
#
# - off: Disable instant prompt. Choose this if you've tried instant prompt and found
# it incompatible with your zsh configuration files.
# - quiet: Enable instant prompt and don't print warnings when detecting console output
# during zsh initialization. Choose this if you've read and understood
# https://github.com/romkatv/powerlevel10k#instant-prompt.
# - verbose: Enable instant prompt and print a warning when detecting console output during
# zsh initialization. Choose this if you've never tried instant prompt, haven't
# seen the warning, or if you are unsure what this all means.
typeset -g POWERLEVEL9K_INSTANT_PROMPT=off
# Hot reload allows you to change POWERLEVEL9K options after Powerlevel10k has been initialized.
# For example, you can type POWERLEVEL9K_BACKGROUND=red and see your prompt turn red. Hot reload
# can slow down prompt by 1-2 milliseconds, so it's better to keep it turned off unless you
# really need it.
typeset -g POWERLEVEL9K_DISABLE_HOT_RELOAD=off
# If p10k is already loaded, reload configuration.
# This works even with POWERLEVEL9K_DISABLE_HOT_RELOAD=true.
(( ! $+functions[p10k] )) || p10k reload
}
# Tell `p10k configure` which file it should overwrite.
typeset -g POWERLEVEL9K_CONFIG_FILE=${${(%):-%x}:a}
(( ${#p10k_config_opts} )) && setopt ${p10k_config_opts[@]}
'builtin' 'unset' 'p10k_config_opts'

5
.pre-commit-config.yaml Normal file
View File

@@ -0,0 +1,5 @@
fail_fast: false
default_stages: [pre-commit]
repos:
- repo: local
hooks: []

5
.prettierignore Normal file
View File

@@ -0,0 +1,5 @@
# Ignore artifacts:
build
coverage
repos/hydejack/**/*.html

16
.prettierrc Normal file
View File

@@ -0,0 +1,16 @@
{
"arrowParens": "always",
"bracketSpacing": true,
"htmlWhitespaceSensitivity": "css",
"insertPragma": false,
"jsxSingleQuote": true,
"printWidth": 80,
"proseWrap": "always",
"quoteProps": "as-needed",
"requirePragma": false,
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "none",
"useTabs": false
}

1
.python-version Normal file
View File

@@ -0,0 +1 @@
3.10.17

267
.rubocop.yml Normal file
View File

@@ -0,0 +1,267 @@
AllCops:
NewCops: enable
Gemspec/AddRuntimeDependency: # new in 1.65
Enabled: true
Gemspec/DeprecatedAttributeAssignment: # new in 1.30
Enabled: true
Gemspec/DevelopmentDependencies: # new in 1.44
Enabled: true
Gemspec/RequireMFA: # new in 1.23
Enabled: true
Layout/LineContinuationLeadingSpace: # new in 1.31
Enabled: true
Layout/LineContinuationSpacing: # new in 1.31
Enabled: true
Layout/LineEndStringConcatenationIndentation: # new in 1.18
Enabled: true
Layout/SpaceBeforeBrackets: # new in 1.7
Enabled: true
Lint/AmbiguousAssignment: # new in 1.7
Enabled: true
Lint/AmbiguousOperatorPrecedence: # new in 1.21
Enabled: true
Lint/AmbiguousRange: # new in 1.19
Enabled: true
Lint/ArrayLiteralInRegexp: # new in 1.71
Enabled: true
Lint/ConstantOverwrittenInRescue: # new in 1.31
Enabled: true
Lint/ConstantReassignment: # new in 1.70
Enabled: true
Lint/CopDirectiveSyntax: # new in 1.72
Enabled: true
Lint/DeprecatedConstants: # new in 1.8
Enabled: true
Lint/DuplicateBranch: # new in 1.3
Enabled: true
Lint/DuplicateMagicComment: # new in 1.37
Enabled: true
Lint/DuplicateMatchPattern: # new in 1.50
Enabled: true
Lint/DuplicateRegexpCharacterClassElement: # new in 1.1
Enabled: true
Lint/DuplicateSetElement: # new in 1.67
Enabled: true
Lint/EmptyBlock: # new in 1.1
Enabled: true
Lint/EmptyClass: # new in 1.3
Enabled: true
Lint/EmptyInPattern: # new in 1.16
Enabled: true
Lint/HashNewWithKeywordArgumentsAsDefault: # new in 1.69
Enabled: true
Lint/IncompatibleIoSelectWithFiberScheduler: # new in 1.21
Enabled: true
Lint/ItWithoutArgumentsInBlock: # new in 1.59
Enabled: true
Lint/LambdaWithoutLiteralBlock: # new in 1.8
Enabled: true
Lint/LiteralAssignmentInCondition: # new in 1.58
Enabled: true
Lint/MixedCaseRange: # new in 1.53
Enabled: true
Lint/NoReturnInBeginEndBlocks: # new in 1.2
Enabled: true
Lint/NonAtomicFileOperation: # new in 1.31
Enabled: true
Lint/NumberedParameterAssignment: # new in 1.9
Enabled: true
Lint/NumericOperationWithConstantResult: # new in 1.69
Enabled: true
Lint/OrAssignmentToConstant: # new in 1.9
Enabled: true
Lint/RedundantDirGlobSort: # new in 1.8
Enabled: true
Lint/RedundantRegexpQuantifiers: # new in 1.53
Enabled: true
Lint/RedundantTypeConversion: # new in 1.72
Enabled: true
Lint/RefinementImportMethods: # new in 1.27
Enabled: true
Lint/RequireRangeParentheses: # new in 1.32
Enabled: true
Lint/RequireRelativeSelfPath: # new in 1.22
Enabled: true
Lint/SharedMutableDefault: # new in 1.70
Enabled: true
Lint/SuppressedExceptionInNumberConversion: # new in 1.72
Enabled: true
Lint/SymbolConversion: # new in 1.9
Enabled: true
Lint/ToEnumArguments: # new in 1.1
Enabled: true
Lint/TripleQuotes: # new in 1.9
Enabled: true
Lint/UnescapedBracketInRegexp: # new in 1.68
Enabled: true
Lint/UnexpectedBlockArity: # new in 1.5
Enabled: true
Lint/UnmodifiedReduceAccumulator: # new in 1.1
Enabled: true
Lint/UselessConstantScoping: # new in 1.72
Enabled: true
Lint/UselessDefined: # new in 1.69
Enabled: true
Lint/UselessNumericOperation: # new in 1.66
Enabled: true
Lint/UselessRescue: # new in 1.43
Enabled: true
Lint/UselessRuby2Keywords: # new in 1.23
Enabled: true
Metrics/CollectionLiteralLength: # new in 1.47
Enabled: true
Naming/BlockForwarding: # new in 1.24
Enabled: true
Security/CompoundHash: # new in 1.28
Enabled: true
Security/IoMethods: # new in 1.22
Enabled: true
Style/AmbiguousEndlessMethodDefinition: # new in 1.68
Enabled: true
Style/ArgumentsForwarding: # new in 1.1
Enabled: true
Style/ArrayIntersect: # new in 1.40
Enabled: true
Style/BitwisePredicate: # new in 1.68
Enabled: true
Style/CollectionCompact: # new in 1.2
Enabled: true
Style/CombinableDefined: # new in 1.68
Enabled: true
Style/ComparableBetween: # new in 1.74
Enabled: true
Style/ComparableClamp: # new in 1.44
Enabled: true
Style/ConcatArrayLiterals: # new in 1.41
Enabled: true
Style/DataInheritance: # new in 1.49
Enabled: true
Style/DigChain: # new in 1.69
Enabled: true
Style/DirEmpty: # new in 1.48
Enabled: true
Style/DocumentDynamicEvalDefinition: # new in 1.1
Enabled: true
Style/EmptyHeredoc: # new in 1.32
Enabled: true
Style/EndlessMethod: # new in 1.8
Enabled: true
Style/EnvHome: # new in 1.29
Enabled: true
Style/ExactRegexpMatch: # new in 1.51
Enabled: true
Style/FetchEnvVar: # new in 1.28
Enabled: true
Style/FileEmpty: # new in 1.48
Enabled: true
Style/FileNull: # new in 1.69
Enabled: true
Style/FileRead: # new in 1.24
Enabled: true
Style/FileTouch: # new in 1.69
Enabled: true
Style/FileWrite: # new in 1.24
Enabled: true
Style/HashConversion: # new in 1.10
Enabled: true
Style/HashExcept: # new in 1.7
Enabled: true
Style/HashFetchChain: # new in 1.75
Enabled: true
Style/HashSlice: # new in 1.71
Enabled: true
Style/IfWithBooleanLiteralBranches: # new in 1.9
Enabled: true
Style/InPatternThen: # new in 1.16
Enabled: true
Style/ItAssignment: # new in 1.70
Enabled: true
Style/ItBlockParameter: # new in 1.75
Enabled: true
Style/KeywordArgumentsMerging: # new in 1.68
Enabled: true
Style/MagicCommentFormat: # new in 1.35
Enabled: true
Style/MapCompactWithConditionalBlock: # new in 1.30
Enabled: true
Style/MapIntoArray: # new in 1.63
Enabled: true
Style/MapToHash: # new in 1.24
Enabled: true
Style/MapToSet: # new in 1.42
Enabled: true
Style/MinMaxComparison: # new in 1.42
Enabled: true
Style/MultilineInPatternThen: # new in 1.16
Enabled: true
Style/NegatedIfElseCondition: # new in 1.2
Enabled: true
Style/NestedFileDirname: # new in 1.26
Enabled: true
Style/NilLambda: # new in 1.3
Enabled: true
Style/NumberedParameters: # new in 1.22
Enabled: true
Style/NumberedParametersLimit: # new in 1.22
Enabled: true
Style/ObjectThen: # new in 1.28
Enabled: true
Style/OpenStructUse: # new in 1.23
Enabled: true
Style/OperatorMethodCall: # new in 1.37
Enabled: true
Style/QuotedSymbols: # new in 1.16
Enabled: true
Style/RedundantArgument: # new in 1.4
Enabled: true
Style/RedundantArrayConstructor: # new in 1.52
Enabled: true
Style/RedundantConstantBase: # new in 1.40
Enabled: true
Style/RedundantCurrentDirectoryInPath: # new in 1.53
Enabled: true
Style/RedundantDoubleSplatHashBraces: # new in 1.41
Enabled: true
Style/RedundantEach: # new in 1.38
Enabled: true
Style/RedundantFilterChain: # new in 1.52
Enabled: true
Style/RedundantFormat: # new in 1.72
Enabled: true
Style/RedundantHeredocDelimiterQuotes: # new in 1.45
Enabled: true
Style/RedundantInitialize: # new in 1.27
Enabled: true
Style/RedundantInterpolationUnfreeze: # new in 1.66
Enabled: true
Style/RedundantLineContinuation: # new in 1.49
Enabled: true
Style/RedundantRegexpArgument: # new in 1.53
Enabled: true
Style/RedundantRegexpConstructor: # new in 1.52
Enabled: true
Style/RedundantSelfAssignmentBranch: # new in 1.19
Enabled: true
Style/RedundantStringEscape: # new in 1.37
Enabled: true
Style/ReturnNilInPredicateMethodDefinition: # new in 1.53
Enabled: true
Style/SafeNavigationChainLength: # new in 1.68
Enabled: true
Style/SelectByRegexp: # new in 1.22
Enabled: true
Style/SendWithLiteralMethodName: # new in 1.64
Enabled: true
Style/SingleLineDoEndBlock: # new in 1.57
Enabled: true
Style/StringChars: # new in 1.12
Enabled: true
Style/SuperArguments: # new in 1.64
Enabled: true
Style/SuperWithArgsParentheses: # new in 1.58
Enabled: true
Style/SwapValues: # new in 1.1
Enabled: true
Style/YAMLFileRead: # new in 1.53
Enabled: true

1
.ruby-version Normal file
View File

@@ -0,0 +1 @@
3.4.1

49
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,49 @@
{
"explorer.excludeGitIgnore": false,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[ignore]": {
"editor.defaultFormatter": "foxundermoon.shell-format"
},
"[shellscript]": {
"editor.defaultFormatter": "mkhl.shfmt"
},
"[xml]": {
"editor.defaultFormatter": "trunk.io"
},
"[html]": {
"editor.defaultFormatter": "trunk.io"
},
"[javascript]": {
"editor.defaultFormatter": "vscode.typescript-language-features"
},
"[markdown]": {
"editor.defaultFormatter": "trunk.io"
},
"[typescript]": {
"editor.defaultFormatter": "vscode.typescript-language-features"
},
"[yaml]": {
"editor.defaultFormatter": "kennylong.kubernetes-yaml-formatter"
},
"[dockercompose]": {
"editor.defaultFormatter": "ms-azuretools.vscode-containers"
},
"[svelte]": {
"editor.defaultFormatter": "svelte.svelte-vscode"
},
"[css]": {
"editor.defaultFormatter": "vscode.css-language-features"
},
"[json]": {
"editor.defaultFormatter": "vscode.json-language-features"
},
"[rust]": {
"editor.defaultFormatter": "rust-lang.rust-analyzer"
},
"[jsonc]": {
"editor.defaultFormatter": "vscode.json-language-features"
},
"[vue]": {
"editor.defaultFormatter": "Vue.volar"
}
}

0
.zlogin Executable file
View File

0
.zlogout Executable file
View File

2
.zprofile Executable file
View File

@@ -0,0 +1,2 @@

1
.zshenv Normal file
View File

@@ -0,0 +1 @@

130
.zshrc Normal file
View File

@@ -0,0 +1,130 @@
if [ -f "$HOME/.init/init.sh" ] ; then
. "$HOME/.init/init.sh"
fi
# Enable Powerlevel10k instant prompt. Should stay close to the top of ~/.zshrc.
# Initialization code that may require console input (password prompts, [y/n]
# confirmations, etc.) must go above this block; everything else may go below.
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
fi
# If you come from bash you might have to change your $PATH.
# export PATH=$HOME/bin:$HOME/.local/bin:/usr/local/bin:$PATH
# Path to your Oh My Zsh installation.
export ZSH="$HOME/.oh-my-zsh"
# Set name of the theme to load --- if set to "random", it will
# load a random theme each time Oh My Zsh is loaded, in which case,
# to know which specific one was loaded, run: echo $RANDOM_THEME
# See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes
ZSH_THEME="powerlevel10k/powerlevel10k"
# Set list of themes to pick from when loading at random
# Setting this variable when ZSH_THEME=random will cause zsh to load
# a theme from this variable instead of looking in $ZSH/themes/
# If set to an empty array, this variable will have no effect.
# ZSH_THEME_RANDOM_CANDIDATES=( "robbyrussell" "agnoster" )
# Uncomment the following line to use case-sensitive completion.
# CASE_SENSITIVE="true"
# Uncomment the following line to use hyphen-insensitive completion.
# Case-sensitive completion must be off. _ and - will be interchangeable.
# HYPHEN_INSENSITIVE="true"
# Uncomment one of the following lines to change the auto-update behavior
# zstyle ':omz:update' mode disabled # disable automatic updates
# zstyle ':omz:update' mode auto # update automatically without asking
# zstyle ':omz:update' mode reminder # just remind me to update when it's time
# Uncomment the following line to change how often to auto-update (in days).
# zstyle ':omz:update' frequency 13
# Uncomment the following line if pasting URLs and other text is messed up.
# DISABLE_MAGIC_FUNCTIONS="true"
# Uncomment the following line to disable colors in ls.
# DISABLE_LS_COLORS="true"
# Uncomment the following line to disable auto-setting terminal title.
# DISABLE_AUTO_TITLE="true"
# Uncomment the following line to enable command auto-correction.
# ENABLE_CORRECTION="true"
# Uncomment the following line to display red dots whilst waiting for completion.
# You can also set it to another string to have that shown instead of the default red dots.
# e.g. COMPLETION_WAITING_DOTS="%F{yellow}waiting...%f"
# Caution: this setting can cause issues with multiline prompts in zsh < 5.7.1 (see #5765)
# COMPLETION_WAITING_DOTS="true"
# Uncomment the following line if you want to disable marking untracked files
# under VCS as dirty. This makes repository status check for large repositories
# much, much faster.
# DISABLE_UNTRACKED_FILES_DIRTY="true"
# Uncomment the following line if you want to change the command execution time
# stamp shown in the history command output.
# You can set one of the optional three formats:
# "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd"
# or set a custom format using the strftime function format specifications,
# see 'man strftime' for details.
# HIST_STAMPS="mm/dd/yyyy"
# Would you like to use another custom folder than $ZSH/custom?
# ZSH_CUSTOM=/path/to/new-custom-folder
# Which plugins would you like to load?
# Standard plugins can be found in $ZSH/plugins/
# Custom plugins may be added to $ZSH_CUSTOM/plugins/
# Example format: plugins=(rails git textmate ruby lighthouse)
# Add wisely, as too many plugins slow down shell startup.
plugins=(git pm2 gh sudo ssh ruby rust python node github rsync nvm rbenv pyenv docker docker-compose qrcode zsh-autosuggestions zsh-syntax-highlighting zsh-interactive-cd zsh-navigation-tools)
source $ZSH/oh-my-zsh.sh
# User configuration
# export MANPATH="/usr/local/man:$MANPATH"
# You may need to manually set your language environment
# export LANG=en_US.UTF-8
# Preferred editor for local and remote sessions
# if [[ -n $SSH_CONNECTION ]]; then
# export EDITOR='vim'
# else
# export EDITOR='nvim'
# fi
# Compilation flags
# export ARCHFLAGS="-arch $(uname -m)"
# Set personal aliases, overriding those provided by Oh My Zsh libs,
# plugins, and themes. Aliases can be placed here, though Oh My Zsh
# users are encouraged to define aliases within a top-level file in
# the $ZSH_CUSTOM folder, with .zsh extension. Examples:
# - $ZSH_CUSTOM/aliases.zsh
# - $ZSH_CUSTOM/macos.zsh
# For a full list of active aliases, run `alias`.
#
# Example aliases
# alias zshconfig="mate ~/.zshrc"
# alias ohmyzsh="mate ~/.oh-my-zsh"
# To customize prompt, run `p10k configure` or edit ~/.p10k.zsh.
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh
# _home_pull
cd "$HOME/$(cat $HOME/.last_pwd)" &>/dev/null
# pnpm
export PNPM_HOME="/home/valknar/.local/share/pnpm"
case ":$PATH:" in
*":$PNPM_HOME:"*) ;;
*) export PATH="$PNPM_HOME:$PATH" ;;
esac
# pnpm end

137
CLAUDE.md Normal file
View File

@@ -0,0 +1,137 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Overview
This is a personal home directory repository managed as a git repository with selective tracking via `.gitignore`. The repository tracks dotfiles and configuration for a Debian development environment supporting Node.js, Python, Ruby, Rust, and Go development.
## Key Architecture
### Initialization System
Shell initialization is managed through `.init/init.sh`, which sources modular configuration:
- `.init/path.sh` - PATH environment setup for all language toolchains
- `.init/alias.sh` - Custom shell aliases
- `.init/functions.sh` - Custom shell functions for deployment and media processing
- `.init/export.sh`, `.init/source.sh`, `.init/eval.sh` - Additional environment setup
### Arty Configuration
`arty.yml` defines the repository structure using Arty (artifact/repository manager):
- **references**: Git subrepositories to clone into specific paths
- **envs**: Environment profiles (dev/prod) for selective repository management
- Manages both development projects and language version managers (nvm, rbenv, pyenv, gvm)
### Ansible Provisioning
`playbook.yml` is an Ansible playbook for system setup:
- Installs and configures language runtimes (Node, Python, Ruby, Rust, Go)
- Sets up Docker, PostgreSQL 18, and development tools
- Configures Zsh with Oh-My-Zsh and Powerlevel10k theme
- Manages system packages via apt
### Git Selective Tracking
The `.gitignore` uses an inverted pattern (ignore everything, then selectively allow):
- Tracks only specific dotfiles and configuration files
- Allows `.github/`, `.init/`, `.vscode/` directories
- Excludes logs, databases, and temporary files
## Development Environment
### Language Version Management
- **Node.js**: Managed by nvm, version specified in `.nvmrc`
- **Ruby**: Managed by rbenv, version in `.ruby-version`
- **Python**: Managed by pyenv, version in `.python-version`
- **Rust**: Via rustup (`.cargo/`, `.rustup/`)
- **Go**: Via gvm (`.gvm/`)
### Shell Environment
- **Shell**: Zsh with Oh-My-Zsh framework
- **Theme**: Powerlevel10k (`.p10k.zsh`)
- **Plugins**: git, pm2, gh, docker, language-specific plugins, zsh-autosuggestions, zsh-syntax-highlighting
## Common Commands
### Environment Setup
```bash
# Reinitialize shell environment
ri # alias for: source ~/.init/init.sh
# Bootstrap system (run as user, prompts for sudo)
sudo -u $USER ansible-playbook -K playbook.yml
# Run specific Ansible tags
ansible-playbook --tags node,python,ruby -K playbook.yml
```
### Arty Repository Management
```bash
# Debug Arty configuration
pnpm arty debug
# Clone/update repositories based on environment
pnpm arty sync --env dev
```
### Git Workflow
```bash
# Stage all changes and check if clean
g0 # alias for: git add . && git diff --quiet && git diff --cached --quiet
# Reset to single commit
g1 # alias for: git reset $(git commit-tree "HEAD^{tree}" -m "A new start")
# Get last commit message
g2 # alias for: git log --format=%B -n 1 HEAD | head -n 1
```
### Code Quality
```bash
# Python pre-commit hooks (configured in .pre-commit-config.yaml)
pre-commit run --all-files
# Ruby style checking
rubocop
# Node.js linting
pnpm eslint
```
### Utility Functions
Available shell functions from `.init/functions.sh`:
- `batch_file_sequence <prefix> <extension>` - Rename files with sequence numbers
- `batch_image_webp` - Convert images to WebP format
- `batch_video_x264` - Convert videos to x264 codec
- `rs` - Rsync with sudo on remote (alias for complex rsync command)
- `ss` - Serve current directory on port 8000
- `yt <url>` - Download YouTube video as MP3
## Projects Structure
The `Projects/` directory contains development projects:
- `butter-sh/` - Butter shell projects
- `docker-compose/` - Docker compose configurations
- `pivoine.art/` - Jekyll-based art portfolio site
- `docs.pivoine.art/` - Documentation site
- `sexy.pivoine.art/` - Includes Rust package (`packages/buttplug/`)
- `node.js/` - Node.js applications (awesome, awesome-app, email-pour-vous, webshot)
## Package Management
### Node.js
- **Package manager**: pnpm (enabled via corepack)
- **Global packages**: Installed to `~/node_modules/`
- **PM2**: Configured via `ecosystem.config.js` for GitHub Copilot language server
### Python
- **Installer**: pip
- **Dependencies**: Listed in `requirements.txt` (currently: pre-commit)
### Ruby
- **Bundler**: Gemfile specifies Jekyll 4.3 and rubocop
## Important Notes
- This repository uses selective git tracking - most files are ignored by default
- Shell must source `.init/init.sh` for full environment setup (automatically done in `.zshrc`)
- Language runtimes are version-managed and installed via Ansible
- Docker requires user to be in `docker` group (managed by Ansible)
- The `.last_pwd` file tracks the last working directory for shell navigation

7
Gemfile Normal file
View File

@@ -0,0 +1,7 @@
# frozen_string_literal: true
source 'https://rubygems.org'
gem 'jekyll', '~> 4.3'
gem 'rubocop'

478
README.md Executable file
View File

@@ -0,0 +1,478 @@
<div align="center">
<pre>
_ _____ __ __ __ _ _____ ____ _ _____
| | / / | / / / //_// | / / | / __ ( ) ___/
| | / / /| | / / / ,< / |/ / /| | / /_/ //\__ \
| |/ / ___ |/ /___/ /| |/ /| / ___ |/ _, _/ ___/ /
|___/_/ |_/_____/_/ |_/_/ |_/_/ |_/_/ |_| /____/
__________ ____ ____________
/ ____/ __ \/ __ \/ ____/ ____/
/ /_ / / / / /_/ / / __/ __/
/ __/ / /_/ / _, _/ /_/ / /___
/_/ \____/_/ |_|\____/_____/
</pre>
# ⚡🔥 WHERE CODE MEETS CHAOS 🔥⚡
[![Debian](https://img.shields.io/badge/Debian-Trixie-A81D33?style=for-the-badge&logo=debian&logoColor=white)](https://www.debian.org/)
[![Powered by Metal](https://img.shields.io/badge/POWERED%20BY-METAL-FF0000?style=for-the-badge)](https://www.slayer.net/)
[![Built with Blood](https://img.shields.io/badge/BUILT%20WITH-BLOOD%20%26%20SWEAT-8B0000?style=for-the-badge)](/)
[![License: MIT](https://img.shields.io/badge/License-MIT-990000?style=for-the-badge)](LICENSE)
**My Debian home directory - forged in the fires of chaos, tempered with configuration files,**
**and wielded with the fury of a thousand riffs.**
*This is where dotfiles headbang and shell scripts scream.*
</div>
---
## ⚡ THE ARSENAL ⚡
### 🎸 **WEAPONS OF MASS DEVELOPMENT**
```
┌─────────────────────────────────────────────────┐
│ ⚔️ NODE.JS │ Managed by nvm │
│ ⚔️ PYTHON │ Managed by pyenv │
│ ⚔️ RUBY │ Managed by rbenv │
│ ⚔️ RUST │ Managed by rustup │
│ ⚔️ GO │ Managed by gvm │
│ ⚔️ DOCKER │ Containerized destruction │
│ ⚔️ POSTGRES │ Version 18 database engine │
└─────────────────────────────────────────────────┘
```
---
## 🔴 INITIALIZATION RITUAL 🔴
### **The `.init/` System - Your Shell's Dark Ceremony**
The `.init/` directory is the beating heart of this environment. When your shell awakens, it performs a sacred ritual through `~/.init/init.sh`, summoning power from these ancient scripts:
#### 🗡️ **THE SEVEN STAGES OF POWER**
```
┌──────────────────────────────────────────────────────────────┐
│ 1. PATH.SH │ Forges the PATH to all binaries │
│ 2. EXPORT.SH │ Exports environment variables │
│ 3. ALIAS.SH │ Summons command shortcuts │
│ 4. SOURCE.SH │ Sources external power (nvm, cargo, etc) │
│ 5. FUNCTIONS.SH │ Unleashes custom shell functions │
│ 6. EVAL.SH │ Evaluates version managers (rbenv, etc) │
│ 7. START.SH │ Executes startup commands (ssh-add) │
└──────────────────────────────────────────────────────────────┘
```
#### 📜 **DETAILED BREAKDOWN OF EACH SCRIPT**
##### **1⃣ `path.sh` - The Path of Destruction**
Adds all binary directories to your `$PATH`:
- `~/bin` - Your personal executables
- `~/.local/bin` - Local user binaries
- `~/.rbenv/bin` - Ruby version manager
- `~/.pyenv/bin` - Python version manager
- `~/.cargo/bin` - Rust binaries
- `~/go/bin` - Go binaries
- `~/node_modules/.bin` - Node.js binaries
- `~/.init/bin` - Custom init scripts
- `~/Projects/kompose` - Kompose tooling
##### **2⃣ `export.sh` - Environmental Warfare**
```bash
export NVM_DIR="$HOME/.nvm" # Node Version Manager home
export REPOS_DIR="$HOME/repos" # Repository directory
export CHORE_CHORE="chore: chore" # Default commit message
```
##### **3⃣ `alias.sh` - Command Line Sorcery**
```bash
ri # Reload init: source ~/.init/init.sh
g0 # Git stage all and check if clean
g1 # Git reset to single commit (nuclear option)
g2 # Get last commit message
rs # Rsync with sudo on remote
ss # Serve static files on port 8000
yt # Download YouTube as MP3
```
##### **4⃣ `source.sh` - External Power Summoning**
Sources critical external scripts:
- **NVM** - Node Version Manager (`$NVM_DIR/nvm.sh`)
- **RVM** - Ruby Version Manager (commented out)
- **Cargo** - Rust environment (`~/.cargo/env`)
- **Bash completion** for NVM
##### **5⃣ `functions.sh` - The Grimoire of Bash**
Custom functions for deployment and media manipulation:
**Git Warfare:**
- `_home_push` - Commit and push changes
- `_home_pull` - Stash, pull, and pop changes
**Deployment Spells:**
- `_site_deploy_jekyll <site>` - Build & deploy Jekyll site
- `_site_deploy_nuxt <site>` - Build & deploy Nuxt site
- `_site_deploy_static <site>` - Deploy static files
**Media Alchemy:**
- `batch_file_sequence <prefix> <ext>` - Rename files with numbers
- `batch_image_webp` - Convert all images to WebP
- `batch_video_x264` - Convert videos to x264 codec
- `_image_optimize <name>` - Full image optimization pipeline
- `_video_optimize <file>` - Optimize video with ffmpeg
##### **6⃣ `eval.sh` - Version Manager Invocation**
Initializes version managers through `eval`:
- **oh-my-posh** - Shell prompt theme engine
- **rbenv** - Ruby version manager
- **pyenv** - Python version manager
##### **7⃣ `start.sh` - The Final Awakening**
Executes startup commands:
- `ssh-add` - Adds SSH keys to the agent silently
#### 🗂️ **Additional Directories**
- **`.init/bin/`** - Custom executable scripts (e.g., `mime_mp4_gif.sh`)
- **`.init/hooks/`** - Reserved for shell hooks (currently empty)
---
## 🩸 QUICK START RITUAL 🩸
### **Summoning the Environment**
```bash
# 1. Clone this unholy repository
git init && git remote add origin git@github.com:valknarogg/home.git
git fetch && git reset --hard origin/main
git branch --set-upstream-to=origin/main main
# 2. Install Ansible (if not already installed)
sudo apt install git ansible
# 3. Configure git
git config --global init.defaultBranch main
git config --global --add safe.directory /home/$USER
# 4. Unleash the Ansible playbook
sudo -u $USER ansible-playbook -K playbook.yml
```
### **Selective Provisioning**
Run specific parts of the setup using tags:
```bash
# Install only Node.js environment
ansible-playbook --tags node -K playbook.yml
# Install Python + Ruby
ansible-playbook --tags python,ruby -K playbook.yml
# Install everything
ansible-playbook -K playbook.yml
```
#### 🏷️ **Available Tags:**
`base` | `node` | `python` | `ruby` | `rust` | `zsh` | `postgres` | `docker` | `fonts` | `flatpak` | `github` | `oh-my-posh`
---
## 🎯 ARTY - REPOSITORY ORCHESTRATION 🎯
### **What is Arty?**
**Arty.sh** is a bash-based dependency and repository manager that orchestrates git subrepositories like a conductor of chaos. It's part of the [butter.sh](https://github.com/butter-sh/butter-sh.github.io) ecosystem - a suite of bash development tools.
### **Installing Arty**
Arty is already installed globally at `/usr/local/bin/arty`. If you need to install/update it:
```bash
# Clone butter.sh ecosystem
git clone https://github.com/butter-sh/butter-sh.github.io.git ~/Projects/butter-sh
# Install arty globally (requires sudo)
cd ~/Projects/butter-sh/projects/arty.sh
sudo ./arty.sh install
```
### **The `arty.yml` Configuration**
The root `~/arty.yml` defines your entire repository ecosystem:
```yaml
name: "Valknar's home"
version: "1.0.0"
envs:
dev: # Development environment
prod: # Production environment
references:
# Project repositories
- url: git@github.com:valknarogg/pivoine.art.git
into: Projects/pivoine.art
env: dev
# Media repositories
- url: git@github.com:valknarogg/home-pictures.git
into: Bilder
env: dev
# Version managers
- url: https://github.com/nvm-sh/nvm.git
into: .nvm
# ... and many more
scripts:
debug: echo "$ARTY_BIN_DIR" && echo "$ARTY_LIBS_DIR"
```
### **Using Arty**
```bash
# Sync all dev environment repositories
arty sync --env dev
# Sync production repositories only
arty sync --env prod
# Install dependencies from arty.yml
arty install
# Run custom scripts defined in arty.yml
arty debug
# Show dependency tree
arty deps
# Update a specific reference
arty update pivoine.art
```
### **What Arty Manages:**
- ✅ Project repositories (pivoine.art, sexy.pivoine.art, etc.)
- ✅ Media repositories (Pictures, Videos, Music)
- ✅ Docker compose configurations
- ✅ Version managers (nvm, rbenv, pyenv, gvm)
- ✅ Oh-My-Zsh and plugins
- ✅ Shell scripts and binaries
### **Environment-Based Management**
References can be tagged with `env: dev` or `env: prod` to control which repositories are synced in different environments. This allows you to:
- Keep heavy media files out of production servers
- Separate development projects from system utilities
- Maintain clean, minimal deployments
---
## 🔥 COMMAND LINE BRUTALITY 🔥
### **Git Operations**
```bash
g0 # Stage all changes and verify clean state
g1 # Nuclear reset to single commit
g2 # Show last commit message
git add -A && git commit -m "$(g2)" # Reuse last commit message
```
### **Media Processing**
```bash
# Convert all images in directory to WebP
batch_image_webp
# Rename files with sequence numbers
batch_file_sequence artwork webp
# Optimize video
_video_optimize input.mov
# Download YouTube video as MP3
yt "https://youtube.com/watch?v=..."
```
### **Development Servers**
```bash
# Serve current directory on port 8000
ss
# Run Jekyll site with livereload
cd ~/Projects/pivoine.art && bundle exec jekyll serve --livereload
# Run Node.js dev server
cd ~/Projects/node.js/awesome && pnpm dev
```
### **Rsync Power**
```bash
# Sync to remote with sudo
rs /local/path/ user@host:/remote/path/
```
---
## 📁 PROJECT STRUCTURE 📁
```
~/Projects/
├── butter-sh/ # Butter.sh ecosystem (arty, judge, myst, etc.)
├── docker-compose/ # Docker orchestration configs
├── pivoine.art/ # Jekyll art portfolio (main site)
├── docs.pivoine.art/ # Documentation site
├── sexy.pivoine.art/ # Rust + web project (includes buttplug package)
└── node.js/
├── awesome/ # GitHub Awesome lists browser
├── awesome-app/ # Awesome list application
├── email-pour-vous/ # Email templating project
└── webshot/ # Website screenshot tool
```
---
## 🛠️ DOTFILE HIGHLIGHTS 🛠️
### **Shell Configuration**
- **`.zshrc`** - Oh-My-Zsh with Powerlevel10k theme
- **`.p10k.zsh`** - Powerlevel10k configuration
- **`.bashrc`** - Bash configuration (fallback)
### **Version Files**
- **`.nvmrc`** - Node.js version
- **`.ruby-version`** - Ruby version
- **`.python-version`** - Python version
### **Code Quality**
- **`.pre-commit-config.yaml`** - Pre-commit hooks (Python)
- **`.rubocop.yml`** - Ruby style enforcement
- **`eslint.config.mts`** - JavaScript/TypeScript linting
- **`.prettierrc`** - Code formatting rules
- **`biome.json`** - Fast linter/formatter
### **Package Management**
- **`requirements.txt`** - Python packages (pip)
- **`Gemfile`** - Ruby gems (bundler)
### **Git Configuration**
- **`.gitignore`** - INVERTED PATTERN (ignore all, allow specific files)
- **`.gitconfig`** - Git user configuration
### **Orchestration**
- **`arty.yml`** - Repository and dependency management
- **`playbook.yml`** - Ansible system provisioning
---
## ⚙️ GIT SELECTIVE TRACKING ⚙️
This repository uses an **inverted `.gitignore`** pattern:
```gitignore
# Ignore everything
*
# Allow specific files
!CLAUDE.md
!README.md
!.gitignore
!.init/**
!arty.yml
!playbook.yml
...
```
**Why?** To track only essential dotfiles and configurations while ignoring cache, logs, and user data. Your home directory becomes a git repository without the chaos.
---
## 🎸 SHELL PLUGIN POWER 🎸
**Oh-My-Zsh Plugins Loaded:**
```
git pm2 gh sudo ssh ruby rust python node github
rsync nvm rbenv pyenv docker docker-compose qrcode
zsh-autosuggestions zsh-syntax-highlighting
zsh-interactive-cd zsh-navigation-tools
```
---
## 🔗 USEFUL RESOURCES 🔗
### System & Shell
- [Ansible Documentation](https://docs.ansible.com/)
- [Oh-My-Zsh](https://ohmyz.sh/)
- [Powerlevel10k](https://github.com/romkatv/powerlevel10k)
### Language Managers
- [nvm](https://github.com/nvm-sh/nvm) - Node Version Manager
- [rbenv](https://github.com/rbenv/rbenv) - Ruby Version Manager
- [pyenv](https://github.com/pyenv/pyenv) - Python Version Manager
- [gvm](https://github.com/moovweb/gvm) - Go Version Manager
- [rustup](https://rustup.rs/) - Rust Toolchain Manager
### Orchestration
- [Arty.sh Documentation](https://github.com/butter-sh/butter-sh.github.io)
- [Butter.sh Ecosystem](https://butter.sh)
---
## 🖤 LICENSE 🖤
MIT License - Do whatever the hell you want with it.
---
<div align="center">
<pre>
═════════════════════════════════════════════════════════════════
__________ ____ ______ _________
/ ____/ __ \/ __ \/ ____/ / _/ ___/
/ / / / / / / / / __/ / / \__ \
/ /___/ /_/ / /_/ / /___ _/ / ___/ /
\____/\____/_____/_____/ /___//____/
______________ _______ ____ ____ ___ ______ __
/_ __/ ____/ |/ / __ \/ __ \/ __ \/ | / __ \ \/ /
/ / / __/ / /|_/ / /_/ / / / / /_/ / /| | / /_/ /\ /
/ / / /___/ / / / ____/ /_/ / _, _/ ___ |/ _, _/ / /
/_/ /_____/_/ /_/_/ \____/_/ |_/_/ |_/_/ |_| /_/
__ __________________ __ _________
/ |/ / ____/_ __/ | / / / _/ ___/
/ /|_/ / __/ / / / /| | / / / / \__ \
/ / / / /___ / / / ___ |/ /___ _/ / ___/ /
/_/ /_/_____/ /_/ /_/ |_/_____/ /___//____/
______________________ _ _____ __
/ ____/_ __/ ____/ __ \/ | / / | / /
/ __/ / / / __/ / /_/ / |/ / /| | / /
/ /___ / / / /___/ _, _/ /| / ___ |/ /___
/_____/ /_/ /_____/_/ |_/_/ |_/_/ |_/_____/
═════════════════════════════════════════════════════════════════
🔥⚡ FORGED BY VALKNAR ⚡🔥
valknar@pivoine.art
Powered by Debian | Fueled by Metal
🤘 🤘 🤘
</pre>
**[⚔️ BACK TO THE TOP ⚔️](#)**
</div>

65
arty.yml Normal file
View File

@@ -0,0 +1,65 @@
name: "Valknar's home"
version: "1.0.0"
description: "Valknar's home repository"
author: "valknar@pivoine.art"
license: "MIT"
envs:
dev:
prod:
references:
- url: git@github.com:butter-sh/butter-sh.github.io.git
into: Projects/butter-sh
env: dev
- url: git@github.com:valknarogg/home-pictures.git
into: Bilder
env: dev
- url: git@github.com:valknarogg/home-videos.git
into: Videos
ref: main
env: dev
- url: git@github.com:valknarogg/home-music.git
into: Musik
ref: main
env: dev
- url: git@github.com:valknarogg/docker-compose.git
into: Projects/docker-compose
env:
- dev
- prod
- url: git@github.com:valknarogg/pivoine.art.git
into: Projects/pivoine.art
ref: main
env: dev
- url: git@github.com:valknarxxx/sexy.pivoine.art.git
into: Projects/sexy.pivoine.art
env: dev
- url: git@github.com:valknarness/awesome.git
into: Projects/node.js/awesome
env:
- dev
- prod
- url: git@github.com:valknarness/awesome-app.git
into: Projects/node.js/awesome-app
env: dev
- url: https://github.com/nvm-sh/nvm.git
into: .nvm
- url: https://github.com/moovweb/gvm.git
into: .gvm
- url: https://github.com/rbenv/rbenv.git
into: .rbenv
- url: https://github.com/pyenv/pyenv.git
into: .pyenv
- url: https://github.com/ohmyzsh/ohmyzsh.git
into: .oh-my-zsh
- url: https://github.com/romkatv/powerlevel10k.git
into: .oh-my-zsh/custom/themes/powerlevel10k
- url: https://github.com/zsh-users/zsh-autosuggestions.git
into: .oh-my-zsh/custom/plugins/zsh-autosuggestions
- url: https://github.com/zsh-users/zsh-syntax-highlighting.git
into: .oh-my-zsh/custom/plugins/zsh-syntax-highlighting
scripts:
debug: echo "$ARTY_BIN_DIR" && echo "$ARTY_LIBS_DIR" && echo "$ARTY_HOME"

34
biome.json Normal file
View File

@@ -0,0 +1,34 @@
{
"$schema": "https://biomejs.dev/schemas/2.2.4/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true
},
"files": {
"ignoreUnknown": false
},
"formatter": {
"enabled": true,
"indentStyle": "tab"
},
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
},
"javascript": {
"formatter": {
"quoteStyle": "double"
}
},
"assist": {
"enabled": true,
"actions": {
"source": {
"organizeImports": "on"
}
}
}
}

9
ecosystem.config.js Normal file
View File

@@ -0,0 +1,9 @@
module.exports = {
apps: [
{
name: "language-server",
script:
"./node_modules/@github/copilot-language-server/dist/language-server.js",
},
],
};

14
eslint.config.mts Normal file
View File

@@ -0,0 +1,14 @@
import js from "@eslint/js";
import globals from "globals";
import tseslint from "typescript-eslint";
import { defineConfig } from "eslint/config";
export default defineConfig([
{
files: ["**/*.{js,mjs,cjs,ts,mts,cts}"],
plugins: { js },
extends: ["js/recommended"],
languageOptions: { globals: globals.browser },
},
tseslint.configs.recommended,
]);

288
playbook.yml Normal file
View File

@@ -0,0 +1,288 @@
- hosts: localhost
connection: local
tasks:
- name: Install base packages
become: true
ansible.builtin.apt:
pkg:
- make
- build-essential
- git
- curl
- wget
- rsync
- zsh
- imagemagick
- ffmpeg
- yt-dlp
- fzf
- icoutils
- postgresql-common
- unzip
tags:
- base
- python
- ruby
- rust
- zsh
- postgres
- name: Prepare postgresql
ansible.builtin.shell: /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh
args:
executable: /bin/bash
tags:
- postgres
- name: Install postgres package
become: true
ansible.builtin.apt:
pkg:
- postgresql-18
update_cache: true
tags:
- postgres
- name: Change root shell to zsh
become: true
ansible.builtin.user:
name: root
shell: /bin/zsh
tags:
- oh-my-posh
- name: Give permissions to /root/bin
become: true
ansible.builtin.file:
path: /root/bin
state: directory
tags:
- oh-my-posh
- name: Install oh-my-posh for root
become: true
ansible.builtin.shell: curl -s https://ohmyposh.dev/install.sh | bash -s -- -d /root/bin
args:
executable: /bin/bash
tags:
- oh-my-posh
- name: Ensure root shell loads user bin
become: true
ansible.builtin.lineinfile:
path: /root/.zshrc
line: |
export PATH="$PATH:/root/bin"
if [ "$TERM_PROGRAM" != "Apple_Terminal" ]; then
eval "$(oh-my-posh init zsh)"
fi
create: yes
tags:
- oh-my-posh
- name: Install node
ansible.builtin.shell: source ~/.init/init.sh && nvm install
args:
executable: /bin/bash
tags:
- node
- name: Enable node corepack
ansible.builtin.shell: source ~/.init/init.sh && corepack enable
args:
executable: /bin/bash
tags:
- node
- name: Install node packages
ansible.builtin.shell: source ~/.init/init.sh && cd ~ && pnpm install
args:
executable: /bin/bash
tags:
- node
- name: Install python required packages
become: true
ansible.builtin.apt:
pkg:
- libssl-dev
- zlib1g-dev
- libbz2-dev
- libreadline-dev
- libsqlite3-dev
- llvm
- libncurses5-dev
tags:
- python
- name: Install python
ansible.builtin.shell: source ~/.init/init.sh && pyenv install --skip-existing
args:
executable: /bin/bash
tags:
- python
- name: Install python packages
ansible.builtin.shell: source ~/.init/init.sh && pip install -r ~/requirements.txt
args:
executable: /bin/bash
tags:
- python
- name: Init python pre-commit
ansible.builtin.shell: source ~/.init/init.sh && cd ~ && pre-commit install
args:
executable: /bin/bash
tags:
- python
- name: Install ruby required packages
become: true
ansible.builtin.apt:
pkg:
- libssl-dev
- libffi-dev
- libyaml-dev
- zlib1g-dev
tags:
- ruby
- name: Install ruby
ansible.builtin.shell: source ~/.init/init.sh && rbenv install --skip-existing
args:
executable: /bin/bash
tags:
- ruby
- name: Install ruby base packages
ansible.builtin.shell: source ~/.init/init.sh && gem install {{ item }}
args:
executable: /bin/bash
with_items:
- bundler
tags:
- ruby
- name: Install ruby packages
ansible.builtin.shell: source ~/.init/init.sh && cd ~ && bundle install
args:
executable: /bin/bash
tags:
- ruby
- name: Install rust required packages
become: true
ansible.builtin.apt:
pkg:
- libudev-dev
- libusb-1.0-0-dev
- libdbus-1-dev
- pkg-config
- cmake
tags:
- rust
- name: Download Installer for rust
ansible.builtin.get_url:
url: https://sh.rustup.rs
dest: /tmp/sh.rustup.rs
mode: '0755'
force: 'yes'
tags:
- rust
- name: Install rust
ansible.builtin.shell: /tmp/sh.rustup.rs -y
tags:
- rust
- name: Change user shell to zsh
become: true
ansible.builtin.user:
name: '{{ ansible_user_id }}'
shell: /bin/zsh
tags:
- zsh
- name: Update font cache
ansible.builtin.shell: fc-cache -f -v
tags:
- fonts
- name: Install flatpak required packages
become: true
ansible.builtin.apt:
pkg:
- flatpak
- gnome-software-plugin-flatpak
- libgtk-3-dev
tags:
- flatpak
- name: Add flathub repo
ansible.builtin.shell: flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
tags:
- flatpak
- name: Install github required packages
become: true
ansible.builtin.apt:
pkg:
- gh
tags:
- github
# - name: Add github copilot extension
# ansible.builtin.shell: gh extension install github/gh-copilot
# tags:
# - github
- name: Install Docker required packages
become: true
ansible.builtin.apt:
name:
- apt-transport-https
- ca-certificates
- curl
- gnupg2
- postgresql-client
tags:
- docker
- name: Add Docker repository
ansible.builtin.deb822_repository:
name: docker
uris: https://download.docker.com/linux/debian
types: deb
suites: trixie
architectures: amd64
components: stable
signed_by: https://download.docker.com/linux/debian/gpg
tags:
- docker
- name: Install Docker Engine
become: true
ansible.builtin.apt:
name:
- docker-ce
- docker-ce-cli
- containerd.io
update_cache: true
tags:
- docker
- name: Add user to docker group
become: true
ansible.builtin.user:
name: '{{ ansible_user_id }}'
groups: docker
tags:
- docker
- name: Start Docker service
become: true
ansible.builtin.service:
name: docker
state: started
tags:
- docker

1
requirements.txt Normal file
View File

@@ -0,0 +1 @@
pre-commit