Files
crumbmissions/lib/waldwaechter.sh
Branko May Trinkwald 599af5b011 New: Crumb Memo - Output-Transparenz System
Neue Befehle für kreatives Output-Tracking:
- crumb_memo <link> [notiz] - Kreativen Link festhalten
- crew_memo - Alle kreativen Krümel anzeigen

Features:
• Auto-Erkennung von Plattformen:
  🎧 Mixcloud, 🔊 SoundCloud, 📹 YouTube, 💾 Git
• Zeitstempel & Notizen
• JSON-basiert in logs/crumb_memo.json
• Statistik nach Typ

Philosophie:
Input-Transparenz (crew_tokens) + Output-Transparenz (crew_memo)
= Vollständige Sichtbarkeit der Krümel im Nullfeld

"Was habe ich geschaffen?" 💚

Beispiel:
  crumb_memo "https://mixcloud.com/digfafunk/" "New Mix"
  crew_memo

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-21 23:01:47 +01:00

654 lines
21 KiB
Bash

#!/bin/bash
# 🌲 Waldwächter Library - AI Assistants for Crumbforest Missions
# Source this file to make all AI characters available as commands
# Determine the repo root directory (lib/ is inside repo root)
# Support both bash and zsh
if [[ -n "$BASH_VERSION" ]]; then
# Bash: use BASH_SOURCE
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
elif [[ -n "$ZSH_VERSION" ]]; then
# Zsh: use ${(%):-%x} to get the script path
SCRIPT_DIR="$(cd "$(dirname "${(%):-%x}")" && pwd)"
else
# Fallback: use $0 (may not work when sourced)
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
fi
WALDWAECHTER_DIR="$(dirname "$SCRIPT_DIR")"
ROLES_DIR="${WALDWAECHTER_DIR}/crumbforest_roles"
# Set logs directory in repo
export CRUMB_LOGS_DIR="${WALDWAECHTER_DIR}/logs"
mkdir -p "${CRUMB_LOGS_DIR}"
# Load .env if it exists
ENV_FILE="${WALDWAECHTER_DIR}/.env"
if [[ -f "${ENV_FILE}" ]]; then
set -a
source "${ENV_FILE}"
set +a
fi
# 🦉 Maya-Eule - Die weise Eule mit Gedächtnis
function mayaeule() {
"${ROLES_DIR}/mayaeule_zero.sh" "$@"
}
# 🔧 Deepbit - Bash-Erklärer
function deepbit() {
"${ROLES_DIR}/deepbit_zero.sh" "$@"
}
# 🐛 Bugsy - Debugging-Helfer
function bugsy() {
"${ROLES_DIR}/bugsy_zero.sh" "$@"
}
# ✂️ Schnippsi - Shell-Helfer
function schnippsi() {
"${ROLES_DIR}/schnippsi_zero.sh" "$@"
}
# 📄 Templatus - HTML/Template-Helfer
function templatus() {
"${ROLES_DIR}/templatus_zero.sh" "$@"
}
# 📊 Tobi - JSON/Daten-Helfer
function tobi() {
"${ROLES_DIR}/tobi_zero.sh" "$@"
}
# 🔧 Schraubbär - Schweres Gerät, Schweißen, Werkzeug
function schraubaer() {
"${ROLES_DIR}/schraubaer_zero_final.sh" "$@"
}
# 🐌 Schnecki - Elektronik-Bastler
function schnecki() {
"${ROLES_DIR}/schnecki_zero.sh" "$@"
}
# === DAS DREIECK ===
# 🐘 DumboSQL - Nie vergessend
function dumbosql() {
"${ROLES_DIR}/dumbosql_zero.sh" "$@"
}
# 🦊 FunkFox - Bash Rapper
function funkfox() {
"${ROLES_DIR}/funkfox_zero.sh" "$@"
}
# 🕊️ Taichi Taube - Balance & Spirale
function taichitaube() {
"${ROLES_DIR}/taichitaube_zero.sh" "$@"
}
# === DIE RESTLICHEN WALDWÄCHTER ===
# 🐍 SnakePy - Python Guide
function snakepy() {
"${ROLES_DIR}/snakepy_zero.sh" "$@"
}
# 🧓 PepperPHP - Structure Mentor
function pepperphp() {
"${ROLES_DIR}/pepperphp_zero.sh" "$@"
}
# 🦀 CrabbyRust - Security Guardian
function crabbyrust() {
"${ROLES_DIR}/crabbyrust_zero.sh" "$@"
}
# 🕷️ Spider - Network Feeler
function spider() {
"${ROLES_DIR}/spider_zero.sh" "$@"
}
# 🧭 Vektor - Point-to-Point Guide
function vektor() {
"${ROLES_DIR}/vektor_zero.sh" "$@"
}
# 👾 ASCII-Monster - Terminal Artist
function asciimonster() {
"${ROLES_DIR}/asciimonster_zero.sh" "$@"
}
# === CREW COMMANDS ===
# 📊 crew_tokens - Token-Verbrauch aller Waldwächter
function crew_tokens() {
# Force C locale for consistent number formatting
export LC_NUMERIC=C
echo "📊 CrumbCrew Token-Verbrauch"
echo ""
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
local total_tokens=0
local total_cost=0
local crew_count=0
# Alle token_log.json Dateien finden und auswerten
for token_file in "${CRUMB_LOGS_DIR}"/*/token_log.json; do
if [[ -f "$token_file" ]]; then
local character=$(basename "$(dirname "$token_file")")
# Tokens und Kosten aus JSON extrahieren (skip erste Zeile falls es [] ist)
local char_tokens=$(grep -v '^\[\]$' "$token_file" | jq -s 'map(.usage.total_tokens // 0) | add // 0' 2>/dev/null || echo 0)
local char_cost=$(grep -v '^\[\]$' "$token_file" | jq -s 'map(.usage.cost // 0) | add // 0' 2>/dev/null || echo 0)
if [[ $char_tokens -gt 0 ]]; then
printf " %-15s %8d tokens (~\$%.6f)\n" "$character:" "$char_tokens" "$char_cost"
total_tokens=$((total_tokens + char_tokens))
total_cost=$(echo "$total_cost + $char_cost" | bc -l)
crew_count=$((crew_count + 1))
fi
fi
done
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
if [[ $total_tokens -gt 0 ]]; then
printf " Gesamt: %d Tokens (~\$%.6f)\n" "$total_tokens" "$total_cost"
printf " %d Waldwächter aktiv 🌲\n" "$crew_count"
else
echo " Gesamt: 0 Tokens"
echo " Jede Frage ist wertvoll 🌲"
fi
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
# Restore locale
unset LC_NUMERIC
}
# 📋 crew_status - Status aller Waldwächter
function crew_status() {
echo "📋 CrumbCrew Status (17 Waldwächter)"
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
local chars=("mayaeule" "deepbit" "bugsy" "schnippsi" "templatus" "tobi" "schraubaer" "schnecki" "dumbosql" "funkfox" "taichitaube" "snakepy" "pepperphp" "crabbyrust" "spider" "vektor" "asciimonster")
for char in "${chars[@]}"; do
local token_file="${CRUMB_LOGS_DIR}/${char}/token_log.json"
if [[ -f "$token_file" ]] && grep -q -v '^\[\]$' "$token_file" 2>/dev/null; then
local last_used=$(grep -v '^\[\]$' "$token_file" | tail -1 | jq -r '.zeit // "unknown"' 2>/dev/null || echo "unknown")
printf " ✅ %-15s (zuletzt: %s)\n" "$char" "$last_used"
else
printf " ⚪ %-15s (noch nicht genutzt)\n" "$char"
fi
done
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
}
# 🧠 crew_memory - Erinnerungen durchsuchen
function crew_memory() {
local query="$1"
if [[ -z "$query" ]]; then
echo "🧠 Crew Memory - Log-basiertes Gedächtnis"
echo ""
echo "Verwendung: crew_memory <suchbegriff>"
echo ""
echo "Beispiele:"
echo " crew_memory 'LED'"
echo " crew_memory 'sensor'"
echo ""
echo "Durchsucht alle Waldwächter-Logs nach dem Begriff."
return
fi
echo "🧠 Suche nach: '$query'"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
local found=0
for history_file in "${CRUMB_LOGS_DIR}"/*/$(basename "${history_file}" | grep '_history.json$'); do
if [[ -f "$history_file" ]]; then
local character=$(basename "$(dirname "$history_file")")
local matches=$(grep -i "$query" "$history_file" 2>/dev/null)
if [[ -n "$matches" ]]; then
echo ""
echo "📍 $character:"
echo "$matches" | jq -r '.content' 2>/dev/null | head -3
found=$((found + 1))
fi
fi
done
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
if [[ $found -gt 0 ]]; then
echo " Gefunden in $found Waldwächter-Logs"
else
echo " Keine Treffer gefunden"
fi
}
# 🩺 crew_doctor - System-Diagnose
function crew_doctor() {
echo "🩺 CrumbCrew System-Diagnose"
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
local issues=0
# 1. Waldwaechter.sh Version Check
echo "📋 Checking waldwaechter.sh..."
local lib_file="${WALDWAECHTER_DIR}/lib/waldwaechter.sh"
if [[ -f "$lib_file" ]]; then
local lib_mtime=$(stat -f "%m" "$lib_file" 2>/dev/null || stat -c "%Y" "$lib_file" 2>/dev/null)
local loaded_check_var="WALDWAECHTER_LOADED_${lib_mtime}"
# Indirect variable expansion (bash: ${!var}, zsh: ${(P)var})
local loaded_value=""
if [[ -n "$BASH_VERSION" ]]; then
loaded_value="${!loaded_check_var}"
elif [[ -n "$ZSH_VERSION" ]]; then
loaded_value="${(P)loaded_check_var}"
fi
if [[ -z "$loaded_value" ]]; then
echo " ⚠️ waldwaechter.sh wurde aktualisiert!"
echo " → Bitte neu laden: source lib/waldwaechter.sh"
issues=$((issues + 1))
else
echo " ✅ waldwaechter.sh ist aktuell"
fi
else
echo " ❌ waldwaechter.sh nicht gefunden!"
issues=$((issues + 1))
fi
# 2. CRUMB_LOGS_DIR Check
echo ""
echo "📂 Checking CRUMB_LOGS_DIR..."
if [[ -d "$CRUMB_LOGS_DIR" ]]; then
echo "$CRUMB_LOGS_DIR existiert"
# Prüfe ob es der richtige Pfad ist (sollte im Repo sein)
if [[ "$CRUMB_LOGS_DIR" == *"CF_Zero_V1/logs"* ]]; then
echo " ✅ Pfad sieht korrekt aus"
else
echo " ⚠️ Pfad sieht ungewöhnlich aus: $CRUMB_LOGS_DIR"
echo " Erwartet: .../CF_Zero_V1/logs"
issues=$((issues + 1))
fi
else
echo "$CRUMB_LOGS_DIR existiert nicht!"
issues=$((issues + 1))
fi
# 3. Character Scripts Check
echo ""
echo "🌲 Checking 17 Waldwächter Scripts..."
local expected_chars=("mayaeule" "deepbit" "bugsy" "schnippsi" "templatus" "tobi" "schraubaer" "schnecki" "dumbosql" "funkfox" "taichitaube" "snakepy" "pepperphp" "crabbyrust" "spider" "vektor" "asciimonster")
local missing_count=0
for char in "${expected_chars[@]}"; do
local script="${ROLES_DIR}/${char}_zero.sh"
[[ "$char" == "schraubaer" ]] && script="${ROLES_DIR}/schraubaer_zero_final.sh"
if [[ ! -f "$script" ]]; then
echo "$char Script fehlt!"
missing_count=$((missing_count + 1))
fi
done
if [[ $missing_count -eq 0 ]]; then
echo " ✅ Alle 17 Waldwächter Scripts vorhanden"
else
echo "$missing_count Scripts fehlen!"
issues=$((issues + 1))
fi
# 4. Dependencies Check
echo ""
echo "🔧 Checking Dependencies..."
local deps_ok=0
for cmd in jq bc curl; do
if command -v "$cmd" &> /dev/null; then
echo "$cmd verfügbar"
deps_ok=$((deps_ok + 1))
else
echo "$cmd fehlt!"
issues=$((issues + 1))
fi
done
# 5. Token-Logging Check
echo ""
echo "📊 Checking Token-Logging..."
local scripts_with_logging=$(grep -l "token_log.json" "${ROLES_DIR}"/*.sh 2>/dev/null | wc -l | tr -d ' ')
if [[ $scripts_with_logging -eq 17 ]]; then
echo " ✅ Alle 17 Scripts haben Token-Logging"
else
echo " ⚠️ Nur $scripts_with_logging/17 Scripts haben Token-Logging"
issues=$((issues + 1))
fi
# 6. API Key Check
echo ""
echo "🔑 Checking API Key..."
if [[ -n "$OPENROUTER_API_KEY" ]]; then
echo " ✅ OPENROUTER_API_KEY gesetzt"
else
echo " ⚠️ OPENROUTER_API_KEY nicht gesetzt"
echo " → Bitte in .env konfigurieren"
issues=$((issues + 1))
fi
# Summary
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
if [[ $issues -eq 0 ]]; then
echo " ✅ Alle Checks bestanden! System gesund 💚"
else
echo " ⚠️ $issues Problem(e) gefunden"
echo " Bitte oben genannte Punkte beheben"
fi
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
}
# 🔍 crew_syntax - Syntax Check aller Scripts
function crew_syntax() {
echo "🔍 CrumbCrew Syntax Check"
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
local errors=0
local checked=0
echo "Prüfe Waldwächter Scripts..."
echo ""
# Check lib/waldwaechter.sh
if bash -n "${WALDWAECHTER_DIR}/lib/waldwaechter.sh" 2>/dev/null; then
echo " ✅ lib/waldwaechter.sh"
else
echo " ❌ lib/waldwaechter.sh - SYNTAX ERROR!"
bash -n "${WALDWAECHTER_DIR}/lib/waldwaechter.sh"
errors=$((errors + 1))
fi
checked=$((checked + 1))
# Check all character scripts
for script in "${ROLES_DIR}"/*_zero*.sh; do
if [[ -f "$script" ]]; then
local name=$(basename "$script")
if bash -n "$script" 2>/dev/null; then
echo "$name"
else
echo "$name - SYNTAX ERROR!"
echo ""
bash -n "$script" 2>&1 | sed 's/^/ /'
echo ""
errors=$((errors + 1))
fi
checked=$((checked + 1))
fi
done
# Check mission scripts (optional)
echo ""
echo "Prüfe Mission Scripts..."
echo ""
for script in "${WALDWAECHTER_DIR}/missions"/*/*.sh; do
if [[ -f "$script" ]]; then
local name=$(basename "$script")
if bash -n "$script" 2>/dev/null; then
echo "$name"
else
echo "$name - SYNTAX ERROR!"
errors=$((errors + 1))
fi
checked=$((checked + 1))
fi
done
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
if [[ $errors -eq 0 ]]; then
echo "$checked Scripts geprüft - Keine Syntax-Fehler! 💚"
else
echo "$errors von $checked Scripts haben Syntax-Fehler"
fi
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
}
# ❓ crew_help - Hilfe für Crew-Befehle
function crew_help() {
cat << 'EOF'
🌲 CrumbCrew Befehle
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Crew-Verwaltung:
crew_help Diese Hilfe anzeigen
crew_status Status aller 17 Waldwächter
crew_tokens Token-Verbrauch ALLER Charaktere (Input)
crew_memo Kreative Krümel anzeigen (Output)
crew_memory Erinnerungen durchsuchen
crew_doctor System-Diagnose (Version, Pfade, Dependencies)
crew_syntax Syntax Check aller Scripts
Krümel-Tracking:
crumb_memo Kreativen Link festhalten (Mixcloud, Git, etc.)
crew_memo Alle kreativen Krümel anzeigen
Einzelne Waldwächter:
🔺 Das Dreieck (Foundation):
dumbosql SQL & Datenstrukturen
funkfox Bash im Beat
taichitaube Balance & Spirale
🔧 Hardware-Team:
tobi Elektronik-Theorie (CapaciTobi)
schnecki Elektronik-Basteln
schraubaer Mechanik & Werkzeug
💻 Code-Team:
snakepy Python Guide
pepperphp Structure Mentor
crabbyrust Security Guardian
spider Network Feeler
🎨 UI-Team:
schnippsi CSS & Styling
templatus Template-Master
asciimonster Terminal Artist
🧭 System-Team:
mayaeule Weise Eule
deepbit Bash-Erklärer
bugsy Debugging-Helfer
vektor Navigation
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Beispiele:
funkfox "Erkläre mir Pipes im Flow!"
crew_tokens
crew_memory "LED"
"Was kostet die Frage eines Kindes?" 💚
EOF
}
# 📝 crumb_memo - Kreative Output-Krümel festhalten
function crumb_memo() {
local link="$1"
local notiz="${2:-}"
if [[ -z "$link" ]]; then
echo "📝 Crumb Memo - Kreative Output-Krümel"
echo ""
echo "Verwendung: crumb_memo <link> [notiz]"
echo ""
echo "Beispiele:"
echo " crumb_memo \"https://mixcloud.com/digfafunk/new-mix\""
echo " crumb_memo \"https://github.com/user/repo\" \"Neues Feature\""
echo " crumb_memo \"https://soundcloud.com/artist/track\""
echo " crumb_memo \"https://youtube.com/watch?v=xyz\" \"Tutorial\""
echo ""
echo "Zeige alle Krümel mit: crew_memo"
return
fi
# Memo-Datei
local memo_file="${CRUMB_LOGS_DIR}/crumb_memo.json"
mkdir -p "${CRUMB_LOGS_DIR}"
# Initialisiere Datei wenn nicht vorhanden
if [[ ! -f "$memo_file" ]]; then
echo "[]" > "$memo_file"
fi
# Erkenne Typ aus URL
local typ="link"
if [[ "$link" =~ mixcloud\.com ]]; then
typ="mixcloud"
elif [[ "$link" =~ soundcloud\.com ]]; then
typ="soundcloud"
elif [[ "$link" =~ (youtube\.com|youtu\.be) ]]; then
typ="youtube"
elif [[ "$link" =~ (github\.com|gitlab\.com) ]]; then
typ="git"
fi
# Zeitstempel
local zeit=$(date '+%Y-%m-%d %H:%M:%S')
# Erstelle JSON-Eintrag
local entry=$(jq -n \
--arg zeit "$zeit" \
--arg link "$link" \
--arg typ "$typ" \
--arg notiz "$notiz" \
'{zeit: $zeit, link: $link, typ: $typ, notiz: $notiz}')
# Füge zur Datei hinzu (append)
if [[ -s "$memo_file" ]]; then
# Datei hat Inhalt - füge zum Array hinzu
jq ". += [$entry]" "$memo_file" > "${memo_file}.tmp" && mv "${memo_file}.tmp" "$memo_file"
else
# Datei ist leer - erstelle Array
echo "[$entry]" > "$memo_file"
fi
# Icon je nach Typ
local icon="🔗"
case "$typ" in
mixcloud) icon="🎧" ;;
soundcloud) icon="🔊" ;;
youtube) icon="📹" ;;
git) icon="💾" ;;
esac
echo "$icon Krümel gespeichert: $typ"
echo " $link"
if [[ -n "$notiz" ]]; then
echo " 📝 $notiz"
fi
}
# 📜 crew_memo - Zeige alle kreativen Krümel
function crew_memo() {
local memo_file="${CRUMB_LOGS_DIR}/crumb_memo.json"
echo "📜 Crumb Memo - Deine kreativen Krümel"
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
if [[ ! -f "$memo_file" ]] || [[ ! -s "$memo_file" ]]; then
echo " Noch keine Krümel gespeichert."
echo ""
echo " Füge welche hinzu mit:"
echo " crumb_memo \"https://mixcloud.com/digfafunk/...\""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
return
fi
# Zähle Einträge pro Typ
local total=$(jq 'length' "$memo_file")
local mixcloud=$(jq '[.[] | select(.typ == "mixcloud")] | length' "$memo_file")
local soundcloud=$(jq '[.[] | select(.typ == "soundcloud")] | length' "$memo_file")
local youtube=$(jq '[.[] | select(.typ == "youtube")] | length' "$memo_file")
local git=$(jq '[.[] | select(.typ == "git")] | length' "$memo_file")
# Zeige letzte 10 Einträge
echo ""
jq -r '.[-10:] | reverse | .[] |
if .typ == "mixcloud" then " 🎧"
elif .typ == "soundcloud" then " 🔊"
elif .typ == "youtube" then " 📹"
elif .typ == "git" then " 💾"
else " 🔗"
end + " " + .zeit + " - " + .typ +
(if .notiz != "" then "\n 📝 " + .notiz else "" end) +
"\n " + .link' "$memo_file"
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
printf " Gesamt: %d Krümel" "$total"
if [[ $mixcloud -gt 0 ]]; then printf " | 🎧 %d" "$mixcloud"; fi
if [[ $soundcloud -gt 0 ]]; then printf " | 🔊 %d" "$soundcloud"; fi
if [[ $youtube -gt 0 ]]; then printf " | 📹 %d" "$youtube"; fi
if [[ $git -gt 0 ]]; then printf " | 💾 %d" "$git"; fi
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "💡 Output-Transparenz: Was habe ich geschaffen? 💚"
}
# Export functions so they're available in subshells
# Note: export -f works in bash, but not in zsh
# In zsh, functions are automatically available in the current shell
# For bash compatibility, we still do export -f, but it's optional in zsh
if [[ -n "$BASH_VERSION" ]]; then
# Bash: use export -f
export -f mayaeule
export -f deepbit
export -f bugsy
export -f schnippsi
export -f templatus
export -f tobi
export -f schraubaer
export -f schnecki
export -f dumbosql
export -f funkfox
export -f taichitaube
export -f snakepy
export -f pepperphp
export -f crabbyrust
export -f spider
export -f vektor
export -f asciimonster
export -f crew_tokens
export -f crew_status
export -f crew_memory
export -f crew_doctor
export -f crew_syntax
export -f crew_help
export -f crumb_memo
export -f crew_memo
fi
# In zsh, functions are available without export -f
# Set version marker for crew_doctor to detect reloads
if [[ -f "${WALDWAECHTER_DIR}/lib/waldwaechter.sh" ]]; then
WALDWAECHTER_LIB_MTIME=$(stat -f "%m" "${WALDWAECHTER_DIR}/lib/waldwaechter.sh" 2>/dev/null || stat -c "%Y" "${WALDWAECHTER_DIR}/lib/waldwaechter.sh" 2>/dev/null)
export "WALDWAECHTER_LOADED_${WALDWAECHTER_LIB_MTIME}=1"
fi