Initial: GPU1-Hooks + Auto-Update + Deploy-Script
This commit is contained in:
parent
58bf4f71b7
commit
7e19208061
25
deploy.sh
Normal file
25
deploy.sh
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#!/bin/bash
|
||||
# Claude Hooks Deploy — läuft auf jedem neuen Mac/Hub-Instanz einmalig
|
||||
# curl -sL https://git.consoro.eu/barby/claude-hooks/raw/branch/main/deploy.sh | bash
|
||||
|
||||
set -e
|
||||
HOOKS_REPO="https://barby:dc9a2241890acb243548342977a6c02d6dde39a7@git.consoro.eu/barby/claude-hooks.git"
|
||||
CLAUDE_DIR="$HOME/.claude"
|
||||
HOOKS_DIR="$CLAUDE_DIR/hooks-v2"
|
||||
LOCAL_REPO="$HOME/git/claude-hooks"
|
||||
|
||||
echo "=== Claude Hooks Deploy ==="
|
||||
mkdir -p "$HOOKS_DIR" "$LOCAL_REPO"
|
||||
|
||||
if [ ! -d "$LOCAL_REPO/.git" ]; then
|
||||
git clone "$HOOKS_REPO" "$LOCAL_REPO"
|
||||
else
|
||||
cd "$LOCAL_REPO" && git pull origin main -q
|
||||
fi
|
||||
|
||||
# Scripts deployen
|
||||
cp "$LOCAL_REPO/hooks-v2/"*.sh "$HOOKS_DIR/" 2>/dev/null
|
||||
chmod +x "$HOOKS_DIR/"*.sh
|
||||
|
||||
echo "✅ $(ls $HOOKS_DIR/*.sh | wc -l | tr -d ' ') Hook-Scripts deployed nach $HOOKS_DIR"
|
||||
echo "Fertig — bitte Claude Code neu starten."
|
||||
25
hooks-v2/gpu1-master-workflow.sh
Executable file
25
hooks-v2/gpu1-master-workflow.sh
Executable file
|
|
@ -0,0 +1,25 @@
|
|||
#!/bin/bash
|
||||
# GPU1-Shadow-Portal MASTER Workflow Hook
|
||||
# Läuft bei jedem UserPromptSubmit wenn CWD = Claude_desktop Projekt
|
||||
|
||||
MASTER="/Users/matthiaskoerner/Library/Mobile Documents/iCloud~md~obsidian/Documents/GPU1-Shadow-Portal-MASTER-2026-07.md"
|
||||
|
||||
# Nur aktiv wenn wir im richtigen Projekt sind
|
||||
CWD_CHECK="${CLAUDE_PROJECT_DIR:-$PWD}"
|
||||
if [[ "$CWD_CHECK" != *"Claude_desktop"* ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ ! -f "$MASTER" ]; then
|
||||
echo "⚠️ MASTER-DOK FEHLT: $MASTER"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Letztes Update + offene Tasks zählen
|
||||
LAST_MOD=$(stat -f "%Sm" -t "%d.%m %H:%M" "$MASTER" 2>/dev/null || echo "?")
|
||||
OPEN=$(grep -c "^\- \[ \]" "$MASTER" 2>/dev/null || echo "?")
|
||||
IN_PROG=$(grep -c "🔄\|in_progress\|⏳" "$MASTER" 2>/dev/null || echo "0")
|
||||
|
||||
echo "📋 MASTER-PROTOKOLL: GPU1-Shadow-Portal-MASTER-2026-07.md"
|
||||
echo " Letztes Update: $LAST_MOD | Offene Tasks: $OPEN | In Arbeit: $IN_PROG"
|
||||
echo " WORKFLOW-PFLICHT: (1) MASTER lesen → (2) Plan mit Bär besprechen → (3) GO abwarten → (4) /swarm → (5) Funktionstest → (6) MASTER+Obsidian+GitLab updaten"
|
||||
33
hooks-v2/sessionstart-hook-autoupdate.sh
Normal file
33
hooks-v2/sessionstart-hook-autoupdate.sh
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#!/bin/bash
|
||||
# SessionStart: Hook-Scripts automatisch vom Hub aktualisieren (max 1x/Stunde)
|
||||
LOCK="/tmp/claude-hooks-update.lock"
|
||||
LOCAL_REPO="$HOME/git/claude-hooks"
|
||||
HOOKS_DIR="$HOME/.claude/hooks-v2"
|
||||
LAST_UPDATE="$HOME/.claude/hooks-v2/.last-update"
|
||||
|
||||
# Max 1x pro Stunde updaten
|
||||
if [ -f "$LAST_UPDATE" ]; then
|
||||
LAST=$(cat "$LAST_UPDATE" 2>/dev/null || echo 0)
|
||||
NOW=$(date +%s)
|
||||
DIFF=$((NOW - LAST))
|
||||
[ $DIFF -lt 3600 ] && exit 0
|
||||
fi
|
||||
|
||||
# Nicht parallel laufen
|
||||
[ -f "$LOCK" ] && exit 0
|
||||
touch "$LOCK"
|
||||
trap "rm -f $LOCK" EXIT
|
||||
|
||||
if [ -d "$LOCAL_REPO/.git" ]; then
|
||||
cd "$LOCAL_REPO"
|
||||
BEFORE=$(git rev-parse HEAD 2>/dev/null)
|
||||
git pull origin main -q 2>/dev/null
|
||||
AFTER=$(git rev-parse HEAD 2>/dev/null)
|
||||
if [ "$BEFORE" != "$AFTER" ]; then
|
||||
cp "$LOCAL_REPO/hooks-v2/"*.sh "$HOOKS_DIR/" 2>/dev/null
|
||||
chmod +x "$HOOKS_DIR/"*.sh
|
||||
echo "🔄 Claude Hooks aktualisiert von Hub"
|
||||
fi
|
||||
fi
|
||||
|
||||
date +%s > "$LAST_UPDATE"
|
||||
76
hooks-v2/stop-chat-snapshot.sh
Executable file
76
hooks-v2/stop-chat-snapshot.sh
Executable file
|
|
@ -0,0 +1,76 @@
|
|||
#!/bin/bash
|
||||
# Stop-Hook: Chat-Snapshot nach jeder Antwort — NUR für Claude_desktop Projekt
|
||||
|
||||
CWD_CHECK="${CLAUDE_PROJECT_DIR:-$PWD}"
|
||||
if [[ "$CWD_CHECK" != *"Claude_desktop"* ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
PROJECT_DIR="/Users/matthiaskoerner/Library/Mobile Documents/com~apple~CloudDocs/Claude_desktop"
|
||||
STATUS_MD="$PROJECT_DIR/status.md"
|
||||
JSONL_DIR="/Users/matthiaskoerner/.claude/projects/-Users-matthiaskoerner-Library-Mobile-Documents-com-apple-CloudDocs-Claude-desktop"
|
||||
|
||||
JSONL=$(ls -t "$JSONL_DIR"/*.jsonl 2>/dev/null | head -1)
|
||||
[ -z "$JSONL" ] && exit 0
|
||||
|
||||
python3 - "$JSONL" "$STATUS_MD" << 'PYEOF'
|
||||
import sys, json, os
|
||||
from datetime import datetime
|
||||
|
||||
jsonl_path, out_path = sys.argv[1], sys.argv[2]
|
||||
|
||||
lines = []
|
||||
try:
|
||||
with open(jsonl_path) as f:
|
||||
lines = f.readlines()
|
||||
except:
|
||||
sys.exit(0)
|
||||
|
||||
msgs = []
|
||||
for line in lines[-60:]:
|
||||
try:
|
||||
entry = json.loads(line)
|
||||
if entry.get("type") == "user":
|
||||
msg = entry.get("message", {})
|
||||
txt = ""
|
||||
if isinstance(msg.get("content"), str):
|
||||
txt = msg["content"]
|
||||
elif isinstance(msg.get("content"), list):
|
||||
for c in msg["content"]:
|
||||
if isinstance(c, dict) and c.get("type") == "text":
|
||||
txt += c.get("text", "")
|
||||
if txt.strip():
|
||||
msgs.append(("Bär", txt.strip()[:600]))
|
||||
elif entry.get("type") == "assistant":
|
||||
msg = entry.get("message", {})
|
||||
txt = ""
|
||||
if isinstance(msg.get("content"), list):
|
||||
for c in msg["content"]:
|
||||
if isinstance(c, dict) and c.get("type") == "text":
|
||||
txt += c.get("text", "")
|
||||
if txt.strip():
|
||||
msgs.append(("Barby", txt.strip()[:1000]))
|
||||
except:
|
||||
continue
|
||||
|
||||
if not msgs:
|
||||
sys.exit(0)
|
||||
|
||||
existing = ""
|
||||
if os.path.exists(out_path):
|
||||
with open(out_path) as f:
|
||||
existing = f.read()
|
||||
|
||||
last_txt = msgs[-1][1] if msgs else ""
|
||||
if last_txt and last_txt[:80] in existing[-3000:]:
|
||||
sys.exit(0) # kein Duplikat
|
||||
|
||||
ts = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
content = f"\n---\n### {ts}\n"
|
||||
for role, text in msgs[-4:]:
|
||||
icon = "🧔" if role == "Bär" else "🤖"
|
||||
content += f"**{icon} {role}:** {text}\n\n"
|
||||
|
||||
with open(out_path, "a") as f:
|
||||
f.write(content)
|
||||
PYEOF
|
||||
18
hooks-v2/sync-chat-status-gitlab.sh
Executable file
18
hooks-v2/sync-chat-status-gitlab.sh
Executable file
|
|
@ -0,0 +1,18 @@
|
|||
#!/bin/bash
|
||||
# Alle 2min: status.md aus Claude_desktop → git.consoro.eu/barby/claude-chat-status
|
||||
|
||||
STATUS_SRC="/Users/matthiaskoerner/Library/Mobile Documents/com~apple~CloudDocs/Claude_desktop/status.md"
|
||||
REPO_DIR="/Users/matthiaskoerner/git/claude-chat-status"
|
||||
|
||||
[ ! -f "$STATUS_SRC" ] && exit 0
|
||||
|
||||
cp "$STATUS_SRC" "$REPO_DIR/status.md"
|
||||
|
||||
cd "$REPO_DIR" || exit 1
|
||||
git add status.md
|
||||
if git diff --cached --quiet; then
|
||||
exit 0 # nix geändert
|
||||
fi
|
||||
|
||||
git commit -m "auto-sync $(date '+%H:%M:%S')" --author="Barby <barby@consoro.eu>" -q
|
||||
git push origin main -q 2>&1 | logger -t claude-chat-sync
|
||||
Loading…
Reference in a new issue