Merge branch 'main' of git.ptrwd.com:peterwood/shell

This commit is contained in:
Peter Wood
2025-11-18 20:39:55 -05:00
4 changed files with 640 additions and 0 deletions

41
backup-calibre.sh Executable file
View File

@@ -0,0 +1,41 @@
#!/bin/bash
# Calibre Library Backup Script
# This script backs up the Calibre Library to a network share
# Configuration
SOURCE_DIR="/home/acedanger/Calibre Library/"
DEST_DIR="/mnt/share/media/books/"
LOG_FILE="/var/log/calibre-backup.log"
# Function to log messages with timestamp
log_message() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}
# Check if source directory exists
if [ ! -d "$SOURCE_DIR" ]; then
log_message "ERROR: Source directory does not exist: $SOURCE_DIR"
exit 1
fi
# Check if destination directory is accessible
if [ ! -d "$DEST_DIR" ]; then
log_message "ERROR: Destination directory not accessible: $DEST_DIR"
log_message "Make sure the network share is mounted"
exit 1
fi
# Start backup
log_message "Starting Calibre Library backup..."
log_message "Source: $SOURCE_DIR"
log_message "Destination: $DEST_DIR"
# Perform the backup using rsync
if rsync -rtvp --delete --exclude="*.tmp" "$SOURCE_DIR" "$DEST_DIR" 2>&1 | tee -a "$LOG_FILE"; then
log_message "Backup completed successfully"
exit 0
else
log_message "ERROR: Backup failed with exit code $?"
exit 1
fi

View File

@@ -4,6 +4,10 @@
[credential "https://gist.github.com"] [credential "https://gist.github.com"]
helper = helper =
helper = !/usr/bin/gh auth git-credential helper = !/usr/bin/gh auth git-credential
[credential "https://git.ptrwd.com"]
username = peterwood
helper =
helper = !tea login helper
[user] [user]
email = peter@peterwood.dev email = peter@peterwood.dev
name = Peter Wood name = Peter Wood

337
download-tea.sh Executable file
View File

@@ -0,0 +1,337 @@
#!/bin/bash
#
# download-tea.sh - Downloads and installs the Gitea Tea CLI tool for Linux
#
# SYNOPSIS
# ./download-tea.sh [OPTIONS]
#
# DESCRIPTION
# This script automatically downloads, verifies, and installs the Tea CLI (Gitea command-line tool).
# It supports automatic detection of the latest version, SHA256 checksum verification, and intelligent
# installation location based on user privileges.
#
# OPTIONS
# -v, --version VERSION Specifies the version of Tea to install. If not provided, the script will
# automatically fetch the latest version from the Gitea releases page.
# -f, --force Bypasses the overwrite confirmation prompt if Tea is already installed.
# -h, --help Display this help message and exit.
#
# EXAMPLES
# ./download-tea.sh
# Automatically detects and installs the latest version of Tea.
#
# ./download-tea.sh -v 0.11.1
# Installs a specific version of Tea (v0.11.1).
#
# ./download-tea.sh --force
# Installs the latest version and overwrites any existing installation without prompting.
#
# ./download-tea.sh -v 0.11.1 -f
# Installs version 0.11.1 and overwrites existing installation without prompting.
#
# NOTES
# - Requires internet connection to download from https://gitea.com
# - Automatically detects system architecture (amd64, arm64, 386, arm)
# - Installation location:
# * With root/sudo privileges: /usr/local/bin
# * Without privileges: ~/.local/bin
# - Automatically updates PATH environment variable if needed
# - After installation, restart your terminal or reload shell configuration
#
# LINK
# https://gitea.com/gitea/tea
#
# Color codes for output
readonly GREEN='\033[0;32m'
readonly RED='\033[0;31m'
readonly YELLOW='\033[1;33m'
readonly CYAN='\033[0;36m'
readonly GRAY='\033[0;37m'
readonly NC='\033[0m' # No Color
# Variables
TEA_VERSION=""
FORCE=false
# Show usage information
show_usage() {
sed -n '3,37p' "$0" | sed 's/^# \?//'
exit 0
}
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
-v|--version)
TEA_VERSION="$2"
shift 2
;;
-f|--force)
FORCE=true
shift
;;
-h|--help)
show_usage
;;
*)
echo -e "${RED}Error: Unknown option: $1${NC}" >&2
echo "Use -h or --help for usage information."
exit 1
;;
esac
done
# 1. Determine version to install
if [[ -z "$TEA_VERSION" ]]; then
echo "No version specified. Fetching latest release..."
# Try to fetch the latest version using curl
if command -v curl &> /dev/null; then
RELEASE_PAGE=$(curl -sL "https://gitea.com/gitea/tea/releases" 2>&1)
if [[ $? -ne 0 ]]; then
echo -e "${RED}Error: Failed to fetch latest version: $RELEASE_PAGE${NC}" >&2
echo "Please specify a version manually using -v parameter."
exit 1
fi
# Fallback to wget if curl is not available
elif command -v wget &> /dev/null; then
RELEASE_PAGE=$(wget -qO- "https://gitea.com/gitea/tea/releases" 2>&1)
if [[ $? -ne 0 ]]; then
echo -e "${RED}Error: Failed to fetch latest version: $RELEASE_PAGE${NC}" >&2
echo "Please specify a version manually using -v parameter."
exit 1
fi
else
echo -e "${RED}Error: Neither curl nor wget is available${NC}" >&2
echo "Please install curl or wget, or specify a version manually using -v parameter."
exit 1
fi
# Parse the HTML to find the latest version tag (format: /gitea/tea/releases/tag/v0.x.x)
if [[ "$RELEASE_PAGE" =~ /gitea/tea/releases/tag/v([0-9]+\.[0-9]+\.[0-9]+) ]]; then
TEA_VERSION="${BASH_REMATCH[1]}"
echo -e "${GREEN}Latest version found: v$TEA_VERSION${NC}"
else
echo -e "${RED}Error: Could not determine the latest version from the releases page.${NC}" >&2
echo "Please specify a version manually using -v parameter."
exit 1
fi
else
echo "Using specified version: v$TEA_VERSION"
fi
# 2. Define variables for the download
# Detect system architecture
ARCH=$(uname -m)
case "$ARCH" in
x86_64)
ARCHITECTURE="amd64"
;;
aarch64|arm64)
ARCHITECTURE="arm64"
;;
i386|i686)
ARCHITECTURE="386"
;;
armv7l|armv6l)
ARCHITECTURE="arm"
;;
*)
echo -e "${RED}Error: Unsupported architecture: $ARCH${NC}" >&2
exit 1
;;
esac
# Construct download URLs
DOWNLOAD_URL="https://gitea.com/gitea/tea/releases/download/v${TEA_VERSION}/tea-${TEA_VERSION}-linux-${ARCHITECTURE}"
CHECKSUM_URL="https://gitea.com/gitea/tea/releases/download/v${TEA_VERSION}/checksums.txt"
# Determine installation directory based on privileges
# Check if we can write to /usr/local/bin (requires root/sudo)
if [[ -w "/usr/local/bin" ]] || [[ "$EUID" -eq 0 ]]; then
INSTALL_DIR="/usr/local/bin"
else
INSTALL_DIR="$HOME/.local/bin"
fi
# Define file names and temp locations
FILE_NAME="tea"
TEMP_FILE="/tmp/tea-${TEA_VERSION}"
TEMP_CHECKSUM="/tmp/tea-checksums.txt"
# 3. Check if file already exists
if [[ -f "$INSTALL_DIR/$FILE_NAME" ]] && [[ "$FORCE" != true ]]; then
# Prompt user before overwriting existing installation
echo -n "tea already exists in $INSTALL_DIR. Overwrite? (Y/N): "
read -r response
if [[ ! "$response" =~ ^[Yy]$ ]]; then
echo "Installation cancelled."
exit 0
fi
fi
# 4. Create the installation directory if it doesn't exist
echo "Creating installation directory: $INSTALL_DIR"
if [[ ! -d "$INSTALL_DIR" ]]; then
if ! mkdir -p "$INSTALL_DIR"; then
echo -e "${RED}Error: Failed to create installation directory${NC}" >&2
exit 1
fi
fi
# 5. Download the binary and checksum
echo "Downloading tea CLI v$TEA_VERSION for $ARCHITECTURE..."
# Use curl if available, otherwise use wget
if command -v curl &> /dev/null; then
if ! curl -fL "$DOWNLOAD_URL" -o "$TEMP_FILE"; then
echo -e "${RED}Error: Failed to download the file. Please check the URL and version number.${NC}" >&2
rm -f "$TEMP_FILE"
exit 1
fi
elif command -v wget &> /dev/null; then
if ! wget -q "$DOWNLOAD_URL" -O "$TEMP_FILE"; then
echo -e "${RED}Error: Failed to download the file. Please check the URL and version number.${NC}" >&2
rm -f "$TEMP_FILE"
exit 1
fi
else
echo -e "${RED}Error: Neither curl nor wget is available${NC}" >&2
exit 1
fi
echo "Binary downloaded successfully."
# Try to download checksum file for verification (optional but recommended)
CHECKSUM_AVAILABLE=false
echo "Attempting to download checksum file..."
if command -v curl &> /dev/null; then
if curl -fL "$CHECKSUM_URL" -o "$TEMP_CHECKSUM" 2>/dev/null; then
CHECKSUM_AVAILABLE=true
echo "Checksum file downloaded."
fi
elif command -v wget &> /dev/null; then
if wget -q "$CHECKSUM_URL" -O "$TEMP_CHECKSUM" 2>/dev/null; then
CHECKSUM_AVAILABLE=true
echo "Checksum file downloaded."
fi
fi
if [[ "$CHECKSUM_AVAILABLE" != true ]]; then
echo -e "${YELLOW}Warning: Checksum file not available for this version. Skipping verification.${NC}"
fi
# 6. Verify checksum (if available)
if [[ "$CHECKSUM_AVAILABLE" == true ]]; then
echo "Verifying file integrity..."
# Check if sha256sum is available
if ! command -v sha256sum &> /dev/null; then
echo -e "${YELLOW}Warning: sha256sum not available. Skipping checksum verification.${NC}"
else
# Calculate SHA256 hash of downloaded file
DOWNLOADED_HASH=$(sha256sum "$TEMP_FILE" | awk '{print $1}')
# Parse checksums.txt to find the hash for our specific file
# The checksums file format is: "hash filename" (two spaces)
EXPECTED_FILE_NAME="tea-${TEA_VERSION}-linux-${ARCHITECTURE}"
EXPECTED_HASH=$(grep -E "^[a-fA-F0-9]+\s+${EXPECTED_FILE_NAME}$" "$TEMP_CHECKSUM" | awk '{print $1}')
if [[ -z "$EXPECTED_HASH" ]]; then
echo -e "${YELLOW}Warning: Could not find checksum for $EXPECTED_FILE_NAME in checksums.txt${NC}"
echo -n "Continue without checksum verification? (Y/N): "
read -r response
if [[ ! "$response" =~ ^[Yy]$ ]]; then
rm -f "$TEMP_FILE" "$TEMP_CHECKSUM"
exit 1
fi
elif [[ "$DOWNLOADED_HASH" == "$EXPECTED_HASH" ]]; then
echo -e "${GREEN}Checksum verification passed.${NC}"
else
echo -e "${RED}Error: Checksum verification failed! Downloaded file may be corrupted or tampered with.${NC}" >&2
echo "Expected: $EXPECTED_HASH"
echo "Got: $DOWNLOADED_HASH"
rm -f "$TEMP_FILE" "$TEMP_CHECKSUM"
exit 1
fi
fi
fi
# 7. Move file to installation directory and make it executable
if ! mv "$TEMP_FILE" "$INSTALL_DIR/$FILE_NAME"; then
echo -e "${RED}Error: Failed to move file to installation directory${NC}" >&2
rm -f "$TEMP_FILE" "$TEMP_CHECKSUM"
exit 1
fi
if ! chmod +x "$INSTALL_DIR/$FILE_NAME"; then
echo -e "${RED}Error: Failed to make file executable${NC}" >&2
rm -f "$INSTALL_DIR/$FILE_NAME" "$TEMP_CHECKSUM"
exit 1
fi
echo "Installed to $INSTALL_DIR/$FILE_NAME"
rm -f "$TEMP_CHECKSUM"
# 8. Add the directory to PATH if necessary
echo ""
echo "Updating PATH environment variable..."
# Check if the directory is already in PATH
if [[ ":$PATH:" == *":$INSTALL_DIR:"* ]]; then
echo "Directory is already in PATH."
else
echo -e "${YELLOW}Directory is not in PATH.${NC}"
# Determine which shell configuration file to update
if [[ -n "$ZSH_VERSION" ]]; then
SHELL_CONFIG="$HOME/.zshrc"
elif [[ -n "$BASH_VERSION" ]]; then
if [[ -f "$HOME/.bashrc" ]]; then
SHELL_CONFIG="$HOME/.bashrc"
elif [[ -f "$HOME/.bash_profile" ]]; then
SHELL_CONFIG="$HOME/.bash_profile"
fi
fi
if [[ -n "$SHELL_CONFIG" ]]; then
# Check if PATH export already exists in config file
if ! grep -q "export PATH=\"\$PATH:$INSTALL_DIR\"" "$SHELL_CONFIG" 2>/dev/null; then
echo "" >> "$SHELL_CONFIG"
echo "# Added by tea installer" >> "$SHELL_CONFIG"
echo "export PATH=\"\$PATH:$INSTALL_DIR\"" >> "$SHELL_CONFIG"
echo -e "${GREEN}Added to PATH in $SHELL_CONFIG${NC}"
echo "You may need to restart your terminal or run: source $SHELL_CONFIG"
else
echo "PATH entry already exists in $SHELL_CONFIG"
fi
else
echo -e "${YELLOW}Warning: Could not determine shell configuration file.${NC}"
echo "You may need to add '$INSTALL_DIR' to your PATH manually."
fi
fi
# 9. Verification
echo ""
echo "Verification:"
if command -v tea &> /dev/null; then
VERSION_OUTPUT=$(tea --version 2>&1)
echo -e "${GREEN}$VERSION_OUTPUT${NC}"
elif [[ -x "$INSTALL_DIR/$FILE_NAME" ]]; then
VERSION_OUTPUT=$("$INSTALL_DIR/$FILE_NAME" --version 2>&1)
echo -e "${GREEN}$VERSION_OUTPUT${NC}"
else
echo -e "${YELLOW}Warning: Could not execute tea. PATH may not be updated in this session.${NC}"
fi
echo ""
echo -e "${CYAN}Installation complete! Run 'tea login add' to start configuring your Gitea instance.${NC}"
if [[ ":$PATH:" != *":$INSTALL_DIR:"* ]]; then
echo -e "${YELLOW}Note: If 'tea' command is not found, restart your terminal or reload PATH with:${NC}"
if [[ -n "$SHELL_CONFIG" ]]; then
echo -e "${GRAY} source $SHELL_CONFIG${NC}"
else
echo -e "${GRAY} export PATH=\"\$PATH:$INSTALL_DIR\"${NC}"
fi
fi

258
powershell/download-tea.ps1 Normal file
View File

@@ -0,0 +1,258 @@
<#
.SYNOPSIS
Downloads and installs the Gitea Tea CLI tool for Windows.
.DESCRIPTION
This script automatically downloads, verifies, and installs the Tea CLI (Gitea command-line tool).
It supports automatic detection of the latest version, SHA256 checksum verification, and intelligent
installation location based on administrator privileges.
.PARAMETER TeaVersion
Specifies the version of Tea to install. If not provided, the script will automatically fetch
the latest version from the Gitea releases page.
.PARAMETER Force
Bypasses the overwrite confirmation prompt if Tea is already installed.
.EXAMPLE
.\download-tea.ps1
Automatically detects and installs the latest version of Tea.
.EXAMPLE
.\download-tea.ps1 -TeaVersion "0.11.1"
Installs a specific version of Tea (v0.11.1).
.EXAMPLE
.\download-tea.ps1 -Force
Installs the latest version and overwrites any existing installation without prompting.
.EXAMPLE
.\download-tea.ps1 -TeaVersion "0.11.1" -Force
Installs version 0.11.1 and overwrites existing installation without prompting.
.NOTES
- Requires internet connection to download from https://gitea.com
- Automatically detects system architecture (AMD64 or 386)
- Installation location:
* With Admin rights: C:\Program Files\tea
* Without Admin rights: %LOCALAPPDATA%\Programs\tea
- Automatically updates PATH environment variable
- After installation, restart your terminal or reload PATH with:
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","User") + ";" + [System.Environment]::GetEnvironmentVariable("Path","Machine")
.LINK
https://gitea.com/gitea/tea
#>
# Parameters
param(
[string]$TeaVersion,
[switch]$Force
)
# 1. Determine version to install
if (-not $TeaVersion) {
Write-Host "No version specified. Fetching latest release..."
try {
# Fetch the releases page and parse HTML to find the latest version
$releasePage = Invoke-WebRequest -Uri "https://gitea.com/gitea/tea/releases" -UseBasicParsing -ErrorAction Stop
# Parse the HTML to find the latest version tag (format: /gitea/tea/releases/tag/v0.x.x)
if ($releasePage.Content -match '/gitea/tea/releases/tag/v([\d.]+)') {
$TeaVersion = $matches[1]
Write-Host "Latest version found: v$TeaVersion" -ForegroundColor Green
}
else {
Write-Error "Could not determine the latest version from the releases page."
Write-Host "Please specify a version manually using -TeaVersion parameter."
exit 1
}
}
catch {
Write-Error "Failed to fetch latest version: $($_.Exception.Message)"
Write-Host "Please specify a version manually using -TeaVersion parameter."
exit 1
}
}
else {
Write-Host "Using specified version: v$TeaVersion"
}
# 2. Define variables for the download
# Detect system architecture (AMD64 = 64-bit, 386 = 32-bit)
$Architecture = if ($env:PROCESSOR_ARCHITECTURE -eq "AMD64") { "amd64" } else { "386" }
# Construct download URLs
$DownloadUrl = "https://gitea.com/gitea/tea/releases/download/v$TeaVersion/tea-$TeaVersion-windows-$Architecture.exe"
$ChecksumUrl = "https://gitea.com/gitea/tea/releases/download/v$TeaVersion/checksums.txt"
# Determine installation directory based on admin privileges
# Admin: Install to Program Files (system-wide)
# Non-Admin: Install to user's AppData (user-specific)
$IsAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
$InstallDir = if ($IsAdmin) { "C:\Program Files\tea" } else { "$env:LOCALAPPDATA\Programs\tea" }
# Define file names and temp locations
$FileName = "tea.exe"
$TempFile = "$env:TEMP\tea-$TeaVersion.exe"
$TempChecksum = "$env:TEMP\tea-checksums.txt"
# 3. Check if file already exists
if ((Test-Path -Path "$InstallDir\$FileName") -and -not $Force) {
# Prompt user before overwriting existing installation
$response = Read-Host "tea.exe already exists in $InstallDir. Overwrite? (Y/N)"
if ($response -ne 'Y' -and $response -ne 'y') {
Write-Host "Installation cancelled."
exit 0
}
}
# 4. Create the installation directory if it doesn't exist
Write-Host "Creating installation directory: $InstallDir"
if (-not (Test-Path -Path $InstallDir)) {
New-Item -Path $InstallDir -ItemType Directory -Force | Out-Null
}
# 5. Download the binary and checksum
Write-Host "Downloading tea CLI v$TeaVersion for $Architecture..."
try {
# Download to temp location first for safety
Invoke-WebRequest -Uri $DownloadUrl -OutFile $TempFile -UseBasicParsing -ErrorAction Stop
Write-Host "Binary downloaded successfully."
}
catch {
Write-Error "Failed to download the file. Please check the URL and version number. Error: $($_.Exception.Message)"
# Cleanup temp files on failure
Remove-Item -Path $TempFile -ErrorAction SilentlyContinue
exit 1
}
# Try to download checksum file for verification (optional but recommended)
$checksumAvailable = $false
try {
Write-Host "Attempting to download checksum file..."
Invoke-WebRequest -Uri $ChecksumUrl -OutFile $TempChecksum -UseBasicParsing -ErrorAction Stop
$checksumAvailable = $true
Write-Host "Checksum file downloaded."
}
catch {
Write-Warning "Checksum file not available for this version. Skipping verification."
}
# 6. Verify checksum (if available)
if ($checksumAvailable) {
Write-Host "Verifying file integrity..."
try {
# Calculate SHA256 hash of downloaded file
$downloadedHash = (Get-FileHash -Path $TempFile -Algorithm SHA256).Hash.ToLower()
# Parse checksums.txt to find the hash for our specific file
$expectedFileName = "tea-$TeaVersion-windows-$Architecture.exe"
$checksumContent = Get-Content -Path $TempChecksum -Raw
$expectedHash = $null
# checksums.txt format is: "hash filename"
foreach ($line in ($checksumContent -split "`n")) {
if ($line -match "^([a-fA-F0-9]+)\s+$expectedFileName") {
$expectedHash = $matches[1].ToLower()
break
}
}
if (-not $expectedHash) {
Write-Warning "Could not find checksum for $expectedFileName in checksums.txt"
$response = Read-Host "Continue without checksum verification? (Y/N)"
if ($response -ne 'Y' -and $response -ne 'y') {
Remove-Item -Path $TempFile -ErrorAction SilentlyContinue
Remove-Item -Path $TempChecksum -ErrorAction SilentlyContinue
exit 1
}
}
elseif ($downloadedHash -eq $expectedHash) {
Write-Host "Checksum verification passed." -ForegroundColor Green
}
else {
Write-Error "Checksum verification failed! Downloaded file may be corrupted or tampered with."
Write-Error "Expected: $expectedHash"
Write-Error "Got: $downloadedHash"
Remove-Item -Path $TempFile -ErrorAction SilentlyContinue
Remove-Item -Path $TempChecksum -ErrorAction SilentlyContinue
exit 1
}
}
catch {
Write-Warning "Could not verify checksum: $($_.Exception.Message)"
$response = Read-Host "Continue without checksum verification? (Y/N)"
if ($response -ne 'Y' -and $response -ne 'y') {
Remove-Item -Path $TempFile -ErrorAction SilentlyContinue
Remove-Item -Path $TempChecksum -ErrorAction SilentlyContinue
exit 1
}
}
}
# 7. Move file to installation directory
try {
Move-Item -Path $TempFile -Destination "$InstallDir\$FileName" -Force -ErrorAction Stop
Write-Host "Installed to $InstallDir\$FileName"
# Cleanup checksum file after successful installation
Remove-Item -Path $TempChecksum -ErrorAction SilentlyContinue
}
catch {
Write-Error "Failed to move file to installation directory: $($_.Exception.Message)"
Remove-Item -Path $TempFile -ErrorAction SilentlyContinue
Remove-Item -Path $TempChecksum -ErrorAction SilentlyContinue
exit 1
}
# 8. Add the directory to PATH
Write-Host ""
Write-Host "Updating PATH environment variable..."
try {
# Try Machine (system-wide) PATH first - requires Administrator privileges
$machinePath = [Environment]::GetEnvironmentVariable("Path", "Machine")
if ($machinePath -notlike "*$InstallDir*") {
[Environment]::SetEnvironmentVariable("Path", "$machinePath;$InstallDir", "Machine")
Write-Host "Added to system PATH (Machine level)." -ForegroundColor Green
Write-Host "You may need to restart your terminal for changes to take effect."
}
else {
Write-Host "Directory is already in system PATH."
}
}
catch {
Write-Warning "Could not modify System PATH (requires Administrator rights)."
Write-Host "Attempting to add to User PATH instead..."
# Fallback to User PATH - doesn't require Administrator privileges
try {
$userPath = [Environment]::GetEnvironmentVariable("Path", "User")
if ($userPath -notlike "*$InstallDir*") {
[Environment]::SetEnvironmentVariable("Path", "$userPath;$InstallDir", "User")
Write-Host "Added to User PATH." -ForegroundColor Green
Write-Host "You may need to restart your terminal for changes to take effect."
}
else {
Write-Host "Directory is already in User PATH."
}
}
catch {
Write-Warning "Could not modify User PATH either. You may need to add '$InstallDir' to your PATH manually."
}
}
# 9. Verification
Write-Host ""
Write-Host "Verification:"
try {
# Test the installation by running tea --version
$version = & "$InstallDir\$FileName" --version 2>&1
Write-Host $version -ForegroundColor Green
}
catch {
Write-Warning "Could not execute tea. PATH may not be updated in this session."
}
Write-Host ""
Write-Host "Installation complete! Run 'tea login add' to start configuring your Gitea instance." -ForegroundColor Cyan
Write-Host "Note: If 'tea' command is not found, restart your terminal or reload PATH with:" -ForegroundColor Yellow
Write-Host ' $env:Path = [System.Environment]::GetEnvironmentVariable("Path","User") + ";" + [System.Environment]::GetEnvironmentVariable("Path","Machine")' -ForegroundColor Gray