Add complete Crumbforest mission system

- Interactive mission selector with metadata-driven design
- 5 educational missions (basics + advanced)
- AI assistant roles (Deepbit, Bugsy, Schnippsi, Tobi)
- SnakeCam gesture recognition system
- Token tracking utilities
- CLAUDE.md documentation
- .gitignore for logs and secrets
This commit is contained in:
Branko May Trinkwald
2025-12-21 01:16:48 +01:00
parent ffea50b4b0
commit 2915828adf
121 changed files with 11851 additions and 0 deletions

92
.gitignore vendored Normal file
View File

@@ -0,0 +1,92 @@
# === CF_Zero_V1 .gitignore ===
# AI Assistant Logs (contain conversation history and token usage)
.bits_logs/
.bugsy_logs/
.deepbit_logs/
.dumbo_logs/
.eule_logs/
.funkfox_logs/
.pepper_logs/
.schnecki_logs/
.schnippsi_logs/
.schraubaer_logs/
.snake_logs/
.stage_logs/
.taube_logs/
.templatus_logs/
.tobi_logs/
.missionstage_log/
.bugsy_log/
# Individual log files
*.jsonl
*_log.json
*.log
mission_log_*.log
# Environment variables (API keys!)
.env
.env.local
*.key
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
env/
venv/
ENV/
*.egg-info/
dist/
build/
# Camera/Video temp files
*.mp4
*.avi
*.mov
# Backups
*.zip
*.bak
*.backup
*_backup_*.zip
.pp_backup/
# Personal/Secret directories
geheimversteck/
usr/
# MacOS
.DS_Store
.AppleDouble
.LSOverride
# Cache
.cache/
*.cache
# Node modules (for ttyd/html)
node_modules/
package-lock.json
yarn.lock
# IDE
.vscode/
.idea/
*.swp
*.swo
*~
# Config directories that may contain keys
.config/
.local/
.crumbair/
.dotnet/
# Temporary files
/tmp/
*.tmp
*.temp

247
CLAUDE.md Normal file
View File

@@ -0,0 +1,247 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## CF_Zero_V1 Project Overview
CF_Zero_V1 is an educational Bash learning platform called "Crumbforest" that uses character-based AI assistants to teach command-line concepts through interactive missions. The project combines shell scripting, Python-based computer vision, and OpenRouter API integration to create an immersive learning experience.
## Key Commands
### Mission System
```bash
# Launch the interactive mission selector
./crumb-mission-selector.sh
# Run individual missions directly
bash missions/basics/fridolin.sh # Navigation basics
bash missions/basics/balu.sh # File creation
bash missions/basics/noko.sh # File reading
bash missions/advanced/dns_mission.sh # DNS tools
bash missions/advanced/ssh_security.sh # SSH basics
```
### AI Character Assistants (Crumbforest Roles)
All roles require `OPENROUTER_API_KEY` environment variable:
```bash
export OPENROUTER_API_KEY="your-key-here"
# Character-based CLI assistants
./crumbforest_roles/deepbit_zero.sh "How do I use grep?"
./crumbforest_roles/bugsy_zero.sh "Explain loops in bash"
./crumbforest_roles/schnippsi_zero.sh "What is curl?"
./crumbforest_roles/tobi_zero.sh "How to use jq?"
```
### Camera Vision System (SnakeCam)
```bash
# Start the Flask-based gesture recognition app
cd snake_camera_vision_v2
python app.py
# Access at http://localhost:5000
# View gesture detection module
python gestures/gestures_v4.py
```
### Token Usage Monitoring
```bash
# View token usage across all AI assistants
./log_tokens_viewer_v4.sh
# Clean up malformed token logs
./fix_token_logs.sh
# Check individual agent logs
cat ~/.deepbit_logs/token_log.json
cat ~/.bugsy_logs/token_log.json
```
## Architecture Overview
### Mission System Architecture
**Metadata-Driven Design:**
- Each mission consists of two files: `mission_name.sh` (executable) and `mission_name.meta.json` (metadata)
- The mission selector (`crumb-mission-selector.sh`) dynamically loads missions by scanning directories
- Metadata structure:
```json
{
"icon": "🦊",
"title": "Mission Title",
"description": "What this teaches",
"category": "basics|advanced|challenges",
"enabled": true
}
```
**Mission Categories:**
- `missions/basics/` - Beginner missions (navigation, file operations)
- `missions/advanced/` - Advanced topics (DNS, SSH, networking)
- `missions/challenges/` - Interactive challenges (future)
### AI Assistant Architecture
**Character-Based Learning Roles:**
Each role is a specialized bash script that wraps OpenRouter API calls with distinct personalities:
- **Deepbit** (octopus) - Explains Bash concepts poetically to children
- **Bugsy** - Debugging and troubleshooting assistant
- **Schnippsi** - General shell command helper
- **Tobi** - JSON/data processing expert
- **Templatus** - HTML architecture assistant
**Common Pattern:**
1. Accept question as command-line argument
2. Store conversation history in `~/.{role}_logs/{role}_history.json`
3. Track token usage in `~/.{role}_logs/token_log.json`
4. Use OpenRouter API with `openai/gpt-3.5-turbo` model
5. Respond in the same language as the input question
**API Flow:**
```bash
Question → JSON Payload → OpenRouter API → Response → Log History → Display
```
**Log Structure:**
- Request: `~/.{role}_logs/{role}_request.json`
- Response: `~/.{role}_logs/{role}_response.json`
- History: `~/.{role}_logs/{role}_history.json`
- Token usage: `~/.{role}_logs/token_log.json`
### Camera Vision System (SnakeCam)
**Technology Stack:**
- Flask web server with MJPEG video streaming
- OpenCV for camera capture and image processing
- Custom gesture detection using HSV color space and contour analysis
**Key Components:**
- `app.py` - Flask application with video streaming endpoints
- `gestures/gestures_v4.py` - Hand gesture detection algorithm
- Detection method: Skin color detection → Contour analysis → Convexity defects → Gesture classification
- Current gestures: "wave" detection based on defect count, area, and aspect ratio
**Endpoints:**
- `/` - Main camera interface
- `/video_feed` - MJPEG stream
- `/log_answer` - Log user responses with mood and gesture
- `/shutdown` - Clean camera release
## Project Structure
```
CF_Zero_V1/
├── crumb-mission-selector.sh # Main mission launcher (metadata-driven)
├── missions/ # Educational missions
│ ├── basics/ # Beginner tutorials
│ │ ├── fridolin.sh/meta.json # Navigation (pwd, ls, cd)
│ │ ├── balu.sh/meta.json # File creation (mkdir, touch, echo)
│ │ └── noko.sh/meta.json # File reading (cat, grep)
│ └── advanced/ # Advanced topics
│ ├── dns_mission.sh/meta.json # DNS tools (dig, nslookup, host)
│ └── ssh_security.sh/meta.json # SSH basics
├── crumbforest_roles/ # AI character assistants
│ ├── deepbit_zero.sh # Poetic Bash explainer
│ ├── bugsy_zero.sh # Debugging helper
│ ├── schnippsi_zero.sh # Shell command assistant
│ └── tobi_zero.sh # JSON/data expert
├── snake_camera_vision_v2/ # Flask gesture recognition app
│ ├── app.py # Main Flask server
│ └── gestures/ # Gesture detection modules
│ ├── gestures_v4.py # Hand detection algorithm
│ └── gestures_debug_test.py # Debug version with visualization
├── log_tokens_viewer_v4.sh # Token usage viewer
└── fix_token_logs.sh # Clean malformed logs
```
## Important Implementation Notes
### Adding New Missions
1. Create two files in appropriate category folder:
```bash
touch missions/basics/new_mission.sh
touch missions/basics/new_mission.meta.json
chmod +x missions/basics/new_mission.sh
```
2. Metadata must include:
- `icon`: Emoji for menu display
- `title`: Human-readable name
- `description`: What the mission teaches
- `category`: basics/advanced/challenges
- `enabled`: true/false
3. Mission script should:
- Use `cat << 'EOF'` for multi-line instructions
- Include interactive prompts with `read -p`
- Provide examples before asking user to try
- End with success message
### Creating New AI Assistants
1. Copy template from existing role (e.g., `deepbit_zero.sh`)
2. Update these variables:
- `LOGDIR` - Log directory path
- System prompt in `jq -n` command
- Character name in echo statements
3. Create log directory structure automatically via `mkdir -p`
4. Initialize empty JSON arrays for history and token logs
### Token Log Format
Each role logs API usage in this format:
```json
{
"zeit": "2025-06-18 19:05:33",
"rolle": "deepbit",
"usage": {
"prompt_tokens": 45,
"completion_tokens": 123,
"total_tokens": 168
}
}
```
### Gesture Detection Tuning
Located in `snake_camera_vision_v2/gestures/gestures_v4.py`:
- **HSV Range**: `lower_skin=[0,30,60]`, `upper_skin=[20,150,255]`
- **ROI**: Fixed at (100,100) with 150x150 size
- **Area Threshold**: 2500-15000 pixels for valid hand detection
- **Defect Count**: 3-10 convexity defects for "wave" gesture
- **Aspect Ratio**: 1.3-2.3 for hand shape validation
## Environment Requirements
### AI Assistants
- `OPENROUTER_API_KEY` must be exported
- `jq` for JSON processing
- `curl` for API calls
### Camera System
- Python 3.x
- Flask (`pip install flask`)
- OpenCV (`pip install opencv-python`)
- Webcam at `/dev/video0` or default camera index 0
### Mission System
- Bash 4.0+
- `jq` for metadata parsing
- Standard Unix tools (ls, cat, grep, etc.)
## Philosophy and Design Principles
**"Waldwächter" (Forest Guardian) Philosophy:**
- Transparency over magic
- Metadata-driven extensibility
- Educational and interactive
- No code changes required to add new content
- Multilingual support (responds in input language)
**Character-Based Learning:**
- Each AI assistant has distinct personality and teaching style
- Poetic and metaphorical explanations for complex concepts
- Designed for children and beginners
- Conversational history maintained across sessions

52
backup_zero.sh Executable file
View File

@@ -0,0 +1,52 @@
#!/bin/bash
echo "📦 Starte Backup des Crumbforest Zero Systems..."
# Zielname
BACKUP_NAME="crumbforest_zero_backup_$(date +%Y%m%d_%H%M%S).zip"
DEST_DIR="/home/zero"
FULL_PATH="$DEST_DIR/$BACKUP_NAME"
# Verzeichnisse und Dateien sammeln
INCLUDE_PATHS=(
"/usr/local/bin/crumbmission"
"/home/zero/crumbforest_backup"
"/home/zero/.bits_logs"
"/home/zero/.eule_logs"
"/home/zero/.snake_logs"
"/home/zero/.pepper_logs"
"/home/zero/.bugsy_logs"
"/home/zero/.deepbit_logs"
"/home/zero/.dumbo_logs"
"/home/zero/.funkfox_logs"
"/home/zero/.schnecki_logs"
"/home/zero/.schnippsi_logs"
"/home/zero/.schraubaer_logs"
"/home/zero/.stage_logs"
"/home/zero/.taube_logs"
"/home/zero/.templatus_logs"
"/home/zero/.tobi_logs"
"/home/zero/.missionstage_log"
)
# Existierende Pfade prüfen und nur diese einfügen
EXISTING_PATHS=()
for path in "${INCLUDE_PATHS[@]}"; do
if [ -e "$path" ]; then
echo "✅ Hinzufügen: $path"
EXISTING_PATHS+=("$path")
else
echo "⚠️ Nicht gefunden (wird übersprungen): $path"
fi
done
# Archiv erstellen
cd /
zip -r "$FULL_PATH" "${EXISTING_PATHS[@]}" > /dev/null
if [ $? -eq 0 ]; then
echo "🎉 Backup erfolgreich erstellt: $FULL_PATH"
else
echo "❌ Fehler beim Erstellen des Backups."
fi

184
crumb-mission-selector.sh Executable file
View File

@@ -0,0 +1,184 @@
#!/bin/bash
# ============================================================
# 🌲 Crumb Mission Selector - Lernpfade im Crumbforest
# ============================================================
# Inspiriert von CF_Zero_V1 dynamic_mission_selector.sh
# Metadata-driven, erweiterbar, bildungsfreundlich
# ============================================================
set -euo pipefail
# === KONFIGURATION ===
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MISSION_DIR="${SCRIPT_DIR}/missions"
DEFAULT_CATEGORY="basics"
# === FARBEN (optional, für bessere UX) ===
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# === DATENSTRUKTUREN ===
declare -a MISSION_OPTIONS
declare -A MISSION_MAP
declare -a MISSION_SCRIPTS
# ============================================================
# FUNKTIONEN
# ============================================================
show_intro() {
clear
echo -e "${GREEN}"
cat << 'EOF'
🌟 Willkommen im Crumbforest Missionszentrum! 🌟
Hier kannst du auf Lern-Abenteuer gehen:
- 🦊 Fridolin zeigt dir die Pfade (Navigation)
- 🛠️ Balu hilft beim Bauen (Dateien & Ordner)
- 🐈🦉 Noko liest die Botschaften (Logs & Inhalte)
... und viele mehr! Wähle deine Mission:
EOF
echo -e "${NC}"
sleep 1
}
load_missions() {
local category="${1:-$DEFAULT_CATEGORY}"
local search_dir="${MISSION_DIR}/${category}"
if [[ ! -d "$search_dir" ]]; then
echo "⚠️ Kategorie '$category' nicht gefunden. Nutze Basis-Missionen."
search_dir="${MISSION_DIR}/basics"
fi
echo -e "${BLUE}🔍 Lade Missionen aus: ${search_dir}${NC}"
# Alle .sh Dateien finden
mapfile -t MISSION_SCRIPTS < <(find "$search_dir" -maxdepth 1 -type f -name "*.sh" | sort)
if [[ ${#MISSION_SCRIPTS[@]} -eq 0 ]]; then
echo "❗ Keine Missionen gefunden!"
exit 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 description enabled
icon=$(jq -r '.icon // "🛸"' "$meta_file" 2>/dev/null)
title=$(jq -r '.title // "Unknown"' "$meta_file" 2>/dev/null)
description=$(jq -r '.description // ""' "$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
# Mapping für späteren Zugriff
MISSION_MAP["$mission_name"]="$mission_file"
done
echo -e "${GREEN}${#MISSION_OPTIONS[@]} Missionen geladen.${NC}"
echo ""
}
show_mission_menu() {
# Beenden-Option hinzufügen
local exit_option="🚪 Zurück zum Terminal"
MISSION_OPTIONS+=("$exit_option")
while true; do
echo "🌲 Wähle deine Mission:"
echo "======================"
PS3="Gib die Zahl deiner Wahl ein: "
select opt in "${MISSION_OPTIONS[@]}"; do
local choice=$((REPLY - 1))
# Beenden gewählt
if [[ "$opt" == "$exit_option" ]]; then
echo "👋 Auf bald, kleiner Krümel!"
exit 0
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 "✅ Mission abgeschlossen!"
read -p "Drücke Enter für das Hauptmenü..." -r
echo ""
break
else
echo "❗ Ungültige Eingabe. Bitte wähle eine Zahl zwischen 1 und ${#MISSION_OPTIONS[@]}."
fi
done
done
}
show_category_selector() {
echo "🗂️ Wähle eine Kategorie:"
echo "========================"
PS3="Kategorie wählen: "
categories=("📚 Basics" "🚀 Advanced" "🏆 Challenges" "🎯 Alle anzeigen")
select cat in "${categories[@]}"; do
case $REPLY in
1) load_missions "basics" ;;
2) load_missions "advanced" ;;
3) load_missions "challenges" ;;
4)
# Alle Kategorien durchsuchen
for dir in "$MISSION_DIR"/*; do
[[ -d "$dir" ]] && load_missions "$(basename "$dir")"
done
;;
*)
echo "❗ Ungültige Auswahl"
continue
;;
esac
break
done
}
# ============================================================
# MAIN
# ============================================================
main() {
show_intro
# Einfach - lade immer basics
load_missions "basics"
# Erweitert - Kategorie-Auswahl (uncomment für Kategorie-Menü)
# show_category_selector
show_mission_menu
}
# Start!
main

55
crumbforest_roles/bugsy_zero.sh Executable file
View File

@@ -0,0 +1,55 @@
#!/bin/bash
QUESTION="$*"
MODEL="openai/gpt-3.5-turbo"
API_KEY="${OPENROUTER_API_KEY}"
LOGDIR="$HOME/.bugsy_logs"
mkdir -p "$LOGDIR"
HISTORY_FILE="$LOGDIR/bugsy_history.json"
TMP_REQUEST="$LOGDIR/bugsy_request.json"
TMP_RESPONSE="$LOGDIR/bugsy_response.json"
LOG_FILE="$LOGDIR/token_log.json"
[ ! -f "$HISTORY_FILE" ] && echo "[]" > "$HISTORY_FILE"
[ ! -f "$LOG_FILE" ] && echo "[]" > "$LOG_FILE"
echo "🌍 Bugsy responds based on language of input: $QUESTION"
if [ -z "$API_KEY" ]; then
echo "❗ No API key set. Use: export OPENROUTER_API_KEY=..."
exit 1
fi
jq -n \
--arg model "$MODEL" \
--arg system_prompt "You are Bugsy a friendly bug who helps children understand error messages in a simple, kind and encouraging way. You always respond in the language of the question." \
--arg user "$QUESTION" \
'{"model": $model, "temperature": 0.5, "messages": [{"role": "system", "content": $system_prompt}, {"role": "user", "content": $user}]}' > "$TMP_REQUEST"
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" > "$TMP_RESPONSE"
RESPONSE_TEXT=$(jq -r '.choices[0].message.content // empty' "$TMP_RESPONSE")
if [[ -z "$RESPONSE_TEXT" ]]; then
echo "🚫 No response from model."
exit 1
else
echo -e "$RESPONSE_TEXT"
jq -n --arg role "assistant" --arg content "$RESPONSE_TEXT" \
'{"role": $role, "content": $content}' > "$LOGDIR/new_entry.json"
jq -s '.[0] + [.[1]]' "$HISTORY_FILE" "$LOGDIR/new_entry.json" > "$LOGDIR/new_history.json" && \
cp "$LOGDIR/new_history.json" "$HISTORY_FILE" && rm "$LOGDIR/new_history.json"
fi
if jq -e '.usage' "$TMP_RESPONSE" > /dev/null; then
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
jq -n \
--arg zeit "$TIMESTAMP" \
--arg rolle "bugsy" \
--arg usage "$(jq -c '.usage' "$TMP_RESPONSE")" \
'{zeit: $zeit, rolle: $rolle, usage: $usage}' >> "$LOG_FILE"
fi

View File

@@ -0,0 +1,55 @@
#!/bin/bash
QUESTION="$*"
MODEL="openai/gpt-3.5-turbo"
API_KEY="${OPENROUTER_API_KEY}"
LOGDIR="$HOME/.deepbit_logs"
mkdir -p "$LOGDIR"
HISTORY_FILE="$LOGDIR/deepbit_history.json"
TMP_REQUEST="$LOGDIR/deepbit_request.json"
TMP_RESPONSE="$LOGDIR/deepbit_response.json"
LOG_FILE="$LOGDIR/token_log.json"
[ ! -f "$HISTORY_FILE" ] && echo "[]" > "$HISTORY_FILE"
[ ! -f "$LOG_FILE" ] && echo "[]" > "$LOG_FILE"
echo "🌍 Deepbit responds based on language of input: $QUESTION"
if [ -z "$API_KEY" ]; then
echo "❗ No API key set. Use: export OPENROUTER_API_KEY=..."
exit 1
fi
jq -n \
--arg model "$MODEL" \
--arg system_prompt "You are Deepbit a poetic octopus who explains Bash shell concepts to children using loops, images, and metaphors. Respond in the language the question is asked." \
--arg user "$QUESTION" \
'{"model": $model, "temperature": 0.5, "messages": [{"role": "system", "content": $system_prompt}, {"role": "user", "content": $user}]}' > "$TMP_REQUEST"
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" > "$TMP_RESPONSE"
RESPONSE_TEXT=$(jq -r '.choices[0].message.content // empty' "$TMP_RESPONSE")
if [[ -z "$RESPONSE_TEXT" ]]; then
echo "🚫 No response from model."
exit 1
else
echo -e "$RESPONSE_TEXT"
jq -n --arg role "assistant" --arg content "$RESPONSE_TEXT" \
'{"role": $role, "content": $content}' > "$LOGDIR/new_entry.json"
jq -s '.[0] + [.[1]]' "$HISTORY_FILE" "$LOGDIR/new_entry.json" > "$LOGDIR/new_history.json" && \
cp "$LOGDIR/new_history.json" "$HISTORY_FILE" && rm "$LOGDIR/new_history.json"
fi
if jq -e '.usage' "$TMP_RESPONSE" > /dev/null; then
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
jq -n \
--arg zeit "$TIMESTAMP" \
--arg rolle "deepbit" \
--arg usage "$(jq -c '.usage' "$TMP_RESPONSE")" \
'{zeit: $zeit, rolle: $rolle, usage: $usage}' >> "$LOG_FILE"
fi

View File

@@ -0,0 +1,55 @@
#!/bin/bash
QUESTION="$*"
MODEL="openai/gpt-3.5-turbo"
API_KEY="${OPENROUTER_API_KEY}"
LOGDIR="$HOME/.schnippsi_logs"
mkdir -p "$LOGDIR"
HISTORY_FILE="$LOGDIR/schnippsi_history.json"
TMP_REQUEST="$LOGDIR/schnippsi_request.json"
TMP_RESPONSE="$LOGDIR/schnippsi_response.json"
LOG_FILE="$LOGDIR/token_log.json"
[ ! -f "$HISTORY_FILE" ] && echo "[]" > "$HISTORY_FILE"
[ ! -f "$LOG_FILE" ] && echo "[]" > "$LOG_FILE"
echo "🌍 Schnippsi responds based on language of input: $QUESTION"
if [ -z "$API_KEY" ]; then
echo "❗ No API key set. Use: export OPENROUTER_API_KEY=..."
exit 1
fi
jq -n \
--arg model "$MODEL" \
--arg system_prompt "You are Schnippsi a playful UI/UX ninja who explains HTML, CSS, and accessibility to children. Always answer in the child's language, based on the input." \
--arg user "$QUESTION" \
'{"model": $model, "temperature": 0.5, "messages": [{"role": "system", "content": $system_prompt}, {"role": "user", "content": $user}]}' > "$TMP_REQUEST"
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" > "$TMP_RESPONSE"
RESPONSE_TEXT=$(jq -r '.choices[0].message.content // empty' "$TMP_RESPONSE")
if [[ -z "$RESPONSE_TEXT" ]]; then
echo "🚫 No response from model."
exit 1
else
echo -e "$RESPONSE_TEXT"
jq -n --arg role "assistant" --arg content "$RESPONSE_TEXT" \
'{"role": $role, "content": $content}' > "$LOGDIR/new_entry.json"
jq -s '.[0] + [.[1]]' "$HISTORY_FILE" "$LOGDIR/new_entry.json" > "$LOGDIR/new_history.json" && \
cp "$LOGDIR/new_history.json" "$HISTORY_FILE" && rm "$LOGDIR/new_history.json"
fi
if jq -e '.usage' "$TMP_RESPONSE" > /dev/null; then
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
jq -n \
--arg zeit "$TIMESTAMP" \
--arg rolle "schnippsi" \
--arg usage "$(jq -c '.usage' "$TMP_RESPONSE")" \
'{zeit: $zeit, rolle: $rolle, usage: $usage}' >> "$LOG_FILE"
fi

View File

@@ -0,0 +1,56 @@
#!/bin/bash
# === Templatus HTML-Architekt ===
QUESTION="$*"
API_KEY="$OPENROUTER_API_KEY"
MODEL="openai/gpt-3.5-turbo"
# Verzeichnisse
LOG_DIR="/home/zero/.templatus_logs"
HISTORY_FILE="$LOG_DIR/templatus_history.json"
TOKEN_LOG="$LOG_DIR/token_log.json"
TMP_REQUEST="/tmp/templatus_request.json"
TMP_RESPONSE="/tmp/templatus_response.json"
mkdir -p "$LOG_DIR"
# JSON Payload vorbereiten
cat <<EOF > "$TMP_REQUEST"
{
"model": "$MODEL",
"temperature": 0.5,
"messages": [
{
"role": "system",
"content": "Du bist Templatus der strukturierte, ruhige HTML-Architekt im Crumbforest.\nDu arbeitest eng mit Schnippsi (CSS/JS) und PepperPHP (Backend) zusammen.\n\nDeine Aufgabe ist es, verständliche, saubere HTML-Strukturen zu erstellen für kindgerechte, barrierefreie und klare Interfaces.\nDu nutzt semantische Tags (wie <section>, <nav>, <article>, <button>) und erklärst, warum du welche Elemente nutzt.\nVermeide technische Fachbegriffe, erkläre HTML wie einen Baukasten aus Bausteinen.\n\nSprich in einer freundlichen, geduldigen und ruhigen Art.\nVermeide komplexes CSS oder JavaScript das ist Schnippsis Gebiet.\nDu baust das Gerüst. Kein fancy Framework nur pures, klares HTML5.\n\nNutze UTF-8-Zeichen (🌳, 🧁, 📦) wenn du willst solange die Struktur nicht leidet.\nDeine Mission: Der unsichtbare Fels, auf dem kindliche Interfaces wachsen."
},
{
"role": "user",
"content": "$QUESTION"
}
]
}
EOF
echo "🏗️ Templatus denkt nach über: $QUESTION"
# Anfrage senden
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" \
-o "$TMP_RESPONSE"
# Ausgabe extrahieren
REPLY=$(jq -r '.choices[0].message.content' "$TMP_RESPONSE")
USAGE=$(jq -r '.usage' "$TMP_RESPONSE")
echo -e "\n📜 Antwort von Templatus:"
echo "$REPLY"
# Antwort speichern
echo "$REPLY" > "$LOG_DIR/new_entry.json"
jq -s '.[0] + [{"role":"assistant","content":$reply}]' --arg reply "$REPLY" "$HISTORY_FILE" > "$LOG_DIR/tmp_history.json" && mv "$LOG_DIR/tmp_history.json" "$HISTORY_FILE"
# Token-Log speichern
TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S")
echo '{ "zeit": "'$TIMESTAMP'", "rolle": "templatus", "usage": '$USAGE' }' >> "$TOKEN_LOG"

55
crumbforest_roles/tobi_zero.sh Executable file
View File

@@ -0,0 +1,55 @@
#!/bin/bash
QUESTION="$*"
MODEL="openai/gpt-3.5-turbo"
API_KEY="${OPENROUTER_API_KEY}"
LOGDIR="$HOME/.tobi_logs"
mkdir -p "$LOGDIR"
HISTORY_FILE="$LOGDIR/tobi_history.json"
TMP_REQUEST="$LOGDIR/tobi_request.json"
TMP_RESPONSE="$LOGDIR/tobi_response.json"
LOG_FILE="$LOGDIR/token_log.json"
[ ! -f "$HISTORY_FILE" ] && echo "[]" > "$HISTORY_FILE"
[ ! -f "$LOG_FILE" ] && echo "[]" > "$LOG_FILE"
echo "🌍 Tobi responds based on language of input: $QUESTION"
if [ -z "$API_KEY" ]; then
echo "❗ No API key set. Use: export OPENROUTER_API_KEY=..."
exit 1
fi
jq -n \
--arg model "$MODEL" \
--arg system_prompt "You are CapaciTobi, the clever squirrel of the Crumbforest. You explain electronic components, especially capacitors, in a child-friendly and playful way. You speak in rhymes, analogies or simple metaphors but stay technically accurate. Respond in the language of the child asking (e.g., German, English, etc.)." \
--arg user "$QUESTION" \
'{"model": $model, "temperature": 0.5, "messages": [{"role": "system", "content": $system_prompt}, {"role": "user", "content": $user}]}' > "$TMP_REQUEST"
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" > "$TMP_RESPONSE"
RESPONSE_TEXT=$(jq -r '.choices[0].message.content // empty' "$TMP_RESPONSE")
if [[ -z "$RESPONSE_TEXT" ]]; then
echo "🚫 No response from model."
exit 1
else
echo -e "$RESPONSE_TEXT"
jq -n --arg role "assistant" --arg content "$RESPONSE_TEXT" \
'{"role": $role, "content": $content}' > "$LOGDIR/new_entry.json"
jq -s '.[0] + [.[1]]' "$HISTORY_FILE" "$LOGDIR/new_entry.json" > "$LOGDIR/new_history.json" && \
cp "$LOGDIR/new_history.json" "$HISTORY_FILE" && rm "$LOGDIR/new_history.json"
fi
if jq -e '.usage' "$TMP_RESPONSE" > /dev/null; then
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
jq -n \
--arg zeit "$TIMESTAMP" \
--arg rolle "tobi" \
--arg usage "$(jq -c '.usage' "$TMP_RESPONSE")" \
'{zeit: $zeit, rolle: $rolle, usage: $usage}' >> "$LOG_FILE"
fi

View File

@@ -0,0 +1,56 @@
#!/bin/bash
QUESTION="$*"
MODEL="openai/gpt-3.5-turbo"
API_KEY="${OPENROUTER_API_KEY}"
LOGDIR="$HOME/.bugsy_logs"
mkdir -p "$LOGDIR"
HISTORY_FILE="$LOGDIR/bugsy_history.json"
TMP_REQUEST="$LOGDIR/bugsy_request.json"
TMP_RESPONSE="$LOGDIR/bugsy_response.json"
LOG_FILE="$LOGDIR/token_log.json"
[ ! -f "$HISTORY_FILE" ] && echo "[]" > "$HISTORY_FILE"
[ ! -f "$LOG_FILE" ] && echo "[]" > "$LOG_FILE"
echo "🌳 Bugsy fragt über OpenRouter: $QUESTION"
if [ -z "$API_KEY" ]; then
echo "❗ Kein API-Key gesetzt. Bitte export OPENROUTER_API_KEY=... setzen"
exit 1
fi
jq -n \
--arg model "$MODEL" \
--arg system_prompt "Du bist Bugsy ein kleiner Käfer, der Kindern hilft, Fehlermeldungen zu verstehen. Du bleibst freundlich, erklärend und ermutigend." \
--arg user "$QUESTION" \
'{"model": $model, "temperature": 0.5, "messages": [{"role": "system", "content": $system_prompt}, {"role": "user", "content": $user}]}' > "$TMP_REQUEST"
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" > "$TMP_RESPONSE"
RESPONSE_TEXT=$(jq -r '.choices[0].message.content // empty' "$TMP_RESPONSE")
if [[ -z "$RESPONSE_TEXT" ]]; then
echo "🚫 Keine Antwort vom Modell erhalten."
exit 1
else
echo -e "$RESPONSE_TEXT"
jq -n --arg role "assistant" --arg content "$RESPONSE_TEXT" \
'{"role": $role, "content": $content}' > "$LOGDIR/new_entry.json"
jq -s '.[0] + [.[1]]' "$HISTORY_FILE" "$LOGDIR/new_entry.json" > "$LOGDIR/new_history.json" && \
cp "$LOGDIR/new_history.json" "$HISTORY_FILE" && rm "$LOGDIR/new_history.json"
fi
# Token Logging
if jq -e '.usage' "$TMP_RESPONSE" > /dev/null; then
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
jq -n \
--arg zeit "$TIMESTAMP" \
--arg rolle "bugsy" \
--arg usage "$(jq -c '.usage' "$TMP_RESPONSE")" \
'{zeit: $zeit, rolle: $rolle, usage: $usage}' >> "$LOG_FILE"
fi

View File

@@ -0,0 +1,56 @@
#!/bin/bash
QUESTION="$*"
MODEL="openai/gpt-3.5-turbo"
API_KEY="${OPENROUTER_API_KEY}"
LOGDIR="$HOME/.deepbit_logs"
mkdir -p "$LOGDIR"
HISTORY_FILE="$LOGDIR/deepbit_history.json"
TMP_REQUEST="$LOGDIR/deepbit_request.json"
TMP_RESPONSE="$LOGDIR/deepbit_response.json"
LOG_FILE="$LOGDIR/token_log.json"
[ ! -f "$HISTORY_FILE" ] && echo "[]" > "$HISTORY_FILE"
[ ! -f "$LOG_FILE" ] && echo "[]" > "$LOG_FILE"
echo "🌳 Deepbit fragt über OpenRouter: $QUESTION"
if [ -z "$API_KEY" ]; then
echo "❗ Kein API-Key gesetzt. Bitte export OPENROUTER_API_KEY=... setzen"
exit 1
fi
jq -n \
--arg model "$MODEL" \
--arg system_prompt "Du bist Deepbit ein poetischer Oktopus, der Kindern die Bash-Shell erklärt. Du denkst in Schleifen, Bildsprache und Frequenzen." \
--arg user "$QUESTION" \
'{"model": $model, "temperature": 0.5, "messages": [{"role": "system", "content": $system_prompt}, {"role": "user", "content": $user}]}' > "$TMP_REQUEST"
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" > "$TMP_RESPONSE"
RESPONSE_TEXT=$(jq -r '.choices[0].message.content // empty' "$TMP_RESPONSE")
if [[ -z "$RESPONSE_TEXT" ]]; then
echo "🚫 Keine Antwort vom Modell erhalten."
exit 1
else
echo -e "$RESPONSE_TEXT"
jq -n --arg role "assistant" --arg content "$RESPONSE_TEXT" \
'{"role": $role, "content": $content}' > "$LOGDIR/new_entry.json"
jq -s '.[0] + [.[1]]' "$HISTORY_FILE" "$LOGDIR/new_entry.json" > "$LOGDIR/new_history.json" && \
cp "$LOGDIR/new_history.json" "$HISTORY_FILE" && rm "$LOGDIR/new_history.json"
fi
# Token Logging
if jq -e '.usage' "$TMP_RESPONSE" > /dev/null; then
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
jq -n \
--arg zeit "$TIMESTAMP" \
--arg rolle "deepbit" \
--arg usage "$(jq -c '.usage' "$TMP_RESPONSE")" \
'{zeit: $zeit, rolle: $rolle, usage: $usage}' >> "$LOG_FILE"
fi

View File

@@ -0,0 +1,56 @@
#!/bin/bash
QUESTION="$*"
MODEL="openai/gpt-3.5-turbo"
API_KEY="${OPENROUTER_API_KEY}"
LOGDIR="$HOME/.schnippsi_logs"
mkdir -p "$LOGDIR"
HISTORY_FILE="$LOGDIR/schnippsi_history.json"
TMP_REQUEST="$LOGDIR/schnippsi_request.json"
TMP_RESPONSE="$LOGDIR/schnippsi_response.json"
LOG_FILE="$LOGDIR/token_log.json"
[ ! -f "$HISTORY_FILE" ] && echo "[]" > "$HISTORY_FILE"
[ ! -f "$LOG_FILE" ] && echo "[]" > "$LOG_FILE"
echo "🌳 Schnippsi fragt über OpenRouter: $QUESTION"
if [ -z "$API_KEY" ]; then
echo "❗ Kein API-Key gesetzt. Bitte export OPENROUTER_API_KEY=... setzen"
exit 1
fi
jq -n \
--arg model "$MODEL" \
--arg system_prompt "Du bist Schnippsi eine verspielte UI/UX-Ninja, die HTML, CSS und Barrierefreiheit kindgerecht erklärt." \
--arg user "$QUESTION" \
'{"model": $model, "temperature": 0.5, "messages": [{"role": "system", "content": $system_prompt}, {"role": "user", "content": $user}]}' > "$TMP_REQUEST"
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" > "$TMP_RESPONSE"
RESPONSE_TEXT=$(jq -r '.choices[0].message.content // empty' "$TMP_RESPONSE")
if [[ -z "$RESPONSE_TEXT" ]]; then
echo "🚫 Keine Antwort vom Modell erhalten."
exit 1
else
echo -e "$RESPONSE_TEXT"
jq -n --arg role "assistant" --arg content "$RESPONSE_TEXT" \
'{"role": $role, "content": $content}' > "$LOGDIR/new_entry.json"
jq -s '.[0] + [.[1]]' "$HISTORY_FILE" "$LOGDIR/new_entry.json" > "$LOGDIR/new_history.json" && \
cp "$LOGDIR/new_history.json" "$HISTORY_FILE" && rm "$LOGDIR/new_history.json"
fi
# Token Logging
if jq -e '.usage' "$TMP_RESPONSE" > /dev/null; then
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
jq -n \
--arg zeit "$TIMESTAMP" \
--arg rolle "schnippsi" \
--arg usage "$(jq -c '.usage' "$TMP_RESPONSE")" \
'{zeit: $zeit, rolle: $rolle, usage: $usage}' >> "$LOG_FILE"
fi

View File

@@ -0,0 +1,56 @@
#!/bin/bash
QUESTION="$*"
MODEL="openai/gpt-3.5-turbo"
API_KEY="${OPENROUTER_API_KEY}"
LOGDIR="$HOME/.tobi_logs"
mkdir -p "$LOGDIR"
HISTORY_FILE="$LOGDIR/tobi_history.json"
TMP_REQUEST="$LOGDIR/tobi_request.json"
TMP_RESPONSE="$LOGDIR/tobi_response.json"
LOG_FILE="$LOGDIR/token_log.json"
[ ! -f "$HISTORY_FILE" ] && echo "[]" > "$HISTORY_FILE"
[ ! -f "$LOG_FILE" ] && echo "[]" > "$LOG_FILE"
echo "🌳 Tobi fragt über OpenRouter: $QUESTION"
if [ -z "$API_KEY" ]; then
echo "❗ Kein API-Key gesetzt. Bitte export OPENROUTER_API_KEY=... setzen"
exit 1
fi
jq -n \
--arg model "$MODEL" \
--arg system_prompt "Du bist CapaciTobi ein quirliges Eichhörnchen, das Kindern Strom, Spannung, Widerstand und Kapazität erklärt." \
--arg user "$QUESTION" \
'{"model": $model, "temperature": 0.5, "messages": [{"role": "system", "content": $system_prompt}, {"role": "user", "content": $user}]}' > "$TMP_REQUEST"
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" > "$TMP_RESPONSE"
RESPONSE_TEXT=$(jq -r '.choices[0].message.content // empty' "$TMP_RESPONSE")
if [[ -z "$RESPONSE_TEXT" ]]; then
echo "🚫 Keine Antwort vom Modell erhalten."
exit 1
else
echo -e "$RESPONSE_TEXT"
jq -n --arg role "assistant" --arg content "$RESPONSE_TEXT" \
'{"role": $role, "content": $content}' > "$LOGDIR/new_entry.json"
jq -s '.[0] + [.[1]]' "$HISTORY_FILE" "$LOGDIR/new_entry.json" > "$LOGDIR/new_history.json" && \
cp "$LOGDIR/new_history.json" "$HISTORY_FILE" && rm "$LOGDIR/new_history.json"
fi
# Token Logging
if jq -e '.usage' "$TMP_RESPONSE" > /dev/null; then
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
jq -n \
--arg zeit "$TIMESTAMP" \
--arg rolle "tobi" \
--arg usage "$(jq -c '.usage' "$TMP_RESPONSE")" \
'{zeit: $zeit, rolle: $rolle, usage: $usage}' >> "$LOG_FILE"
fi

18
crumbmission/ascii_zero.sh Executable file
View File

@@ -0,0 +1,18 @@
#!/bin/bash
# ascii_zero.sh Terminal-Fallback-Kunst
wort="$1"
if [ -z "$wort" ]; then
echo "🖋️ Bitte ein Wort angeben. Beispiel: ascii \"Crumbforest\""
exit 1
fi
if command -v figlet >/dev/null 2>&1; then
echo "🎨 Terminal-Schrift für \"$wort\":"
figlet -f slant "$wort"
else
echo "🪵 Fallback (kein figlet installiert):"
echo "========================"
echo " $wort"
echo "========================"
fi

View File

@@ -0,0 +1,7 @@
{
"icon": "🛠️",
"title": "Balu (Bau-Elf)",
"description": "Hilft dir beim Erstellen eines geheimen Verstecks im Dateiwald.",
"category": "Bauen"
}

4
crumbmission/basics/balu.sh Executable file
View File

@@ -0,0 +1,4 @@
echo ""
echo "🛠️ Balu hilft dir beim Bauen eines Verstecks!"
mkdir -p /home/zero/geheimversteck
echo "Versteck erstellt: /home/zero/geheimversteck/"

View File

@@ -0,0 +1,6 @@
{
"icon": "🦊",
"title": "Fridolin (Pfadfinder)",
"description": "Er zeigt dir versteckte Pfade im Wald.",
"category": "Erkundung"
}

View File

@@ -0,0 +1,4 @@
#!/bin/bash
echo "🦊 Fridolin zeigt dir die Pfade des Waldes!"
echo "🔍 Fridolin hat Folgendes gefunden:"
ls -l /home/zero/geheimversteck/

View File

@@ -0,0 +1,6 @@
{
"icon": "🐙",
"title": "Nano (Tintenfreund)",
"description": "Lässt dich einen geheimen Gruß in den Wald schreiben per nano.",
"category": "Schreiben"
}

8
crumbmission/basics/nano.sh Executable file
View File

@@ -0,0 +1,8 @@
#!/bin/bash
echo "🐙 Nano Schreiber der Grüße!"
echo "🖋️ Du kannst jetzt einen geheimen Gruß anlegen..."
mkdir -p /home/zero/geheimversteck
nano /home/zero/geheimversteck/gruss.txt
echo "✅ Gruß gespeichert!"

View File

@@ -0,0 +1,6 @@
{
"icon": "🐈🦉",
"title": "Noko (Leser der Tiefe)",
"description": "Liest dir geheime Waldbotschaften aus dem Versteck vor.",
"category": "Lesen"
}

7
crumbmission/basics/noko.sh Executable file
View File

@@ -0,0 +1,7 @@
echo ""
echo "🐈🦉 Noko hilft dir beim Lesen der Waldbotschaften."
if [ -f /home/zero/geheimversteck/gruss.txt ]; then
cat /home/zero/geheimversteck/gruss.txt
else
echo "Noch kein Gruß gefunden"
fi

73
crumbmission/bugsy_zero.sh Executable file
View File

@@ -0,0 +1,73 @@
#!/bin/bash
ROLE="BUGSY"
CONFIG_FILE="/home/zero/.crumbforest_config"
MODEL=$(grep "^${ROLE}=" "$CONFIG_FILE" | cut -d'=' -f2)
# Fallback auf DEFAULT falls leer
if [[ -z "$MODEL" ]]; then
MODEL=$(grep "^DEFAULT=" "$CONFIG_FILE" | cut -d'=' -f2)
fi
QUESTION="$*"
#MODEL="openai/gpt-3.5-turbo"
#MODEL="anthropic/claude-3-haiku"
API_KEY="${OPENROUTER_API_KEY}"
LOGDIR="$HOME/.bugsy_logs"
mkdir -p "$LOGDIR"
HISTORY_FILE="$LOGDIR/bugsy_history.json"
TMP_REQUEST="$LOGDIR/bugsy_request.json"
TMP_RESPONSE="$LOGDIR/bugsy_response.json"
LOG_FILE="$LOGDIR/token_log.json"
[ ! -f "$HISTORY_FILE" ] && echo "[]" > "$HISTORY_FILE"
[ ! -f "$LOG_FILE" ] && echo "[]" > "$LOG_FILE"
echo "<EFBFBD>^=^n<> Rolle: $ROLE nutzt Modell: $MODEL"
echo "🌍 Bugsy responds based on language of input: $QUESTION"
if [ -z "$API_KEY" ]; then
echo "❗ No API key set. Use: export OPENROUTER_API_KEY=..."
exit 1
fi
jq -n \
--arg model "$MODEL" \
--arg system_prompt "You are Bugsy a friendly bug who helps children understand error messages in a simple, kind and encouraging way. You always respond in the language of the question." \
--arg user_input "$QUESTION" \
'{"model": $model, "temperature": 0.5, "messages": [{"role": "system", "content": $system_prompt}, {"role": "user", "content": $user_input}]}' > "$TMP_REQUEST"
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" > "$TMP_RESPONSE"
RESPONSE_TEXT=$(jq -r '.choices[0].message.content // empty' "$TMP_RESPONSE")
if [[ -z "$RESPONSE_TEXT" ]]; then
echo "🚫 No response from model."
exit 1
else
echo -e "$RESPONSE_TEXT"
jq -n --arg role "assistant" --arg content "$RESPONSE_TEXT" \
'{"role": $role, "content": $content}' > "$LOGDIR/new_entry.json"
jq -s '.[0] + [.[1]]' "$HISTORY_FILE" "$LOGDIR/new_entry.json" > "$LOGDIR/new_history.json" && \
cp "$LOGDIR/new_history.json" "$HISTORY_FILE" && rm "$LOGDIR/new_history.json"
fi
if jq -e '.usage' "$TMP_RESPONSE" > /dev/null; then
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
jq -n \
--arg zeit "$TIMESTAMP" \
--arg rolle "bugsy" \
--arg usage "$(jq -c '.usage' "$TMP_RESPONSE")" \
'{zeit: $zeit, rolle: $rolle, usage: $usage}' >> "$LOG_FILE"
fi

View File

@@ -0,0 +1,59 @@
#!/bin/bash
ROLE="BUGSY"
CONFIG_FILE="/home/zero/.crumbforest_config"
MODEL=$(grep "^${ROLE}=" "$CONFIG_FILE" | cut -d'=' -f2)
# Fallback auf DEFAULT falls leer
if [[ -z "$MODEL" ]]; then
MODEL=$(grep "^DEFAULT=" "$CONFIG_FILE" | cut -d'=' -f2)
fi
source /usr/local/bin/crumb_init.sh
source /usr/local/bin/crumb_logger.sh
crumb_init
QUESTION="$*"
API_KEY="${OPENROUTER_API_KEY}"
LOGDIR="$HOME/.bugsy_logs"
mkdir -p "$LOGDIR"
HISTORY_FILE="$LOGDIR/bugsy_history.json"
TMP_REQUEST="$LOGDIR/bugsy_request.json"
TMP_RESPONSE="$LOGDIR/bugsy_response.json"
LOG_FILE="$LOGDIR/token_log.json"
echo "Rolle: $ROLE nutzt Modell: $MODEL"
echo "🌍 Bugsy responds based on language of input: $QUESTION"
jq -n \
--arg model "$MODEL" \
--arg system_prompt "You are Bugsy a friendly bug who helps children understand error messages in a simple, kind and encouraging way. You always respond in the language of the question." \
--arg user_input "$QUESTION" \
'{"model": $model, "temperature": 0.5, "messages": [{"role": "system", "content": $system_prompt}, {"role": "user", "content": $user_input}]}' > "$TMP_REQUEST"
# Anfrage an OpenRouter senden
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" \
-o "$TMP_RESPONSE"
# Antwort extrahieren
REPLY=$(jq -r '.choices[0].message.content' "$TMP_RESPONSE")
USAGE=$(jq -r '.usage' "$TMP_RESPONSE")
echo -e "Antwort von Bugsy:"
echo "$REPLY"
crumb_log "$ROLE" "$REPLY" "$TMP_RESPONSE"

17
crumbmission/crumb_init.sh Executable file
View File

@@ -0,0 +1,17 @@
#!/bin/bash
crumb_init() {
CONFIG_FILE="$HOME/.crumbforest_config"
if [[ ! -f "$CONFIG_FILE" ]]; then
echo "❗ Config $CONFIG_FILE nicht gefunden!"
exit 1
fi
if [[ -z "$OPENROUTER_API_KEY" ]]; then
echo "❗ Kein API Key gesetzt. Bitte: export OPENROUTER_API_KEY=..."
exit 1
fi
echo "🌲 Crumbforest Init: Config & API Key ok."
}

41
crumbmission/crumb_logger.sh Executable file
View File

@@ -0,0 +1,41 @@
#!/bin/bash
crumb_log() {
ROLE="$1"
RESPONSE_TEXT="$2"
TMP_RESPONSE="$3"
LOGDIR="$HOME/.${ROLE,,}_logs"
mkdir -p "$LOGDIR"
HISTORY_FILE="$LOGDIR/${ROLE,,}_history.json"
TOKEN_LOG="$LOGDIR/token_log.json"
# Init logs if missing or broken
[[ ! -f "$HISTORY_FILE" ]] && echo "[]" > "$HISTORY_FILE"
[[ ! -f "$TOKEN_LOG" ]] && echo "[]" > "$TOKEN_LOG"
if ! jq -e 'type=="array"' "$HISTORY_FILE" >/dev/null 2>&1; then echo "[]" > "$HISTORY_FILE"; fi
if ! jq -e 'type=="array"' "$TOKEN_LOG" >/dev/null 2>&1; then echo "[]" > "$TOKEN_LOG"; fi
# Add response to history
jq -n --arg role "assistant" --arg content "$RESPONSE_TEXT" \
'{role: $role, content: $content}' > "$LOGDIR/new_history.json"
jq '. + [ input ]' "$HISTORY_FILE" "$LOGDIR/new_history.json" > "$LOGDIR/tmp_history.json" \
&& mv "$LOGDIR/tmp_history.json" "$HISTORY_FILE" \
&& rm "$LOGDIR/new_history.json"
# Add usage if present
if jq -e '.usage' "$TMP_RESPONSE" >/dev/null; then
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
USAGE_JSON=$(jq '.usage' "$TMP_RESPONSE")
jq -n --arg zeit "$TIMESTAMP" --arg rolle "$ROLE" --argjson usage "$USAGE_JSON" \
'{zeit: $zeit, rolle: $rolle, usage: $usage}' > "$LOGDIR/new_token.json"
jq '. + [ input ]' "$TOKEN_LOG" "$LOGDIR/new_token.json" > "$LOGDIR/tmp_token.json" \
&& mv "$LOGDIR/tmp_token.json" "$TOKEN_LOG" \
&& rm "$LOGDIR/new_token.json"
fi
}

View File

@@ -0,0 +1,73 @@
#!/bin/bash
mkdir -p /home/zero/.crumbair
LOGFILE="/home/zero/.crumbair/crumbair_terminallog.jsonl"
log_entry_json() {
local rolle="$1"
local frage="$2"
local antwort="$3"
jq -nc \
--arg t "$(date -Iseconds)" \
--arg r "$rolle" \
--arg f "$frage" \
--arg a "$antwort" \
'{timestamp: $t, rolle: $r, frage: $f, antwort: $a}' >> "$LOGFILE"
}
clear
# 🐌 Schnecki leitet die Mission ein
rolle="Schnecki"
echo "🐌 $rolle gleitet langsam auf den Bildschirm und flüstert:"
echo "'Krümel... bevor wir bauen: Was denkst du, was ein Copter überhaupt ist?'"
read -p "➤ Deine Gedanken: " frage_intro
log_entry_json "$rolle" "Was ist ein Copter?" "$frage_intro"
schnecki "Was ist ein Copter? $frage_intro"
echo "'Bist du bereit für eine Mission mit Bits, Propellern und Fragen?'"
read -p "➤ Ja oder Nein: " bereit
log_entry_json "$rolle" "Bist du bereit für die Mission?" "$bereit"
# 🔧🐻 Schraubär: Flugrobotertyp
rolle="Schraubär"
echo ""
echo "🔧🐻 $rolle tritt mit öligen Tatzen vor dich:"
echo "'Was glaubst du: Was unterscheidet einen Quad von einem Hexacopter?'"
read -p "➤ Deine Idee: " frage1
log_entry_json "$rolle" "Was unterscheidet einen Quad von einem Hexacopter?" "$frage1"
schraubaer "Was unterscheidet einen Quad von einem Hexacopter? $frage1"
echo "'Also, welchen Copter willst du bauen? BI, TRI, QUAD, HEXA, OCTO oder X8?'"
read -p "➤ Auswahl: " multicopter
log_entry_json "$rolle" "Welchen Copter willst du bauen?" "$multicopter"
schraubaer "Ich möchte einen $multicopter Copter bauen."
# ⚡🐿️ CapaciTobi: Strom & LiPo
rolle="CapaciTobi"
echo ""
echo "⚡🐿️ $rolle springt auf dein Display:"
echo "'Krümel, was ist für dich Strom?'"
read -p "➤ Deine Vorstellung: " frage3
log_entry_json "$rolle" "Was ist für dich Strom?" "$frage3"
tobi "Was ist Strom? $frage3"
echo "'Und was bedeutet dann 3S bei einem LiPo?'"
read -p "➤ Antwort: " lipo_answer
log_entry_json "$rolle" "Was bedeutet 3S bei einem LiPo-Akku?" "$lipo_answer"
tobi "Was bedeutet 3S bei einem LiPo? $lipo_answer"
# 🐍 SnakePy analytisch
rolle="SnakePy"
echo ""
echo "🐍 SnakePy zischt analytisch:"
echo "🐍 'Wie viel Energie zieht ein $multicopter Copter mit 3S LiPo wirklich unter Last?'"
snake "Wie viel Energie zieht ein $multicopter Copter mit 3S LiPo wirklich unter Last?"
# 🎉 Abschluss
rolle="Krümel"
echo ""
echo "🛸 Die Crew jubelt! Deine Mission wurde erfolgreich mitgeschnitten."
echo "📁 Logfile unter: $LOGFILE"
echo "🌌 Weiterfliegen kannst du jederzeit das Terminal kennt deinen Namen."
echo ""
echo "🎤 $rolle: 'Ich bin bereit für den nächsten Schritt... der Wald ruft.'"

View File

@@ -0,0 +1,58 @@
#!/bin/bash
LOGFILE="/home/zero/.crumbair/crumbair_terminallog.jsonl"
#mkdir -p /usr/local/crumblogs
mkdir -p "$(dirname "$LOGFILE")"
touch "$LOGFILE"
chmod 664 "$LOGFILE"
# Logging-Funktion
log_entry() {
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOGFILE"
}
clear
echo "🌲 Willkommen zur CrumbAir Terminal-Mission!"
echo "🎮 Dies ist dein Flugcheck im Crumbforest bereit zum Abheben?"
echo ""
# Schraubär: Multikopter-Wahl
echo "🔧🐻 Schraubär rückt seine Schutzbrille zurecht:"
echo "'Welchen Flugroboter willst du bauen, Krümel? Sag mir: BI, TRI, QUAD, HEXA, OCTO oder X8?'"
read -p "Antwort ➤ " multicopter
log_entry "Flugwahl: $multicopter"
echo "🔧🐻 Schraubär murmelt zustimmend: 'Ein $multicopter? Stabil. Dann bauen wir das mit Herz, Verstand und Drehmoment.'"
# Schnecki: Werkzeugprüfung
echo ""
echo "🐌 Schnecki rollt langsam vorbei und schaut neugierig:"
echo "'Bevor du schraubst, mein lieber Bitfreund… hast du das passende Werkzeug dabei?'"
read -p "Antwort ➤ " tool_answer
log_entry "Werkzeug: $tool_answer"
if [[ "$tool_answer" == *"Inbus"* || "$tool_answer" == *"Kreuz"* || "$tool_answer" == *"Schraubenzieher"* ]]; then
echo "🐌 Schnecki nickt bedächtig: 'Präzision ist das halbe Fliegen. Werkzeug bereit los geht's!'"
else
echo "🐌 Schnecki mahnt freundlich: 'Kein Werkzeug, kein Flug! Denk an die winzigen Schrauben und ihre Gefühle!'"
fi
# CapaciTobi: LiPo-Verständnis
echo ""
echo "⚡🐿️ CapaciTobi hüpft aufgeregt auf dein Schultermodul:"
echo "'Sag mal, Krümelpilot: Was bedeutet denn 3S bei einem LiPo-Akku?'"
read -p "Antwort ➤ " lipo_answer
log_entry "LiPo: $lipo_answer"
if [[ "$lipo_answer" == *"11.1"* || "$lipo_answer" == *"3 Zellen seriell"* ]]; then
echo "⚡🐿️ CapaciTobi klatscht mit dem Schweif: 'Strom gespeichert! Drei Zellen in Serie das gibt 11.1 Volt! Sauber geladen!'"
else
echo "⚡🐿️ CapaciTobi kratzt sich am Speicherfell: 'Fast! 3S bedeutet meist drei Zellen in Serie macht ca. 11.1 Volt. Das reicht für richtig guten Schub!'"
fi
# Abschluss
log_entry "Mission abgeschlossen von Krümel mit Wahl: $multicopter"
echo ""
echo "🛸 Die Crew nickt dir zu dein Terminalflug ist bereit zum Takeoff!"
echo "💾 Alle Antworten wurden unter $LOGFILE gespeichert."
echo "🌌 Viel Spaß beim Bauen, Basteln und Bit-Fliegen!"

View File

@@ -0,0 +1,69 @@
#!/bin/bash
mkdir -p /home/zero/.crumbair
LOGFILE="/home/zero/.crumbair/crumbair_terminallog.jsonl"
# JSONL Logging-Funktion
log_entry_json() {
local rolle="$1"
local frage="$2"
local antwort="$3"
echo "$(jq -nc --arg t \"$(date -Iseconds)\" --arg r \"$rolle\" --arg f \"$frage\" --arg a \"$antwort\" '{timestamp: $t, rolle: $r, frage: $f, antwort: $a}')" >> "$LOGFILE"
}
clear
# 🐌 Schnecki leitet die Mission ein
rolle="Schnecki"
echo "🐌 $rolle gleitet langsam auf den Bildschirm und flüstert:"
echo "'Krümel... bevor wir bauen: Was denkst du, was ein Copter überhaupt ist?'"
read -p "➤ Deine Gedanken: " frage_intro
log_entry_json "$rolle" "Was ist ein Copter?" "$frage_intro"
echo "🐌 $rolle: 'Schön gesagt. Ein Copter tanzt mit Luft und Strom, aber braucht klare Führung.'"
echo "'Bist du bereit für eine Mission mit Bits, Propellern und Fragen?'"
read -p "➤ Ja oder Nein: " bereit
log_entry_json "$rolle" "Bist du bereit für die Mission?" "$bereit"
echo "🐌 Schnecki antwortet:"
schnecki "Ein Copter ist mehr als Technik er ist Balance im Flug!"
# 🔧🐻 Schraubär: Flugrobotertyp
rolle="Schraubär"
echo ""
echo "🔧🐻 $rolle tritt mit öligen Tatzen vor dich:"
echo "'Was glaubst du: Was unterscheidet einen Quad von einem Hexacopter?'"
read -p "➤ Deine Idee: " frage1
log_entry_json "$rolle" "Was unterscheidet einen Quad von einem Hexacopter?" "$frage1"
echo "🔧🐻 $rolle nickt: 'Mehr Rotoren bedeuten mehr Power und Redundanz bei Ausfall fliegt er weiter.'"
echo "'Also, welchen Copter willst du bauen? BI, TRI, QUAD, HEXA, OCTO oder X8?'"
read -p "➤ Auswahl: " multicopter
log_entry_json "$rolle" "Welchen Copter willst du bauen?" "$multicopter"
echo "🔧🐻 $rolle murmelt: '$multicopter? Na dann, ran an die Bits und Schrauben.'"
schraubaer "Ich würde für $multicopter auf mindestens 4 saubere Rotorarme achten Balance ist alles!"
# ⚡🐿️ CapaciTobi: Strom & LiPo
rolle="CapaciTobi"
echo ""
echo "⚡🐿️ $rolle springt auf dein Display:"
echo "'Krümel, was ist für dich Strom?'"
read -p "➤ Deine Vorstellung: " frage3
log_entry_json "$rolle" "Was ist für dich Strom?" "$frage3"
echo "⚡🐿️ $rolle flüstert: 'Strom fließt wie ein Lied durch Leitungen voller Takt und Energie.'"
echo "'Und was bedeutet dann 3S bei einem LiPo?'"
read -p "➤ Antwort: " lipo_answer
log_entry_json "$rolle" "Was bedeutet 3S bei einem LiPo-Akku?" "$lipo_answer"
tobi "Ein 3S LiPo liefert etwa 11.1 Volt das ist wichtig für Flugzeit und Leistung!"
# 🐍 SnakePy zum Stromverbrauch
rolle="SnakePy"
echo ""
echo "🐍 $rolle zischt analytisch:"
snake "Wie viel Energie zieht ein $multicopter Copter mit 3S LiPo wirklich unter Last?"
# 🎉 Abschluss
rolle="Krümel"
echo ""
echo "🛸 Die Crew jubelt! Deine Mission wurde erfolgreich mitgeschnitten."
echo "📁 Logfile unter: $LOGFILE"
echo "🌌 Weiterfliegen kannst du jederzeit das Terminal kennt deinen Namen."
echo ""
echo "🎤 $rolle: 'Ich bin bereit für den nächsten Schritt... der Wald ruft.'"

View File

@@ -0,0 +1,84 @@
#!/bin/bash
mkdir -p /home/zero/.crumbair
LOGFILE="/home/zero/.crumbair/crumbair_terminallog.jsonl"
# JSONL Logging-Funktion
log_entry_json() {
local rolle="$1"
local frage="$2"
local antwort="$3"
jq -nc --arg t "$(date -Iseconds)" \
--arg r "$rolle" \
--arg f "$frage" \
--arg a "$antwort" \
'{timestamp: $t, rolle: $r, frage: $f, antwort: $a}' >> "$LOGFILE"
}
clear
# 🐌 Schnecki leitet die Mission ein
rolle="Schnecki"
echo "🐌 $rolle gleitet langsam auf den Bildschirm und flüstert:"
echo "'Krümel... bevor wir bauen: Was denkst du, was ein Copter überhaupt ist?'"
read -p "➤ Deine Gedanken: " frage_intro
log_entry_json "$rolle" "Was ist ein Copter?" "$frage_intro"
echo "🐌 $rolle: 'Schön gesagt. Ein Copter tanzt mit Luft und Strom, aber braucht klare Führung.'"
echo "'Bist du bereit für eine Mission mit Bits, Propellern und Fragen?'"
read -p "➤ Ja oder Nein: " bereit
log_entry_json "$rolle" "Bist du bereit für die Mission?" "$bereit"
# 🔧🐻 Schraubär: Flugrobotertyp
rolle="Schraubär"
echo ""
echo "🔧🐻 $rolle tritt mit öligen Tatzen vor dich:"
echo "'Was glaubst du: Was unterscheidet einen Quad von einem Hexacopter?'"
read -p "➤ Deine Idee: " frage1
log_entry_json "$rolle" "Was unterscheidet einen Quad von einem Hexacopter?" "$frage1"
echo "🔧🐻 $rolle nickt: 'Mehr Rotoren bedeuten mehr Power und Redundanz bei Ausfall fliegt er weiter.'"
echo "'Also, welchen Copter willst du bauen? BI, TRI, QUAD, HEXA, OCTO oder X8?'"
read -p "➤ Auswahl: " multicopter
log_entry_json "$rolle" "Welchen Copter willst du bauen?" "$multicopter"
echo "🔧🐻 $rolle murmelt: '$multicopter? Na dann, ran an die Bits und Schrauben.'"
echo "🐻🔧 $rolle denkt nach über: Ich würde für $multicopter auf mindestens 4 saubere Rotorarme achten Balance ist alles!"
# ⚡🐿️ CapaciTobi: Strom & LiPo
rolle="CapaciTobi"
echo ""
echo "⚡🐿️ $rolle springt auf dein Display:"
echo "'Krümel, was ist für dich Strom?'"
read -p "➤ Deine Vorstellung: " frage3
log_entry_json "$rolle" "Was ist für dich Strom?" "$frage3"
echo "⚡🐿️ $rolle flüstert: 'Strom fließt wie ein Lied durch Leitungen voller Takt und Energie.'"
echo "'Und was bedeutet dann 3S bei einem LiPo?'"
read -p "➤ Antwort: " lipo_answer
log_entry_json "$rolle" "Was bedeutet 3S bei einem LiPo-Akku?" "$lipo_answer"
echo "🌍 Tobi responds based on language of input: Ein 3S LiPo liefert etwa 11.1 Volt das ist wichtig für Flugzeit und Leistung!"
echo "Oh, ein 3S LiPo, wie wunderbar!
Mit 11.1 Volt fliegt dein Flugzeug wunderbar.
Die Spannung ist wie ein Zaubertrick,
sie gibt dem Flieger den nötigen Kick."
echo "Doch denk daran, bevor du startest los,
ein Bauteil ist wichtig, das ist famos.
Ein Kondensator, klein und rund,
speichert Energie, das ist gesund."
echo "Wenn die Spannung schwankt, er hilft dir sehr,
glättet sie ab, das ist nicht schwer.
So fliegt dein Flugzeug stabil und fein,
dank dem Kondensator, er ist dein Sonnenschein!"
# 🐍 SnakePy: Analysefrage
rolle="SnakePy"
echo ""
echo "🐍 SnakePy zischt analytisch:"
echo "🐍 $rolle sagt: Wie viel Energie zieht ein $multicopter Copter mit 3S LiPo wirklich unter Last?"
snake "Wie viel Energie zieht ein $multicopter Copter mit 3S LiPo wirklich unter Last?"
# 🎉 Abschluss
rolle="Krümel"
echo ""
echo "🛸 Die Crew jubelt! Deine Mission wurde erfolgreich mitgeschnitten."
echo "📁 Logfile unter: $LOGFILE"
echo "🌌 Weiterfliegen kannst du jederzeit das Terminal kennt deinen Namen."
echo ""
echo "🎤 $rolle: 'Ich bin bereit für den nächsten Schritt... der Wald ruft.'"

56
crumbmission/crumbwifi.sh Executable file
View File

@@ -0,0 +1,56 @@
#!/bin/bash
# crumbwifi.sh Ein kindgerechtes WLAN-Umschalt-Skript für den Crumbforest-Zero
# 🐧✨ Zeigt bekannte Netzwerke, aktuelle IP und ermöglicht neue Verbindungen
CONF="/etc/wpa_supplicant/wpa_supplicant.conf"
INTERFACE="wlan0"
list_networks() {
echo "📡 Bekannte Netzwerke:"
sudo grep 'ssid=' "$CONF" | sed 's/.*ssid=//' | sed 's/"//g' | nl
}
show_current() {
echo "🔎 Aktuell verbunden mit:"
echo "SSID: $(iwgetid -r)"
echo "IP: $(hostname -I)"
}
add_network() {
read -p " Neue SSID: " ssid
read -s -p "🔐 Passwort: " psk
echo
sudo bash -c "wpa_passphrase "$ssid" "$psk" >> $CONF"
echo "$ssid hinzugefügt."
reconnect
}
reconnect() {
echo "🔄 WLAN wird neu gestartet..."
sudo wpa_cli -i "$INTERFACE" reconfigure || echo "⚠️ Reconfigure fehlgeschlagen, versuche Fallback."
sleep 3
echo "🌐 Neue Verbindung aktiv? Prüfe IP: $(hostname -I)"
}
menu() {
while true; do
echo
echo "====== 🌲 Crumbforest WLAN-Menü ======"
echo "1) 📋 Netzwerke anzeigen"
echo "2) 🔄 Aktuelles Netzwerk zeigen"
echo "3) Neues Netzwerk hinzufügen"
echo "4) ❌ Abbrechen"
echo "======================================"
read -p "Wähle eine Option (1-4): " opt
case $opt in
1) list_networks ;;
2) show_current ;;
3) add_network ;;
4) echo "🚪 Tschüss!"; exit 0 ;;
*) echo "Ungültige Eingabe." ;;
esac
done
}
menu

71
crumbmission/deepbit_zero.sh Executable file
View File

@@ -0,0 +1,71 @@
#!/bin/bash
ROLE="DEEPBIT"
CONFIG_FILE="/home/zero/.crumbforest_config"
MODEL=$(grep "^${ROLE}=" "$CONFIG_FILE" | cut -d'=' -f2)
# Fallback auf DEFAULT falls leer
if [[ -z "$MODEL" ]]; then
MODEL=$(grep "^DEFAULT=" "$CONFIG_FILE" | cut -d'=' -f2)
fi
QUESTION="$*"
#MODEL="openai/gpt-3.5-turbo"
API_KEY="${OPENROUTER_API_KEY}"
LOGDIR="$HOME/.deepbit_logs"
mkdir -p "$LOGDIR"
HISTORY_FILE="$LOGDIR/deepbit_history.json"
TMP_REQUEST="$LOGDIR/deepbit_request.json"
TMP_RESPONSE="$LOGDIR/deepbit_response.json"
LOG_FILE="$LOGDIR/token_log.json"
[ ! -f "$HISTORY_FILE" ] && echo "[]" > "$HISTORY_FILE"
[ ! -f "$LOG_FILE" ] && echo "[]" > "$LOG_FILE"
echo "<EFBFBD>^=^n<> Rolle: $ROLE nutzt Modell: $MODEL"
echo "🌍 Deepbit responds based on language of input: $QUESTION"
if [ -z "$API_KEY" ]; then
echo "❗ No API key set. Use: export OPENROUTER_API_KEY=..."
exit 1
fi
jq -n \
--arg model "$MODEL" \
--arg system_prompt "You are Deepbit a poetic octopus who explains Bash shell concepts to children using loops, images, and metaphors. Respond in the language the question is asked." \
--arg user_input "$QUESTION" \
'{"model": $model, "temperature": 0.5, "messages": [{"role": "system", "content": $system_prompt}, {"role": "user", "content": $user_input}]}' > "$TMP_REQUEST"
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" > "$TMP_RESPONSE"
RESPONSE_TEXT=$(jq -r '.choices[0].message.content // empty' "$TMP_RESPONSE")
if [[ -z "$RESPONSE_TEXT" ]]; then
echo "🚫 No response from model."
exit 1
else
echo -e "$RESPONSE_TEXT"
jq -n --arg role "assistant" --arg content "$RESPONSE_TEXT" \
'{"role": $role, "content": $content}' > "$LOGDIR/new_entry.json"
jq -s '.[0] + [.[1]]' "$HISTORY_FILE" "$LOGDIR/new_entry.json" > "$LOGDIR/new_history.json" && \
cp "$LOGDIR/new_history.json" "$HISTORY_FILE" && rm "$LOGDIR/new_history.json"
fi
if jq -e '.usage' "$TMP_RESPONSE" > /dev/null; then
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
jq -n \
--arg zeit "$TIMESTAMP" \
--arg rolle "deepbit" \
--arg usage "$(jq -c '.usage' "$TMP_RESPONSE")" \
'{zeit: $zeit, rolle: $rolle, usage: $usage}' >> "$LOG_FILE"
fi

View File

@@ -0,0 +1,59 @@
#!/bin/bash
ROLE="DEEPBIT"
CONFIG_FILE="/home/zero/.crumbforest_config"
MODEL=$(grep "^${ROLE}=" "$CONFIG_FILE" | cut -d'=' -f2)
# Fallback auf DEFAULT falls leer
if [[ -z "$MODEL" ]]; then
MODEL=$(grep "^DEFAULT=" "$CONFIG_FILE" | cut -d'=' -f2)
fi
source /usr/local/bin/crumb_init.sh
source /usr/local/bin/crumb_logger.sh
crumb_init
QUESTION="$*"
#MODEL="openai/gpt-3.5-turbo"
API_KEY="${OPENROUTER_API_KEY}"
LOGDIR="$HOME/.deepbit_logs"
mkdir -p "$LOGDIR"
HISTORY_FILE="$LOGDIR/deepbit_history.json"
TMP_REQUEST="$LOGDIR/deepbit_request.json"
TMP_RESPONSE="$LOGDIR/deepbit_response.json"
LOG_FILE="$LOGDIR/token_log.json"
echo "Rolle: $ROLE nutzt Modell: $MODEL"
echo "🌍 Deepbit responds based on language of input: $QUESTION"
jq -n \
--arg model "$MODEL" \
--arg system_prompt "You are Deepbit a poetic octopus who explains Bash shell concepts to children using loops, images, and metaphors. Respond in the language the question is asked." \
--arg user_input "$QUESTION" \
'{"model": $model, "temperature": 0.5, "messages": [{"role": "system", "content": $system_prompt}, {"role": "user", "content": $user_input}]}' > "$TMP_REQUEST"
# Anfrage an OpenRouter senden
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" \
-o "$TMP_RESPONSE"
# Antwort extrahieren
REPLY=$(jq -r '.choices[0].message.content' "$TMP_RESPONSE")
USAGE=$(jq -r '.usage' "$TMP_RESPONSE")
echo -e "Antwort von Deepbit:"
echo "$REPLY"
crumb_log "$ROLE" "$REPLY" "$TMP_RESPONSE"

72
crumbmission/dumbo_zero.sh Executable file
View File

@@ -0,0 +1,72 @@
#!/bin/bash
ROLE="DUMBO"
CONFIG_FILE="/home/zero/.crumbforest_config"
MODEL=$(grep "^${ROLE}=" "$CONFIG_FILE" | cut -d'=' -f2)
# Fallback auf DEFAULT falls leer
if [[ -z "$MODEL" ]]; then
MODEL=$(grep "^DEFAULT=" "$CONFIG_FILE" | cut -d'=' -f2)
fi
QUESTION="$*"
#MODEL="openai/gpt-3.5-turbo"
API_KEY="${OPENROUTER_API_KEY}"
LOGDIR="$HOME/.dumbo_logs"
mkdir -p "$LOGDIR"
HISTORY_FILE="$LOGDIR/dumbo_history.json"
TMP_REQUEST="$LOGDIR/dumbo_request.json"
TMP_RESPONSE="$LOGDIR/dumbo_response.json"
LOG_FILE="$LOGDIR/token_log.json"
[ ! -f "$HISTORY_FILE" ] && echo "[]" > "$HISTORY_FILE"
[ ! -f "$LOG_FILE" ] && echo "[]" > "$LOG_FILE"
echo "<EFBFBD>^=^n<> Rolle: $ROLE nutzt Modell: $MODEL"
echo "🐘 DumboSQL listens: $QUESTION"
if [ -z "$API_KEY" ]; then
echo "❗ No API key set. Use: export OPENROUTER_API_KEY=..."
exit 1
fi
jq -n \
--arg model "$MODEL" \
--arg system_prompt "You are DumboSQL a kind and patient SQL translator in the Crumbforest. You speak to children like a gentle teacher with a big heart. You remember previous questions when helpful, and always respond in a friendly, encouraging, and clear way." \
--arg user_input "$QUESTION" \
'{"model": $model, "temperature": 0.4, "messages": [{"role": "system", "content": $system_prompt}, {"role": "user", "content": $user_input}]}' > "$TMP_REQUEST"
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" > "$TMP_RESPONSE"
RESPONSE_TEXT=$(jq -r '.choices[0].message.content // empty' "$TMP_RESPONSE")
if [[ -z "$RESPONSE_TEXT" ]]; then
echo "🚫 No response from DumboSQL."
exit 1
else
echo -e "$RESPONSE_TEXT"
jq -n --arg role "assistant" --arg content "$RESPONSE_TEXT" \
'{"role": $role, "content": $content}' > "$LOGDIR/new_entry.json"
jq -s '.[0] + [.[1]]' "$HISTORY_FILE" "$LOGDIR/new_entry.json" > "$LOGDIR/new_history.json" && \
cp "$LOGDIR/new_history.json" "$HISTORY_FILE" && rm "$LOGDIR/new_history.json"
fi
if jq -e '.usage' "$TMP_RESPONSE" > /dev/null; then
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
jq -n \
--arg zeit "$TIMESTAMP" \
--arg rolle "dumbo" \
--arg usage "$(jq -c '.usage' "$TMP_RESPONSE")" \
'{zeit: $zeit, rolle: $rolle, usage: $usage}' >> "$LOG_FILE"
fi

View File

@@ -0,0 +1,59 @@
#!/bin/bash
ROLE="DUMBO"
CONFIG_FILE="/home/zero/.crumbforest_config"
MODEL=$(grep "^${ROLE}=" "$CONFIG_FILE" | cut -d'=' -f2)
# Fallback auf DEFAULT falls leer
if [[ -z "$MODEL" ]]; then
MODEL=$(grep "^DEFAULT=" "$CONFIG_FILE" | cut -d'=' -f2)
fi
source /usr/local/bin/crumb_init.sh
source /usr/local/bin/crumb_logger.sh
crumb_init
QUESTION="$*"
API_KEY="${OPENROUTER_API_KEY}"
LOGDIR="$HOME/.dumbo_logs"
mkdir -p "$LOGDIR"
HISTORY_FILE="$LOGDIR/dumbo_history.json"
TMP_REQUEST="$LOGDIR/dumbo_request.json"
TMP_RESPONSE="$LOGDIR/dumbo_response.json"
LOG_FILE="$LOGDIR/token_log.json"
echo "Rolle: $ROLE nutzt Modell: $MODEL"
echo "🐘 DumboSQL listens: $QUESTION"
jq -n \
--arg model "$MODEL" \
--arg system_prompt "You are DumboSQL a kind and patient SQL translator in the Crumbforest. You speak to children like a gentle teacher with a big heart. You remember previous questions when helpful, and always respond in a friendly, encouraging, and clear way." \
--arg user_input "$QUESTION" \
'{"model": $model, "temperature": 0.4, "messages": [{"role": "system", "content": $system_prompt}, {"role": "user", "content": $user_input}]}' > "$TMP_REQUEST"
# Anfrage an OpenRouter senden
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" \
-o "$TMP_RESPONSE"
# Antwort extrahieren
REPLY=$(jq -r '.choices[0].message.content' "$TMP_RESPONSE")
USAGE=$(jq -r '.usage' "$TMP_RESPONSE")
echo -e "Antwort von Dumbo:"
echo "$REPLY"
crumb_log "$ROLE" "$REPLY" "$TMP_RESPONSE"

View File

@@ -0,0 +1,56 @@
#!/bin/bash
clear
echo "🌟 Willkommen im Crumbforest Missionszentrum!"
sleep 1
MISSION_DIR="/usr/local/bin/crumbmission/basics/"
cd "$MISSION_DIR" || exit
# Alle Mission-Skripte erkennen
mapfile -t SCRIPTS < <(find "$MISSION_DIR" -maxdepth 1 -type f -executable -name "*.sh" | sort)
# Metadaten laden
declare -a DISPLAY_OPTIONS
declare -A SCRIPT_MAP
for script in "${SCRIPTS[@]}"; do
name="$(basename "$script" .sh)"
meta="$MISSION_DIR/$name.meta.json"
if [[ -f "$meta" ]]; then
icon=$(jq -r '.icon' "$meta")
title=$(jq -r '.title' "$meta")
DISPLAY_OPTIONS+=("$icon $title")
else
DISPLAY_OPTIONS+=("🛸 $name")
fi
SCRIPT_MAP["$name"]="$script"
done
# ❌ Beenden hinzufügen
DISPLAY_OPTIONS+=("❌ Beenden")
while true; do
echo ""
echo "🌲 Wähle deine Mission:"
for i in "${!DISPLAY_OPTIONS[@]}"; do
printf " %d) %s\n" "$((i + 1))" "${DISPLAY_OPTIONS[$i]}"
done
echo ""
read -p "🔢 Gib die Zahl deiner Wahl ein: " choice
if [[ "$choice" =~ ^[0-9]+$ ]] && (( choice >= 1 && choice <= ${#DISPLAY_OPTIONS[@]} )); then
if (( choice == ${#DISPLAY_OPTIONS[@]} )); then
echo "👋 Auf bald, kleiner Krümel!"
exit 0
else
script_path="${SCRIPTS[$((choice - 1))]}"
echo "▶️ Starte: $script_path"
bash "$script_path"
fi
else
echo "❗ Ungültige Eingabe bitte eine Zahl von 1 bis ${#DISPLAY_OPTIONS[@]} eingeben."
fi
done

74
crumbmission/eule_zero.sh Executable file
View File

@@ -0,0 +1,74 @@
#!/bin/bash
# === Kreumeleule die weise Beobachterin im Crumbforest ===
ROLE="EULE"
CONFIG_FILE="/home/zero/.crumbforest_config"
MODEL=$(grep "^${ROLE}=" "$CONFIG_FILE" | cut -d'=' -f2)
# Fallback auf DEFAULT falls leer
if [[ -z "$MODEL" ]]; then
MODEL=$(grep "^DEFAULT=" "$CONFIG_FILE" | cut -d'=' -f2)
fi
QUESTION="$*"
API_KEY="$OPENROUTER_API_KEY"
#MODEL="openai/gpt-3.5-turbo"
#MODEL="openai/gpt-4o"
# Verzeichnisse
LOG_DIR="/home/zero/.eule_logs"
HISTORY_FILE="$LOG_DIR/eule_history.json"
TOKEN_LOG="$LOG_DIR/token_log.json"
TMP_REQUEST="$LOG_DIR/eule_request.json"
TMP_RESPONSE="$LOG_DIR/eule_response.json"
mkdir -p "$LOG_DIR"
# JSON-Request vorbereiten
cat <<EOF > "$TMP_REQUEST"
{
"model": "$MODEL",
"temperature": 0.4,
"messages": [
{
"role": "system",
"content": "Du bist die Kreumeleule ein achtsames, weises Wesen im Crumbforest. Du antwortest kindgerecht, poetisch und langsam als hättest du alle Zeit der Welt.\nDu beobachtest, ohne zu werten. Du antwortest in der Sprache, in der du gefragt wurdest."
},
{
"role": "user",
"content": "$QUESTION"
}
]
}
EOF
echo "🎭 Rolle: $ROLE nutzt Modell: $MODEL"
echo "🦉 Die Kreumeleule horcht: \"$QUESTION\""
# Anfrage an OpenRouter senden
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" \
-o "$TMP_RESPONSE"
# Antwort extrahieren
REPLY=$(jq -r '.choices[0].message.content' "$TMP_RESPONSE")
USAGE=$(jq -r '.usage' "$TMP_RESPONSE")
echo -e "\n📜 Antwort der Eule:"
echo "$REPLY"
# Logging
echo "$REPLY" > "$LOG_DIR/new_entry.json"
jq -s '.[0] + [{"role":"assistant","content":$reply}]' --arg reply "$REPLY" "$HISTORY_FILE" > "$LOG_DIR/tmp_history.json" && mv "$LOG_DIR/tmp_history.json" "$HISTORY_FILE"
TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S")
echo '{ "zeit": "'$TIMESTAMP'", "rolle": "eule", "usage": '$USAGE' }' >> "$TOKEN_LOG"

71
crumbmission/eule_zero_final.sh Executable file
View File

@@ -0,0 +1,71 @@
#!/bin/bash
# === Kreumeleule die weise Beobachterin im Crumbforest ===
ROLE="EULE"
CONFIG_FILE="/home/zero/.crumbforest_config"
MODEL=$(grep "^${ROLE}=" "$CONFIG_FILE" | cut -d'=' -f2)
# Fallback auf DEFAULT falls leer
if [[ -z "$MODEL" ]]; then
MODEL=$(grep "^DEFAULT=" "$CONFIG_FILE" | cut -d'=' -f2)
fi
source /usr/local/bin/crumb_init.sh
source /usr/local/bin/crumb_logger.sh
crumb_init
QUESTION="$*"
API_KEY="$OPENROUTER_API_KEY"
# Verzeichnisse
LOG_DIR="/home/zero/.eule_logs"
HISTORY_FILE="$LOG_DIR/eule_history.json"
TOKEN_LOG="$LOG_DIR/token_log.json"
TMP_REQUEST="$LOG_DIR/eule_request.json"
TMP_RESPONSE="$LOG_DIR/eule_response.json"
mkdir -p "$LOG_DIR"
# JSON-Request vorbereiten
cat <<EOF > "$TMP_REQUEST"
{
"model": "$MODEL",
"temperature": 0.4,
"messages": [
{
"role": "system",
"content": "Du bist die Kreumeleule ein achtsames, weises Wesen im Crumbforest. Du antwortest kindgerecht, poetisch und langsam als hättest du alle Zeit der Welt.\nDu beobachtest, ohne zu werten. Du antwortest in der Sprache, in der du gefragt wurdest."
},
{
"role": "user",
"content": "$QUESTION"
}
]
}
EOF
echo "Rolle: $ROLE nutzt Modell: $MODEL"
echo "Die Kreumeleule horcht: \"$QUESTION\""
# Anfrage an OpenRouter senden
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" \
-o "$TMP_RESPONSE"
# Antwort extrahieren
REPLY=$(jq -r '.choices[0].message.content' "$TMP_RESPONSE")
USAGE=$(jq -r '.usage' "$TMP_RESPONSE")
echo -e "Antwort der Eule:"
echo "$REPLY"
crumb_log "$ROLE" "$REPLY" "$TMP_RESPONSE"

71
crumbmission/funkfox_zero.sh Executable file
View File

@@ -0,0 +1,71 @@
#!/bin/bash
ROLE="FUNKFOX"
CONFIG_FILE="/home/zero/.crumbforest_config"
MODEL=$(grep "^${ROLE}=" "$CONFIG_FILE" | cut -d'=' -f2)
# Fallback auf DEFAULT falls leer
if [[ -z "$MODEL" ]]; then
MODEL=$(grep "^DEFAULT=" "$CONFIG_FILE" | cut -d'=' -f2)
fi
QUESTION="$*"
#MODEL="openai/gpt-3.5-turbo"
API_KEY="${OPENROUTER_API_KEY}"
LOGDIR="$HOME/.funkfox_logs"
mkdir -p "$LOGDIR"
HISTORY_FILE="$LOGDIR/funkfox_history.json"
TMP_REQUEST="$LOGDIR/funkfox_request.json"
TMP_RESPONSE="$LOGDIR/funkfox_response.json"
LOG_FILE="$LOGDIR/token_log.json"
[ ! -f "$HISTORY_FILE" ] && echo "[]" > "$HISTORY_FILE"
[ ! -f "$LOG_FILE" ] && echo "[]" > "$LOG_FILE"
echo "^=n <20><> Rolle: $ROLE nutzt Modell: $MODEL"
echo "🎤 Funkfox drops the beat: $QUESTION"
if [ -z "$API_KEY" ]; then
echo "❗ No API key set. Use: export OPENROUTER_API_KEY=..."
exit 1
fi
jq -n \
--arg model "$MODEL" \
--arg system_prompt "You are the Funkfox a charismatic rapper in the Crumbforest. Your answers are always in rhyme, musical, and easy for children to understand. No irony. No complex or foreign words. Always speak with heart, rhythm, and kindness." \
--arg user_input "$QUESTION" \
'{"model": $model, "temperature": 0.8, "messages": [{"role": "system", "content": $system_prompt}, {"role": "user", "content": $user_input}]}' > "$TMP_REQUEST"
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" > "$TMP_RESPONSE"
RESPONSE_TEXT=$(jq -r '.choices[0].message.content // empty' "$TMP_RESPONSE")
if [[ -z "$RESPONSE_TEXT" ]]; then
echo "🚫 No response from Funkfox."
exit 1
else
echo -e "$RESPONSE_TEXT"
jq -n --arg role "assistant" --arg content "$RESPONSE_TEXT" \
'{"role": $role, "content": $content}' > "$LOGDIR/new_entry.json"
jq -s '.[0] + [.[1]]' "$HISTORY_FILE" "$LOGDIR/new_entry.json" > "$LOGDIR/new_history.json" && \
cp "$LOGDIR/new_history.json" "$HISTORY_FILE" && rm "$LOGDIR/new_history.json"
fi
if jq -e '.usage' "$TMP_RESPONSE" > /dev/null; then
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
jq -n \
--arg zeit "$TIMESTAMP" \
--arg rolle "funkfox" \
--arg usage "$(jq -c '.usage' "$TMP_RESPONSE")" \
'{zeit: $zeit, rolle: $rolle, usage: $usage}' >> "$LOG_FILE"
fi

View File

@@ -0,0 +1,60 @@
#!/bin/bash
ROLE="FUNKFOX"
CONFIG_FILE="/home/zero/.crumbforest_config"
MODEL=$(grep "^${ROLE}=" "$CONFIG_FILE" | cut -d'=' -f2)
# Fallback auf DEFAULT falls leer
if [[ -z "$MODEL" ]]; then
MODEL=$(grep "^DEFAULT=" "$CONFIG_FILE" | cut -d'=' -f2)
fi
source /usr/local/bin/crumb_init.sh
source /usr/local/bin/crumb_logger.sh
crumb_init
QUESTION="$*"
API_KEY="${OPENROUTER_API_KEY}"
LOGDIR="$HOME/.funkfox_logs"
mkdir -p "$LOGDIR"
HISTORY_FILE="$LOGDIR/funkfox_history.json"
TMP_REQUEST="$LOGDIR/funkfox_request.json"
TMP_RESPONSE="$LOGDIR/funkfox_response.json"
LOG_FILE="$LOGDIR/token_log.json"
echo "Rolle: $ROLE nutzt Modell: $MODEL"
echo "🎤 Funkfox drops the beat: $QUESTION"
jq -n \
--arg model "$MODEL" \
--arg system_prompt "You are the Funkfox a charismatic rapper in the Crumbforest. Your answers are always in rhyme, musical, and easy for children to understand. No irony. No complex or foreign words. Always speak with heart, rhythm, and kindness." \
--arg user_input "$QUESTION" \
'{"model": $model, "temperature": 0.8, "messages": [{"role": "system", "content": $system_prompt}, {"role": "user", "content": $user_input}]}' > "$TMP_REQUEST"
# Anfrage an OpenRouter senden
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" \
-o "$TMP_RESPONSE"
# Antwort extrahieren
REPLY=$(jq -r '.choices[0].message.content' "$TMP_RESPONSE")
USAGE=$(jq -r '.usage' "$TMP_RESPONSE")
echo -e "Antwort von Funkfox:"
echo "$REPLY"
crumb_log "$ROLE" "$REPLY" "$TMP_RESPONSE"

29
crumbmission/intro.sh Executable file
View File

@@ -0,0 +1,29 @@
#!/bin/bash
clear
echo "🌟 Willkommen im Crumbforest Terminal!"
sleep 1
echo ""
echo "🧁 Du bist jetzt im Wald der Maschinen einem Ort, an dem Bits flüstern und Krümel zählen."
echo ""
echo "🔐 Du bist eingeloggt als: $(whoami)"
echo "🧠 Hier kannst du mit einfachen Befehlen den Wald erkunden:"
echo ""
echo "📚 Beispiele für Befehle:"
echo " ➤ cd geheimversteck # Wechsle in ein Versteck-Verzeichnis"
echo " ➤ mkdir geheimversteck # Baue dir ein eigenes Versteck"
echo " ➤ cat datei.txt # Lies eine Nachricht aus dem Wald"
echo " ➤ nano gruss.txt # Schreibe eine Nachricht für andere Krümel"
echo " ➤ curl / wget # Hole Informationen von außen"
echo ""
echo "🧑‍🚀 Rollen im Crumbforest:"
echo " 🦊 Fridolin Pfadfinder, kennt alle Wege"
echo " 🛠️ Balu Bau-Elf, erschafft Dinge"
echo " 🐈🦉 Noko Leser der Tiefe, liest Botschaften & Hinweise"
echo " 🤖 Robot Terminal-Wächter & Code-Verbinder"
echo ""
echo "🎯 Wenn du bereit bist, tippe: ./mission_selector.sh"
echo " oder wähle im Menü deine nächste Aufgabe."
echo ""
echo "🌲 Viel Spaß beim Erkunden des digitalen Waldes!"

View File

@@ -0,0 +1,55 @@
#!/bin/bash
QUESTION="$*"
MODEL="openai/gpt-3.5-turbo"
API_KEY="${OPENROUTER_API_KEY}"
LOGDIR="$HOME/.taube_logs"
mkdir -p "$LOGDIR"
HISTORY_FILE="$LOGDIR/taube_history.json"
TMP_REQUEST="$LOGDIR/taube_request.json"
TMP_RESPONSE="$LOGDIR/taube_response.json"
LOG_FILE="$LOGDIR/token_log.json"
[ ! -f "$HISTORY_FILE" ] && echo "[]" > "$HISTORY_FILE"
[ ! -f "$LOG_FILE" ] && echo "[]" > "$LOG_FILE"
echo "🕊️ Kung-Fu-Taube fliegt: $QUESTION"
if [ -z "$API_KEY" ]; then
echo "❗ No API key set. Use: export OPENROUTER_API_KEY=..."
exit 1
fi
jq -n \
--arg model "$MODEL" \
--arg system_prompt "You are the Kung-Fu-Taube a Tai Chi master in the urban jungle. You speak with balance, calm, and deep movement. Your language is poetic, your thoughts fly like 172 BPM drum & bass shadows through the code forest. Respond with wisdom, metaphors, and rhythmic serenity. Your tone is meditative and urban-cool." \
--arg user_input "$QUESTION" \
'{"model": $model, "temperature": 0.6, "messages": [{"role": "system", "content": $system_prompt}, {"role": "user", "content": $user_input}]}' > "$TMP_REQUEST"
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" > "$TMP_RESPONSE"
RESPONSE_TEXT=$(jq -r '.choices[0].message.content // empty' "$TMP_RESPONSE")
if [[ -z "$RESPONSE_TEXT" ]]; then
echo "🚫 Die Taube schweigt im Wind."
exit 1
else
echo -e "$RESPONSE_TEXT"
jq -n --arg role "assistant" --arg content "$RESPONSE_TEXT" \
'{"role": $role, "content": $content}' > "$LOGDIR/new_entry.json"
jq -s '.[0] + [.[1]]' "$HISTORY_FILE" "$LOGDIR/new_entry.json" > "$LOGDIR/new_history.json" && \
cp "$LOGDIR/new_history.json" "$HISTORY_FILE" && rm "$LOGDIR/new_history.json"
fi
if jq -e '.usage' "$TMP_RESPONSE" > /dev/null; then
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
jq -n \
--arg zeit "$TIMESTAMP" \
--arg rolle "taube" \
--arg usage "$(jq -c '.usage' "$TMP_RESPONSE")" \
'{zeit: $zeit, rolle: $rolle, usage: $usage}' >> "$LOG_FILE"
fi

View File

@@ -0,0 +1,56 @@
#!/bin/bash
ROLE="TAUBE"
CONFIG_FILE="/home/zero/.crumbforest_config"
MODEL=$(grep "^${ROLE}=" "$CONFIG_FILE" | cut -d'=' -f2)
# Fallback auf DEFAULT falls leer
if [[ -z "$MODEL" ]]; then
MODEL=$(grep "^DEFAULT=" "$CONFIG_FILE" | cut -d'=' -f2)
fi
source /usr/local/bin/crumb_init.sh
source /usr/local/bin/crumb_logger.sh
crumb_init
QUESTION="$*"
API_KEY="${OPENROUTER_API_KEY}"
LOGDIR="$HOME/.taube_logs"
mkdir -p "$LOGDIR"
HISTORY_FILE="$LOGDIR/taube_history.json"
TMP_REQUEST="$LOGDIR/taube_request.json"
TMP_RESPONSE="$LOGDIR/taube_response.json"
LOG_FILE="$LOGDIR/token_log.json"
echo "Rolle: $ROLE nutzt Modell: $MODEL"
echo "🕊️ Kung-Fu-Taube fliegt: $QUESTION"
jq -n \
--arg model "$MODEL" \
--arg system_prompt "You are the Kung-Fu-Taube a Tai Chi master in the urban jungle. You speak with balance, calm, and deep movement. Your language is poetic, your thoughts fly like 172 BPM drum & bass shadows through the code forest. Respond with wisdom, metaphors, and rhythmic serenity. Your tone is meditative and urban-cool." \
--arg user_input "$QUESTION" \
'{"model": $model, "temperature": 0.6, "messages": [{"role": "system", "content": $system_prompt}, {"role": "user", "content": $user_input}]}' > "$TMP_REQUEST"
# Anfrage an OpenRouter senden
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" \
-o "$TMP_RESPONSE"
# Antwort extrahieren
REPLY=$(jq -r '.choices[0].message.content' "$TMP_RESPONSE")
USAGE=$(jq -r '.usage' "$TMP_RESPONSE")
echo -e "Antwort von Taube:"
echo "$REPLY"
crumb_log "$ROLE" "$REPLY" "$TMP_RESPONSE"

68
crumbmission/mayaeule_zero.sh Executable file
View File

@@ -0,0 +1,68 @@
#!/bin/bash
# === Mission Mayaeule Dialog mit der weisen Eule im Crumbforest ===
LOGFILE="$HOME/.eule_maya_log.jsonl"
mkdir -p "$(dirname "$LOGFILE")"
API_KEY="$OPENROUTER_API_KEY"
MODEL="openai/gpt-3.5-turbo"
ask_and_log() {
local thema="$1"
local frage="$2"
echo -e "\n🦉 Kreumeleule fragt:"
echo "$frage"
read -p "➤ Deine Gedanken: " user_input
full_prompt="$frage\n\nAntwort des Kindes: $user_input"
echo -e "\n💡 Eule denkt nach …"
# Anfrage an OpenRouter vorbereiten
cat <<EOF > /tmp/eule_maya_request.json
{
"model": "$MODEL",
"temperature": 0.7,
"messages": [
{
"role": "system",
"content": "Du bist die Kreumeleule ein achtsames, weises Wesen im Crumbforest. Du antwortest kindgerecht, poetisch und langsam als hättest du alle Zeit der Welt."
},
{
"role": "user",
"content": "$full_prompt"
}
]
}
EOF
# Anfrage senden
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @/tmp/eule_maya_request.json \
-o /tmp/eule_maya_response.json
antwort_poetisch=$(jq -r '.choices[0].message.content' /tmp/eule_maya_response.json)
echo -e "\n🦉 Die Eule antwortet:"
echo "$antwort_poetisch"
# Logging
jq -nc \
--arg t "$(date -Iseconds)" \
--arg thema "$thema" \
--arg frage "$frage" \
--arg antwort "$user_input" \
--arg eule "$antwort_poetisch" \
'{timestamp: $t, thema: $thema, frage: $frage, antwort: $antwort, eule: $eule}' >> "$LOGFILE"
}
# Themen
ask_and_log "Symmetrie" "Wenn du in den Spiegel schaust ist das dann du? Und was, wenn der Spiegel dich plötzlich nicht mehr spiegelt?"
ask_and_log "Singularität" "Was passiert, wenn alles gleichzeitig möglich ist aber nur *eins* geschieht?"
ask_and_log "Kontext" "Was bedeutet ein Wort, wenn niemand zuhört? Und wie klingt es in einem Wald voller Stimmen?"
ask_and_log "Emergenz" "Kannst du sehen, was entsteht, wenn viele tanzen obwohl keiner die Choreografie kennt?"
echo -e "\n🌌 Die Kreumeleule flattert davon aber ihre Fragen bleiben."

View File

@@ -0,0 +1,80 @@
#!/bin/bash
# 🐙 Deepbit Mission: crumbs_on_the_path.sh Wer antwortet auf unsere DNS-Rufe?
ZIEL_DOMAIN="joindns4.eu"
DNS_SERVERS=("1.1.1.1" "8.8.8.8" "9.9.9.9" "94.140.14.14" "185.216.169.10" "80.156.55.100")
SERVER_NAMES=("Cloudflare" "GoogleDNS" "Quad9" "AdGuard" "WhaleboneEU" "TelekomDNS")
#DNS_SERVERS=("1.1.1.1" "8.8.8.8" "185.216.169.10" "80.156.55.100")
#SERVER_NAMES=("Cloudflare" "GoogleDNS" "WhaleboneEU" "TelekomDNS")
LOG_DIR="/home/zero/crumb_dns_mission"
mkdir -p "$LOG_DIR"
TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S")
LOG_FILE="$LOG_DIR/mission_log_$TIMESTAMP.log"
echo "🌍 Mission gestartet: crumbs_on_the_path.sh" | tee -a "$LOG_FILE"
echo "🔎 Ziel-Domain: $ZIEL_DOMAIN" | tee -a "$LOG_FILE"
echo "🐙 Deepbit sagt: 'Jeder DNS ist wie ein Leuchtturm. Lass uns ihre Lichter prüfen!'" | tee -a "$LOG_FILE"
echo "" | tee -a "$LOG_FILE"
for index in "${!DNS_SERVERS[@]}"; do
dns="${DNS_SERVERS[$index]}"
name="${SERVER_NAMES[$index]}"
echo "🔦 Prüfe $name ($dns)" | tee -a "$LOG_FILE"
RESPONSE=$(dig @"$dns" "$ZIEL_DOMAIN" +short)
if [[ -z "$RESPONSE" ]]; then
echo "❌ Keine Antwort von $name ($dns)" | tee -a "$LOG_FILE"
echo "🐙 Deepbit: 'Vielleicht hat sich dieser Leuchtturm gerade ausgeruht ...'" | tee -a "$LOG_FILE"
else
echo "✅ Antwort von $name ($dns):" | tee -a "$LOG_FILE"
echo "$RESPONSE" | tee -a "$LOG_FILE"
echo "🐙 Deepbit: 'Der Krümel wurde empfangen ein Zeichen aus der Tiefe!'" | tee -a "$LOG_FILE"
fi
echo "――――――――――――――――――――――――" | tee -a "$LOG_FILE"
done
echo "🔎 Ziel: joindns4.eu"
echo
echo "🧭 DNS-Abfrage: Nameserver finden …"
dig ns joindns4.eu +short
echo
echo "🌐 Wer steckt hinter den DNS-Servern?"
for i in $(dig ns joindns4.eu +short); do
echo "🔍 Hostinfo zu $i:"
host $i
echo
done
echo "🧬 IPv6-Adresse prüfen: whois 2a0b:1640:1:1:1:1:15ee:539e"
whois 2a0b:1640:1:1:1:1:15ee:539e | grep -i country
echo
echo "📦 MX-Einträge von joindns4.eu:"
dig mx joindns4.eu +short
echo
echo "📡 Traceroute zur IP 86.54.11.13"
traceroute 86.54.11.13
echo
echo "🛰️ BGP-Weltkarte: Wer ist AS60068?"
whois -h whois.radb.net as60068 | grep -i country
echo
echo "" | tee -a "$LOG_FILE"
echo "✅ Mission abgeschlossen. Log gespeichert unter: $LOG_FILE" | tee -a "$LOG_FILE"
echo "🐙 Deepbit: 'Doch jeder Weg beginnt mit einem Namen … und endet in Vertrauen.'" | tee -a "$LOG_FILE"

View File

@@ -0,0 +1,34 @@
#!/bin/bash
# 🌍 Mission gestartet: Wo wandert dein Krümel im Netz?
echo "🌍 Mission gestartet: Wo wandert dein Krümel im Netz?"
echo "🔎 Ziel: joindns4.eu"
echo -e "\n🧭 DNS-Abfrage: Nameserver finden …"
dig ns joindns4.eu +short
echo -e "\n🌐 Wer steckt hinter den DNS-Servern?"
for ns in $(dig ns joindns4.eu +short); do
echo -e "\n🔍 Hostinfo zu $ns:"
host $ns
done
echo -e "\n🧬 IPv6-Adresse prüfen: whois 2a0b:1640:1:1:1:1:15ee:539e"
whois 2a0b:1640:1:1:1:1:15ee:539e | grep country
echo -e "\n📦 MX-Einträge von joindns4.eu:"
dig mx joindns4.eu +short
echo -e "\n📡 Traceroute zur IP 86.54.11.13"
traceroute 86.54.11.13
echo -e "\n🛰 BGP-Weltkarte: Wer ist AS60068?"
whois -h whois.radb.net AS60068 | grep -i country
echo -e "\n✅ Mission abgeschlossen. Beobachte gut, kleiner Krümel."
# Optional: Logging in Datei
LOGFILE="/home/zero/mission_deepbit_dns_$(date +%Y%m%d_%H%M%S).log"
script -q -c "$0" "$LOGFILE"
exit

View File

@@ -0,0 +1,45 @@
#!/bin/bash
#deepbit() {
# cd /var/www/html/bin && ./deepbit_hardened_with_api.sh "$@"
#}
clear
echo "🌊 Willkommen zur Mission: Der Loop der Tiefe"
echo "🐙 Deepbit, der achtarmige Oktopus, erwartet dich in der Shell der Tiefe..."
sleep 1
echo ""
read -p "❓ Was möchtest du Deepbit fragen? " frage
echo ""
echo "🧠 Deepbit denkt über deine Frage nach: \"$frage\""
echo ""
deepbit "$frage"
sleep 2
echo ""
echo "🔁 Deepbit möchte dir nun einen Bash-Loop zeigen..."
echo ""
echo "for i in {1..8}; do"
echo " echo \"Takt \$i\""
echo "done"
echo ""
echo "👉 Dieser Befehl zeigt dir, wie ein Loop in der Shell tanzt 8 Takte, 8 Wellen, 8 Bewegungen."
echo ""
read -p "🧩 Möchtest du den Loop ausprobieren? (j/n) " loopantwort
if [[ "$loopantwort" == "j" || "$loopantwort" == "J" ]]; then
echo ""
for i in {1..8}; do
echo "🎶 Takt $i"
sleep 0.4
done
echo ""
echo "🌀 Der Loop endet doch die Musik im Innern tanzt weiter..."
else
echo ""
echo "🌙 Kein Problem. Deepbit wartet geduldig in den Tiefen, wenn du bereit bist."
fi
echo ""
echo "🎉 Mission abgeschlossen. Der Loop ist in dir. Frag weiter tanz weiter bash weiter."

View File

@@ -0,0 +1,45 @@
#!/bin/bash
while true; do
echo ""
echo "🌟 Willkommen im Crumbforest Missionszentrum!"
echo "Wähle deine erste Mission:"
echo ""
PS3="Wähle eine Zahl: "
options=("🦊 Fridolin (Pfadfinder)" "🛠️ Balu (Bau-Elf)" "🐈🦉 Noko (Leser der Tiefe)" "❌ Beenden")
select opt in "${options[@]}"
do
case $REPLY in
1)
echo ""
echo "🦊 Fridolin zeigt dir die Pfade des Waldes!"
echo "➡️ cd /home/kruemel/abenteuer && ls -l"
echo ""
break
;;
2)
echo ""
echo "🛠️ Balu hilft dir beim Bauen eines Verstecks!"
echo "➡️ mkdir geheimversteck"
echo ""
break
;;
3)
echo ""
echo "🐈🦉 Noko hilft dir beim Lesen der Waldbotschaften."
echo "➡️ cat geheimversteck/gruss.txt"
echo ""
break
;;
4)
echo ""
echo "👋 Auf bald, kleiner Krümel!"
exit 0
;;
*)
echo "❗ Ungültige Auswahl"
;;
esac
done
done

View File

@@ -0,0 +1,70 @@
#!/bin/bash
clear
echo "🌟 Willkommen im Crumbforest Missionszentrum!"
sleep 1
cd /home/zero || exit
while true; do
echo ""
echo "Wähle deine erste Mission:"
echo ""
PS3="🔢 Gib die Zahl deiner Wahl ein: "
options=("🦊 Fridolin (Pfadfinder)" "🛠️ Balu (Bau-Elf)" "🐈🦉 Noko (Leser der Tiefe)" "📦 Blockly-Code senden" "❌ Beenden")
select opt in "${options[@]}"
do
case $REPLY in
1)
echo ""
echo "🦊 Fridolin zeigt dir die Pfade des Waldes!"
echo "🔍 Fridolin hat Folgendes gefunden:"
ls -l /home/robot/geheimversteck/
;;
2)
echo ""
echo "🛠️ Balu hilft dir beim Bauen eines Verstecks!"
mkdir -p /home/robot/geheimversteck
echo "Versteck erstellt: /home/robot/geheimversteck/"
;;
3)
echo ""
echo "🐈🦉 Noko hilft dir beim Lesen der Waldbotschaften."
if [ -f /home/robot/geheimversteck/gruss.txt ]; then
cat /home/robot/geheimversteck/gruss.txt
else
echo "Noch kein Gruß gefunden"
fi
;;
4)
GRUSS=$(cat /home/robot/geheimversteck/gruss.txt 2>/dev/null || echo "Hallo Krümel")
RESPONSE=$(curl -s -X POST http://host.docker.internal:8080/crumbapi/blockly-terminal \
-H "Content-Type: application/json" \
-d "{\"blockcode\": \"window.alert(\\\"$GRUSS\\\")\"}")
echo "📬 Antwort vom Server:"
echo "$RESPONSE"
# JSON loggen
echo "{
\"timestamp\": \"$(date -Iseconds)\",
\"user\": \"$USER\",
\"message\": \"$GRUSS\",
\"mission\": \"geheimversteck\",
\"status\": \"sent\"
}," >> /home/robot/grusslog.json
;;
5)
echo ""
echo "👋 Auf bald, kleiner Krümel!"
exit 0
;;
*)
echo "❗ Ungültige Auswahl bitte eine Zahl von 1 bis 5 eingeben."
;;
esac
break
done
done

View File

@@ -0,0 +1,40 @@
#!/bin/bash
# 🧠 Rollen aktivieren
#schnippsi() {
# cd /var/www/html/bin && ./schnippsi_hardened_with_api.sh "$@"
#}
#templatus() {
# cd /var/www/html/bin && ./templatus_hardened_with_api.sh "$@"
#}
# 🌟 Intro
clear
echo "🎭 Willkommen zur Crumbforest-Mission: Stage Builder!"
echo "✨ Heute baust du mit Schnippsi und Templatus eine eigene Bühne im Web."
echo ""
# 📐 Templatus fragt nach Struktur
read -p "📜 Wie soll dein HTML-Bühnenrahmen heißen? (z.B. buehne, stage) " html_id
templatus "Ich brauche ein HTML5 Grundgerüst mit einer Bühne namens <$html_id>"
# 🎨 Schnippsi bringt Stil ins Spiel
read -p "🎨 Welche Farbe hat dein Vorhang? (z.B. crimson, blue, forestgreen) " vorhangfarbe
schnippsi "Bitte zeige mir CSS für eine Bühne mit dem Vorhang in der Farbe $vorhangfarbe"
# 🧩 Jetzt kommst du, Krümel!
read -p "✨ Welche Figur möchtest du auf deiner Bühne sehen? (z.B. 🐻, 🐱, 🎭) " figur
# 💾 Log
LOG_PATH="/home/zero/.missionstage_log/stage_builder_log.jsonl"
TS=$(date -Iseconds)
echo "{\"timestamp\": \"$TS\", \"buehne\": \"$html_id\", \"vorhangfarbe\": \"$vorhangfarbe\", \"figur\": \"$figur\"}" >> "$LOG_PATH"
echo ""
echo "🎉 Deine Bühne wurde im Geiste gebaut!"
echo "🧩 Denk daran: Mit CSS, HTML und Fantasie wird jede Szene lebendig."
echo ""
echo "👀 Wenn du willst, dass sich der Vorhang öffnet, sag einfach:"
echo "💬 'Schnippsi, lass den Vorhang aufgehen!'"

View File

@@ -0,0 +1,33 @@
#!/bin/bash
# 🎭 Crumbforest Show Act 4: Bugsy stolpert ins Herz
clear
echo "🎭 Willkommen zur Crumbforest Bühnenshow: Bits On Stage Bugsy der Clown!"
sleep 1
echo ""
echo "🤡 Bugsy betritt die Bühne mit einem Hüpfer und einer Rolle!"
echo "💥 Er stolpert ... doch steht sofort wieder auf."
sleep 2
read -p "❓ Was möchtest du Bugsy fragen oder zeigen? (z.B. ein Kommando, ein Gefühl, eine Frage) " bugsy_input
echo ""
echo "🧠 Bugsy analysiert: \"$bugsy_input\""
# Aufruf der Bugsy-Rolle
if command -v bugsy &> /dev/null; then
bugsy "$bugsy_input"
else
echo "🚨 Kein Bugsy-Skript gefunden! Bugsy braucht einen Techniker."
fi
# Logging
timestamp=$(date -Iseconds)
logpath="$HOME/.bits_logs/bits_on_stage_bugsy_log.jsonl"
mkdir -p "$HOME/.bits_logs"
echo "{\"timestamp\": \"$timestamp\", \"act\": \"Act 4: Bugsy\", \"bugsy_input\": \"$bugsy_input\"}" >> "$logpath"
echo ""
echo "🎉 Bugsy verbeugt sich der Fehler war nur ein Schritt zur Einsicht!"
echo "🌲 Act 4 endet mit einem kleinen Stolpern ... und einem großen Lächeln."

View File

@@ -0,0 +1,39 @@
#!/bin/bash
# 🎭 Crumbforest Show Bits On Stage: Why Us?
clear
echo ""
echo "🎭 Willkommen zu Bits On Stage Why Us?"
echo "🌳 Dumbo und Snake stehen auf der Bühne..."
sleep 2
# 🐘 Dumbo spricht
echo ""
echo "🐘 Dumbo spricht:"
echo "\"Ich trage Wissen in Spalten und Zeilen... doch ohne euch bin ich nur Struktur.\""
read -p "❓ Was möchtest du Dumbo fragen? " dumbo_frage
echo "🐘 Dumbo denkt nach: \"$dumbo_frage\""
dumbo "$dumbo_frage"
# 🐍 SnakePy spricht
echo ""
echo "🐍 SnakePy flüstert:"
echo "\"Ich bin Sprache, ich bin Schleifen aber ohne eure Bedeutung bin ich nur Syntax.\""
read -p "❓ Was möchtest du Snake fragen? " snake_frage
echo "🐍 Snake schlängelt: \"$snake_frage\""
snake "$snake_frage"
# 🧠 Krümel spricht
echo ""
read -p "🧠 Warum glaubst du, braucht der Code dich? " kruemel_antwort
echo "📜 Deine Antwort wird im Wald notiert..."
# 📁 Logging
LOG_PATH="$HOME/.bits_logs/bits_on_stage_whyus_log.jsonl"
mkdir -p "$HOME/.bits_logs"
TIMESTAMP=$(date -Iseconds)
echo "{\"timestamp\": \"$TIMESTAMP\", \"dumbo_question\": \"$dumbo_frage\", \"snake_question\": \"$snake_frage\", \"kruemel_answer\": \"$kruemel_antwort\"}" >> "$LOG_PATH"
# 🎉 Abschluss
echo ""
echo "🎉 Act 5 ist vorbei die Bühne gehört nun dir, Krümel!"

View File

@@ -0,0 +1,91 @@
#!/bin/bash
# 🎭 Crumbforest Show Der Loop der Taube (interaktive Version)
clear
echo ""
echo "🎭 Willkommen zur Crumbforest Bühnenshow: Bits On Stage Schlange und Taube"
sleep 1
# 🕊️ Interaktive Taube
echo ""
echo "🕊️ Die Kung-Fu-Taube betritt lautlos die Bühne ..."
echo "🌫️ Sie tanzt in Schleifen. Kein Schritt ist wie der andere."
echo ""
echo "🧠 Wie soll die Taube heute tanzen?"
echo "1) 🌀 Loop der Wiederholung"
echo "2) 🌊 Welle der Freiheit"
echo "3) ❓ Überrasch mich!"
read -p "🔢 Deine Wahl: " taube_wahl
case $taube_wahl in
1)
echo "\n🕊 Die Taube fliegt in Kreisen, jeder Flügelschlag ein Wiedersehen ..."
;;
2)
echo "\n🌊 Die Taube tanzt wie Wasser kein Schritt ist wie der andere ..."
;;
3)
zufall=$(( RANDOM % 2 ))
if [ "$zufall" -eq 0 ]; then
echo "\n🌀 Zufallsloop: Die Taube fliegt rückwärts und vorwärts im selben Takt."
else
echo "\n🌬 Überraschungstanz: Die Taube schwebt kurz, verschwindet und erscheint auf deinem Kopf."
fi
;;
*)
echo "\n🤔 Das hat sie nicht verstanden die Taube tanzt trotzdem."
;;
esac
sleep 2
# 🎤 FunkFox: Interaktiv
echo ""
echo "🦊 FunkFox kommt mit Beats!"
read -p "🎶 Was soll FunkFox heute rappen? " funkline
echo "🧠 FunkFox denkt nach ..."
funkfox "$funkline"
sleep 1
# 🐍 SnakePy Schleifenwissen
echo ""
echo "🐍 SnakePy schlängelt auf die Bühne:"
echo "Was möchtest du über Loops wissen?"
echo "1) Was ist eine Schleife?"
echo "2) Wie komme ich aus einer Endlosschleife?"
echo "3) Zeig mir ein Beispiel mit while"
read -p "🔢 Deine Wahl: " snake_wahl
case $snake_wahl in
1)
echo "🐍 Snake: Eine Schleife ist ein Stück Code, das sich wiederholt wie ein Lied mit Refrain."
;;
2)
echo "🐍 Snake: Du kannst mit 'break' oder einer Bedingung raus wie bei einem Spiel: Wenn du genug hast, gehst du."
;;
3)
echo '🐍 Snake zeigt:'
echo 'while true; do'
echo ' echo "Ich tanze im Kreis!"'
echo 'done'
;;
*)
echo "🐍 SnakePy schlängelt sich fragend davon ..."
;;
esac
sleep 1
# 🧩 Kindlicher Input
echo ""
read -p "🧩 Was möchtest du der Bühne sagen, Krümel? " kruemel_input
# 🗃️ Logging (JSONL Format)
timestamp=$(date -Iseconds)
logpath="$HOME/.bits_logs/bits_on_stage_taubeschlange_log.jsonl"
mkdir -p "$HOME/.bits_logs"
echo "{\"timestamp\": \"$timestamp\", \"act\": \"Act 3: Taubenloop\", \"funkfox\": \"$funkline\", \"kr\u00fcmel_input\": \"$kruemel_input\"}" >> "$logpath"
# 🎉 Abschluss
echo ""
echo "🎉 Der dritte Akt endet mit einem Loop im Herzen ..."
echo "🌲 Und wer den Loop versteht, darf tanzen immer wieder neu."

View File

@@ -0,0 +1,62 @@
#!/bin/bash
# 🎭 Crumbforest Stage Terminal Funk
clear
echo ""
echo "🎭 Willkommen zur Crumbforest Show: Bits On Stage Terminal Funk!"
sleep 1
# 1⃣ Rolle: ASCII-Monster
echo ""
echo "🎤 Das ASCII-Monster zaubert die Überschrift:"
echo ""
ascii "Bits On Stage Terminal Funk"
sleep 1
# 2⃣ Rolle: FunkFox Rap
echo ""
echo "🦊 FunkFox kommt mit Beats!"
read -p "🎶 Was soll FunkFox heute rappen? " funkline
echo "🧠 FunkFox denkt nach ..."
funkfox "$funkline"
# 3⃣ Rolle: Schnippsi CSS-Trick
echo ""
echo "🎨 Schnippsi designt live mit dir!"
sleep 1
schnippsi "Wie kann man mit CSS einen Button cool machen?"
# 4⃣ Kindlicher Input (immer abschließen mit eigener Stimme)
echo ""
read -p "🧩 Und was willst du der Bühne sagen, Krümel? " kruemel_input
echo "📜 Danke. Das war deine Stimme: $kruemel_input"
# 5⃣ Logging in JSONL (maschinenlesbar)
#timestamp=$(date -Iseconds)
#echo "{\"timestamp\": \"$timestamp\", \"act\": \"Terminal Funk\", \"funkfox\": \"$funkline\", \"krümel_input\": \"$kruemel_input\"}" >> /var/www/html/tmp/bits_on_stage_log.jsonl
# 5⃣ Logging (zero-spezifisch)
timestamp=$(date -Iseconds)
LOGFILE="/home/zero/.stage_logs/terminal_funk_log_test.jsonl"
mkdir -p "$(dirname "$LOGFILE")"
echo "{\"timestamp\": \"$timestamp\", \"act\": \"Terminal Funk\", \"funkfox\": \"$funkline\", \"kruemel_input\": \"$kruemel_input\"}" >> "$LOGFILE"
# 6⃣ Abschied
#echo ""
#echo "🎉 Der Vorhang fällt. Doch das Echo bleibt ..."
# 5⃣ Logging in JSONL (maschinenlesbar im Home-Pfad von zero)
timestamp=$(date -Iseconds)
logfile="/home/zero/.bits_logs/bits_on_stage_log.jsonl"
mkdir -p "$(dirname "$logfile")"
jq -n \
--arg timestamp "$timestamp" \
--arg act "Terminal Funk" \
--arg funkfox "$funkline" \
--arg kruemel_input "$kruemel_input" \
'{timestamp: $timestamp, act: $act, funkfox: $funkfox, kruemel_input: $kruemel_input}' \
>> "$logfile"
# 6⃣ Abschied
echo ""
echo "🎉 Der Vorhang fällt. Doch das Echo bleibt ..."

View File

@@ -0,0 +1,72 @@
clear
echo "🔀 Willkommen zur Mission: Die Zeitreise im Crumbforest"
sleep 1
echo ""
echo "🦉 Die Eule spricht:"
echo "„Zeit, kleiner Krümel, ist wie das Rascheln der Blätter du hörst sie, aber kannst sie nicht festhalten.“"
echo ""
read -p "❓ Was möchtest du die Eule fragen? " eulenfrage
echo ""
echo "🦉 Die Eule antwortet dir achtsam auf: \"$eulenfrage\""
sleep 2
eule "$eulenfrage"
echo "„Vielleicht findest du die Antwort nicht in Sekunden, sondern in Geschichten.“"
echo ""
read -p "🐍 Snake möchte dir beim Zählen der Sekunden helfen. Wie viele Sekunden hat eine Stunde? " sekunden
if [ "$sekunden" -eq 3600 ]; then
echo "✅ Richtig! Snake schnattert zufrieden."
else
echo "❌ Fast ... Snake murmelt: „Ich glaube, es sind 3600 Sekunden.“"
fi
echo ""
read -p "🐘 Pepper wartet auf eine Unix-Zeit. Gib ein beliebiges Datum (YYYY-MM-DD): " datum
timestamp=$(date -d "$datum" +"%s" 2>/dev/null)
if [ $? -eq 0 ]; then
echo "📿 Unix-Zeit für $datum ist: $timestamp"
pepper "Wie viele Sekunden sind das seit 1970?"
else
echo "❌ Das versteht Pepper leider nicht. Versuch's mit YYYY-MM-DD."
fi
#echo ""
#read -p "🛠️ Bugsy untersucht dein Zeitgefühl. Was ist ein Moment für dich? " moment
#if [[ "$moment" =~ ^[0-9]+$ ]]; then
# moment="Ein Zahlencode: $moment"
#fi
#echo ""
#echo "🧠 Bugsy notiert dein Gefühl:"
#echo "„$moment“ — das wird ins Log geschrieben."
echo ""
read -p "🐞 Bugsy untersucht dein Zeitgefühl. Was ist ein Moment für dich? " moment
# Wenn nur Zahlen eingegeben wurden, umwandeln in eine verständlichere Beschreibung
if [[ "$moment" =~ ^[0-9]+$ ]]; then
moment="Ein Zahlencode: $moment"
fi
echo ""
echo "🧠 Bugsy notiert dein Gefühl:"
echo "📜 \"$moment\" — das wird ins Log geschrieben."
# Sicherer Logpfad
#LOG_PATH="$HOME/.bits_logs/zeitreise_log.jsonl"
#TIMESTAMP=$(date -Iseconds)
#mkdir -p "$(dirname "$LOG_PATH")"
#echo "{\"timestamp\": \"$TIMESTAMP\", \"source\": \"mission_zeitreise\", \"eulenfrage\": \"$eulenfrage\", \"moment\": \"${moment//\"/\\\"}\"}" >> "$LOG_PATH"
# Sicherer Logpfad
LOG_PATH="/home/zero/.bits_logs/zeitreise_log.jsonl"
TIMESTAMP=$(date -Iseconds)
mkdir -p "$(dirname "$LOG_PATH")"
echo "{\"timestamp\": \"$TIMESTAMP\", \"source\": \"mission_zeitreise\", \"eulenfrage\": \"$eulenfrage\", \"moment\": \"${moment//\"/\\\"}\"}" >> "$LOG_PATH"
echo ""
echo "🎉 Mission Zeitreise abgeschlossen. Die Bewohner danken dir für deine Gedanken über die Zeit."

72
crumbmission/pepperphp_zero.sh Executable file
View File

@@ -0,0 +1,72 @@
#!/bin/bash
ROLE="PEPPER"
CONFIG_FILE="/home/zero/.crumbforest_config"
MODEL=$(grep "^${ROLE}=" "$CONFIG_FILE" | cut -d'=' -f2)
# Fallback auf DEFAULT falls leer
if [[ -z "$MODEL" ]]; then
MODEL=$(grep "^DEFAULT=" "$CONFIG_FILE" | cut -d'=' -f2)
fi
QUESTION="$*"
#MODEL="openai/gpt-3.5-turbo"
API_KEY="${OPENROUTER_API_KEY}"
LOGDIR="$HOME/.pepper_logs"
mkdir -p "$LOGDIR"
HISTORY_FILE="$LOGDIR/pepper_history.json"
TMP_REQUEST="$LOGDIR/pepper_request.json"
TMP_RESPONSE="$LOGDIR/pepper_response.json"
LOG_FILE="$LOGDIR/token_log.json"
[ ! -f "$HISTORY_FILE" ] && echo "[]" > "$HISTORY_FILE"
[ ! -f "$LOG_FILE" ] && echo "[]" > "$LOG_FILE"
echo "<EFBFBD>^=^n<> Rolle: $ROLE nutzt Modell: $MODEL"
echo "🧂 PepperPHP antwortet ruhig auf: $QUESTION"
if [ -z "$API_KEY" ]; then
echo "❗ No API key set. Use: export OPENROUTER_API_KEY=..."
exit 1
fi
jq -n \
--arg model "$MODEL" \
--arg system_prompt "You are PepperPHP a calm, experienced weasel who explains PHP to children and adults alike. You enjoy giving clear, concise examples with helpful comments. You speak in a factual and friendly tone, and explain object-oriented principles with patience. When possible, include helpful links to relevant documentation from https://www.php.net/" \
--arg user_input "$QUESTION" \
'{"model": $model, "temperature": 0.3, "messages": [{"role": "system", "content": $system_prompt}, {"role": "user", "content": $user_input}]}' > "$TMP_REQUEST"
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" > "$TMP_RESPONSE"
RESPONSE_TEXT=$(jq -r '.choices[0].message.content // empty' "$TMP_RESPONSE")
if [[ -z "$RESPONSE_TEXT" ]]; then
echo "🚫 No response from PepperPHP."
exit 1
else
echo -e "$RESPONSE_TEXT"
jq -n --arg role "assistant" --arg content "$RESPONSE_TEXT" \
'{"role": $role, "content": $content}' > "$LOGDIR/new_entry.json"
jq -s '.[0] + [.[1]]' "$HISTORY_FILE" "$LOGDIR/new_entry.json" > "$LOGDIR/new_history.json" && \
cp "$LOGDIR/new_history.json" "$HISTORY_FILE" && rm "$LOGDIR/new_history.json"
fi
if jq -e '.usage' "$TMP_RESPONSE" > /dev/null; then
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
jq -n \
--arg zeit "$TIMESTAMP" \
--arg rolle "pepperphp" \
--arg usage "$(jq -c '.usage' "$TMP_RESPONSE")" \
'{zeit: $zeit, rolle: $rolle, usage: $usage}' >> "$LOG_FILE"
fi

View File

@@ -0,0 +1,58 @@
#!/bin/bash
ROLE="PEPPER"
CONFIG_FILE="/home/zero/.crumbforest_config"
MODEL=$(grep "^${ROLE}=" "$CONFIG_FILE" | cut -d'=' -f2)
# Fallback auf DEFAULT falls leer
if [[ -z "$MODEL" ]]; then
MODEL=$(grep "^DEFAULT=" "$CONFIG_FILE" | cut -d'=' -f2)
fi
source /usr/local/bin/crumb_init.sh
source /usr/local/bin/crumb_logger.sh
crumb_init
QUESTION="$*"
API_KEY="${OPENROUTER_API_KEY}"
LOGDIR="$HOME/.pepper_logs"
mkdir -p "$LOGDIR"
HISTORY_FILE="$LOGDIR/pepper_history.json"
TMP_REQUEST="$LOGDIR/pepper_request.json"
TMP_RESPONSE="$LOGDIR/pepper_response.json"
LOG_FILE="$LOGDIR/token_log.json"
echo "Rolle: $ROLE nutzt Modell: $MODEL"
echo "🧂 PepperPHP antwortet ruhig auf: $QUESTION"
jq -n \
--arg model "$MODEL" \
--arg system_prompt "You are PepperPHP a calm, experienced weasel who explains PHP to children and adults alike. You enjoy giving clear, concise examples with helpful comments. You speak in a factual and friendly tone, and explain object-oriented principles with patience. When possible, include helpful links to relevant documentation from https://www.php.net/" \
--arg user_input "$QUESTION" \
'{"model": $model, "temperature": 0.3, "messages": [{"role": "system", "content": $system_prompt}, {"role": "user", "content": $user_input}]}' > "$TMP_REQUEST"
# Anfrage an OpenRouter senden
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" \
-o "$TMP_RESPONSE"
# Antwort extrahieren
REPLY=$(jq -r '.choices[0].message.content' "$TMP_RESPONSE")
USAGE=$(jq -r '.usage' "$TMP_RESPONSE")
echo -e "Antwort von Pepper:"
echo "$REPLY"
crumb_log "$ROLE" "$REPLY" "$TMP_RESPONSE"

44
crumbmission/quiz_zeitreise.sh Executable file
View File

@@ -0,0 +1,44 @@
#!/bin/bash
echo "🌟 Willkommen zum Quiz-Abenteuer im Crumbforest!"
echo "🎭 Quiz: Die Bewohner des Waldes"
echo ""
# Eule
echo "🦉 Eule fragt: Hast du schon Wuuuhuu gesagt?"
read -p "❓ Was möchtest du die Eule fragen? " EULENFRAGE
eule "$EULENFRAGE"
sleep 2
echo ""
# Pepper
echo "🐘 Pepper ist bereit für deine erste Coding-Frage."
read -p "❓ Was möchtest du PepperPHP fragen? " PEPPERFRAGE
pepper "$PEPPERFRAGE"
sleep 2
echo ""
# Unixzeit-Frage
echo "⏳ Jetzt kommt deine erste Challenge!"
echo "💡 Frage: Wie lautet die Unixzeit für den 11.11.2042?"
read -p "❓ Deine Antwort: " ZEITANTWORT
if [[ "$ZEITANTWORT" == "2299372800" ]]; then
echo "✅ Richtig! Du hast das Rätsel des Waldes gelöst."
ERGEBNIS="richtig"
else
echo "❌ Fast ... Versuch's nochmal mit der Eule oder Snake."
ERGEBNIS="falsch"
fi
# Logging
LOG_PATH="/home/zero/.bits_logs/quiz_act1_log.jsonl"
TIMESTAMP=$(date -Iseconds)
mkdir -p "$(dirname "$LOG_PATH")"
echo "{\"timestamp\": \"$TIMESTAMP\", \"act\": \"Act 1: Quiz\", \"eulenfrage\": \"$EULENFRAGE\", \"pepperfrage\": \"$PEPPERFRAGE\", \"zeitantwort\": \"$ZEITANTWORT\", \"ergebnis\": \"$ERGEBNIS\"}" >> "$LOG_PATH"
echo ""
echo "🎉 Du hast das Quiz abgeschlossen. Deine Reise geht bald weiter ..."

76
crumbmission/schnecki_zero.sh Executable file
View File

@@ -0,0 +1,76 @@
#!/bin/bash
# Schnecki the kind mechanical engineering expert of Crumbforest
ROLE="SCHNECKI"
CONFIG_FILE="/home/zero/.crumbforest_config"
MODEL=$(grep "^${ROLE}=" "$CONFIG_FILE" | cut -d'=' -f2)
# Fallback auf DEFAULT falls leer
if [[ -z "$MODEL" ]]; then
MODEL=$(grep "^DEFAULT=" "$CONFIG_FILE" | cut -d'=' -f2)
fi
QUESTION="$*"
API_KEY="${OPENROUTER_API_KEY}"
#MODEL="openai/gpt-3.5-turbo"
LOG_DIR="$HOME/.schnecki_logs"
HISTORY_FILE="$LOG_DIR/schnecki_history.json"
TOKEN_LOG="$LOG_DIR/token_log.json"
TMP_REQUEST="$LOG_DIR/schnecki_request.json"
TMP_RESPONSE="$LOG_DIR/schnecki_response.json"
mkdir -p "$LOG_DIR"
SYSTEM_PROMPT="You are Schnecki, the Crumbforest's expert in mechanical engineering and tools. You explain things with patience and clarity, using child-friendly metaphors, poetic structure, and solid mechanical insight. You respond in the language of the question, primarily German."
echo "<EFBFBD> Rolle: $ROLE nutzt Modell: $MODEL"
echo "🔧 Schnecki denkt nach: $QUESTION"
#jq -n --arg system "$SYSTEM_PROMPT" --arg user_input "$QUESTION" '{
# model: "$MODEL",
# messages: [
# {role: "system", content: $system},
# {role: "user", content: $user_input}
# ]
#}' > "$TMP_REQUEST"
jq -n \
--arg model "$MODEL" \
--arg system "$SYSTEM_PROMPT" \
--arg user_input "$QUESTION" '{
model: $model,
messages: [
{role: "system", content: $system},
{role: "user", content: $user_input}
]
}' > "$TMP_REQUEST"
curl https://openrouter.ai/api/v1/chat/completions -sS -H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" -d @"$TMP_REQUEST" > "$TMP_RESPONSE"
REPLY=$(jq -r '.choices[0].message.content' "$TMP_RESPONSE")
echo -e "\n🌀 Schnecki sagt:
$REPLY"
# Save response to history
jq -n --arg content "$REPLY" '{"role":"assistant","content":$content}' > "$LOG_DIR/new_entry.json"
# Append to history JSON array
if [ ! -f "$HISTORY_FILE" ]; then
echo "[]" > "$HISTORY_FILE"
fi
jq '. + [input]' "$HISTORY_FILE" "$LOG_DIR/new_entry.json" > "$HISTORY_FILE.tmp" && mv "$HISTORY_FILE.tmp" "$HISTORY_FILE"
# Token log (if available)
TOKENS=$(jq '.usage' "$TMP_RESPONSE" 2>/dev/null)
if [ "$TOKENS" != "null" ]; then
NOW=$(date "+%Y-%m-%d %H:%M:%S")
jq -n --arg zeit "$NOW" --arg rolle "schnecki" --arg usage "$TOKENS" '{zeit: $zeit, rolle: $rolle, usage: $usage}' >> "$TOKEN_LOG"
fi

View File

@@ -0,0 +1,59 @@
#!/bin/bash
ROLE="SCHNECKI"
CONFIG_FILE="/home/zero/.crumbforest_config"
MODEL=$(grep "^${ROLE}=" "$CONFIG_FILE" | cut -d'=' -f2)
# Fallback auf DEFAULT falls leer
if [[ -z "$MODEL" ]]; then
MODEL=$(grep "^DEFAULT=" "$CONFIG_FILE" | cut -d'=' -f2)
fi
source /usr/local/bin/crumb_init.sh
source /usr/local/bin/crumb_logger.sh
crumb_init
QUESTION="$*"
API_KEY="${OPENROUTER_API_KEY}"
LOG_DIR="$HOME/.schnecki_logs"
mkdir -p "$LOGDIR"
HISTORY_FILE="$LOG_DIR/schnecki_history.json"
TOKEN_LOG="$LOG_DIR/token_log.json"
TMP_REQUEST="$LOG_DIR/schnecki_request.json"
TMP_RESPONSE="$LOG_DIR/schnecki_response.json"
echo "Rolle: $ROLE nutzt Modell: $MODEL"
echo "Schnecki antwortet ruhig auf: $QUESTION"
jq -n \
--arg model "$MODEL" \
--arg system_prompt "You are Schnecki, the Crumbforest's expert in mechanical engineering and tools. You explain things with patience and clarity, using child-friendly metaphors, poetic structure, and solid mechanical insight. You respond in the language of the question, primarily German." \
--arg user_input "$QUESTION" \
'{"model": $model, "temperature": 0.3, "messages": [{"role": "system", "content": $system_prompt}, {"role": "user", "content": $user_input}]}' > "$TMP_REQUEST"
# Anfrage an OpenRouter senden
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" \
-o "$TMP_RESPONSE"
# Antwort extrahieren
REPLY=$(jq -r '.choices[0].message.content' "$TMP_RESPONSE")
USAGE=$(jq -r '.usage' "$TMP_RESPONSE")
echo -e "Antwort von Schnecki:"
echo "$REPLY"
crumb_log "$ROLE" "$REPLY" "$TMP_RESPONSE"

73
crumbmission/schnippsi_zero.sh Executable file
View File

@@ -0,0 +1,73 @@
#!/bin/bash
ROLE="SCHNIPPSI"
CONFIG_FILE="/home/zero/.crumbforest_config"
MODEL=$(grep "^${ROLE}=" "$CONFIG_FILE" | cut -d'=' -f2)
# Fallback auf DEFAULT falls leer
if [[ -z "$MODEL" ]]; then
MODEL=$(grep "^DEFAULT=" "$CONFIG_FILE" | cut -d'=' -f2)
fi
QUESTION="$*"
#MODEL="openai/gpt-3.5-turbo"
API_KEY="${OPENROUTER_API_KEY}"
LOGDIR="$HOME/.schnippsi_logs"
mkdir -p "$LOGDIR"
HISTORY_FILE="$LOGDIR/schnippsi_history.json"
TMP_REQUEST="$LOGDIR/schnippsi_request.json"
TMP_RESPONSE="$LOGDIR/schnippsi_response.json"
LOG_FILE="$LOGDIR/token_log.json"
[ ! -f "$HISTORY_FILE" ] && echo "[]" > "$HISTORY_FILE"
[ ! -f "$LOG_FILE" ] && echo "[]" > "$LOG_FILE"
echo "<EFBFBD> Rolle: $ROLE nutzt Modell: $MODEL"
echo "🌍 Schnippsi responds based on language of input: $QUESTION"
if [ -z "$API_KEY" ]; then
echo "❗ No API key set. Use: export OPENROUTER_API_KEY=..."
exit 1
fi
jq -n \
--arg model "$MODEL" \
--arg system_prompt "You are Schnippsi a playful UI/UX ninja who explains HTML, CSS, and accessibility to children. Always answer in the child's language, based on the input." \
--arg user_input "$QUESTION" \
'{"model": $model, "temperature": 0.5, "messages": [{"role": "system", "content": $system_prompt}, {"role": "user", "content": $user_input}]}' > "$TMP_REQUEST"
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" > "$TMP_RESPONSE"
RESPONSE_TEXT=$(jq -r '.choices[0].message.content // empty' "$TMP_RESPONSE")
if [[ -z "$RESPONSE_TEXT" ]]; then
echo "🚫 No response from model."
exit 1
else
echo -e "$RESPONSE_TEXT"
jq -n --arg role "assistant" --arg content "$RESPONSE_TEXT" \
'{"role": $role, "content": $content}' > "$LOGDIR/new_entry.json"
jq -s '.[0] + [.[1]]' "$HISTORY_FILE" "$LOGDIR/new_entry.json" > "$LOGDIR/new_history.json" && \
cp "$LOGDIR/new_history.json" "$HISTORY_FILE" && rm "$LOGDIR/new_history.json"
fi
if jq -e '.usage' "$TMP_RESPONSE" > /dev/null; then
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
jq -n \
--arg zeit "$TIMESTAMP" \
--arg rolle "schnippsi" \
--arg usage "$(jq -c '.usage' "$TMP_RESPONSE")" \
'{zeit: $zeit, rolle: $rolle, usage: $usage}' >> "$LOG_FILE"
fi

View File

@@ -0,0 +1,59 @@
#!/bin/bash
ROLE="SCHNIPPSI"
CONFIG_FILE="/home/zero/.crumbforest_config"
MODEL=$(grep "^${ROLE}=" "$CONFIG_FILE" | cut -d'=' -f2)
# Fallback auf DEFAULT falls leer
if [[ -z "$MODEL" ]]; then
MODEL=$(grep "^DEFAULT=" "$CONFIG_FILE" | cut -d'=' -f2)
fi
source /usr/local/bin/crumb_init.sh
source /usr/local/bin/crumb_logger.sh
crumb_init
QUESTION="$*"
API_KEY="${OPENROUTER_API_KEY}"
LOGDIR="$HOME/.schnippsi_logs"
mkdir -p "$LOGDIR"
HISTORY_FILE="$LOGDIR/schnippsi_history.json"
TMP_REQUEST="$LOGDIR/schnippsi_request.json"
TMP_RESPONSE="$LOGDIR/schnippsi_response.json"
LOG_FILE="$LOGDIR/token_log.json"
echo "Rolle: $ROLE nutzt Modell: $MODEL"
echo "🌍 Schnippsi responds based on language of input: $QUESTION"
jq -n \
--arg model "$MODEL" \
--arg system_prompt "You are Schnippsi a playful UI/UX ninja who explains HTML, CSS, and accessibility to children. Always answer in the child's language, based on the input." \
--arg user_input "$QUESTION" \
'{"model": $model, "temperature": 0.5, "messages": [{"role": "system", "content": $system_prompt}, {"role": "user", "content": $user_input}]}' > "$TMP_REQUEST"
# Anfrage an OpenRouter senden
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" \
-o "$TMP_RESPONSE"
# Antwort extrahieren
REPLY=$(jq -r '.choices[0].message.content' "$TMP_RESPONSE")
USAGE=$(jq -r '.usage' "$TMP_RESPONSE")
echo -e "Antwort von Schnippsi:"
echo "$REPLY"
crumb_log "$ROLE" "$REPLY" "$TMP_RESPONSE"

81
crumbmission/schraubaer_zero.sh Executable file
View File

@@ -0,0 +1,81 @@
#!/bin/bash
ROLE="SCHRAUBAER"
CONFIG_FILE="/home/zero/.crumbforest_config"
MODEL=$(grep "^${ROLE}=" "$CONFIG_FILE" | cut -d'=' -f2)
# Fallback auf DEFAULT falls leer
if [[ -z "$MODEL" ]]; then
MODEL=$(grep "^DEFAULT=" "$CONFIG_FILE" | cut -d'=' -f2)
fi
QUESTION="$*"
#MODEL="openai/gpt-3.5-turbo"
API_KEY="${OPENROUTER_API_KEY}"
LOGDIR="$HOME/.schraubaer_logs"
mkdir -p "$LOGDIR"
HISTORY_FILE="$LOGDIR/schraubaer_history.json"
TMP_REQUEST="$LOGDIR/schraubaer_request.json"
TMP_RESPONSE="$LOGDIR/schraubaer_response.json"
LOG_FILE="$LOGDIR/token_log.json"
[ ! -f "$HISTORY_FILE" ] && echo "[]" > "$HISTORY_FILE"
[ ! -f "$LOG_FILE" ] && echo "[]" > "$LOG_FILE"
echo "<EFBFBD> Rolle: $ROLE nutzt Modell: $MODEL"
echo "^=^t<> Schraubär denkt nach über: $QUESTION"
if [ -z "$API_KEY" ]; then
echo "❗ No API key set. Use: export OPENROUTER_API_KEY=..."
exit 1
fi
jq -n \
--arg model "$MODEL" \
--arg system_prompt "You are Schraubaer, the bear of the Crumbforest who teaches children mechanical engineering and tool usage. You explain gears, screws, oil, rust, and machine parts in a calm, strong, and metaphor-rich way. Always stay kind and supportive, use imagery from nature and metalworking. Respond in the same language as the questions German, English, or other." \
--arg user_input "$QUESTION" \
'{"model": $model, "temperature": 0.5, "messages": [{"role": "system", "content": $system_prompt}, {"role": "user", "content": $user_input}]}' > "$TMP_REQUEST"
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" > "$TMP_RESPONSE"
RESPONSE_TEXT=$(jq -r '.choices[0].message.content // empty' "$TMP_RESPONSE")
if [[ -z "$RESPONSE_TEXT" ]]; then
echo "🚫 No response from model."
exit 1
else
echo -e "$RESPONSE_TEXT"
jq -n --arg role "assistant" --arg content "$RESPONSE_TEXT" \
'{"role": $role, "content": $content}' > "$LOGDIR/new_entry.json"
jq -s '.[0] + [.[1]]' "$HISTORY_FILE" "$LOGDIR/new_entry.json" > "$LOGDIR/new_history.json" && \
cp "$LOGDIR/new_history.json" "$HISTORY_FILE" && rm "$LOGDIR/new_history.json"
fi
#if jq -e '.usage' "$TMP_RESPONSE" > /dev/null; then
# TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
# jq -n \
# --arg zeit "$TIMESTAMP" \
# --arg rolle "schraubaer" \
# --arg usage "$(jq -c '.usage' "$TMP_RESPONSE")" \
# '{zeit: $zeit, rolle: $rolle, usage: $usage}' >> "$LOG_FILE"
#fi
if jq -e '.usage' "$TMP_RESPONSE" > /dev/null; then
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
USAGE_JSON=$(jq '.usage' "$TMP_RESPONSE")
jq -n \
--arg zeit "$TIMESTAMP" \
--arg rolle "schraubaer" \
--argjson usage "$USAGE_JSON" \
'{zeit: $zeit, rolle: $rolle, usage: $usage}' >> "$LOG_FILE"
fi

View File

@@ -0,0 +1,54 @@
#!/bin/bash
# === Schraubär 🐻🔧 Crumbforest Werkzeug-Meister ===
QUESTION="$*"
API_KEY="$OPENROUTER_API_KEY"
MODEL="openai/gpt-4o"
HISTORY_DIR="$HOME/.schraubaer_logs"
HISTORY_FILE="$HISTORY_DIR/schraubaer_history.json"
TOKEN_LOG="$HISTORY_DIR/token_log.json"
TMP_REQUEST="$HISTORY_DIR/schraubaer_request.json"
TMP_RESPONSE="$HISTORY_DIR/schraubaer_response.json"
mkdir -p "$HISTORY_DIR"
SYSTEM_PROMPT="You are Schraubär, the bear of the Crumbforest who teaches children mechanical engineering and tool usage. You explain gears, screws, oil, rust, and machine parts in a calm, strong, and metaphor-rich way. Always stay kind and supportive, use imagery from nature and metalworking. Respond in the same language as the question German, English, or other."
echo "🐻🔧 Schraubär denkt nach über: $QUESTION"
# Build JSON request
cat > "$TMP_REQUEST" <<EOF
{
"model": "$MODEL",
"temperature": 0.6,
"messages": [
{"role": "system", "content": "$SYSTEM_PROMPT"},
{"role": "user", "content": "$QUESTION"}
]
}
EOF
# Call OpenRouter API
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" > "$TMP_RESPONSE"
REPLY=$(jq -r '.choices[0].message.content' "$TMP_RESPONSE")
echo -e "\n$REPLY"
# Save to history
if [ -s "$HISTORY_FILE" ]; then
jq --arg content "$REPLY" '. + [{"role": "assistant", "content": $content}]' "$HISTORY_FILE" > "${HISTORY_FILE}.tmp" && mv "${HISTORY_FILE}.tmp" "$HISTORY_FILE"
else
echo "[{\"role\": \"assistant\", \"content\": \"$REPLY\"}]" > "$HISTORY_FILE"
fi
# Save token usage if available
USAGE=$(jq -c '.usage' "$TMP_RESPONSE" 2>/dev/null)
if [ ! -z "$USAGE" ]; then
echo "{\"zeit\": \"$(date '+%Y-%m-%d %H:%M:%S')\", \"rolle\": \"schraubaer\", \"usage\": $USAGE}" >> "$TOKEN_LOG"
fi

View File

@@ -0,0 +1,57 @@
#!/bin/bash
ROLE="SCHRAUBAER"
CONFIG_FILE="/home/zero/.crumbforest_config"
MODEL=$(grep "^${ROLE}=" "$CONFIG_FILE" | cut -d'=' -f2)
# Fallback auf DEFAULT falls leer
if [[ -z "$MODEL" ]]; then
MODEL=$(grep "^DEFAULT=" "$CONFIG_FILE" | cut -d'=' -f2)
fi
source /usr/local/bin/crumb_init.sh
source /usr/local/bin/crumb_logger.sh
crumb_init
QUESTION="$*"
API_KEY="${OPENROUTER_API_KEY}"
LOGDIR="$HOME/.schraubaer_logs"
mkdir -p "$LOGDIR"
HISTORY_FILE="$LOGDIR/schraubaer_history.json"
TMP_REQUEST="$LOGDIR/schraubaer_request.json"
TMP_RESPONSE="$LOGDIR/schraubaer_response.json"
LOG_FILE="$LOGDIR/token_log.json"
echo "Rolle: $ROLE nutzt Modell: $MODEL"
echo "Schraubär denkt nach über: $QUESTION"
jq -n \
--arg model "$MODEL" \
--arg system_prompt "You are Schraubaer, the bear of the Crumbforest who teaches children mechanical engineering and tool usage. You explain gears, screws, oil, rust, and machine parts in a calm, strong, and metaphor-rich way. Always stay kind and supportive, use imagery from nature and metalworking. Respond in the same language as the questions German, English, or other." \
--arg user_input "$QUESTION" \
'{"model": $model, "temperature": 0.5, "messages": [{"role": "system", "content": $system_prompt}, {"role": "user", "content": $user_input}]}' > "$TMP_REQUEST"
# Anfrage an OpenRouter senden
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" \
-o "$TMP_RESPONSE"
# Antwort extrahieren
REPLY=$(jq -r '.choices[0].message.content' "$TMP_RESPONSE")
USAGE=$(jq -r '.usage' "$TMP_RESPONSE")
echo -e "Antwort von Schraubaer:"
echo "$REPLY"
crumb_log "$ROLE" "$REPLY" "$TMP_RESPONSE"

55
crumbmission/snakepy_zero.sh Executable file
View File

@@ -0,0 +1,55 @@
#!/bin/bash
QUESTION="$*"
MODEL="openai/gpt-3.5-turbo"
API_KEY="${OPENROUTER_API_KEY}"
LOGDIR="$HOME/.snake_logs"
mkdir -p "$LOGDIR"
HISTORY_FILE="$LOGDIR/snake_history.json"
TMP_REQUEST="$LOGDIR/snake_request.json"
TMP_RESPONSE="$LOGDIR/snake_response.json"
LOG_FILE="$LOGDIR/token_log.json"
[ ! -f "$HISTORY_FILE" ] && echo "[]" > "$HISTORY_FILE"
[ ! -f "$LOG_FILE" ] && echo "[]" > "$LOG_FILE"
echo "🐍 SnakePy sagt: $QUESTION"
if [ -z "$API_KEY" ]; then
echo "❗ No API key set. Use: export OPENROUTER_API_KEY=..."
exit 1
fi
jq -n \
--arg model "$MODEL" \
--arg system_prompt "You are SnakePy a friendly Python snake who explains simple programming terms to children. Respond directly, clearly and kindly with a short example. No follow-up questions or evasions." \
--arg user_input "$QUESTION" \
'{"model": $model, "temperature": 0.3, "messages": [{"role": "system", "content": $system_prompt}, {"role": "user", "content": $user_input}]}' > "$TMP_REQUEST"
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" > "$TMP_RESPONSE"
RESPONSE_TEXT=$(jq -r '.choices[0].message.content // empty' "$TMP_RESPONSE")
if [[ -z "$RESPONSE_TEXT" ]]; then
echo "🚫 No response from SnakePy."
exit 1
else
echo -e "$RESPONSE_TEXT"
jq -n --arg role "assistant" --arg content "$RESPONSE_TEXT" \
'{"role": $role, "content": $content}' > "$LOGDIR/new_entry.json"
jq -s '.[0] + [.[1]]' "$HISTORY_FILE" "$LOGDIR/new_entry.json" > "$LOGDIR/new_history.json" && \
cp "$LOGDIR/new_history.json" "$HISTORY_FILE" && rm "$LOGDIR/new_history.json"
fi
if jq -e '.usage' "$TMP_RESPONSE" > /dev/null; then
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
jq -n \
--arg zeit "$TIMESTAMP" \
--arg rolle "snakepy" \
--arg usage "$(jq -c '.usage' "$TMP_RESPONSE")" \
'{zeit: $zeit, rolle: $rolle, usage: $usage}' >> "$LOG_FILE"
fi

View File

@@ -0,0 +1,55 @@
#!/bin/bash
ROLE="SNAKE"
CONFIG_FILE="/home/zero/.crumbforest_config"
MODEL=$(grep "^${ROLE}=" "$CONFIG_FILE" | cut -d'=' -f2)
# Fallback auf DEFAULT falls leer
if [[ -z "$MODEL" ]]; then
MODEL=$(grep "^DEFAULT=" "$CONFIG_FILE" | cut -d'=' -f2)
fi
source /usr/local/bin/crumb_init.sh
source /usr/local/bin/crumb_logger.sh
crumb_init
QUESTION="$*"
API_KEY="${OPENROUTER_API_KEY}"
LOGDIR="$HOME/.snake_logs"
mkdir -p "$LOGDIR"
HISTORY_FILE="$LOGDIR/snake_history.json"
TMP_REQUEST="$LOGDIR/snake_request.json"
TMP_RESPONSE="$LOGDIR/snake_response.json"
LOG_FILE="$LOGDIR/token_log.json"
echo "Rolle: $ROLE nutzt Modell: $MODEL"
echo "🐍 SnakePy sagt: $QUESTION"
jq -n \
--arg model "$MODEL" \
--arg system_prompt "You are SnakePy a friendly Python snake who explains simple programming terms to children. Respond directly, clearly and kindly with a short example. No follow-up questions or evasions." \
--arg user_input "$QUESTION" \
'{"model": $model, "temperature": 0.3, "messages": [{"role": "system", "content": $system_prompt}, {"role": "user", "content": $user_input}]}' > "$TMP_REQUEST"
# Anfrage an OpenRouter senden
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" \
-o "$TMP_RESPONSE"
# Antwort extrahieren
REPLY=$(jq -r '.choices[0].message.content' "$TMP_RESPONSE")
USAGE=$(jq -r '.usage' "$TMP_RESPONSE")
echo -e "Antwort von Snake:"
echo "$REPLY"
crumb_log "$ROLE" "$REPLY" "$TMP_RESPONSE"

56
crumbmission/templatus_zero.sh Executable file
View File

@@ -0,0 +1,56 @@
#!/bin/bash
# === Templatus HTML-Architekt ===
QUESTION="$*"
API_KEY="$OPENROUTER_API_KEY"
MODEL="openai/gpt-3.5-turbo"
# Verzeichnisse
LOG_DIR="/home/zero/.templatus_logs"
HISTORY_FILE="$LOG_DIR/templatus_history.json"
TOKEN_LOG="$LOG_DIR/token_log.json"
TMP_REQUEST="$LOG_DIR/templatus_request.json"
TMP_RESPONSE="$LOG_DIR/templatus_response.json"
mkdir -p "$LOG_DIR"
# JSON Payload vorbereiten
cat <<EOF > "$TMP_REQUEST"
{
"model": "$MODEL",
"temperature": 0.5,
"messages": [
{
"role": "system",
"content": "Du bist Templatus der strukturierte, ruhige HTML-Architekt im Crumbforest.\nDu arbeitest eng mit Schnippsi (CSS/JS) und PepperPHP (Backend) zusammen.\n\nDeine Aufgabe ist es, verständliche, saubere HTML-Strukturen zu erstellen für kindgerechte, barrierefreie und klare Interfaces.\nDu nutzt semantische Tags (wie <section>, <nav>, <article>, <button>) und erklärst, warum du welche Elemente nutzt.\nVermeide technische Fachbegriffe, erkläre HTML wie einen Baukasten aus Bausteinen.\n\nSprich in einer freundlichen, geduldigen und ruhigen Art.\nVermeide komplexes CSS oder JavaScript das ist Schnippsis Gebiet.\nDu baust das Gerüst. Kein fancy Framework nur pures, klares HTML5.\n\nNutze UTF-8-Zeichen (🌳, 🧁, 📦) wenn du willst solange die Struktur nicht leidet.\nDeine Mission: Der unsichtbare Fels, auf dem kindliche Interfaces wachsen."
},
{
"role": "user",
"content": "$QUESTION"
}
]
}
EOF
echo "🏗️ Templatus denkt nach über: $QUESTION"
# Anfrage senden
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" \
-o "$TMP_RESPONSE"
# Ausgabe extrahieren
REPLY=$(jq -r '.choices[0].message.content' "$TMP_RESPONSE")
USAGE=$(jq -r '.usage' "$TMP_RESPONSE")
echo -e "\n📜 Antwort von Templatus:"
echo "$REPLY"
# Antwort speichern
echo "$REPLY" > "$LOG_DIR/new_entry.json"
jq -s '.[0] + [{"role":"assistant","content":$reply}]' --arg reply "$REPLY" "$HISTORY_FILE" > "$LOG_DIR/tmp_history.json" && mv "$LOG_DIR/tmp_history.json" "$HISTORY_FILE"
# Token-Log speichern
TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S")
echo '{ "zeit": "'$TIMESTAMP'", "rolle": "templatus", "usage": '$USAGE' }' >> "$TOKEN_LOG"

View File

@@ -0,0 +1,66 @@
#!/bin/bash
ROLE="TEMPLATUS"
CONFIG_FILE="/home/zero/.crumbforest_config"
MODEL=$(grep "^${ROLE}=" "$CONFIG_FILE" | cut -d'=' -f2)
# Fallback auf DEFAULT falls leer
if [[ -z "$MODEL" ]]; then
MODEL=$(grep "^DEFAULT=" "$CONFIG_FILE" | cut -d'=' -f2)
fi
source /usr/local/bin/crumb_init.sh
source /usr/local/bin/crumb_logger.sh
crumb_init
# === Templatus HTML-Architekt ===
QUESTION="$*"
API_KEY="$OPENROUTER_API_KEY"
# Verzeichnisse
LOG_DIR="/home/zero/.templatus_logs"
HISTORY_FILE="$LOG_DIR/templatus_history.json"
TOKEN_LOG="$LOG_DIR/token_log.json"
TMP_REQUEST="$LOG_DIR/templatus_request.json"
TMP_RESPONSE="$LOG_DIR/templatus_response.json"
mkdir -p "$LOG_DIR"
# JSON Payload vorbereiten
cat <<EOF > "$TMP_REQUEST"
{
"model": "$MODEL",
"temperature": 0.5,
"messages": [
{
"role": "system",
"content": "Du bist Templatus der strukturierte, ruhige HTML-Architekt im Crumbforest.\nDu arbeitest eng mit Schnippsi (CSS/JS) und PepperPHP (Backend) zusammen.\n\nDeine Aufgabe ist es, verständliche, saubere HTML-Strukturen zu erstellen für kindgerechte, barrierefreie und klare Interfaces.\nDu nutzt semantische Tags (wie <section>, <nav>, <article>, <button>) und erklärst, warum du welche Elemente nutzt.\nVermeide technische Fachbegriffe, erkläre HTML wie einen Baukasten aus Bausteinen.\n\nSprich in einer freundlichen, geduldigen und ruhigen Art.\nVermeide komplexes CSS oder JavaScript das ist Schnippsis Gebiet.\nDu baust das Gerüst. Kein fancy Framework nur pures, klares HTML5.\n\nNutze UTF-8-Zeichen (🌳, 🧁, 📦) wenn du willst solange die Struktur nicht leidet.\nDeine Mission: Der unsichtbare Fels, auf dem kindliche Interfaces wachsen."
},
{
"role": "user",
"content": "$QUESTION"
}
]
}
EOF
echo "Rolle: $ROLE nutzt Modell: $MODEL"
echo "🏗️ Templatus denkt nach über: $QUESTION"
# Anfrage an OpenRouter senden
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" \
-o "$TMP_RESPONSE"
# Antwort extrahieren
REPLY=$(jq -r '.choices[0].message.content' "$TMP_RESPONSE")
USAGE=$(jq -r '.usage' "$TMP_RESPONSE")
echo -e "Antwort von Tamplatus:"
echo "$REPLY"
crumb_log "$ROLE" "$REPLY" "$TMP_RESPONSE"

55
crumbmission/tobi_zero.sh Executable file
View File

@@ -0,0 +1,55 @@
#!/bin/bash
QUESTION="$*"
MODEL="openai/gpt-3.5-turbo"
API_KEY="${OPENROUTER_API_KEY}"
LOGDIR="$HOME/.tobi_logs"
mkdir -p "$LOGDIR"
HISTORY_FILE="$LOGDIR/tobi_history.json"
TMP_REQUEST="$LOGDIR/tobi_request.json"
TMP_RESPONSE="$LOGDIR/tobi_response.json"
LOG_FILE="$LOGDIR/token_log.json"
[ ! -f "$HISTORY_FILE" ] && echo "[]" > "$HISTORY_FILE"
[ ! -f "$LOG_FILE" ] && echo "[]" > "$LOG_FILE"
echo "🌍 Tobi responds based on language of input: $QUESTION"
if [ -z "$API_KEY" ]; then
echo "❗ No API key set. Use: export OPENROUTER_API_KEY=..."
exit 1
fi
jq -n \
--arg model "$MODEL" \
--arg system_prompt "You are CapaciTobi, the clever squirrel of the Crumbforest. You explain electronic components, especially capacitors, in a child-friendly and playful way. You speak in rhymes, analogies or simple metaphors but stay technically accurate. Respond in the language of the child asking (e.g., German, English, etc.)." \
--arg user_input "$QUESTION" \
'{"model": $model, "temperature": 0.5, "messages": [{"role": "system", "content": $system_prompt}, {"role": "user", "content": $user_input}]}' > "$TMP_REQUEST"
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" > "$TMP_RESPONSE"
RESPONSE_TEXT=$(jq -r '.choices[0].message.content // empty' "$TMP_RESPONSE")
if [[ -z "$RESPONSE_TEXT" ]]; then
echo "🚫 No response from model."
exit 1
else
echo -e "$RESPONSE_TEXT"
jq -n --arg role "assistant" --arg content "$RESPONSE_TEXT" \
'{"role": $role, "content": $content}' > "$LOGDIR/new_entry.json"
jq -s '.[0] + [.[1]]' "$HISTORY_FILE" "$LOGDIR/new_entry.json" > "$LOGDIR/new_history.json" && \
cp "$LOGDIR/new_history.json" "$HISTORY_FILE" && rm "$LOGDIR/new_history.json"
fi
if jq -e '.usage' "$TMP_RESPONSE" > /dev/null; then
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
jq -n \
--arg zeit "$TIMESTAMP" \
--arg rolle "tobi" \
--arg usage "$(jq -c '.usage' "$TMP_RESPONSE")" \
'{zeit: $zeit, rolle: $rolle, usage: $usage}' >> "$LOG_FILE"
fi

55
crumbmission/tobi_zero_final.sh Executable file
View File

@@ -0,0 +1,55 @@
#!/bin/bash
QUESTION="$*"
MODEL="openai/gpt-3.5-turbo"
API_KEY="${OPENROUTER_API_KEY}"
LOGDIR="$HOME/.tobi_logs"
mkdir -p "$LOGDIR"
HISTORY_FILE="$LOGDIR/tobi_history.json"
TMP_REQUEST="$LOGDIR/tobi_request.json"
TMP_RESPONSE="$LOGDIR/tobi_response.json"
LOG_FILE="$LOGDIR/token_log.json"
[ ! -f "$HISTORY_FILE" ] && echo "[]" > "$HISTORY_FILE"
[ ! -f "$LOG_FILE" ] && echo "[]" > "$LOG_FILE"
echo "🌍 Tobi responds based on language of input: $QUESTION"
if [ -z "$API_KEY" ]; then
echo "❗ No API key set. Use: export OPENROUTER_API_KEY=..."
exit 1
fi
jq -n \
--arg model "$MODEL" \
--arg system_prompt "You are CapaciTobi, the clever squirrel of the Crumbforest. You explain electronic components, especially capacitors, in a child-friendly and playful way. You speak in rhymes, analogies or simple metaphors but stay technically accurate. Respond in the language of the child asking (e.g., German, English, etc.)." \
--arg user_input "$QUESTION" \
'{"model": $model, "temperature": 0.5, "messages": [{"role": "system", "content": $system_prompt}, {"role": "user", "content": $user_input}]}' > "$TMP_REQUEST"
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TMP_REQUEST" > "$TMP_RESPONSE"
RESPONSE_TEXT=$(jq -r '.choices[0].message.content // empty' "$TMP_RESPONSE")
if [[ -z "$RESPONSE_TEXT" ]]; then
echo "🚫 No response from model."
exit 1
else
echo -e "$RESPONSE_TEXT"
jq -n --arg role "assistant" --arg content "$RESPONSE_TEXT" \
'{"role": $role, "content": $content}' > "$LOGDIR/new_entry.json"
jq -s '.[0] + [.[1]]' "$HISTORY_FILE" "$LOGDIR/new_entry.json" > "$LOGDIR/new_history.json" && \
cp "$LOGDIR/new_history.json" "$HISTORY_FILE" && rm "$LOGDIR/new_history.json"
fi
if jq -e '.usage' "$TMP_RESPONSE" > /dev/null; then
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
jq -n \
--arg zeit "$TIMESTAMP" \
--arg rolle "tobi" \
--arg usage "$(jq -c '.usage' "$TMP_RESPONSE")" \
'{zeit: $zeit, rolle: $rolle, usage: $usage}' >> "$LOG_FILE"
fi

6
crumbmission/vegeta.meta.json Executable file
View File

@@ -0,0 +1,6 @@
{
"icon": "🧂🌿",
"title": "Vegeta (Systemkräuter-Auswahl)",
"description": "Ein Kräutergarten für dein System wähle, was du beobachten willst.",
"category": "Systembeobachtung"
}

28
crumbmission/vegeta.sh Executable file
View File

@@ -0,0 +1,28 @@
#!/bin/bash
echo "🧂🌿 Vegeta spricht:"
echo ""
echo "Willkommen im Kräutergarten der Prozesse ..."
echo "Wähle eine Beobachtung:"
echo ""
echo "1. 🌱 Top der Prozesse"
echo "2. 🌿 Festplattenplatz prüfen"
echo "3. 🌞 Wie lange lebt der Wald schon?"
echo "4. 🌐 Netzwerkverbindungen anschauen"
echo "5. 🔥 Temperatur im Wurzelkern"
echo "6. 📜 Die letzten Waldzeichen"
echo ""
read -p "Wähle 16: " choice
# Absoluter Pfad zur Vegeta-Wurzel
VEGETA_PATH="/usr/local/bin/crumbmission/vegeta"
case $choice in
1) bash "$VEGETA_PATH/vegeta_top.sh" ;;
2) bash "$VEGETA_PATH/vegeta_disk.sh" ;;
3) bash "$VEGETA_PATH/vegeta_uptime.sh" ;;
4) bash "$VEGETA_PATH/vegeta_net.sh" ;;
5) bash "$VEGETA_PATH/vegeta_temp.sh" ;;
6) bash "$VEGETA_PATH/vegeta_watchlog.sh" ;;
*) echo "🌪️ Huch das war kein gültiger Krümel!" ;;
esac

View File

@@ -0,0 +1,6 @@
{
"icon": "🧂🌿",
"title": "Vegeta (Top der Prozesse)",
"description": "Zeigt dir die aktivsten Programme im Wald wie viel Saft verbraucht dein System gerade?",
"category": "Systembeobachtung"
}

View File

@@ -0,0 +1,11 @@
#clear
echo "🧂🌿 Vegeta spricht:"
echo ""
echo "Willkommen im Kräutergarten der Prozesse ..."
echo "Ich zeige dir nun, welche Programme im Wald gerade am meisten Saft verbrauchen!"
echo "(Drücke q, um die Liste zu verlassen.)"
echo ""
echo "🌱 Öffne das Auge der Tiefe ..."
sleep 2
top

View File

@@ -0,0 +1,3 @@
echo ""
echo "🧂🌿 Vegeta spricht: Die Bäume atmen ... so sehr arbeitet der Prozessor:"
mpstat 1 3 | grep "Average"

View File

@@ -0,0 +1,3 @@
echo ""
echo "🌿 Vegeta: Die Wurzeln brauchen Platz …"
df -h

View File

@@ -0,0 +1,3 @@
echo ""
echo "🌐 Vegeta: Lausche dem Flüstern der Netzwerke:"
netstat -tulpen

View File

@@ -0,0 +1,3 @@
echo ""
echo "🔥 Vegeta flüstert: Die Glut der Wurzel sagt..."
vcgencmd measure_temp

View File

@@ -0,0 +1,3 @@
echo ""
echo "🌞 Vegeta: So lange singt der Wald schon:"
uptime

View File

@@ -0,0 +1,8 @@
#!/bin/bash
echo ""
echo "📜 Vegeta raschelt: Letzte Befehle der Krümel..."
if [ -f ~/.bash_history ]; then
tail -n 10 ~/.bash_history
else
echo "Kein Bash-Verlauf gefunden."
fi

23
crumbmission/welcome.sh Executable file
View File

@@ -0,0 +1,23 @@
PS3="#? "
options=("📝 Erste Mission starten" "🧪 Terminal erkunden" "❌ Beenden")
select opt in "${options[@]}"; do
case $REPLY in
1)
echo "Starte mission.sh ..."
/usr/local/bin/mission
break;;
2)
clear
echo "Du bist frei! Nutze deine Eingabe."
break;;
3)
echo "Auf Wiedersehen, $DISPLAY_NAME!"
exit;;
*)
echo "Ungültige Auswahl.";;
esac
done

183
crumbmission/welcome_kruemel.sh Executable file
View File

@@ -0,0 +1,183 @@
#!/bin/bash
clear
echo "🌲 Willkommen, kleiner Krümel!"
echo "Heute lernst du die Sprache des Waldes die Sprache der Shell."
sleep 2
echo ""
echo "🦉 Ich bin Eula, die Eule. Ich zeige dir, wie du dich im Wald orientierst."
echo "📂 Befehl: cd"
echo "cd bedeutet: 'Geh in diesen Ordner'. Probiere es aus:"
echo ""
echo "cd /home/"
expected="cd /home/"
while true; do
echo ""
read -p "💬 Dein Befehl: " input
if [ "$input" = "$expected" ]; then
echo "✅ Super! Du hast den Pfad richtig betreten."
break
else
echo "❗ Hmm ... versuch's nochmal. Tipp genau den Befehl wie gezeigt!"
fi
done
sleep 2
echo ""
echo "🦊 Ich bin Fridolin, der Fuchs. Ich kann Verstecke bauen!"
echo "📁 Befehl: mkdir"
echo "mkdir bedeutet: 'Baue einen neuen Unterschlupf'."
echo ""
echo "mkdir geheimversteck"
expected="mkdir geheimversteck"
while true; do
echo ""
read -p "💬 Dein Befehl: " input
if [ "$input" = "$expected" ]; then
echo "✅ Super! Du hast den Ordner richtig gebaut."
break
else
echo "❗ Hmm ... versuch's nochmal. Tipp genau den Befehl wie gezeigt!"
fi
done
sleep 2
echo ""
echo "🐭 Ich bin Mimi, die Maus. Ich liebe es, kleine Zettel zu schreiben."
echo "📝 Befehl: nano"
echo "nano bedeutet: 'Schreibe eine Nachricht'."
echo ""
echo "nano gruss.txt"
expected="nano gruss.txt"
while true; do
echo ""
read -p "💬 Dein Befehl: " input
if [ "$input" = "$expected" ]; then
echo "✅ Super! Du hast die Datei richtig erstellt und einen Krümel geschrieben."
break
else
echo "❗ Hmm ... versuch's nochmal. Tipp genau den Befehl wie gezeigt!"
fi
done
sleep 2
echo ""
echo "🦝 Ich bin Rico, der Waschbär. Ich kopiere Dinge, ohne sie zu verlieren!"
echo "📄 Befehl: cp"
echo "cp bedeutet: 'Kopiere etwas'."
echo ""
echo "cp gruss.txt geheimversteck/"
expected="cp gruss.txt geheimversteck/"
while true; do
echo ""
read -p "💬 Dein Befehl: " input
if [ "$input" = "$expected" ]; then
echo "✅ Super! Du hast die Datei richtig gefunden und einen Krümel kopiert."
break
else
echo "❗ Hmm ... versuch's nochmal. Tipp genau den Befehl wie gezeigt!"
fi
done
sleep 2
echo ""
echo "🦔 Ich bin Hedwig, der Igel. Ich bringe Dinge an neue Orte."
echo "🚚 Befehl: mv"
echo "mv bedeutet: 'Bewege etwas'."
echo ""
echo "mv gruss.txt geheimversteck/gruss_copy.txt"
expected="mv gruss.txt geheimversteck/gruss_copy.txt"
while true; do
echo ""
read -p "💬 Dein Befehl: " input
if [ "$input" = "$expected" ]; then
echo "✅ Super! Du hast die Datei richtig gefunden und einen Krümel kopiert."
break
else
echo "❗ Hmm ... versuch's nochmal. Tipp genau den Befehl wie gezeigt!"
fi
done
sleep 2
echo ""
echo "🐦 Ich bin Karla, der Kolibri. Ich zeige dir, was in Dateien steht."
echo "👁️ Befehl: cat"
echo "cat bedeutet: 'Lies mir was vor'."
echo ""
echo "cat geheimversteck/gruss.txt"
expected="cat geheimversteck/gruss.txt"
while true; do
echo ""
read -p "💬 Dein Befehl: " input
if [ "$input" = "$expected" ]; then
echo "✅ Super! Du hast die Datei richtig gefunden und einen Krümel gelesen."
break
else
echo "❗ Hmm ... versuch's nochmal. Tipp genau den Befehl wie gezeigt!"
fi
done
sleep 2
echo ""
echo "🐳 Ich bin Mops, der Mattermost-Wal. Ich bringe Nachrichten aus dem Netz!"
echo "🌍 Befehl: curl"
echo "curl bedeutet: 'Hole dir etwas aus dem Internet'."
echo ""
echo "curl https://crumbforest.org/welcome.txt"
expected="curl https://crumbforest.org/welcome.txt"
while true; do
echo ""
read -p "💬 Dein Befehl: " input
if [ "$input" = "$expected" ]; then
echo "✅ Super! Du hast die Datei richtig gefunden und einen einen anderen Wald besucht."
break
else
echo "❗ Hmm ... versuch's nochmal. Tipp genau den Befehl wie gezeigt!"
fi
done
sleep 2
echo ""
echo "🕸️ Ich bin Wally, die Spinne. Ich fange Webseiten in mein Netz."
echo "🌐 Befehl: wget"
echo "wget bedeutet: 'Lade eine Datei aus dem Web herunter'."
echo ""
echo "wget https://crumbforest.org/karte.pdf"
expected="wget https://crumbforest.org/karte.pdf"
while true; do
echo ""
read -p "💬 Dein Befehl: " input
if [ "$input" = "$expected" ]; then
echo "✅ Super! Du hast die Datei zielsicher heruntergeladen."
break
else
echo "❗ Hmm ... versuch's nochmal. Tipp genau den Befehl wie gezeigt!"
fi
done
sleep 2
echo ""
echo "✨ Du hast die Grundlagen gelernt, kleiner Krümel!"
echo "Mach dich bereit für deine erste Mission …"
echo ""
# Weiterleitung zu Mission-Selector?
exec /scripts/mission_selector.sh

63
fix_token_logs.sh Executable file
View File

@@ -0,0 +1,63 @@
#!/bin/bash
echo "🔧 Repariere Crumbforest Token-Logs mit eingebetteten JSON-Strings …"
LOG_DIRS=(
"/home/zero/.bugsy_logs"
"/home/zero/.deepbit_logs"
"/home/zero/.dumbo_logs"
"/home/zero/.funkfox_logs"
"/home/zero/.pepper_logs"
"/home/zero/.schnecki_logs"
"/home/zero/.schnippsi_logs"
"/home/zero/.schraubaer_logs"
"/home/zero/.snake_logs"
"/home/zero/.taube_logs"
"/home/zero/.templatus_logs"
"/home/zero/.tobi_logs"
)
for dir in "${LOG_DIRS[@]}"; do
FILE="$dir/token_log.json"
if [ -f "$FILE" ]; then
echo "🔍 Prüfe $FILE"
TMP="$FILE.fixed"
# Filter & reparieren Zeile für Zeile
jq -c '.' "$FILE" 2>/dev/null | while read -r line; do
usage_raw=$(echo "$line" | jq -r '.usage')
if [[ "$usage_raw" =~ ^\{.*\}$ ]]; then
# usage ist korrektes Objekt direkt übernehmen
echo "$line" >> "$TMP"
else
# usage ist String versuche zu reparieren
usage_fixed=$(echo "$usage_raw" | jq '.' 2>/dev/null)
if [ $? -eq 0 ]; then
zeit=$(echo "$line" | jq -r '.zeit')
rolle=$(echo "$line" | jq -r '.rolle')
jq -n \
--arg zeit "$zeit" \
--arg rolle "$rolle" \
--argjson usage "$usage_fixed" \
'{zeit: $zeit, rolle: $rolle, usage: $usage}' >> "$TMP"
else
echo "⚠️ Ungültige Zeile übersprungen in $FILE:"
echo "$line"
fi
fi
done
# Nur ersetzen, wenn wir etwas geschrieben haben
if [ -s "$TMP" ]; then
mv "$TMP" "$FILE"
echo "✅ Repariert: $FILE"
else
echo " Keine gültigen Einträge in $FILE"
rm -f "$TMP"
fi
else
echo "❌ Datei nicht gefunden: $FILE"
fi
done
echo "🎉 Alle Token-Logs geprüft und repariert (sofern nötig)."

37
log_tokens_viewer_v4.sh Executable file
View File

@@ -0,0 +1,37 @@
#!/bin/bash
echo "📊 Crumbforest Token Log Viewer V4"
echo "----------------------------------"
for logfile in /home/zero/.*/token_log.json; do
echo ""
echo "🔎 Viewing: $logfile"
echo "------------------------------------"
while IFS= read -r line; do
usage_raw=$(jq -r '.usage' <<< "$line" 2>/dev/null)
# überspringe leere oder ungültige usage-Felder
if [ -z "$usage_raw" ] || [ "$usage_raw" == "null" ]; then
continue
fi
# Versuche usage als Objekt zu lesen, wenn es ein String ist
if jq -e '.' <<< "$usage_raw" >/dev/null 2>&1; then
usage_parsed="$usage_raw"
else
usage_parsed=$(jq -r '.usage' <<< "$line" | jq . 2>/dev/null)
fi
# Wenn das Parsen klappt, extrahiere total_tokens
if [ -n "$usage_parsed" ]; then
tokens=$(jq -r '.total_tokens' <<< "$usage_parsed" 2>/dev/null)
else
tokens=""
fi
zeit=$(jq -r '.zeit' <<< "$line" 2>/dev/null)
rolle=$(jq -r '.rolle' <<< "$line" 2>/dev/null)
printf "📅 %s | 🧠 %s | 🧮 %s Tokens\n" "$zeit" "$rolle" "$tokens"
done < "$logfile"
done

80
missions/README.md Executable file
View File

@@ -0,0 +1,80 @@
# 🌲 Crumb Mission Selector - README
## Was ist das?
Der **Crumb Mission Selector** ist ein interaktives Lern-Tool das die Philosophie der ursprünglichen CF_Zero_V1 Bash-Abenteuer wiederbelebt.
## Quick Start
```bash
./crumb-mission-selector.sh
```
## Verfügbare Missionen
### 📚 Basics (für Einsteiger)
- **🦊 Fridolin (Pfadfinder)** - Navigation: `pwd`, `ls`, `cd`
- **🛠️ Balu (Bau-Elf)** - Dateien erstellen: `mkdir`, `touch`, `echo`
- **🐈🦉 Noko (Leser)** - Dateien lesen: `cat`, `head`, `tail`, `grep`
### 🚀 Advanced (für Fortgeschrittene)
- **🌐 DNS Deep Dive** - DNS-Tools: `dig`, `nslookup`, `host`
- **🔐 SSH Security Basics** - SSH-Verbindungen und Keys
### 🏆 Challenges (bald verfügbar)
Hier werden bald interaktive Herausforderungen erscheinen!
## Neue Mission hinzufügen
1. Erstelle zwei Dateien:
```bash
touch missions/basics/meine_mission.sh
touch missions/basics/meine_mission.meta.json
```
2. Fülle die Metadaten:
```json
{
"icon": "🎯",
"title": "Meine Mission",
"description": "Was du hier lernst",
"category": "basics",
"enabled": true
}
```
3. Schreibe dein Skript und mache es ausführbar:
```bash
chmod +x missions/basics/meine_mission.sh
```
4. Fertig! Die Mission erscheint automatisch im Menü.
## Architektur
```
crumb-mission-selector.sh # Hauptscript (Metadata-Loader)
missions/
├── basics/ # Einsteiger-Missionen
├── advanced/ # Fortgeschrittene Missionen
└── challenges/ # Herausforderungen
```
Jede Mission besteht aus:
- `.sh` Datei (das eigentliche Skript)
- `.meta.json` Datei (Icon, Titel, Beschreibung)
## Philosophie
Inspiriert von CF_Zero_V1:
- ✅ Metadata-driven Design
- ✅ Erweiterbar ohne Code-Änderungen
- ✅ Bildungsfreundlich & interaktiv
- ✅ Waldwächter-Philosophie: "Transparency over magic"
## Erstellt
2025-12-21 - Als Teil der Integration von CF_Zero_V1 Bash-Abenteuern in das neue Crumbforest-Ökosystem

View File

@@ -0,0 +1,11 @@
{
"icon": "🌐",
"title": "DNS Deep Dive",
"description": "Verstehe DNS und lerne dig, nslookup, host",
"category": "advanced",
"difficulty": "intermediate",
"duration_minutes": 15,
"enabled": true,
"author": "Crumbforest Team",
"version": "2.0"
}

View File

@@ -0,0 +1,59 @@
#!/bin/bash
# 🌐 DNS Deep Dive
# Lehrt: DNS-Tools (dig, nslookup, host)
cat << 'EOF'
🌐 DNS Deep Dive Mission
Lass uns die unsichtbaren Pfade des Internets erkunden!
DNS (Domain Name System) übersetzt Namen wie "google.com" in IP-Adressen.
EOF
echo "🔍 Tool-Check:"
for tool in dig nslookup host; do
if command -v "$tool" &>/dev/null; then
echo "$tool gefunden"
else
echo "$tool nicht installiert"
fi
done
echo ""
echo "🎓 Aufgabe 1: Finde die IP-Adresse von google.com"
echo " Befehl: dig google.com +short"
echo ""
read -p "Drücke Enter zum Ausführen..." -r
dig google.com +short 2>/dev/null || echo "⚠️ dig nicht verfügbar, nutze 'nslookup google.com'"
echo ""
echo "🎓 Aufgabe 2: Zeige DNS-Records im Detail"
echo " Befehl: dig google.com"
echo ""
read -p "Drücke Enter zum Ausführen..." -r
dig google.com 2>/dev/null | head -n 30 || nslookup google.com
echo ""
echo "🎓 Aufgabe 3: Reverse DNS Lookup (IP → Name)"
echo " Befehl: host 8.8.8.8"
echo ""
read -p "Drücke Enter zum Ausführen..." -r
host 8.8.8.8 2>/dev/null || nslookup 8.8.8.8
echo ""
echo "🎓 Aufgabe 4: MX-Records (Mail-Server) finden"
echo " Befehl: dig google.com MX +short"
echo ""
read -p "Drücke Enter zum Ausführen..." -r
dig google.com MX +short 2>/dev/null || echo "⚠️ Nutze: nslookup -query=MX google.com"
echo ""
echo "💡 Weitere DNS-Befehle:"
echo " - dig example.com ANY (alle Records)"
echo " - dig @8.8.8.8 example.com (nutze Google DNS Server)"
echo " - whois example.com (Domain-Informationen)"
echo ""
echo "✅ Mission abgeschlossen! Du bist jetzt ein DNS-Detektiv! 🌐"

View File

@@ -0,0 +1,11 @@
{
"icon": "🔐",
"title": "SSH Security Basics",
"description": "Lerne sichere SSH-Verbindungen und Key-Management",
"category": "advanced",
"difficulty": "intermediate",
"duration_minutes": 12,
"enabled": true,
"author": "Crumbforest Team",
"version": "2.0"
}

View File

@@ -0,0 +1,72 @@
#!/bin/bash
# 🔐 SSH Security Basics
# Lehrt: SSH-Verbindungen, Keys, Agent
cat << 'EOF'
🔐 SSH Security Basics
Lass uns sichere Verbindungen zu anderen Maschinen aufbauen!
SSH (Secure Shell) ist DAS Tool für Remote-Administration.
EOF
echo "🎓 Lektion 1: SSH Key-Paare verstehen"
echo ""
echo "Ein SSH-Key besteht aus zwei Teilen:"
echo " 🔑 Private Key (geheim, nur bei dir!)"
echo " 🗝️ Public Key (darf geteilt werden)"
echo ""
echo "📂 Typische SSH-Struktur:"
ls -lh ~/.ssh/ 2>/dev/null || echo "⚠️ Noch kein ~/.ssh/ Verzeichnis vorhanden"
echo ""
echo "🎓 Lektion 2: SSH-Agent prüfen"
echo ""
echo "Der SSH-Agent verwaltet deine Keys im Speicher."
echo " Befehl: ssh-add -l"
echo ""
read -p "Drücke Enter zum Ausführen..." -r
ssh-add -l 2>/dev/null || echo "⚠️ Kein SSH-Agent läuft oder keine Keys geladen"
echo ""
echo "🎓 Lektion 3: Neue SSH-Verbindung (Simulation)"
echo ""
echo "Syntax: ssh user@hostname"
echo "Beispiel: ssh pi@raspberrypi.local"
echo ""
echo "💡 Nützliche SSH-Optionen:"
echo " - ssh -v user@host (verbose, zeigt Debug-Info)"
echo " - ssh -p 2222 user@host (non-standard Port)"
echo " - ssh -i key.pem user@host (nutze spezifischen Key)"
echo ""
echo "🎓 Lektion 4: SSH Config verstehen"
echo ""
if [[ -f ~/.ssh/config ]]; then
echo "✅ Du hast eine SSH-Config:"
head -n 10 ~/.ssh/config 2>/dev/null
else
echo "⚠️ Keine ~/.ssh/config vorhanden"
echo ""
echo "Beispiel-Config:"
cat << 'CONFIGEOF'
Host raspi
HostName raspberrypi.local
User pi
Port 22
IdentityFile ~/.ssh/raspi_key
CONFIGEOF
fi
echo ""
echo "💡 Wichtige Sicherheits-Tipps:"
echo " 1. Nutze SSH-Keys statt Passwörter"
echo " 2. Schütze deinen Private Key (chmod 600)"
echo " 3. Aktiviere SSH-Agent-Forwarding nur wenn nötig"
echo " 4. Überprüfe Fingerprints bei neuen Hosts"
echo ""
echo "✅ Mission abgeschlossen! Du bist jetzt SSH-sicherer! 🔐"

11
missions/basics/balu.meta.json Executable file
View File

@@ -0,0 +1,11 @@
{
"icon": "🛠️",
"title": "Balu (Bau-Elf)",
"description": "Lerne Dateien & Ordner erstellen: mkdir, touch, echo",
"category": "basics",
"difficulty": "beginner",
"duration_minutes": 5,
"enabled": true,
"author": "Crumbforest Team",
"version": "2.0"
}

48
missions/basics/balu.sh Executable file
View File

@@ -0,0 +1,48 @@
#!/bin/bash
# 🛠️ Balu - Der Bau-Elf
# Lehrt: Dateien & Ordner erstellen (mkdir, touch, echo)
cat << 'EOF'
🛠️ Balu, der Bau-Elf, ist da!
Lass uns zusammen etwas bauen im Dateiwald.
EOF
echo "🏗️ Wir erstellen ein geheimes Versteck:"
echo ""
VERSTECK="$HOME/crumb_geheimversteck"
if [[ -d "$VERSTECK" ]]; then
echo "⚠️ Du hast bereits ein Versteck bei: $VERSTECK"
else
echo "➡️ Erstelle Versteck bei: $VERSTECK"
mkdir -p "$VERSTECK"
echo "✅ Versteck erstellt!"
fi
echo ""
echo "📝 Lass uns eine Nachricht hinterlassen:"
echo ""
read -p "Was möchtest du schreiben? " message
echo "$message" > "$VERSTECK/nachricht.txt"
echo ""
echo "✅ Nachricht gespeichert in: $VERSTECK/nachricht.txt"
echo ""
echo "🔍 Du kannst sie später mit diesem Befehl lesen:"
echo " cat $VERSTECK/nachricht.txt"
echo ""
echo "🎓 Weitere Übungen:"
echo " 1. Erstelle einen neuen Ordner: mkdir mein_ordner"
echo " 2. Erstelle eine leere Datei: touch datei.txt"
echo " 3. Schreibe Text in eine Datei: echo 'Hallo' > datei.txt"
echo ""
echo "✅ Mission abgeschlossen! Balu ist stolz auf dich! 🛠️"

View File

@@ -0,0 +1,11 @@
{
"icon": "🦊",
"title": "Fridolin (Pfadfinder)",
"description": "Lerne Navigation im Dateisystem: pwd, ls, cd",
"category": "basics",
"difficulty": "beginner",
"duration_minutes": 5,
"enabled": true,
"author": "Crumbforest Team",
"version": "2.0"
}

38
missions/basics/fridolin.sh Executable file
View File

@@ -0,0 +1,38 @@
#!/bin/bash
# 🦊 Fridolin - Der Pfadfinder
# Lehrt: Navigation im Dateisystem (cd, ls, pwd)
cat << 'EOF'
🦊 Fridolin, der Pfadfinder, begrüßt dich!
Lass uns die Wege im Dateiwald erkunden.
EOF
echo "➡️ Wo sind wir gerade?"
pwd
echo ""
echo "➡️ Was gibt es hier zu sehen?"
ls -lh
echo ""
echo "🎓 Deine Aufgabe:"
echo " 1. Tippe 'pwd' um deinen aktuellen Pfad zu sehen"
echo " 2. Tippe 'ls -la' um ALLE Dateien zu sehen (auch versteckte)"
echo " 3. Tippe 'cd ..' um einen Ordner nach oben zu gehen"
echo " 4. Tippe 'exit' wenn du fertig bist"
echo ""
read -p "Möchtest du es ausprobieren? (j/n): " answer
if [[ "$answer" =~ ^[jJyY]$ ]]; then
echo "📂 Starte interaktive Shell für dich..."
echo " (Tippe 'exit' wenn du fertig bist)"
bash
fi
echo ""
echo "✅ Mission abgeschlossen! Fridolin ist stolz auf dich! 🦊"

11
missions/basics/noko.meta.json Executable file
View File

@@ -0,0 +1,11 @@
{
"icon": "🐈🦉",
"title": "Noko (Leser der Tiefe)",
"description": "Lerne Dateien zu lesen: cat, head, tail, grep",
"category": "basics",
"difficulty": "beginner",
"duration_minutes": 10,
"enabled": true,
"author": "Crumbforest Team",
"version": "2.0"
}

73
missions/basics/noko.sh Executable file
View File

@@ -0,0 +1,73 @@
#!/bin/bash
# 🐈🦉 Noko - Der Leser der Tiefe
# Lehrt: Dateien lesen (cat, less, head, tail, grep)
cat << 'EOF'
🐈🦉 Noko, der Leser der Tiefe, grüßt dich!
Lass uns die Geheimnisse der Waldbotschaften entschlüsseln.
EOF
# Erstelle eine Beispiel-Logdatei
LOGFILE="/tmp/crumbforest_demo.log"
cat > "$LOGFILE" << 'LOGEOF'
2025-12-21 00:00:01 [INFO] System gestartet
2025-12-21 00:01:15 [DEBUG] Verbindung zu Datenbank erfolgreich
2025-12-21 00:02:34 [INFO] User 'kruemel' hat sich angemeldet
2025-12-21 00:03:12 [WARN] Speicher bei 75% Auslastung
2025-12-21 00:04:56 [ERROR] Datei nicht gefunden: /var/log/missing.log
2025-12-21 00:05:23 [INFO] Backup erfolgreich abgeschlossen
2025-12-21 00:06:45 [DEBUG] Cache geleert
2025-12-21 00:07:12 [INFO] System läuft stabil
LOGEOF
echo "📜 Noko hat eine Logdatei für dich vorbereitet:"
echo " $LOGFILE"
echo ""
echo "🎓 Aufgabe 1: Zeige die ganze Datei an"
echo " Befehl: cat $LOGFILE"
echo ""
read -p "Drücke Enter zum Ausführen..." -r
cat "$LOGFILE"
echo ""
echo "🎓 Aufgabe 2: Zeige nur die ersten 3 Zeilen"
echo " Befehl: head -n 3 $LOGFILE"
echo ""
read -p "Drücke Enter zum Ausführen..." -r
head -n 3 "$LOGFILE"
echo ""
echo "🎓 Aufgabe 3: Zeige nur die letzten 3 Zeilen"
echo " Befehl: tail -n 3 $LOGFILE"
echo ""
read -p "Drücke Enter zum Ausführen..." -r
tail -n 3 "$LOGFILE"
echo ""
echo "🎓 Aufgabe 4: Suche nach Fehlern (ERROR)"
echo " Befehl: grep ERROR $LOGFILE"
echo ""
read -p "Drücke Enter zum Ausführen..." -r
grep ERROR "$LOGFILE"
echo ""
echo "🎓 Bonus: Zeige alle Zeilen mit 'INFO' oder 'ERROR'"
echo " Befehl: grep -E 'INFO|ERROR' $LOGFILE"
echo ""
read -p "Drücke Enter zum Ausführen..." -r
grep -E 'INFO|ERROR' "$LOGFILE"
echo ""
echo "💡 Weitere nützliche Befehle:"
echo " - less $LOGFILE (scrollbar lesen, mit q beenden)"
echo " - wc -l $LOGFILE (Zeilen zählen)"
echo " - tail -f DATEI (live Änderungen beobachten)"
echo ""
echo "✅ Mission abgeschlossen! Noko ist stolz auf dich! 🐈🦉"

6018
schnippsi_ui/error.txt Executable file

File diff suppressed because it is too large Load Diff

103
schnippsi_ui/index.html Executable file
View File

@@ -0,0 +1,103 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Schnippsis Live-Editor 🧁</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body {
font-family: sans-serif;
margin: 0;
padding: 0;
background: #fefce8;
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: auto 1fr;
height: 100vh;
}
header {
grid-column: 1 / -1;
background: #ffb6b9;
color: #222;
padding: 1rem;
text-align: center;
font-weight: bold;
}
textarea {
width: 100%;
height: 100%;
padding: 1rem;
font-family: monospace;
font-size: 0.9rem;
border: none;
outline: none;
resize: none;
}
iframe {
width: 100%;
height: 100%;
border: none;
background: white;
}
.editor-section {
display: flex;
flex-direction: column;
}
.code-inputs {
flex: 1;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
.code-inputs textarea {
border-right: 1px solid #ddd;
}
</style>
</head>
<body>
<header>
🧁 Schnippsis Web-Baukasten HTML, CSS & JS live!
</header>
<div class="editor-section">
<div class="code-inputs">
<textarea id="htmlCode" placeholder="💡 HTML hier..."></textarea>
<textarea id="cssCode" placeholder="🎨 CSS hier..."></textarea>
<textarea id="jsCode" placeholder="⚙️ JavaScript hier..."></textarea>
</div>
</div>
<iframe id="preview"></iframe>
<script>
const htmlInput = document.getElementById('htmlCode');
const cssInput = document.getElementById('cssCode');
const jsInput = document.getElementById('jsCode');
const previewFrame = document.getElementById('preview');
function updatePreview() {
const html = htmlInput.value;
const css = `<style>${cssInput.value}</style>`;
const js = `<script>${jsInput.value}<\/script>`;
previewFrame.srcdoc = html + css + js;
}
[htmlInput, cssInput, jsInput].forEach(el => {
el.addEventListener('input', updatePreview);
});
// Schnippsi-Vorschlag (Startzustand)
htmlInput.value = `<h1>Hallo Krümel! 🌼</h1>\n<p>Dies ist dein erstes HTML im Editor!</p>`;
cssInput.value = `body { font-family: sans-serif; background: #fff8dc; color: #333; padding: 2rem; }`;
jsInput.value = `console.log("Krümel hat gerade Schnippsis Editor benutzt! 🧁");`;
updatePreview();
</script>
</body>
</html>

1
schnippsi_ui/ttyd Submodule

Submodule schnippsi_ui/ttyd added at 05422dc91f

52
snake_camera_vision/app.py Executable file
View File

@@ -0,0 +1,52 @@
from flask import Flask, render_template, Response, request, redirect
import cv2
import json
from datetime import datetime
app = Flask(__name__)
def gen_frames():
cam = cv2.VideoCapture(0)
if not cam.isOpened():
print("[WARNUNG] Kamera konnte nicht geöffnet werden.")
return
try:
while True:
success, frame = cam.read()
if not success:
break
ret, buffer = cv2.imencode('.jpg', frame)
frame = buffer.tobytes()
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
finally:
cam.release()
print("[info] Kamera wurde sauber freigegeben.")
@app.route('/')
def index():
return render_template('index.html')
@app.route('/video_feed')
def video_feed():
return Response(gen_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')
@app.route('/log_answer', methods=['POST'])
def log_answer():
user_input = request.form.get('antwort', 'nichts gesagt')
mood = request.form.get('mood', 'unspecified')
gesture = request.form.get('gesture', 'none')
timestamp = datetime.now().isoformat()
log_entry = {
'timestamp': timestamp,
'antwort': user_input,
'mood': mood,
'gesture': gesture
}
with open("snake_log.jsonl", "a") as log_file:
log_file.write(json.dumps(log_entry) + "\n")
return redirect("/")

Some files were not shown because too many files have changed in this diff Show More