diff --git a/README.md b/README.md
index 65c565a..3db823a 100644
--- a/README.md
+++ b/README.md
@@ -253,14 +253,20 @@ bash missions/robots/mond_maschine.sh
---
+### 🎨 Crumbblocks & UI ⭐ NEU!
+- **Dein Zeichen im Wald** - Designe ein UI-Element im Browser
+- **Bridge-Technology** - Sende Daten via Clipboard vom Browser ins Terminal
+- **Smart Evaluation** - Die Crew erkennt automatisch, was du gebaut hast!
+
## 🏷️ Version
-**v0.1-robots-complete**
+**v0.0-RC3-crumbblocks**
+- Crumbblocks Integration (Browser <-> Terminal)
+- Neue UI Mission "Dein Zeichen im Wald"
+- Smart Routing für Evaluations-Skripte
+- macOS Pfad-Fixes für Waldwächter
- 3 Robot-Missionen
- 17 Waldwächter komplett
-- Logs im Repo
-- Token-Tracking
-- Crew Memory (log-basiert)
---
diff --git a/crumb-mission-selector.sh b/crumb-mission-selector.sh
index 88ae670..6799368 100755
--- a/crumb-mission-selector.sh
+++ b/crumb-mission-selector.sh
@@ -565,32 +565,63 @@ function eule_memory() {
}
function eule_tokens() {
- LOGDIR="\$HOME/.eule_logs"
- if [[ -f "\$LOGDIR/token_log.json" ]]; then
+ # Use the new crew_tokens function from waldwaechter.sh
+ # All logs are now in the repo logs/ directory
+ if command -v crew_tokens &> /dev/null; then
+ crew_tokens
+ else
+ # Fallback if waldwaechter.sh not loaded
+ LOGDIR="${REPO_ROOT}/logs"
echo -e "\${CYAN}📊 Token-Verbrauch:\${NC}"
echo ""
- TOTAL=0
- # Filter leere Arrays und parse JSON robuster
- while IFS= read -r line; do
- # Skip leere Zeilen und [] Arrays
- if [[ -z "\$line" ]] || [[ "\$line" == "[]" ]]; then
- continue
- fi
- zeit=\$(echo "\$line" | jq -r '.zeit // "unknown"' 2>/dev/null)
- # Unterstütze usage als String oder Objekt
- tokens=\$(echo "\$line" | jq -r 'if .usage | type == "string" then .usage | fromjson | .total_tokens // 0 else .usage.total_tokens // 0 end' 2>/dev/null)
+ if [[ -d "\$LOGDIR" ]]; then
+ local total_tokens=0
+ local found_any=false
- if [[ "\$tokens" =~ ^[0-9]+\$ ]]; then
- TOTAL=\$((TOTAL + tokens))
- echo " \$zeit: \$tokens Tokens"
+ for token_file in "\$LOGDIR"/*/token_log.json; do
+ if [[ -f "\$token_file" ]]; then
+ local character=\$(basename "\$(dirname "\$token_file")")
+ local char_tokens=\$(grep -v '^\[\]\$' "\$token_file" | jq -s 'map(.usage.total_tokens // 0) | add // 0' 2>/dev/null || echo 0)
+
+ if [[ \$char_tokens -gt 0 ]]; then
+ echo " \$character: \$char_tokens Tokens"
+ total_tokens=\$((total_tokens + char_tokens))
+ found_any=true
+ fi
+ fi
+ done
+
+ echo ""
+ if [[ \$found_any == true ]]; then
+ echo -e "\${GREEN}Gesamt: \$total_tokens Tokens\${NC}"
+ else
+ echo "Noch keine Token-Logs vorhanden"
fi
- done < "\$LOGDIR/token_log.json"
+ else
+ echo "Log-Verzeichnis nicht gefunden: \$LOGDIR"
+ fi
+
echo ""
- echo -e "\${GREEN}Gesamt: \$TOTAL Tokens\${NC}"
- echo -e "\${YELLOW}Jede Frage ist wertvoll 🌲\${NC}"
- else
- echo "Noch keine Token-Logs."
+ echo -e "\${YELLOW}Token Budget & Philosophie:\${NC}"
+ echo " \"Was kostet die Frage eines Kindes?\""
+ echo " Im Wald unbezahlbar - Token lehren achtsames Fragen."
+ echo ""
+ if [[ -n "\${DAILY_TOKEN_BUDGET}" ]] && [[ "\${DAILY_TOKEN_BUDGET}" != "0" ]]; then
+ echo " Tages-Budget: \${DAILY_TOKEN_BUDGET} Tokens"
+ else
+ echo " Tages-Budget: Unbegrenzt"
+ fi
+ if [[ "\${ENABLE_TOKEN_TRACKING}" == "true" ]]; then
+ echo " Token-Tracking: Aktiviert"
+ fi
+ echo ""
+ echo -e "\${CYAN}Waldwächter (AI Charaktere):\${NC}"
+ echo ""
+ echo -e "\${YELLOW}Token-Logs:\${NC}"
+ if [[ \$found_any == false ]]; then
+ echo " Noch keine Logs vorhanden"
+ fi
fi
}
diff --git a/crumbblocks/bezier.html b/crumbblocks/bezier.html
new file mode 100644
index 0000000..d81856e
--- /dev/null
+++ b/crumbblocks/bezier.html
@@ -0,0 +1,628 @@
+
+
+
+
+
+ One‑Liner Painter • Bezier Pen + Editor
+
+
+
+
+ One‑Liner Painter • Bezier-Pen + Editor • Replay • SVG/PNG/JSON
+
+
+
+
+
+
+
+ Omi Omega – One‑Liner
+ a→Spirale→y; Bits 1+1; Funken.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Neu: richtiger Bezier‑Pen wie in Illustrator/Inkscape (Anker setzen & ziehen).
+
+
+
+
+
diff --git a/crumbblocks/bezier_stream.html b/crumbblocks/bezier_stream.html
new file mode 100644
index 0000000..87e6ce1
--- /dev/null
+++ b/crumbblocks/bezier_stream.html
@@ -0,0 +1,452 @@
+
+
+
+
+
+Schnippsi Painter — Stream + Bezier
+
+
+
+
+
+
+ Shortcuts
+ Hilfe ? / H • Tool-Bezier B • Tool-Freihand F • Stream S
+ Bezier beenden Enter • Letzten Anker löschen Backspace • Ecke halten Alt • Snap Shift
+ A11y
Tab-fokussierbar, ARIA Live-Status, hoher Kontrast, 200% Zoom stabil.
+
+
+
+
+
diff --git a/crumbblocks/crumbblocks.html b/crumbblocks/crumbblocks.html
new file mode 100644
index 0000000..b1aa35d
--- /dev/null
+++ b/crumbblocks/crumbblocks.html
@@ -0,0 +1,366 @@
+
+
+
+
+ Crumbblocks – Wasserkocher (Demo)
+
+
+
+
+
+
+
+
+ 🧁 Crumbblocks – Virtueller Wasserkocher (Kids-Demo)
+
+ Variablen: power_w, wasser_ml, sensor_temp_c, zeit_s,
+ energie_wh, verbrauch_wh. Ziel: Bis 100 °C erhitzen, Energie/Zeit mitrechnen.
+
+
+
+
+ 🎬 Demo laden
+ ▶️ Ausführen
+ 🧹 Leeren
+ Sendet per POST /crumbapi/blockly-terminal (Fallback: Echo).
+
+
+
+
+
🌲 Terminal wartet …
+
+
+
+
+
+
+
+
+
+
+
+ 10
+ WHILE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/crumbblocks/index.html b/crumbblocks/index.html
new file mode 100644
index 0000000..ddbe35f
--- /dev/null
+++ b/crumbblocks/index.html
@@ -0,0 +1,298 @@
+
+
+
+
+ Blockly to Crumbforest Terminal Bridge
+
+
+
+
+
+
+
+
+ 🧁 Blockly Crumbforest Bridge
+
+ 🧪 Demo
+ 🗑️ Neu
+ 🔍+
+ 🔍-
+ ▶️ Ausführen
+
+
+
+
+
+
+
Variablen: energie_wh, verbrauch_wh, sensor_temp_c, power_w, wasser_ml, zeit_s
+
Endpoint: /crumbapi/blockly-terminal (Echo-Fallback aktiv)
+
+
🌲 Terminal wartet ...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/crumbblocks/index_v1.html b/crumbblocks/index_v1.html
new file mode 100644
index 0000000..bcd5887
--- /dev/null
+++ b/crumbblocks/index_v1.html
@@ -0,0 +1,278 @@
+
+
+
+
+ Crumbblocks – Blockly ↔ Crumbforest
+
+
+
+
+
+
+
+
+
+ 🧁 Crumbblocks
+
+ Demo laden
+ –
+ +
+ Mülleimer
+ Ausführen → Terminal
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 10
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Konsole
+
bereit
+
+
Leeren
+
Ein-/Ausklappen
+
+ 🌲 Terminal wartet …
+
+
+
+
+
+
diff --git a/crumbblocks/lipo_6s_charger.html b/crumbblocks/lipo_6s_charger.html
new file mode 100644
index 0000000..64f1ef2
--- /dev/null
+++ b/crumbblocks/lipo_6s_charger.html
@@ -0,0 +1,575 @@
+
+
+
+
+ 🔋 6S LiPo Charger – Blockly Simulation (SAFE)
+
+
+
+
+
+
+
+
+
+ 🧁 Crumbforest • 6S LiPo Charger – Simulation (SAFE)
+
+ 📄 Doku
+ T1
+ T2
+ T3
+ T4
+ 🎲 Zufall
+ 🗑️ Neu
+ ▶️ Ausführen
+
+
+
+
+
+
🌲 Bereit. Lade „Doku“ / Testfälle oder baue eigene Logik und drücke ▶️.
+
+
+
+
+ Marker (6S): 19,2 V (leer, ~3,2/Z) • 22,2 V (Nominal) • 22,8 V (Storage 3,8/Z) • 25,2 V (Full 4,2/Z) • 26,1 V (HV 4,35/Z).
+ Nur Simulation / Didaktik. Keine echte Ladefunktion.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ⚠️ Sicherheits-Hinweis: Das ist nur eine Simulation . Echte LiPos nur mit geeignetem Ladegerät & Balancer laden.
+ Packs mit starker Zellabweichung (≥0,30 V ) nicht verwenden. Keine echten Ströme werden hier geschaltet.
+
+
+
diff --git a/crumbblocks/lipo_6s_charger_sim_safe_v2.html b/crumbblocks/lipo_6s_charger_sim_safe_v2.html
new file mode 100644
index 0000000..ea0287c
--- /dev/null
+++ b/crumbblocks/lipo_6s_charger_sim_safe_v2.html
@@ -0,0 +1,453 @@
+
+
+
+
+ 🔋 6S LiPo Charger – Blockly Simulation (SAFE v3)
+
+
+
+
+
+
+
+
+
+ 🧁 Crumbforest • 6S LiPo Charger – Simulation (SAFE v3)
+
+ 📄 Doku
+ T1
+ T2
+ T3
+ T4
+ 🎲 Zufall
+ 🗑️ Neu
+ ▶️ Ausführen
+
+
+
+
+
+
🌲 Bereit. Lade „Doku“ / Testfälle oder baue eigene Logik und drücke ▶️.
+
+
+
+
+ Marker (6S): 19,2 V (leer) • 22,8 V (Storage 3,8/Z) • 25,2 V (Full 4,2/Z) • 26,1 V (HV 4,35/Z).
+ Nur Simulation / Didaktik. Keine echte Ladefunktion.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ⚠️ Sicherheits-Hinweis: Das ist nur eine Simulation . Echte LiPos nur mit geeignetem Ladegerät & Balancer laden.
+ Packs mit starker Zellabweichung (≥0,30 V) nicht verwenden. Keine echten Ströme werden hier geschaltet.
+
+
+
diff --git a/crumbblocks/lipo_6s_charger_sim_safe_v4.html b/crumbblocks/lipo_6s_charger_sim_safe_v4.html
new file mode 100644
index 0000000..59d18de
--- /dev/null
+++ b/crumbblocks/lipo_6s_charger_sim_safe_v4.html
@@ -0,0 +1,322 @@
+
+
+
+
+ 🔋 6S LiPo Charger – Blockly Simulation (SAFE v4)
+
+
+
+
+
+
+
+
+
+ 🧁 Crumbforest • 6S LiPo Charger – Simulation (SAFE v4)
+
+ 📄 Doku
+ T1
+ T2
+ T3
+ T4
+ 🎲 Zufall
+ 🗑️ Neu
+ ▶️ Ausführen
+
+
+
+
+
+
🌲 Bereit. Lade „Doku“ / Testfälle oder baue eigene Logik und drücke ▶️.
+
+
+
+
+ Marker (6S): 19,2 V (leer) • 22,8 V (Storage 3,8/Z) • 25,2 V (Full 4,2/Z) • 26,1 V (HV 4,35/Z).
+ Nur Simulation / Didaktik. Keine echte Ladefunktion.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ⚠️ Sicherheits-Hinweis: Das ist nur eine Simulation . Echte LiPos nur mit geeignetem Ladegerät & Balancer laden.
+ Packs mit starker Zellabweichung (≥0,30 V) nicht verwenden. Keine echten Ströme werden hier geschaltet.
+
+
+
diff --git a/crumbblocks/lipo_6s_charger_sim_safe_v5.html b/crumbblocks/lipo_6s_charger_sim_safe_v5.html
new file mode 100644
index 0000000..59d18de
--- /dev/null
+++ b/crumbblocks/lipo_6s_charger_sim_safe_v5.html
@@ -0,0 +1,322 @@
+
+
+
+
+ 🔋 6S LiPo Charger – Blockly Simulation (SAFE v4)
+
+
+
+
+
+
+
+
+
+ 🧁 Crumbforest • 6S LiPo Charger – Simulation (SAFE v4)
+
+ 📄 Doku
+ T1
+ T2
+ T3
+ T4
+ 🎲 Zufall
+ 🗑️ Neu
+ ▶️ Ausführen
+
+
+
+
+
+
🌲 Bereit. Lade „Doku“ / Testfälle oder baue eigene Logik und drücke ▶️.
+
+
+
+
+ Marker (6S): 19,2 V (leer) • 22,8 V (Storage 3,8/Z) • 25,2 V (Full 4,2/Z) • 26,1 V (HV 4,35/Z).
+ Nur Simulation / Didaktik. Keine echte Ladefunktion.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ⚠️ Sicherheits-Hinweis: Das ist nur eine Simulation . Echte LiPos nur mit geeignetem Ladegerät & Balancer laden.
+ Packs mit starker Zellabweichung (≥0,30 V) nicht verwenden. Keine echten Ströme werden hier geschaltet.
+
+
+
diff --git a/crumbblocks/lipo_6s_charger_sim_safe_v6.html b/crumbblocks/lipo_6s_charger_sim_safe_v6.html
new file mode 100644
index 0000000..e064d90
--- /dev/null
+++ b/crumbblocks/lipo_6s_charger_sim_safe_v6.html
@@ -0,0 +1,409 @@
+
+
+
+
+ 🔋 6S LiPo Charger – Blockly Simulation (DIAG v6)
+
+
+
+
+
+ 🧁 Crumbforest • 6S LiPo Charger – Simulation (DIAG v6)
+
+ 📄 Doku
+ T1
+ T2
+ T3
+ T4
+ 🎲 Zufall
+ 🗑️ Neu
+ ▶️ Ausführen
+
+
+
+
+
+
🌲 Bereit. Lade „Doku“ / Testfälle oder baue eigene Logik und drücke ▶️.
+
+
+
Diag lädt …
+
+ Marker (6S): 19,2 V (leer) • 22,8 V (Storage 3,8/Z) • 25,2 V (Full 4,2/Z) • 26,1 V (HV 4,35/Z).
+ Nur Simulation / Didaktik. Keine echte Ladefunktion.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ⚠️ Sicherheits-Hinweis: Das ist nur eine Simulation . Echte LiPos nur mit geeignetem Ladegerät & Balancer laden.
+ Packs mit starker Zellabweichung (≥0,30 V) nicht verwenden. Keine echten Ströme werden hier geschaltet.
+
+
+
+
+
Lokale Vendor-Dateien (empfohlen, falls CDN/CSP blockt):
+
mkdir -p /var/www/crumbblocks/vendor/blockly
+
curl -L -o /var/www/crumbblocks/vendor/blockly/blockly.min.js https://unpkg.com/blockly/blockly.min.js
+
curl -L -o /var/www/crumbblocks/vendor/blockly/javascript.min.js https://unpkg.com/blockly/javascript.min.js
+
curl -L -o /var/www/crumbblocks/vendor/blockly/msg/de.js https://unpkg.com/blockly/msg/de.js
+
+
CSP (falls Eval/Inline blockiert → „nix passiert“):
+ Erweitere Header minimal für die Simulation:
+
Content-Security-Policy: default-src 'self';
+script-src 'self' https://unpkg.com 'unsafe-inline' 'unsafe-eval';
+style-src 'self' 'unsafe-inline';
+connect-src 'self';
+img-src 'self' data:;
+font-src 'self' data:;
+ (Nur für diese Lernseite. Produktion später strenger machen.)
+
+
+
diff --git a/crumbblocks/lipo_6s_charger_sim_safe_v7.html b/crumbblocks/lipo_6s_charger_sim_safe_v7.html
new file mode 100644
index 0000000..e5ea2b0
--- /dev/null
+++ b/crumbblocks/lipo_6s_charger_sim_safe_v7.html
@@ -0,0 +1,500 @@
+
+
+
+
+ 🔋 6S LiPo Charger – Blockly Simulation (DIAG v7)
+
+
+
+
+
+ 🧁 Crumbforest • 6S LiPo Charger – Simulation (DIAG v7)
+
+ 📄 Doku
+ T1
+ T2
+ T3
+ T4
+ 🎲 Zufall
+ 🗑️ Neu
+ ▶️ Ausführen
+
+
+
+
+
+
🌲 Bereit. Lade „Doku“ / Testfälle oder baue eigene Logik und drücke ▶️.
+
+
+
Diag lädt …
+
+ Marker (6S): 19,2 V (leer) • 22,8 V (Storage 3,8/Z) • 25,2 V (Full 4,2/Z) • 26,1 V (HV 4,35/Z). Nur Simulation.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ⚠️ Sicherheits-Hinweis: Nur Simulation. Echte LiPos ausschließlich mit geeignetem Ladegerät & Balancer laden. Packs mit Zell-Delta ≥ 0,30 V nicht verwenden.
+
+
+
+
diff --git a/crumbblocks/mock_ws_server.js b/crumbblocks/mock_ws_server.js
new file mode 100644
index 0000000..129d97e
--- /dev/null
+++ b/crumbblocks/mock_ws_server.js
@@ -0,0 +1,22 @@
+// Minimal WebSocket echo server for testing Painter stream
+// Usage: npm i ws; node mock_ws_server.js
+const WebSocket = require('ws');
+const wss = new WebSocket.Server({ port: 9980 });
+console.log('WS server on ws://localhost:9980');
+wss.on('connection', (ws)=>{
+ console.log('client connected');
+ ws.on('message', (msg)=>{
+ try{
+ const obj = JSON.parse(msg);
+ // log only essentials to keep console tidy
+ if(obj.type==='point'){
+ process.stdout.write(`• point ${obj.p.x.toFixed(1)},${obj.p.y.toFixed(1)}\r`);
+ }else{
+ console.log(obj.type);
+ }
+ }catch(e){}
+ // optionally echo back
+ // ws.send(msg);
+ });
+ ws.on('close', ()=>console.log('client closed'));
+});
diff --git a/crumbblocks/painter.html b/crumbblocks/painter.html
new file mode 100644
index 0000000..bd5f3a3
--- /dev/null
+++ b/crumbblocks/painter.html
@@ -0,0 +1,395 @@
+
+
+
+
+
+ One‑Liner Painter (Multi‑Stroke) – draw → export SVG + Motion JSON
+
+
+
+
+ One‑Liner Painter (Multi‑Stroke) → SVG & Motion JSON • a→Spirale→y • Start/Stop/Dynamik
+
+
+
+
+
+
+
+ Omi Omega – One‑Liner
+ Mehrere Pfade mit Start/Stop und Zeitdynamik: a→Spirale→y; Bits 1+1; Funken.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Mehrere Klicks & Pfade sind erlaubt. Start/Stop wird als Ereignis erfasst; Geschwindigkeiten landen im Motion‑JSON.
+
+
+
+
+
diff --git a/crumbblocks/painter_lines.html b/crumbblocks/painter_lines.html
new file mode 100644
index 0000000..31b6d44
--- /dev/null
+++ b/crumbblocks/painter_lines.html
@@ -0,0 +1,647 @@
+
+
+
+
+
+ One-Liner Painter + Bezier-Editor (Fix)
+
+
+
+
+ One-Liner Painter → SVG/PNG/JSON • Replay • Bezier-Editor (Fix)
+
+
+
+
+
+
+
+ Omi Omega – One-Liner
+ a→Spirale→y; Bits 1+1; Funken.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Fixes: keine (0,0)-Griffe mehr; Drag startet sofort; UI blockiert keine Klicks.
+
+
+
+
+
diff --git a/crumbblocks/painter_spray.html b/crumbblocks/painter_spray.html
new file mode 100644
index 0000000..bd5f3a3
--- /dev/null
+++ b/crumbblocks/painter_spray.html
@@ -0,0 +1,395 @@
+
+
+
+
+
+ One‑Liner Painter (Multi‑Stroke) – draw → export SVG + Motion JSON
+
+
+
+
+ One‑Liner Painter (Multi‑Stroke) → SVG & Motion JSON • a→Spirale→y • Start/Stop/Dynamik
+
+
+
+
+
+
+
+ Omi Omega – One‑Liner
+ Mehrere Pfade mit Start/Stop und Zeitdynamik: a→Spirale→y; Bits 1+1; Funken.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Mehrere Klicks & Pfade sind erlaubt. Start/Stop wird als Ereignis erfasst; Geschwindigkeiten landen im Motion‑JSON.
+
+
+
+
+
diff --git a/crumbblocks/rainbow_counter.html b/crumbblocks/rainbow_counter.html
new file mode 100644
index 0000000..c23c912
--- /dev/null
+++ b/crumbblocks/rainbow_counter.html
@@ -0,0 +1,722 @@
+
+
+
+
+
+ 🌈 Rainbow Counter v2 (ohne Anbindung)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
🌲 Bereit. Lade „Doku“/„T1–T3“ oder baue eigene Logik und drücke ▶️.
+
+
+
+
+ Ziel-JSON: {"total_events","classes","dominant","mapping"} •
+ Optional: Debounce (N), Gleichstand-Strategie (per Blocks).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/crumbblocks/readme.txt b/crumbblocks/readme.txt
new file mode 100644
index 0000000..3d957df
--- /dev/null
+++ b/crumbblocks/readme.txt
@@ -0,0 +1,31 @@
+# Schnippsi Painter — Streaming Quickstart
+
+## 1) Datei
+Öffne `schnippsi_painter_stream.html` im Browser. Zeichne frei oder mit dem Bezier‑Tool.
+- `Verbinden` stellt eine WebSocket-Verbindung zu **ws://localhost:9980** her.
+- Alle Events werden als JSON gesendet:
+ - `session` — Sessionstart
+ - `strokeStart` — neues Stroke (tool, colors, width)
+ - `point` — Punkte beim Freihandzeichnen (x,y,t,pressure,tilt)
+ - `anchor` / `anchors` — Bezier-Anker & Griffe (inkl. h1/h2)
+ - `strokeEnd` — Stroke abgeschlossen
+
+## 2) TouchDesigner (ohne extra Code)
+- Füge **WebSocket DAT** hinzu, setze **Mode = Server** und **Port = 9980**.
+- Verbinde Browser (Button `Verbinden`).
+- Hänge einen **JSON DAT** an den WebSocket-Ausgang (zum Parsen).
+- Alternativ direkt WebSocket DAT -> **WebSocket In CHOP** (vereinfachte Skalare), für volle Struktur aber JSON DAT + Python DAT-Execute.
+- Beispiel: Aus `point`-Messages `x,y` in einen **Trail CHOP** oder zum Zeichnen in einen **TOP**.
+
+## 3) Test ohne TouchDesigner (Node)
+Optionale Mini‑WS:
+```bash
+npm i ws
+node mock_ws_server.js
+```
+Dann im Painter `ws://localhost:9980` verwenden.
+
+## 4) Export
+Buttons: JSON, SVG, PNG — jeweils Download.
+
+A11y: Tastaturbedienung, ARIA‑Status, hoher Kontrast, 200% Zoom stabil.
diff --git a/crumbblocks/schnippsi_ui.html b/crumbblocks/schnippsi_ui.html
new file mode 100755
index 0000000..fb45f43
--- /dev/null
+++ b/crumbblocks/schnippsi_ui.html
@@ -0,0 +1,293 @@
+
+
+
+
+
+
+ Dein Zeichen im Wald 🌿
+
+
+
+
+
+
+
+
+ 🌲
+ ZEICHEN SETZEN
+
+
Daten kopiert! Zurück zum Terminal.
+
+
+
+
+
+
Dein Zeichen im Wald
+
Hinterlasse eine Nachricht für die anderen Krümel.
+
+
Dein Name (oder Pseudonym)
+
+
+
Deine Botschaft
+
+
+
+ Abbrechen
+ 🚀 Senden
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/crumbforest_roles/templatus_zero.sh b/crumbforest_roles/templatus_zero.sh
index c1a7c04..9e61f7f 100755
--- a/crumbforest_roles/templatus_zero.sh
+++ b/crumbforest_roles/templatus_zero.sh
@@ -5,13 +5,14 @@ API_KEY="$OPENROUTER_API_KEY"
MODEL="openai/gpt-3.5-turbo"
# Verzeichnisse
-LOG_DIR="/home/zero/.templatus_logs"
+LOG_DIR="${CRUMB_LOGS_DIR:-$HOME/.crumbforest_logs}/templatus"
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"
+[ ! -f "$HISTORY_FILE" ] && echo "[]" > "$HISTORY_FILE"
# JSON Payload vorbereiten
cat < "$TMP_REQUEST"
diff --git a/missions/challenges/schnippsi_ui_design.meta.json b/missions/challenges/schnippsi_ui_design.meta.json
new file mode 100644
index 0000000..754b475
--- /dev/null
+++ b/missions/challenges/schnippsi_ui_design.meta.json
@@ -0,0 +1,8 @@
+{
+ "title": "Dein Zeichen im Wald",
+ "icon": "🎨",
+ "description": "Erstelle ein UI-Blatt mit HTML & CSS und hinterlasse eine Nachricht.",
+ "difficulty": "medium",
+ "author": "Schnippsi",
+ "enabled": true
+}
\ No newline at end of file
diff --git a/missions/challenges/schnippsi_ui_design.sh b/missions/challenges/schnippsi_ui_design.sh
new file mode 100755
index 0000000..7024fca
--- /dev/null
+++ b/missions/challenges/schnippsi_ui_design.sh
@@ -0,0 +1,70 @@
+#!/bin/bash
+# 🖌️ Design-Challenge: Dein Zeichen im Wald
+# Eine Mission über Struktur, Stil und Gefühl.
+
+# Waldwächter laden
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+# Relativer Pfad zur Lib, da wir in missions/challenges/ sind (2 Ebenen tiefer)
+LIB_PATH="${SCRIPT_DIR}/../../lib/waldwaechter.sh"
+
+if [ -f "$LIB_PATH" ]; then
+ source "$LIB_PATH"
+else
+ # Fallback für direkte Ausführung
+ echo "⚠️ Waldwächter Lib nicht gefunden. Nutze Standard-Ausgabe."
+ function templatus() { echo "🏛️ Templatus: $1"; }
+ function schnippsi() { echo "✂️ Schnippsi: $1"; }
+ function pepperphp() { echo "🌶️ Pepper: $1"; }
+fi
+
+clear
+cat << "EOF"
+ 🎨 DEIN ZEICHEN IM WALD 🎨
+
+ Eine Mission für HTML, CSS und das gute Gefühl.
+EOF
+echo ""
+sleep 1
+
+echo "🏛️ Templatus betritt die Lichtung..."
+echo ""
+templatus "Sei gegrüßt, Architekt. Der Wald braucht Struktur. Ein Baum ist nicht nur Holz, er ist ein Gerüst (DOM). Wir brauchen ein stabiles Fundament."
+templatus "Deine Aufgabe: Erstelle ein HTML-Dokument. Ein 'Blatt' im Wind des Browsers."
+echo ""
+read -p " (Drücke ENTER um das Gerüst zu bauen...)"
+echo ""
+
+echo "✂️ Schnippsi schwebt herein..."
+echo ""
+schnippsi "Struktur? Pfff, Templatus, du bist so trocken wie altes Papier! Ein Blatt muss LEBEN!"
+schnippsi "Es braucht Farbe, Licht und Schatten. Wir wollen Glassmorphism – durchscheinend wie Tau auf einem Blatt. Und es muss auf jedem Gerät gut aussehen (Responsive). Das ist Ästhetik!"
+echo ""
+read -p " (Drücke ENTER für den Style...)"
+echo ""
+
+echo "🌶️ PepperPHP flitzt vorbei..."
+echo ""
+pepperphp "Und es muss was TUN! Ein statisches Blatt ist langweilig. Wenn man draufklickt, muss ein MODAL aufgehen! 'onClick', 'classList.add', Action! Wir wollen eine Nachricht hinterlassen."
+echo ""
+echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
+echo ""
+
+echo "📋 DEINE MISSION:"
+echo "1. Öffne im Browser: crumbblocks/schnippsi_ui.html"
+echo "2. Betrachte das Werk. Es ist... noch leer (oder?)"
+echo "3. Dein Ziel: Eine mittige Box ('Das Zeichen')."
+echo "4. Klick -> Modal -> Nachricht eingeben -> Senden."
+echo "5. Das Ergebnis bringst du zurück zur Crew."
+
+echo ""
+read -p "🚀 Bereit zum Coden? (j/n) " READY
+
+if [[ "$READY" == "j" ]]; then
+ echo ""
+ echo "Dann los! Starte den Server:"
+ echo "./start_crumbblocks.sh"
+ echo ""
+ echo "Und bearbeite die Datei: crumbblocks/schnippsi_ui.html"
+else
+ echo "Lass dir Zeit. Gutes Design braucht Muße."
+fi
diff --git a/missions/evaluate_mission_data.sh b/missions/evaluate_mission_data.sh
new file mode 100755
index 0000000..4c983db
--- /dev/null
+++ b/missions/evaluate_mission_data.sh
@@ -0,0 +1,133 @@
+#!/bin/bash
+# 🚀 Mission Data Evaluator (Master Gateway)
+# Liest JSON vom Browser und routet zur richtigen Mission.
+
+# Waldwächter laden
+# Waldwächter laden
+MISSION_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+source "${MISSION_DIR}/../lib/waldwaechter.sh"
+
+clear
+cat << "EOF"
+ 📡 CRUMB-MISSION DATA LINK 📡
+
+ Verbindung zum Browser wird hergestellt...
+
+ Anleitung:
+ 1. Öffne die Crumbblocks Mission im Browser
+ 2. Baue deinen Code und klicke "▶️ Ausführen"
+ 3. Klicke "🚀 An Crew Senden"
+ 4. Füge den kopierten Code hier ein (Ctrl+V / Cmd+V)
+ 5. Drücke ENTER und dann CTRL+D (um das Einfügen beenden)
+EOF
+
+echo ""
+echo "👇 Bitte JSON-Daten jetzt einfügen:"
+echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
+
+# Lese Input bis EOF
+INPUT_DATA=$(cat)
+
+echo ""
+echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
+echo "🔄 Daten empfangen. Prüfe Mission-Typ..."
+sleep 0.5
+
+# Extrahiere Mission-ID aus dem JSON
+# Wir nutzen grep/cut als robusten Fallback, falls jq fehlt
+MISSION_ID=$(echo "$INPUT_DATA" | grep -o '"mission": *"[^"]*"' | cut -d'"' -f4)
+
+# Routing Logic
+if [[ "$MISSION_ID" == "schnippsi_ui" ]]; then
+ # --> Rerouting zur UI Mission
+ echo ">> Routing zu: Dein Zeichen im Wald (Schnippsi UI)"
+ echo "$INPUT_DATA" | "${MISSION_DIR}/evaluate_sign.sh"
+ exit $?
+fi
+
+# ============================================================
+# DEFAULT / LEGACY LOGIC (Rainbow Counter)
+# ============================================================
+
+# Falls keine Mission-ID gefunden wurde oder unbekannt, gehen wir davon aus,
+# dass es der Rainbow Counter ist (Backward Compatibility).
+
+echo ">> Routing zu: Standard (Rainbow Counter)"
+echo ""
+
+# Validierung
+if [[ "$INPUT_DATA" != *"{"* ]] || [[ "$INPUT_DATA" != *"}"* ]]; then
+ echo "❌ FEHLER: Das sieht nicht wie gültiges JSON aus."
+ exit 1
+fi
+
+has_jq=$(command -v jq)
+
+# Versuch, die relevante Zeile zu finden (total_events)
+VALID_JSON_LINE=$(echo "$INPUT_DATA" | grep '"total_events":' | head -n 1)
+
+if [ -z "$VALID_JSON_LINE" ]; then
+ CLEAN_JSON="$INPUT_DATA"
+else
+ CLEAN_JSON="$VALID_JSON_LINE"
+fi
+
+CLEAN_JSON=$(echo "$CLEAN_JSON" | sed 's/^[^{]*{/{/; s/}[^}]*$/}/')
+
+if [ -n "$has_jq" ] && echo "$CLEAN_JSON" | jq . >/dev/null 2>&1; then
+ TOTAL=$(echo "$CLEAN_JSON" | jq -r '.total_events // 0')
+ DOMINANT=$(echo "$CLEAN_JSON" | jq -r '.dominant // "unknown"')
+ RED=$(echo "$CLEAN_JSON" | jq -r '.classes.red // 0')
+ BLUE=$(echo "$CLEAN_JSON" | jq -r '.classes.blue // 0')
+else
+ # Fallback Parser
+ TOTAL=$(echo "$CLEAN_JSON" | grep -o '"total_events": *[0-9]*' | awk -F: '{print $2}' | tr -d ' ,')
+ DOMINANT=$(echo "$INPUT_DATA" | grep -o '"dominant": *"[^"]*"' | awk -F: '{print $2}' | tr -d ' "')
+ RED=$(echo "$INPUT_DATA" | grep -o '"red": *[0-9]*' | awk -F: '{print $2}' | tr -d ' ,')
+ BLUE=$(echo "$INPUT_DATA" | grep -o '"blue": *[0-9]*' | awk -F: '{print $2}' | tr -d ' ,')
+fi
+
+# Default Werte falls leer
+TOTAL=${TOTAL:-0}
+RED=${RED:-0}
+BLUE=${BLUE:-0}
+DOMINANT=${DOMINANT:-unknown}
+
+# Feedback der Crew
+echo "🐘 DumboSQL prüft die Struktur..."
+sleep 1
+dumbosql "Datensatz empfangen. $TOTAL Ereignisse gefunden. Die Syntax ist valide. Speichere in temporärem Cache..."
+echo ""
+
+echo "🦊 FunkFox analysiert den Flow..."
+sleep 1
+if [ "$TOTAL" -gt 10 ]; then
+ funkfox "Wow, da ist ordentlich was los! $TOTAL Signale verarbeitet. Der Flow ist fast schon ein Stream!"
+elif [ "$TOTAL" -eq 0 ]; then
+ funkfox "Äh, Stille? Ich höre nichts. Null Events. Sicher, dass der Code lief?"
+else
+ funkfox "Okay, $TOTAL Signale. Ein guter Start für einen kleinen Loop."
+fi
+echo ""
+
+echo "🦉 Maya-Eule betrachtet die Farben..."
+sleep 1
+case $DOMINANT in
+ "red") mayaeule "Rot dominiert. Energie und Warnung." ;;
+ "blue") mayaeule "Blau ist stark. Ruhe und Technik." ;;
+ "green") mayaeule "Grün wie der Wald. Alles im Bereich." ;;
+ "yellow") mayaeule "Gelb leuchtet wie die Sonne." ;;
+ *) mayaeule "Eine interessante Mischung ($DOMINANT). Vielfalt ist gut." ;;
+esac
+echo ""
+
+echo "📊 Statistik:"
+echo " 🔴 Rot: $RED"
+echo " 🔵 Blau: $BLUE"
+echo ""
+
+cat << "EOF"
+ ✅ ANALYSE ABGESCHLOSSEN
+
+ Die Crew bestätigt: Dein Blockly-Code funktioniert!
+EOF
diff --git a/missions/evaluate_sign.sh b/missions/evaluate_sign.sh
new file mode 100755
index 0000000..2716791
--- /dev/null
+++ b/missions/evaluate_sign.sh
@@ -0,0 +1,60 @@
+#!/bin/bash
+# 🌿 Auswertung: Dein Zeichen im Wald
+
+# Waldwächter laden
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+source "${SCRIPT_DIR}/../lib/waldwaechter.sh"
+
+clear
+cat << "EOF"
+ 🌿 WALD-LOGBUCH EMPFÄNGER 🌿
+
+ Bitte füge dein "Zeichen" (JSON) aus dem Browser ein.
+ (Drücke danach ENTER und CTRL+D)
+EOF
+echo ""
+echo "👇 DATA DROP:"
+echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
+
+# Input lesen mit sed trick um nur valid JSON zu finden (wie bei evaluate_mission_data)
+INPUT_DATA=$(cat)
+
+echo ""
+echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
+echo "🔄 Analysiere Ästhetik und Inhalt..."
+sleep 1
+echo ""
+
+# JSON Extraction (Simple Grep/Sed Fallback)
+# Wir suchen nach "author" und "message"
+AUTHOR=$(echo "$INPUT_DATA" | grep -o '"author": *"[^"]*"' | cut -d'"' -f4)
+MESSAGE=$(echo "$INPUT_DATA" | grep -o '"message": *"[^"]*"' | cut -d'"' -f4)
+STYLE=$(echo "$INPUT_DATA" | grep -o '"style": *"[^"]*"' | cut -d'"' -f4)
+
+if [ -z "$AUTHOR" ]; then
+ echo "❌ Fehler: Konnte keinen Autor im JSON finden. Ist es das richtige Format?"
+ exit 1
+fi
+
+echo "✂️ Schnippsi begutachtet das Design..."
+if [[ "$STYLE" == "glassmorphism" ]]; then
+ echo " \"Ohhh, Glassmorphism! Sehr modern. Durchscheinend und elegant. 10/10 Style-Punkte!\" ✨"
+else
+ echo " \"Style: $STYLE. Interessant, aber ist es 'très chic'?\""
+fi
+echo ""
+sleep 1
+
+echo "🏛️ Templatus prüft die Struktur..."
+LENGTH=${#MESSAGE}
+echo " \"Die Nachricht ist $LENGTH Zeichen lang. Ein stabiler Block im DOM.\""
+echo ""
+sleep 1
+
+echo "🌶️ PepperPHP liest den Inhalt..."
+echo " \"Hallo $AUTHOR! Deine Nachricht wurde in den Baum geritzt:\""
+echo ""
+echo " 📝 \"$MESSAGE\""
+echo ""
+
+echo "🌳 Der Wald hat dein Zeichen angenommen."
diff --git a/release_notes.md b/release_notes.md
new file mode 100644
index 0000000..1a03a4d
--- /dev/null
+++ b/release_notes.md
@@ -0,0 +1,38 @@
+# 🌲 Crumbforest v0.0-RC3: "Dein Zeichen im Wald"
+
+**"Etwas bauen was noch keiner gebaut hat"** – Die Crumbblocks Ära beginnt!
+
+Dieser Release Candidate bringt das erste visuelle Design-Abenteuer in den Wald und verbindet die Browser-Welt mit dem Terminal.
+
+## 🎨 Neue Features
+
+### 1. Crumbblocks Integration
+- **Browser-to-Terminal Bridge:** Baue Code oder UI im Browser, schicke die Daten per Clipboard an die Crew im Terminal.
+- **Start-Helper:** `./start_crumbblocks.sh` startet automatisch lokalen Webserver (PHP/Python) und Browser.
+
+### 2. Neue Mission: "Dein Zeichen im Wald"
+- **Kategorie:** 🏆 Challenges
+- **Ziel:** Erstelle ein digitales "Blatt" mit HTML/CSS im Glassmorphism-Stil.
+- **Tech-Stack:** 100% Single-File HTML/CSS/JS. Keine externen deps.
+- **Workflow:**
+ 1. Intro mit Templatus & Schnippsi (`./missions/challenges/schnippsi_ui_design.sh`)
+ 2. Design im Browser (`crumbblocks/schnippsi_ui.html`)
+ 3. Auswertung & Feedback (`./evaluate_mission_data.sh`)
+
+### 3. Smart Evaluation Gateway
+- Das Skript `evaluate_mission_data.sh` ist jetzt intelligent!
+- Es erkennt automatisch, ob es sich um Roboter-Daten oder ein UI-Design handelt.
+- **Auto-Routing:** Leitet UI-JSON automatisch an Schnippsi (`evaluate_sign.sh`) weiter.
+
+### 4. Logging & Bugfixes
+- **Templatus & Schnippsi:** Pfad-Fehler (`/home/zero`) auf macOS behoben.
+- **Logging:** Alle Logs landen jetzt zuverlässig in deinem Repo-Ordner (`logs/`), wo sie hingehören.
+
+## 🤖 Crew Updates
+- **Schnippsi:** Hat jetzt ein Auge für Ästhetik und Glassmorphism.
+- **Templatus:** Baut stabile HTML5-Gerüste auch auf Mac.
+- **PepperPHP:** Backend-Logik für JSON-Export verbessert.
+
+---
+
+**"Der Wald ist nie fertig - er wächst mit jeder Idee!"** 🌱
diff --git a/start_crumbblocks.sh b/start_crumbblocks.sh
new file mode 100755
index 0000000..30e4868
--- /dev/null
+++ b/start_crumbblocks.sh
@@ -0,0 +1,71 @@
+#!/bin/bash
+# 🌍 Startet den Crumbblocks Server
+# Damit die Clipboard-API funktioniert, brauchen wir "localhost".
+# Dieses Script startet einen mini Python-Server und öffnet den Browser.
+
+# Waldwächter laden (für Pfade, optional)
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+ROOT_DIR="${SCRIPT_DIR}" # Wir starten direkt im Root
+
+# Port
+PORT=8123
+URL="http://localhost:${PORT}/crumbblocks/rainbow_counter.html"
+
+clear
+echo "🌍 CRUMBBLOCKS SERVER START"
+echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
+echo ""
+
+# Server-Auswahl (PHP bevorzugt via User-Request, sonst Python)
+if command -v php &>/dev/null; then
+ SERVER_CMD="php -S localhost:$PORT"
+ echo "🐘 PHP gefunden! Starte PHP Development Server..."
+elif command -v python3 &>/dev/null; then
+ SERVER_CMD="python3 -m http.server $PORT"
+ echo "🐍 Python 3 gefunden! Starte http.server..."
+elif command -v python &>/dev/null; then
+ SERVER_CMD="python -m http.server $PORT"
+ echo "🐍 Python gefunden! Starte http.server..."
+else
+ echo "❌ Weder PHP noch Python gefunden."
+ echo "Bitte installiere eines von beiden für den lokalen Server."
+ exit 1
+fi
+
+echo "🚀 Starte Server auf Port $PORT..."
+echo "👉 $URL"
+echo ""
+echo "Drücke [CTRL+C] um den Server zu stoppen."
+echo ""
+
+# Server im Hintergrund starten
+cd "$ROOT_DIR"
+# Wir führen den Befehl aus der Variable aus (shell splitting allowed here)
+$SERVER_CMD >/dev/null 2>&1 &
+SERVER_PID=$!
+
+# Warten bis Server da ist (kurz)
+sleep 1
+
+# Browser öffnen
+if [[ "$OSTYPE" == "darwin"* ]]; then
+ open "$URL"
+elif command -v xdg-open &>/dev/null; then
+ xdg-open "$URL"
+else
+ echo "⚠️ Konnte Browser nicht automatisch öffnen."
+ echo "Bitte öffne: $URL"
+fi
+
+# Auf CTRL+C warten (Trap für Cleanup)
+cleanup() {
+ echo ""
+ echo "🛑 Stoppe Server (PID $SERVER_PID)..."
+ kill "$SERVER_PID" 2>/dev/null
+ echo "✅ Tschüss!"
+ exit
+}
+trap cleanup SIGINT
+
+# Endlosschleife damit Script offen bleibt
+wait $SERVER_PID