Files
thrillwiki_django_no_react/shared/scripts/vm/automation-config.sh
pacnpal d504d41de2 feat: complete monorepo structure with frontend and shared resources
- Add complete backend/ directory with full Django application
- Add frontend/ directory with Vite + TypeScript setup ready for Next.js
- Add comprehensive shared/ directory with:
  - Complete documentation and memory-bank archives
  - Media files and avatars (letters, park/ride images)
  - Deployment scripts and automation tools
  - Shared types and utilities
- Add architecture/ directory with migration guides
- Configure pnpm workspace for monorepo development
- Update .gitignore to exclude .django_tailwind_cli/ build artifacts
- Preserve all historical documentation in shared/docs/memory-bank/
- Set up proper structure for full-stack development with shared resources
2025-08-23 18:40:07 -04:00

838 lines
26 KiB
Bash
Executable File

#!/bin/bash
#
# ThrillWiki Automation Configuration Library
# Centralized configuration management for bulletproof automation system
#
# Features:
# - Configuration file reading/writing with validation
# - GitHub PAT token management and validation
# - Environment variable management with secure file permissions
# - Configuration migration and backup utilities
# - Comprehensive error handling and logging
#
# [AWS-SECRET-REMOVED]====================================
# LIBRARY METADATA
# [AWS-SECRET-REMOVED]====================================
AUTOMATION_CONFIG_VERSION="1.0.0"
AUTOMATION_CONFIG_LOADED="true"
# [AWS-SECRET-REMOVED]====================================
# CONFIGURATION CONSTANTS
# [AWS-SECRET-REMOVED]====================================
# Configuration file paths
readonly CONFIG_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
readonly SYSTEMD_CONFIG_DIR="$CONFIG_DIR/scripts/systemd"
readonly VM_CONFIG_DIR="$CONFIG_DIR/scripts/vm"
# Environment configuration files
readonly ENV_EXAMPLE_FILE="$SYSTEMD_CONFIG_DIR/thrillwiki-automation***REMOVED***.example"
readonly ENV_CONFIG_FILE="$SYSTEMD_CONFIG_DIR/thrillwiki-automation***REMOVED***"
readonly PROJECT_ENV_FILE="$CONFIG_DIR/***REMOVED***"
# GitHub authentication files
readonly GITHUB_TOKEN_FILE="$CONFIG_DIR/.github-pat"
readonly GITHUB_AUTH_SCRIPT="$CONFIG_DIR/scripts/github-auth.py"
readonly GITHUB_TOKEN_BACKUP="$CONFIG_DIR/.github-pat.backup"
# Service configuration
readonly SERVICE_NAME="thrillwiki-automation"
readonly SERVICE_FILE="$SYSTEMD_CONFIG_DIR/$SERVICE_NAME.service"
# Backup configuration
readonly CONFIG_BACKUP_DIR="$CONFIG_DIR/backups/config"
readonly MAX_BACKUPS=5
# [AWS-SECRET-REMOVED]====================================
# COLOR DEFINITIONS
# [AWS-SECRET-REMOVED]====================================
if [[ -z "${RED:-}" ]]; then
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
fi
# [AWS-SECRET-REMOVED]====================================
# LOGGING FUNCTIONS
# [AWS-SECRET-REMOVED]====================================
# Configuration-specific logging functions
config_log() {
local level="$1"
local color="$2"
local message="$3"
local timestamp="$(date '+%Y-%m-%d %H:%M:%S')"
echo -e "${color}[$timestamp] [CONFIG-$level]${NC} $message"
}
config_info() {
config_log "INFO" "$BLUE" "$1"
}
config_success() {
config_log "SUCCESS" "$GREEN" "$1"
}
config_warning() {
config_log "WARNING" "$YELLOW" "⚠️ $1"
}
config_error() {
config_log "ERROR" "$RED" "$1"
}
config_debug() {
if [[ "${CONFIG_DEBUG:-false}" == "true" ]]; then
config_log "DEBUG" "$PURPLE" "🔍 $1"
fi
}
# [AWS-SECRET-REMOVED]====================================
# UTILITY FUNCTIONS
# [AWS-SECRET-REMOVED]====================================
# Check if command exists
command_exists() {
command -v "$1" >/dev/null 2>&1
}
# Create directory with proper permissions if it doesn't exist
ensure_directory() {
local dir="$1"
local permissions="${2:-755}"
if [[ ! -d "$dir" ]]; then
config_debug "Creating directory: $dir"
mkdir -p "$dir"
chmod "$permissions" "$dir"
config_debug "Directory created with permissions $permissions"
fi
}
# Set secure file permissions
set_secure_permissions() {
local file="$1"
local permissions="${2:-600}"
if [[ -f "$file" ]]; then
chmod "$permissions" "$file"
config_debug "Set permissions $permissions on $file"
fi
}
# Backup a file with timestamp
backup_file() {
local source_file="$1"
local backup_dir="${2:-$CONFIG_BACKUP_DIR}"
if [[ ! -f "$source_file" ]]; then
config_debug "Source file does not exist for backup: $source_file"
return 1
fi
ensure_directory "$backup_dir"
local filename
filename=$(basename "$source_file")
local timestamp
timestamp=$(date '+%Y%m%d_%H%M%S')
local backup_file="$backup_dir/${filename}.${timestamp}.backup"
if cp "$source_file" "$backup_file"; then
config_debug "File backed up: $source_file -> $backup_file"
# Clean up old backups (keep only MAX_BACKUPS)
local backup_count
backup_count=$(find "$backup_dir" -name "${filename}.*.backup" | wc -l)
if [[ $backup_count -gt $MAX_BACKUPS ]]; then
config_debug "Cleaning up old backups (keeping $MAX_BACKUPS)"
find "$backup_dir" -name "${filename}.*.backup" -type f -printf '%T@ %p\n' | \
sort -n | head -n -"$MAX_BACKUPS" | cut -d' ' -f2- | \
xargs rm -f
fi
echo "$backup_file"
return 0
else
config_error "Failed to backup file: $source_file"
return 1
fi
}
# [AWS-SECRET-REMOVED]====================================
# CONFIGURATION FILE MANAGEMENT
# [AWS-SECRET-REMOVED]====================================
# Read configuration value from file
read_config_value() {
local key="$1"
local config_file="${2:-$ENV_CONFIG_FILE}"
local default_value="${3:-}"
config_debug "Reading config value: $key from $config_file"
if [[ ! -f "$config_file" ]]; then
config_debug "Config file not found: $config_file"
echo "$default_value"
return 1
fi
# Look for the key (handle both commented and uncommented lines)
local value
value=$(grep -E "^[#[:space:]]*${key}[[:space:]]*=" "$config_file" | \
grep -v "^[[:space:]]*#" | \
tail -1 | \
cut -d'=' -f2- | \
sed 's/^[[:space:]]*//' | \
sed 's/[[:space:]]*$//' | \
sed 's/^["'\'']\(.*\)["'\'']$/\1/')
if [[ -n "$value" ]]; then
echo "$value"
return 0
else
echo "$default_value"
return 1
fi
}
# Write configuration value to file
write_config_value() {
local key="$1"
local value="$2"
local config_file="${3:-$ENV_CONFIG_FILE}"
local create_if_missing="${4:-true}"
config_debug "Writing config value: $key=$value to $config_file"
# Create config file from example if it doesn't exist
if [[ ! -f "$config_file" ]] && [[ "$create_if_missing" == "true" ]]; then
if [[ -f "$ENV_EXAMPLE_FILE" ]]; then
config_info "Creating config file from template: $config_file"
cp "$ENV_EXAMPLE_FILE" "$config_file"
set_secure_permissions "$config_file" 600
else
config_info "Creating new config file: $config_file"
touch "$config_file"
set_secure_permissions "$config_file" 600
fi
fi
# Backup existing file
backup_file "$config_file" >/dev/null
# Check if key already exists
if grep -q "^[#[:space:]]*${key}[[:space:]]*=" "$config_file" 2>/dev/null; then
# Update existing key
config_debug "Updating existing key: $key"
# Use a temporary file for safe updating
local temp_file
temp_file=$(mktemp)
# Process the file line by line
while IFS= read -r line || [[ -n "$line" ]]; do
if [[ "$line" =~ ^[#[:space:]]*${key}[[:space:]]*= ]]; then
# Replace this line with the new value
echo "$key=$value"
config_debug "Replaced line: $line -> $key=$value"
else
echo "$line"
fi
done < "$config_file" > "$temp_file"
# Replace original file
mv "$temp_file" "$config_file"
set_secure_permissions "$config_file" 600
else
# Add new key
config_debug "Adding new key: $key"
echo "$key=$value" >> "$config_file"
fi
config_success "Configuration updated: $key"
return 0
}
# Remove configuration value from file
remove_config_value() {
local key="$1"
local config_file="${2:-$ENV_CONFIG_FILE}"
config_debug "Removing config value: $key from $config_file"
if [[ ! -f "$config_file" ]]; then
config_warning "Config file not found: $config_file"
return 1
fi
# Backup existing file
backup_file "$config_file" >/dev/null
# Remove the key using sed
sed -i.tmp "/^[#[:space:]]*${key}[[:space:]]*=/d" "$config_file"
rm -f "${config_file}.tmp"
config_success "Configuration removed: $key"
return 0
}
# Validate configuration file
validate_config_file() {
local config_file="${1:-$ENV_CONFIG_FILE}"
local errors=0
config_info "Validating configuration file: $config_file"
if [[ ! -f "$config_file" ]]; then
config_error "Configuration file not found: $config_file"
return 1
fi
# Check file permissions
local perms
perms=$(stat -c "%a" "$config_file" 2>/dev/null || stat -f "%A" "$config_file" 2>/dev/null)
if [[ "$perms" != "600" ]] && [[ "$perms" != "0600" ]]; then
config_warning "Configuration file has insecure permissions: $perms (should be 600)"
((errors++))
fi
# Check for required variables if GitHub token is configured
local github_token
github_token=$(read_config_value "GITHUB_TOKEN" "$config_file")
if [[ -n "$github_token" ]]; then
config_debug "GitHub token found in configuration"
# Check token format
if [[ ! "$github_token" =~ ^gh[pousr]_[A-Za-z0-9_]{36,255}$ ]]; then
config_warning "GitHub token format appears invalid"
((errors++))
fi
fi
# Check syntax by sourcing in a subshell
if ! (source "$config_file" >/dev/null 2>&1); then
config_error "Configuration file has syntax errors"
((errors++))
fi
if [[ $errors -eq 0 ]]; then
config_success "Configuration file validation passed"
return 0
else
config_error "Configuration file validation failed with $errors errors"
return 1
fi
}
# [AWS-SECRET-REMOVED]====================================
# GITHUB PAT TOKEN MANAGEMENT
# [AWS-SECRET-REMOVED]====================================
# Validate GitHub PAT token format
validate_github_token_format() {
local token="$1"
if [[ -z "$token" ]]; then
config_debug "Empty token provided"
return 1
fi
# GitHub token formats:
# - Classic PAT: ghp_[36-40 chars]
# - Fine-grained PAT: github_pat_[40+ chars]
# - OAuth token: gho_[36-40 chars]
# - User token: ghu_[36-40 chars]
# - Server token: ghs_[36-40 chars]
# - Refresh token: ghr_[36-40 chars]
if [[ "$token" =~ ^gh[pousr]_[A-Za-z0-9_]{36,255}$ ]] || [[ "$token" =~ ^github_pat_[A-Za-z0-9_]{40,255}$ ]]; then
config_debug "Token format is valid"
return 0
else
config_debug "Token format is invalid"
return 1
fi
}
# Test GitHub PAT token by making API call
test_github_token() {
local token="$1"
local timeout="${2:-10}"
config_debug "Testing GitHub token with API call"
if [[ -z "$token" ]]; then
config_error "No token provided for testing"
return 1
fi
# Test with GitHub API
local response
local http_code
response=$(curl -s -w "%{http_code}" \
--max-time "$timeout" \
-H "Authorization: Bearer $token" \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"https://api.github.com/user" 2>/dev/null)
http_code="${response: -3}"
case "$http_code" in
200)
config_debug "GitHub token is valid"
return 0
;;
401)
config_error "GitHub token is invalid or expired"
return 1
;;
403)
config_error "GitHub token lacks required permissions"
return 1
;;
*)
config_error "GitHub API request failed with HTTP $http_code"
return 1
;;
esac
}
# Get GitHub user information using PAT
get_github_user_info() {
local token="$1"
local timeout="${2:-10}"
if [[ -z "$token" ]]; then
config_error "No token provided"
return 1
fi
config_debug "Fetching GitHub user information"
local response
response=$(curl -s --max-time "$timeout" \
-H "Authorization: Bearer $token" \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"https://api.github.com/user" 2>/dev/null)
if [[ $? -eq 0 ]] && [[ -n "$response" ]]; then
# Extract key information using simple grep/sed (avoid jq dependency)
local login
local name
local email
login=$(echo "$response" | grep -o '"login"[[:space:]]*:[[:space:]]*"[^"]*"' | sed 's/.*"login"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/')
name=$(echo "$response" | grep -o '"name"[[:space:]]*:[[:space:]]*"[^"]*"' | sed 's/.*"name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/')
email=$(echo "$response" | grep -o '"email"[[:space:]]*:[[:space:]]*"[^"]*"' | sed 's/.*"email"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/')
echo "login:$login"
echo "name:$name"
echo "email:$email"
return 0
else
config_error "Failed to fetch GitHub user information"
return 1
fi
}
# Store GitHub PAT token securely
store_github_token() {
local token="$1"
local token_file="${2:-$GITHUB_TOKEN_FILE}"
config_debug "Storing GitHub token to: $token_file"
if [[ -z "$token" ]]; then
config_error "No token provided for storage"
return 1
fi
# Validate token format
if ! validate_github_token_format "$token"; then
config_error "Invalid GitHub token format"
return 1
fi
# Test token before storing
if ! test_github_token "$token"; then
config_error "GitHub token validation failed"
return 1
fi
# Backup existing token file
if [[ -f "$token_file" ]]; then
backup_file "$token_file" >/dev/null
fi
# Store token with secure permissions
echo "$token" > "$token_file"
set_secure_permissions "$token_file" 600
# Also store in environment configuration
write_config_value "GITHUB_TOKEN" "$token"
config_success "GitHub token stored successfully"
return 0
}
# Load GitHub PAT token from various sources
load_github_token() {
config_debug "Loading GitHub token from available sources"
local token=""
# Priority order:
# 1. Environment variable GITHUB_TOKEN
# 2. Token file
# 3. Configuration file
# 4. GitHub auth script
# Check environment variable
if [[ -n "${GITHUB_TOKEN:-}" ]]; then
config_debug "Using GitHub token from environment variable"
token="$GITHUB_TOKEN"
# Check token file
elif [[ -f "$GITHUB_TOKEN_FILE" ]]; then
config_debug "Loading GitHub token from file: $GITHUB_TOKEN_FILE"
token=$(cat "$GITHUB_TOKEN_FILE" 2>/dev/null | tr -d '\n\r')
# Check configuration file
elif [[ -f "$ENV_CONFIG_FILE" ]]; then
config_debug "Loading GitHub token from config file"
token=$(read_config_value "GITHUB_TOKEN")
# Try GitHub auth script
elif [[ -x "$GITHUB_AUTH_SCRIPT" ]]; then
config_debug "Attempting to get token from GitHub auth script"
token=$(python3 "$GITHUB_AUTH_SCRIPT" token 2>/dev/null || echo "")
fi
if [[ -n "$token" ]]; then
# Validate token
if validate_github_token_format "$token" && test_github_token "$token"; then
export GITHUB_TOKEN="$token"
config_debug "GitHub token loaded and validated successfully"
return 0
else
config_warning "Loaded GitHub token is invalid"
return 1
fi
else
config_debug "No GitHub token found"
return 1
fi
}
# Remove GitHub PAT token
remove_github_token() {
local token_file="${1:-$GITHUB_TOKEN_FILE}"
config_info "Removing GitHub token"
# Remove token file
if [[ -f "$token_file" ]]; then
backup_file "$token_file" >/dev/null
rm -f "$token_file"
config_debug "Token file removed: $token_file"
fi
# Remove from configuration
remove_config_value "GITHUB_TOKEN"
# Clear environment variable
unset GITHUB_TOKEN
config_success "GitHub token removed successfully"
return 0
}
# [AWS-SECRET-REMOVED]====================================
# MIGRATION AND UPGRADE UTILITIES
# [AWS-SECRET-REMOVED]====================================
# Migrate configuration from old format to new format
migrate_configuration() {
config_info "Checking for configuration migration needs"
local migration_needed=false
# Check for old configuration files
local old_configs=(
"$CONFIG_DIR/***REMOVED***.automation"
"$CONFIG_DIR/automation.conf"
"$CONFIG_DIR/config***REMOVED***"
)
for old_config in "${old_configs[@]}"; do
if [[ -f "$old_config" ]]; then
config_info "Found old configuration file: $old_config"
migration_needed=true
# Backup old config
backup_file "$old_config" >/dev/null
# Migrate values if possible
if [[ -r "$old_config" ]]; then
config_info "Migrating values from $old_config"
# Simple migration - source old config and write values to new config
while IFS='=' read -r key value; do
# Skip comments and empty lines
[[ "$key" =~ ^[[:space:]]*# ]] && continue
[[ -z "$key" ]] && continue
# Clean up key and value
key=$(echo "$key" | sed 's/^[[:space:]]*//' | sed 's/[[:space:]]*$//')
value=$(echo "$value" | sed 's/^[[:space:]]*//' | sed 's/[[:space:]]*$//' | sed 's/^["'\'']\(.*\)["'\'']$/\1/')
if [[ -n "$key" ]] && [[ -n "$value" ]]; then
write_config_value "$key" "$value"
config_debug "Migrated: $key=$value"
fi
done < "$old_config"
fi
fi
done
if [[ "$migration_needed" == "true" ]]; then
config_success "Configuration migration completed"
else
config_debug "No migration needed"
fi
return 0
}
# [AWS-SECRET-REMOVED]====================================
# SYSTEM INTEGRATION
# [AWS-SECRET-REMOVED]====================================
# Check if systemd service is available and configured
check_systemd_service() {
config_debug "Checking systemd service configuration"
if ! command_exists systemctl; then
config_warning "systemd not available on this system"
return 1
fi
if [[ ! -f "$SERVICE_FILE" ]]; then
config_warning "Service file not found: $SERVICE_FILE"
return 1
fi
# Check if service is installed
if systemctl list-unit-files "$SERVICE_NAME.service" >/dev/null 2>&1; then
config_debug "Service is installed: $SERVICE_NAME"
# Check service status
local status
status=$(systemctl is-active "$SERVICE_NAME" 2>/dev/null || echo "inactive")
config_debug "Service status: $status"
return 0
else
config_debug "Service is not installed: $SERVICE_NAME"
return 1
fi
}
# Get systemd service status
get_service_status() {
if ! command_exists systemctl; then
echo "systemd_unavailable"
return 1
fi
local status
status=$(systemctl is-active "$SERVICE_NAME" 2>/dev/null || echo "inactive")
echo "$status"
case "$status" in
active)
return 0
;;
inactive|failed)
return 1
;;
*)
return 2
;;
esac
}
# [AWS-SECRET-REMOVED]====================================
# MAIN CONFIGURATION INTERFACE
# [AWS-SECRET-REMOVED]====================================
# Show current configuration status
show_config_status() {
config_info "ThrillWiki Automation Configuration Status"
echo "[AWS-SECRET-REMOVED]======"
echo ""
# Project information
echo "📁 Project Directory: $CONFIG_DIR"
echo "🔧 Configuration Version: $AUTOMATION_CONFIG_VERSION"
echo ""
# Configuration files
echo "📄 Configuration Files:"
if [[ -f "$ENV_CONFIG_FILE" ]]; then
echo " ✅ Environment config: $ENV_CONFIG_FILE"
local perms
perms=$(stat -c "%a" "$ENV_CONFIG_FILE" 2>/dev/null || stat -f "%A" "$ENV_CONFIG_FILE" 2>/dev/null)
echo " Permissions: $perms"
else
echo " ❌ Environment config: Not found"
fi
if [[ -f "$ENV_EXAMPLE_FILE" ]]; then
echo " ✅ Example config: $ENV_EXAMPLE_FILE"
else
echo " ❌ Example config: Not found"
fi
echo ""
# GitHub authentication
echo "🔐 GitHub Authentication:"
if load_github_token >/dev/null 2>&1; then
echo " ✅ GitHub token: Available and valid"
# Get user info
local user_info
user_info=$(get_github_user_info "$GITHUB_TOKEN" 2>/dev/null)
if [[ -n "$user_info" ]]; then
local login
login=$(echo "$user_info" | grep "^login:" | cut -d: -f2)
if [[ -n "$login" ]]; then
echo " Authenticated as: $login"
fi
fi
else
echo " ❌ GitHub token: Not available or invalid"
fi
if [[ -f "$GITHUB_TOKEN_FILE" ]]; then
echo " ✅ Token file: $GITHUB_TOKEN_FILE"
else
echo " ❌ Token file: Not found"
fi
echo ""
# Systemd service
echo "⚙️ Systemd Service:"
if check_systemd_service; then
echo " ✅ Service file: Available"
local status
status=$(get_service_status)
echo " Status: $status"
else
echo " ❌ Service: Not configured or available"
fi
echo ""
# Backups
echo "💾 Backups:"
if [[ -d "$CONFIG_BACKUP_DIR" ]]; then
local backup_count
backup_count=$(find "$CONFIG_BACKUP_DIR" -name "*.backup" 2>/dev/null | wc -l)
echo " 📦 Backup directory: $CONFIG_BACKUP_DIR"
echo " 📊 Backup files: $backup_count"
else
echo " ❌ No backup directory found"
fi
}
# Initialize configuration system
init_configuration() {
config_info "Initializing ThrillWiki automation configuration"
# Create necessary directories
ensure_directory "$CONFIG_BACKUP_DIR"
ensure_directory "$(dirname "$ENV_CONFIG_FILE")"
# Run migration if needed
migrate_configuration
# Create configuration file from example if it doesn't exist
if [[ ! -f "$ENV_CONFIG_FILE" ]] && [[ -f "$ENV_EXAMPLE_FILE" ]]; then
config_info "Creating configuration file from template"
cp "$ENV_EXAMPLE_FILE" "$ENV_CONFIG_FILE"
set_secure_permissions "$ENV_CONFIG_FILE" 600
config_success "Configuration file created: $ENV_CONFIG_FILE"
fi
# Validate configuration
validate_config_file
config_success "Configuration system initialized"
return 0
}
# [AWS-SECRET-REMOVED]====================================
# COMMAND LINE INTERFACE
# [AWS-SECRET-REMOVED]====================================
# Show help information
show_config_help() {
echo "ThrillWiki Automation Configuration Library v$AUTOMATION_CONFIG_VERSION"
echo "Usage: source automation-config.sh"
echo ""
echo "Available Functions:"
echo " Configuration Management:"
echo " read_config_value <key> [file] [default] - Read configuration value"
echo " write_config_value <key> <value> [file] - Write configuration value"
echo " remove_config_value <key> [file] - Remove configuration value"
echo " validate_config_file [file] - Validate configuration file"
echo ""
echo " GitHub Token Management:"
echo " load_github_token - Load GitHub token from sources"
echo " store_github_token <token> [file] - Store GitHub token securely"
echo " test_github_token <token> - Test GitHub token validity"
echo " remove_github_token [file] - Remove GitHub token"
echo ""
echo " System Status:"
echo " show_config_status - Show configuration status"
echo " check_systemd_service - Check systemd service status"
echo " get_service_status - Get service active status"
echo ""
echo " Utilities:"
echo " init_configuration - Initialize configuration system"
echo " migrate_configuration - Migrate old configuration"
echo " backup_file <file> [backup_dir] - Backup file with timestamp"
echo ""
echo "Configuration Files:"
echo " $ENV_CONFIG_FILE"
echo " $GITHUB_TOKEN_FILE"
echo ""
}
# If script is run directly (not sourced), show help
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
show_config_help
exit 0
fi
# Export key functions for use by other scripts
export -f read_config_value write_config_value remove_config_value validate_config_file
export -f load_github_token store_github_token test_github_token remove_github_token
export -f show_config_status check_systemd_service get_service_status
export -f init_configuration migrate_configuration backup_file
export -f config_info config_success config_warning config_error config_debug
config_debug "Automation configuration library loaded successfully"