Compare commits

..
5 Commits
Author SHA1 Message Date
martin f2b8bdd86b chore: Settings auf auto-Modus und herdr-Hook anpassen 2026-09-20 08:01:56 +02:00
martinandClaude Opus 5 012e87064a chore: herdr-SessionStart-Hook aufnehmen
Von herdr generiertes Script, das die Claude-Session an den herdr-Socket
meldet. Wird von herdr-Updates ueberschrieben.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-20 07:52:54 +02:00
martinandClaude Opus 5 9302f0b222 docs: Erledigtes ersatzlos loeschen statt markieren
Abgehakte Eintraege und Mess-Metadaten ohne Aussagekraft blaehen
Dokumente auf, ohne Information zu tragen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-20 07:51:11 +02:00
martin e290dbe7a4 Merge branch 'main' of https://gitea.troeger-net.org/martin/claude-workflow 2026-09-20 07:49:59 +02:00
martinandClaude Opus 5 a7e9e0d55e feat: Superpowers-Plugin im Workflow verankern
Deklaration in settings.json statt Vendorn der Skill-Dateien, damit
Upstream-Updates weiter greifen. bootstrap.sh installiert das Plugin auf
neuen Maschinen und aktualisiert es bei jedem Lauf.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-20 07:49:30 +02:00
4 changed files with 140 additions and 4 deletions
+13
View File
@@ -145,6 +145,19 @@ echo ""
echo "=== Claude-Code-Integrationen ==="
if command -v claude &>/dev/null; then
if claude plugin list 2>/dev/null | grep -q "superpowers@superpowers-marketplace"; then
claude plugin marketplace update superpowers-marketplace &>/dev/null || true
claude plugin update superpowers@superpowers-marketplace &>/dev/null || true
echo " OK superpowers Plugin (aktualisiert)"
else
claude plugin marketplace add obra/superpowers-marketplace &>/dev/null || true
if claude plugin install superpowers@superpowers-marketplace &>/dev/null; then
echo " OK superpowers Plugin installiert"
else
echo " FEHLT superpowers Plugin -- claude plugin install superpowers@superpowers-marketplace"
fi
fi
if claude mcp list 2>/dev/null | grep -q "context7"; then
echo " OK context7 Plugin"
else
+2
View File
@@ -8,6 +8,8 @@ Alle Texte, Kommentare und Kommunikation auf Deutsch. Technische Begriffe und Co
**Immer AsciiDoc (`.adoc`) statt Markdown** für alle Dokumente (Analysen, Pläne, Berichte, Anfragen usw.). Neue Dokumente als `.adoc` anlegen. Bestehende `.md`-Dateien nur auf ausdrücklichen Wunsch konvertieren. Ausnahmen: von Tools erzwungene Dateien (`CLAUDE.md`, `MEMORY.md`, `README.md` wo vom Workflow verlangt) bleiben Markdown.
**Erledigtes wird gelöscht, nicht markiert.** In Listen offener Punkte einen erledigten Eintrag ersatzlos entfernen — kein „erledigt"-Vermerk, kein Durchstreichen. Ebenso keine Metadaten ohne Aussagekraft (Mess-/Erhebungsdatum), wenn nur der Wert zählt.
## Entwicklungsprinzipien
- **Single Responsibility:** Jede Datei, jede Funktion hat genau eine Aufgabe
+25 -4
View File
@@ -60,8 +60,9 @@
"Bash(docker *)",
"Bash(which *)"
],
"defaultMode": "default"
"defaultMode": "auto"
},
"model": "opus",
"hooks": {
"UserPromptSubmit": [
{
@@ -105,6 +106,18 @@
}
]
}
],
"SessionStart": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "bash '/home/martin/.claude/hooks/herdr-agent-state.sh' session",
"timeout": 10
}
]
}
]
},
"statusLine": {
@@ -117,11 +130,19 @@
"context7@claude-plugins-official": true,
"code-review@claude-plugins-official": true,
"code-simplifier@claude-plugins-official": true,
"skill-creator@claude-plugins-official": true
"skill-creator@claude-plugins-official": true,
"superpowers@superpowers-marketplace": true
},
"extraKnownMarketplaces": {
"superpowers-marketplace": {
"source": {
"source": "github",
"repo": "obra/superpowers-marketplace"
}
}
},
"language": "German",
"tui": "fullscreen",
"editorMode": "vim",
"terminalProgressBarEnabled": false,
"model": "opus"
"terminalProgressBarEnabled": false
}
+100
View File
@@ -0,0 +1,100 @@
#!/bin/sh
# installed by herdr
# managed by herdr; reinstalling or updating the integration overwrites this file.
# add custom hooks beside this file instead of editing it.
# HERDR_INTEGRATION_ID=claude
# HERDR_INTEGRATION_VERSION=9
set -eu
action="${1:-}"
hook_input_file="$(mktemp "${TMPDIR:-/tmp}/herdr-claude-hook.XXXXXX")" || exit 0
trap 'rm -f "$hook_input_file"' EXIT HUP INT TERM
cat >"$hook_input_file" 2>/dev/null || true
case "$action" in
session) ;;
*) exit 0 ;;
esac
[ "${HERDR_ENV:-}" = "1" ] || exit 0
[ -n "${HERDR_SOCKET_PATH:-}" ] || exit 0
[ -n "${HERDR_PANE_ID:-}" ] || exit 0
command -v python3 >/dev/null 2>&1 || exit 0
HERDR_ACTION="$action" HERDR_HOOK_INPUT_FILE="$hook_input_file" python3 - <<'PY'
import json
import os
import random
import socket
import time
source = "herdr:claude"
action = os.environ.get("HERDR_ACTION", "")
pane_id = os.environ.get("HERDR_PANE_ID")
socket_path = os.environ.get("HERDR_SOCKET_PATH")
hook_input_file = os.environ.get("HERDR_HOOK_INPUT_FILE")
if not pane_id or not socket_path:
raise SystemExit(0)
hook_input = {}
if hook_input_file:
try:
with open(hook_input_file, encoding="utf-8") as handle:
content = handle.read()
if content.strip():
hook_input = json.loads(content)
except Exception:
hook_input = {}
if "CURSOR_VERSION" in os.environ or "cursor_version" in hook_input:
raise SystemExit(0)
hook_event_name = str(hook_input.get("hook_event_name") or "")
if hook_event_name != "SessionStart":
raise SystemExit(0)
is_subagent = bool(hook_input.get("agent_id"))
if is_subagent:
raise SystemExit(0)
request_id = f"{source}:{int(time.time() * 1000)}:{random.randrange(1_000_000):06d}"
report_seq = time.time_ns()
session_id = hook_input.get("session_id")
agent_session_id = session_id if isinstance(session_id, str) and session_id else None
transcript_path = hook_input.get("transcript_path")
agent_session_path = transcript_path if isinstance(transcript_path, str) and transcript_path else None
session_start_source = hook_input.get("source") if hook_event_name == "SessionStart" else None
if not isinstance(session_start_source, str) or not session_start_source:
session_start_source = None
if agent_session_id:
params = {
"pane_id": pane_id,
"source": source,
"agent": "claude",
"seq": report_seq,
"agent_session_id": agent_session_id,
}
if agent_session_path:
params["agent_session_path"] = agent_session_path
if session_start_source:
params["session_start_source"] = session_start_source
request = {
"id": request_id,
"method": "pane.report_agent_session",
"params": params,
}
else:
raise SystemExit(0)
try:
client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
client.settimeout(0.5)
client.connect(socket_path)
client.sendall((json.dumps(request) + "\n").encode())
try:
client.recv(4096)
except Exception:
pass
client.close()
except Exception:
pass
PY