Files
crumbmissions/crumb-mission-selector.sh
Branko May Trinkwald 562d1f78ea Feature: Maya-Eule Weisheitsportal mit Qdrant Memory 🦉
🌲 Die weise Eule erwacht!

New Features:
- Maya-Eule als Waldwächter hinzugefügt
- Qdrant Memory Integration (erinnert frühere Gespräche)
- Token-Tracking mit philosophischem Kontext
- Interactive Wisdom Shell (wie Git/Tools Doktor)

Maya-Eule Weisheitsportal:
8) 🦉 Maya-Eule Weisheit
   └─> Interaktive Shell mit farbigem Prompt
       (🦉 Maya-Eule) user@host:path$

Befehle in der Shell:
- eule "Frage"    - Stelle der Eule eine Frage
- eule_memory      - Zeige Erinnerungen
- eule_tokens      - Zeige Token-Verbrauch
- exit             - Zurück zum Hauptmenü

Qdrant Memory Features:
- Speichert Gespräche mit Vektor-Embeddings
- Sucht ähnliche frühere Konversationen
- Bezieht Kontext in neue Antworten ein
- Persistente Erinnerung über Sessions hinweg

Token Philosophy:
"Was kostet die Frage eines Kindes?"
- Im Wald unbezahlbar
- Token lehren achtsames Fragen
- Jede Frage ist wertvoll
- Kinder lernen bewusster zu denken

System Prompt:
Maya-Eule antwortet kindgerecht, poetisch, langsam.
Sie lehrt durch Fragen, nicht nur Antworten.
Sie erinnert sich und bezieht frühere Gespräche ein.

WUHUUUU! 🌲
2025-12-21 14:34:50 +01:00

639 lines
18 KiB
Bash
Executable File

#!/bin/bash
# 🌲 Crumbforest Mission Doktor v2.0
# Metadata-driven, erweiterbar, Bash 3.2+ kompatibel
# Inspiriert vom crumbpages-doktor.sh Konzept
set -euo pipefail
# === FARBEN ===
GREEN='\033[0;32m'
BLUE='\033[0;34m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
# === KONFIGURATION ===
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MISSION_DIR="${SCRIPT_DIR}/missions"
ENV_FILE="${SCRIPT_DIR}/.env"
# === ENVIRONMENT LOADER ===
function load_env() {
if [[ -f "${ENV_FILE}" ]]; then
# Lade .env, aber nur nicht-kommentierte Zeilen
while IFS='=' read -r key value; do
# Skip Kommentare und leere Zeilen
[[ "$key" =~ ^#.*$ ]] && continue
[[ -z "$key" ]] && continue
# Entferne Quotes
value="${value%\"}"
value="${value#\"}"
# Exportiere Variable
export "$key=$value"
done < <(grep -v '^#' "${ENV_FILE}" | grep -v '^$')
return 0
else
return 1
fi
}
# Versuche .env zu laden
if ! load_env; then
# Keine .env gefunden - das ist OK, AI Features sind dann deaktiviert
AI_AVAILABLE=false
else
AI_AVAILABLE=true
fi
# ============================================================
# HILFSFUNKTIONEN
# ============================================================
function show_header() {
clear
echo -e "${GREEN}"
cat << 'EOF'
🌲 Crumbforest Mission Doktor 🌲
Willkommen im Waldlern-System!
Wähle deine Kategorie:
EOF
echo -e "${NC}"
}
function load_missions_from_category() {
local category="$1"
local search_dir="${MISSION_DIR}/${category}"
if [[ ! -d "$search_dir" ]]; then
echo -e "${RED}Kategorie '$category' nicht gefunden.${NC}"
return 1
fi
# Arrays für Missionen (Bash 3.2+ kompatibel)
MISSION_OPTIONS=()
MISSION_SCRIPTS=()
# Alle .sh Dateien finden
while IFS= read -r file; do
[[ -n "$file" ]] && MISSION_SCRIPTS+=("$file")
done < <(find "$search_dir" -maxdepth 1 -type f -name "*.sh" | sort)
if [[ ${#MISSION_SCRIPTS[@]} -eq 0 ]]; then
echo -e "${YELLOW}Keine Missionen in dieser Kategorie gefunden.${NC}"
return 1
fi
# Metadaten laden
for mission_file in "${MISSION_SCRIPTS[@]}"; do
local mission_name
mission_name="$(basename "$mission_file" .sh)"
local meta_file="${search_dir}/${mission_name}.meta.json"
if [[ -f "$meta_file" ]]; then
local icon title enabled
icon=$(jq -r '.icon // "🛸"' "$meta_file" 2>/dev/null)
title=$(jq -r '.title // "Unknown"' "$meta_file" 2>/dev/null)
enabled=$(jq -r '.enabled // true' "$meta_file" 2>/dev/null)
# Ignoriere deaktivierte Missionen
[[ "$enabled" == "false" ]] && continue
MISSION_OPTIONS+=("${icon} ${title}")
else
# Fallback ohne Metadaten
MISSION_OPTIONS+=("🛸 ${mission_name}")
fi
done
return 0
}
# ============================================================
# MISSION RUNNER
# ============================================================
function run_mission_menu() {
local category="$1"
local category_name="$2"
if ! load_missions_from_category "$category"; then
read -p "Drücke Enter..." -r
return
fi
while true; do
clear
echo -e "${BLUE}=== ${category_name} ===${NC}"
echo ""
# Beenden-Option hinzufügen
MISSION_OPTIONS+=("🚪 Zurück zum Hauptmenü")
PS3="Gib die Zahl deiner Wahl ein: "
select opt in "${MISSION_OPTIONS[@]}"; do
local choice=$((REPLY - 1))
# Beenden gewählt
if [[ "$opt" == "🚪 Zurück zum Hauptmenü" ]]; then
return
fi
# Mission starten
if (( choice >= 0 && choice < ${#MISSION_OPTIONS[@]} - 1 )); then
local selected_script="${MISSION_SCRIPTS[$choice]}"
echo ""
echo -e "${YELLOW}▶️ Starte Mission: $(basename "$selected_script")${NC}"
echo ""
# Mission ausführen
bash "$selected_script"
# Nach Mission: Zurück zum Menü
echo ""
echo -e "${GREEN}✅ Mission abgeschlossen!${NC}"
read -p "Drücke Enter für das Menü..." -r
break
else
echo -e "${RED}❗ Ungültige Eingabe.${NC}"
fi
done
# Reload für nächste Iteration
if ! load_missions_from_category "$category"; then
return
fi
done
}
# ============================================================
# DOKTOR SYSTEM-CHECK
# ============================================================
function system_doktor() {
clear
echo -e "${BLUE}=== 🖥️ System Doktor ===${NC}"
echo ""
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
echo -e "${CYAN}🐧 Linux System${NC}"
hostnamectl 2>/dev/null || hostname
echo ""
uname -r
echo ""
free -h 2>/dev/null || echo "free: nicht verfügbar"
echo ""
df -h / 2>/dev/null
elif [[ "$OSTYPE" == "darwin"* ]]; then
echo -e "${CYAN}🍏 macOS System${NC}"
hostname
echo ""
sw_vers 2>/dev/null
echo ""
echo "Memory:"
vm_stat | head -n 5
echo ""
echo "Disk:"
df -h /
else
echo -e "${YELLOW}Unbekanntes System: $OSTYPE${NC}"
fi
echo ""
echo -e "${GREEN}Bash Version: $BASH_VERSION${NC}"
echo ""
read -p "Drücke Enter..." -r
}
# ============================================================
# TOOLS CHECK (Interactive Shell)
# ============================================================
function tools_doktor() {
echo -e "${BLUE}--- 🛠️ Crumbforest Werkzeugkasten ---${NC}"
# Temporäres RC File für die Shell
TOOL_RC="/tmp/crumb_tools_$$.rc"
cat > "${TOOL_RC}" << 'EOF'
if [ -f /etc/bashrc ]; then source /etc/bashrc; fi
if [ -f ~/.bashrc ]; then source ~/.bashrc; fi
# Farben
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Prompt im Crumbforest-Style
export PS1="\[\033[0;33m\](🛠️ Werkzeug) \u@\h:\w$ \[\033[0m\]"
function tool_check() {
echo -e "${YELLOW}=== Werkzeug-Verfügbarkeit ===${NC}"
echo ""
TOOLS="jq git curl wget python3 nano vim htop ncdu tree"
for tool in $TOOLS; do
if command -v "$tool" &> /dev/null; then
echo -e "${GREEN}✅ $tool${NC} - $(command -v "$tool")"
else
echo -e "${RED}❌ $tool${NC} - Nicht installiert"
fi
done
echo ""
echo -e "${YELLOW}Mission System Requirements:${NC}"
if command -v jq &> /dev/null; then
echo -e "${GREEN}✅ jq verfügbar${NC} - Mission Selector funktioniert"
else
echo -e "${RED}⚠️ jq fehlt${NC} - Bitte installieren!"
fi
}
alias check="tool_check"
alias logs="tail -f /var/log/syslog 2>/dev/null || tail -f /var/log/system.log 2>/dev/null || echo 'Keine Standard-Logs gefunden'"
echo ""
echo "🌲 Willkommen im Crumbforest Werkzeugkasten!"
echo ""
echo "Befehle:"
echo " check - Werkzeug-Verfügbarkeit prüfen"
echo " logs - System-Logs anzeigen"
echo " exit - Zurück zum Hauptmenü"
echo ""
tool_check
EOF
bash --rcfile "${TOOL_RC}"
rm -f "${TOOL_RC}"
}
# ============================================================
# GIT DOKTOR (Interactive Shell)
# ============================================================
function git_doktor() {
echo -e "${BLUE}--- 🌲 Crumbforest Git Workstation ---${NC}"
if [[ ! -d ".git" ]]; then
echo -e "${RED}❌ Kein Git Repository gefunden.${NC}"
read -p "Drücke Enter..." -r
return
fi
# Temporäres RC File für die Shell
GIT_RC="/tmp/crumb_git_$$.rc"
cat > "${GIT_RC}" << 'EOF'
if [ -f /etc/bashrc ]; then source /etc/bashrc; fi
if [ -f ~/.bashrc ]; then source ~/.bashrc; fi
# Farben
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
# Prompt im Crumbforest-Style
export PS1="\[\033[0;34m\](🌲 Git) \u@\h:\w$ \[\033[0m\]"
function check_health() {
echo -e "${YELLOW}=== Repository Gesundheit ===${NC}"
echo ""
if [ ! -d ".git" ]; then
echo -e "${RED}❌ Kein Git Repo!${NC}"
return
fi
# Remote Info
echo -e "${YELLOW}Remote:${NC}"
git remote -v 2>/dev/null || echo "Keine Remotes"
echo ""
# Branch Info
echo -e "${YELLOW}Current Branch:${NC}"
git branch --show-current 2>/dev/null || git branch | grep '*'
echo ""
# Sync Check
git remote update > /dev/null 2>&1
LOCAL=$(git rev-parse @ 2>/dev/null)
REMOTE=$(git rev-parse @{u} 2>/dev/null)
if [ "$LOCAL" = "$REMOTE" ]; then
echo -e "${GREEN}✅ Synchron mit Remote${NC}"
else
echo -e "${YELLOW}⚠️ Nicht synchron / Push needed${NC}"
fi
echo ""
# Status
echo -e "${YELLOW}Status:${NC}"
git status --short
echo ""
# Letzter Commit
echo -e "${YELLOW}Letzter Commit:${NC}"
git log -1 --oneline --decorate 2>/dev/null
}
# Praktische Aliases
alias gst="git status"
alias gd="git diff"
alias gl="git log --oneline --graph --decorate --all -n 10"
alias ga="git add"
alias gc="git commit"
alias gp="git push"
alias health="check_health"
echo ""
echo "🌲 Willkommen in der Crumbforest Git Workstation!"
echo ""
echo "Befehle:"
echo " health - Repository Gesundheit prüfen"
echo " gst - git status"
echo " gd - git diff"
echo " gl - git log (graphisch)"
echo " ga - git add"
echo " gc - git commit"
echo " gp - git push"
echo " exit - Zurück zum Hauptmenü"
echo ""
check_health
EOF
bash --rcfile "${GIT_RC}"
rm -f "${GIT_RC}"
}
# ============================================================
# AI DOKTOR (Token-Tracking & Status)
# ============================================================
function ai_doktor() {
clear
echo -e "${BLUE}=== 🤖 AI Assistenten & Token-Tracking ===${NC}"
echo ""
if [[ "$AI_AVAILABLE" == "false" ]]; then
echo -e "${YELLOW}⚠️ Keine .env Datei gefunden${NC}"
echo ""
echo "Um AI-Assistenten zu nutzen:"
echo "1. Kopiere .env.template zu .env"
echo " ${CYAN}cp .env.template .env${NC}"
echo ""
echo "2. Füge deine API-Keys ein"
echo " ${CYAN}nano .env${NC}"
echo ""
echo "3. Starte Mission Doktor neu"
echo ""
read -p "Drücke Enter..." -r
return
fi
echo -e "${CYAN}🌲 Crumbforest AI Status${NC}"
echo ""
# Check welche APIs konfiguriert sind
echo -e "${YELLOW}Konfigurierte APIs:${NC}"
[[ -n "$OPENROUTER_API_KEY" ]] && echo -e " ${GREEN}✅ OpenRouter${NC} (Model: ${OPENROUTER_MODEL:-nicht gesetzt})"
[[ -n "$CLAUDE_API_KEY" ]] && echo -e " ${GREEN}✅ Claude API${NC} (Model: ${CLAUDE_MODEL:-nicht gesetzt})"
[[ -n "$OPENAI_API_KEY" ]] && echo -e " ${GREEN}✅ OpenAI${NC} (Model: ${OPENAI_MODEL:-nicht gesetzt})"
if [[ "$USE_OLLAMA" == "true" ]]; then
echo -e " ${GREEN}✅ Ollama (Local)${NC} (Model: ${OLLAMA_MODEL:-nicht gesetzt})"
fi
if [[ -z "$OPENROUTER_API_KEY" ]] && [[ -z "$CLAUDE_API_KEY" ]] && [[ -z "$OPENAI_API_KEY" ]] && [[ "$USE_OLLAMA" != "true" ]]; then
echo -e " ${RED}❌ Keine API-Keys konfiguriert${NC}"
fi
echo ""
# Qdrant Status
echo -e "${YELLOW}Vector Database (Qdrant):${NC}"
if [[ -n "$QDRANT_URL" ]]; then
echo -e " ${GREEN}✅ Konfiguriert${NC} (URL: ${QDRANT_URL})"
else
echo -e " ${YELLOW}⚠️ Nicht konfiguriert${NC}"
fi
echo ""
# Token Budget
echo -e "${YELLOW}Token Budget & Philosophie:${NC}"
echo -e " ${CYAN}\"Was kostet die Frage eines Kindes?\"${NC}"
echo -e " ${CYAN}Im Wald unbezahlbar - Token lehren achtsames Fragen.${NC}"
echo ""
if [[ "${DAILY_TOKEN_BUDGET:-0}" -gt 0 ]]; then
echo -e " Tages-Budget: ${GREEN}${DAILY_TOKEN_BUDGET} Tokens${NC}"
else
echo -e " Tages-Budget: ${GREEN}Unbegrenzt${NC}"
fi
if [[ "${ENABLE_TOKEN_TRACKING}" == "true" ]]; then
echo -e " Token-Tracking: ${GREEN}Aktiviert${NC}"
else
echo -e " Token-Tracking: ${YELLOW}Deaktiviert${NC}"
fi
echo ""
# Aktivierte Charaktere
echo -e "${YELLOW}Waldwächter (AI Charaktere):${NC}"
[[ "${ENABLE_MAYAEULE}" == "true" ]] && echo -e " ${GREEN}✅ Maya-Eule${NC} (Weisheit)"
[[ "${ENABLE_DEEPBIT}" == "true" ]] && echo -e " ${GREEN}✅ Deepbit${NC} (Bash-Erklärer)"
[[ "${ENABLE_BUGSY}" == "true" ]] && echo -e " ${GREEN}✅ Bugsy${NC} (Debugging)"
[[ "${ENABLE_SCHNIPPSI}" == "true" ]] && echo -e " ${GREEN}✅ Schnippsi${NC} (Shell-Helfer)"
[[ "${ENABLE_TOBI}" == "true" ]] && echo -e " ${GREEN}✅ Tobi${NC} (JSON/Daten)"
echo ""
# Token Logs anzeigen (wenn vorhanden)
if [[ "${ENABLE_TOKEN_TRACKING}" == "true" ]]; then
echo -e "${YELLOW}Token-Logs:${NC}"
LOG_DIR="${LOG_DIR:-$HOME/.crumbforest_logs}"
if [[ -d "$LOG_DIR" ]]; then
TOKEN_COUNT=$(find "$LOG_DIR" -name "token_log.json" 2>/dev/null | wc -l | tr -d ' ')
echo -e " Gefunden: ${GREEN}${TOKEN_COUNT} Log-Dateien${NC}"
echo ""
echo -e " Ansehen mit: ${CYAN}./log_tokens_viewer_v4.sh${NC}"
else
echo -e " ${YELLOW}Noch keine Logs vorhanden${NC}"
fi
fi
echo ""
read -p "Drücke Enter..." -r
}
# ============================================================
# MAYA-EULE DOKTOR (Interactive Wisdom Shell)
# ============================================================
function mayaeule_doktor() {
echo -e "${BLUE}--- 🦉 Maya-Eule Weisheitsportal ---${NC}"
if [[ "$AI_AVAILABLE" == "false" ]] || [[ -z "$OPENROUTER_API_KEY" ]]; then
echo -e "${YELLOW}⚠️ Maya-Eule braucht einen API-Key${NC}"
echo ""
echo "Bitte konfiguriere .env mit OPENROUTER_API_KEY"
read -p "Drücke Enter..." -r
return
fi
# Temporäres RC File für die Shell
EULE_RC="/tmp/crumb_eule_$$.rc"
cat > "${EULE_RC}" << 'EOF'
if [ -f /etc/bashrc ]; then source /etc/bashrc; fi
if [ -f ~/.bashrc ]; then source ~/.bashrc; fi
# Farben
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
BLUE='\033[0;34m'
NC='\033[0m'
# Prompt im Crumbforest-Style
export PS1="\[\033[1;35m\](🦉 Maya-Eule) \u@\h:\w$ \[\033[0m\]"
# Pfad zum Maya-Eule Script
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && cd .. && pwd)"
MAYAEULE_SCRIPT="${SCRIPT_DIR}/crumbforest_roles/mayaeule_zero.sh"
function eule() {
if [[ -z "$1" ]]; then
echo -e "${YELLOW}Verwendung: eule \"Deine Frage\"${NC}"
return
fi
if [[ -x "$MAYAEULE_SCRIPT" ]]; then
"$MAYAEULE_SCRIPT" "$@"
else
echo -e "${RED}Maya-Eule Script nicht gefunden${NC}"
fi
}
function eule_help() {
echo -e "${CYAN}🦉 Maya-Eule Weisheitsportal${NC}"
echo ""
echo -e "${YELLOW}Philosophie:${NC}"
echo " \"Was kostet die Frage eines Kindes?\""
echo " Im Wald unbezahlbar - Token lehren achtsames Fragen."
echo ""
echo -e "${YELLOW}Befehle:${NC}"
echo " eule \"Frage\" - Stelle Maya-Eule eine Frage"
echo " eule_memory - Zeige Erinnerungen"
echo " eule_tokens - Zeige Token-Verbrauch"
echo " exit - Zurück zum Hauptmenü"
echo ""
echo -e "${CYAN}Beispiele:${NC}"
echo " eule \"Was ist Zeit?\""
echo " eule \"Warum ist der Himmel blau?\""
echo " eule \"Was bedeutet Freundschaft?\""
}
function eule_memory() {
LOGDIR="$HOME/.eule_logs"
if [[ -f "$LOGDIR/eule_history.json" ]]; then
echo -e "${CYAN}📜 Erinnerungen der Eule:${NC}"
jq -r '.[] | " \(.role): \(.content | .[0:100])..."' "$LOGDIR/eule_history.json" 2>/dev/null || \
echo "Noch keine Erinnerungen."
else
echo "Noch keine Gespräche mit Maya-Eule."
fi
}
function eule_tokens() {
LOGDIR="$HOME/.eule_logs"
if [[ -f "$LOGDIR/token_log.json" ]]; then
echo -e "${CYAN}📊 Token-Verbrauch:${NC}"
echo ""
TOTAL=0
while IFS= read -r line; do
zeit=$(echo "$line" | jq -r '.zeit')
tokens=$(echo "$line" | jq -r '.usage.total_tokens')
TOTAL=$((TOTAL + tokens))
echo " $zeit: $tokens Tokens"
done < "$LOGDIR/token_log.json"
echo ""
echo -e "${GREEN}Gesamt: $TOTAL Tokens${NC}"
echo -e "${YELLOW}Jede Frage ist wertvoll 🌲${NC}"
else
echo "Noch keine Token-Logs."
fi
}
alias help="eule_help"
echo ""
echo "🌲 Willkommen im Maya-Eule Weisheitsportal!"
echo ""
eule_help
EOF
bash --rcfile "${EULE_RC}"
rm -f "${EULE_RC}"
}
# ============================================================
# HAUPTMENÜ
# ============================================================
function main_menu() {
while true; do
show_header
echo "1) 📚 Basics - Einsteiger Missionen"
echo "2) 🚀 Advanced - Fortgeschrittene Missionen"
echo "3) 🏆 Challenges - Herausforderungen"
echo ""
echo "--- Doktor Tools ---"
echo "4) 🖥️ System Doktor"
echo "5) 🛠️ Werkzeug-Check"
echo "6) 🌲 Git Doktor"
echo "7) 🤖 AI & Token-Tracking"
echo "8) 🦉 Maya-Eule Weisheit"
echo ""
echo "9) 👋 Beenden"
echo ""
read -p "Auswahl [1-9]: " CHOICE
case $CHOICE in
1) run_mission_menu "basics" "📚 Basics - Einsteiger" ;;
2) run_mission_menu "advanced" "🚀 Advanced - Fortgeschrittene" ;;
3) run_mission_menu "challenges" "🏆 Challenges" ;;
4) system_doktor ;;
5) tools_doktor ;;
6) git_doktor ;;
7) ai_doktor ;;
8) mayaeule_doktor ;;
9)
clear
echo -e "${GREEN}"
echo "👋 Auf bald im Crumbforest!"
echo -e "${NC}"
exit 0
;;
*)
echo -e "${RED}Bitte 1-9 wählen.${NC}"
sleep 1
;;
esac
done
}
# ============================================================
# START
# ============================================================
main_menu