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

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