diff --git a/deploy/agent-hooks/box-steckbrief-inject.sh b/deploy/agent-hooks/box-steckbrief-inject.sh new file mode 100644 index 0000000..251f886 --- /dev/null +++ b/deploy/agent-hooks/box-steckbrief-inject.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# pre_llm_call-Hook (Faden 5, 13.07.2026): verdrahtet Box-Selbstwissen MECHANISCH in +# JEDEN Kanban-Worker — egal welches Profil (werkstatt, default=Lucys Persona als Worker, +# kuenftige betrieb-/Ops-Profile). Der Kontext wird ephemer pro Turn an die User-Message +# angehaengt (agent/turn_context.py), NUR wenn eine Kanban-task_id gesetzt ist. Lucys +# interaktiver/Voice-Chat hat KEINE task_id → sofortiger No-op, kein Persona- oder +# Latenz-Eingriff. Loest Fallstrick #1 (Ops/Mess/Verify-Worker landen auf der am +# schlechtesten geruesteten Persona und flailen, weil sie llama-swap :8080 nicht kennen). +# Ausgabe {"context":"..."} = anhaengen; {} = durchlassen (No-op). +set -u +payload="$(cat -)" + +# Scope-Gate: nur echte Kanban-Worker (task_id gesetzt). Alles andere (Lucy-Chat, Voice, +# CLI, Telegram) faellt hier sofort raus — der Hook feuert zwar pro Turn, kostet aber nur +# ein jq und ist damit fuer den Voice-Pfad vernachlaessigbar. +task_id=$(printf %s "$payload" | jq -r '.extra.task_id // .task_id // ""' 2>/dev/null || echo "") +case "$task_id" in ""|null) printf '{}'; exit 0 ;; esac + +# Zeiger auf den vollen, naechtlich generierten Selbst-Steckbrief (nur wenn er existiert). +STECKBRIEF="$HOME/.hermes/state/selbst-steckbrief.md" +hint="" +[ -f "$STECKBRIEF" ] && hint=" Dein vollstaendiger Selbst-Steckbrief (aktuelle Versionen/Dienste/Modelle/Crons/offene Karten) liegt in $STECKBRIEF — dort nachlesen statt raten." + +# Stabile Anti-Flail-Orientierung: WER bin ich, WO laufen die Modelle, WAS ist tabu. +ctx="$(cat </dev/null || echo 0) +# Ein-Schuss: nach dem ersten Nudge nicht erneut nerven (Docs-Empfehlung). +if [ "$attempt" != "0" ]; then printf '{}'; exit 0; fi +mapfile -t paths < <(printf %s "$payload" | jq -r '.extra.changed_paths[]? // empty' 2>/dev/null) +[ ${#paths[@]} -eq 0 ] && { printf '{}'; exit 0; } +msgs=() + +# Gate 1: py_compile fuer alle geaenderten .py, die existieren +pyfail="" +for p in "${paths[@]}"; do + case "$p" in + *.py) + if [ -f "$p" ] && ! err=$(python3 -m py_compile "$p" 2>&1); then + pyfail="${pyfail}${p}: ${err}"$'\n' + fi + ;; + esac +done +if [ -n "$pyfail" ]; then + msgs+=("py_compile-Gate ROT:"$'\n'"${pyfail}Erst fixen, dann fertigmelden.") +fi + +# Gate 2: dist-Falle — frontend/src geaendert, aber kein frontend/dist angefasst. +# Feuert NUR in Repos mit der MC2-Konvention (frontend/dist ist git-getrackt) — +# sonst nudgt es in beliebigen Spielordnern ohne Build (False-Positive, 09.07. beobachtet). +srcfile=""; dist=0 +for p in "${paths[@]}"; do + case "$p" in + */frontend/src/*|frontend/src/*) srcfile="$p" ;; + */frontend/dist/*|frontend/dist/*) dist=1 ;; + esac +done +if [ -n "$srcfile" ] && [ $dist -eq 0 ]; then + # Repo-Wurzel vom geaenderten File aus hochlaufen (max 8 Ebenen). + root=$(dirname "$srcfile"); n=0 + while [ $n -lt 8 ] && [ -n "$root" ] && [ "$root" != "/" ] && [ ! -e "$root/.git" ]; do + root=$(dirname "$root"); n=$((n+1)) + done + if [ -e "$root/.git" ] && git -C "$root" ls-files frontend/dist 2>/dev/null | head -1 | grep -q .; then + msgs+=("AGENTS.md-Gate: Du hast frontend/src geaendert, aber frontend/dist nicht. Die Box baut NICHT selbst: cd frontend && npm run build, dann das neue dist im selben Branch mit-committen — sonst zeigt die Box nach Merge+Deploy den alten Stand.") + fi +fi + +if [ ${#msgs[@]} -eq 0 ]; then printf '{}'; exit 0; fi +joined=$(printf '%s\n\n' "${msgs[@]}") +jq --null-input --arg m "$joined" '{action:"continue", message:$m}' diff --git a/deploy/deploy.sh b/deploy/deploy.sh index 5889e51..92b6d70 100644 --- a/deploy/deploy.sh +++ b/deploy/deploy.sh @@ -119,6 +119,14 @@ chmod +x "$HOME/.hermes/scripts/pc_path_lookup.sh" # Portiert vom PC-Skill (F:\Coding Stuff\projekt-start), Zed-Verweise durch Hermes Desktop ersetzt. mkdir -p "$HOME/.hermes/skills/projekt-start" cp "$SRC/deploy/skills/projekt-start/SKILL.md" "$HOME/.hermes/skills/projekt-start/SKILL.md" +# Agent-Hooks (Faden 5, 13.07.2026): Skripte frisch halten (reproduzierbar, ueberlebt +# Box-Neuaufbau). box-steckbrief-inject.sh = Box-Selbstwissen in JEDEN Kanban-Worker +# (pre_llm_call, scoped auf task_id → Lucy-Chat unberuehrt); pre-verify-gates.sh = das +# bestehende py_compile/dist-Gate. Die REGISTRIERUNG in ~/.hermes/config.yaml (hooks:) +# ist EINMALIG von Hand (config.yaml ist Zwei-Schreiber-sensibel, kein Deploy-Schreiber). +mkdir -p "$HOME/.hermes/agent-hooks" +cp "$SRC/deploy/agent-hooks/box-steckbrief-inject.sh" "$SRC/deploy/agent-hooks/pre-verify-gates.sh" "$HOME/.hermes/agent-hooks/" +chmod +x "$HOME/.hermes/agent-hooks/box-steckbrief-inject.sh" "$HOME/.hermes/agent-hooks/pre-verify-gates.sh" # Eingebaute Hermes-Web-GUI (`hermes serve`) für die Einbettung in MC2 (routers/hermes_ui.py → # same-origin /hermes-ui/) vorbereiten: das SPA-Bundle mit Vite-base=/hermes-ui/ (neu) bauen, sonst # kollidieren seine absoluten Pfade (/assets, /api) mit MC2s eigenen. Läuft auch nach jedem