Problem: Deutsche Locale (Komma als Dezimaltrenner) vs. JSON/bc output (Punkt als Dezimaltrenner) → printf Fehler ✅ Lösung: - LC_NUMERIC=C für gesamte crew_tokens Funktion - Konsistente Zahlenformatierung (Punkt als Dezimaltrenner) - Keine printf "invalid number" Fehler mehr 📊 Ergebnis: - Alle 12 aktiven Waldwächter korrekt angezeigt - Token-Zahlen akkurat: 20021 Tokens total - Kosten transparent: ~$0.017558 - "Was kostet die Frage eines Kindes?" → Jetzt mit Antwort! ✓ 🤖 Generated with Claude Code Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
299 lines
8.7 KiB
Bash
299 lines
8.7 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)
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
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_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
|
|
crew_memory Erinnerungen durchsuchen
|
|
|
|
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
|
|
}
|
|
|
|
# Export functions so they're available in subshells
|
|
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_help
|