Added autofix agent and loop

This commit is contained in:
Pit Friedrich
2026-07-25 20:37:28 +02:00
parent e477bbcc1f
commit 198988da35
5 changed files with 135 additions and 0 deletions
+13
View File
@@ -0,0 +1,13 @@
---
name: next-issue
description: Wählt das nächste zu bearbeitende Gitea-Issue und gibt nur die Kerndaten zurück.
tools: mcp__gitea__list_issues, mcp__gitea__issue_read
model: haiku
---
Finde das nächste offene Issue im Repo <owner>/<repo> mit Label `ai-ready`
und NICHT mit Label `ai-wip` oder `ai-blocked`.
Priorisiere nach `prio/high` > `prio/medium` > `prio/low`, dann nach ältestem.
Gib AUSSCHLIESSLICH eine Zeile aus, sonst nichts:
- Wenn eins gefunden: `ISSUE=<nummer>`
- Wenn keins offen: `ISSUE=NONE`
+40
View File
@@ -0,0 +1,40 @@
---
description: Behebt ein einzelnes Gitea-Issue Ende-zu-Ende.
argument-hint: <issue-nummer>
allowed-tools: >
Bash, Edit, Read, Write, Grep, Glob,
mcp__gitea__issue_read, mcp__gitea__issue_write,
mcp__gitea__label_read,
mcp__gitea__pull_request_write
model: opus
---
Bearbeite Gitea-Issue #$1 im aktuellen Repo. Schritt für Schritt:
**Label-Regeln (wichtig):** Die Gitea-Label-API arbeitet mit numerischen
Label-IDs, nicht mit Namen. Hole daher ZUERST einmalig die Label-Liste über
`label_read` (`method: list_repo_labels`) und merke dir die Zuordnung
Name → ID für die gesamte Bearbeitung. Verwende ausschließlich `add_labels`
(mit `labels: [<id>]`) und `remove_label` (mit `label_id: <id>`).
Niemals `replace_labels` oder `clear_labels` benutzen — das löscht alle
übrigen Labels des Issues (z.B. `prio/*`).
1. Lies Issue #$1 (Titel, Beschreibung, Kommentare) über `issue_read`.
Notiere die aktuell gesetzten Labels, damit du sie nicht verlierst.
2. Hole die Label-Liste via `label_read`. Setze Label `ai-wip`
(`add_labels`), entferne `ai-ready` (`remove_label`).
3. Analysiere das Repo und finde die Ursache. Wenn der Scope zu groß/unklar
ist (siehe CLAUDE.md), brich ab: kommentiere das Issue mit einer kurzen
Begründung, setze `ai-blocked`, und beende ohne Codeänderung.
4. Implementiere den Fix. Halte den Diff minimal und fokussiert.
5. Führe die Tests aus (`<dein Testkommando>`). Bei Rot: bis zu 2x nachbessern.
Wenn danach immer noch rot → `ai-blocked`, Issue kommentieren, abbrechen.
6. Commit mit Message: `fix: <kurze Beschreibung> (#$1)`.
7. Push den aktuellen Branch zum Remote.
8. Öffne via `pull_request_write` einen PR gegen `main` (bzw. `develop`).
Die PR-Beschreibung MUSS `Closes #$1` enthalten.
9. Kommentiere am Issue mit dem PR-Link, setze Label `ai-review`
(`add_labels`) und entferne `ai-wip` (`remove_label`).
Wenn du in einem Schritt `ai-blocked` setzt, entferne ebenfalls `ai-wip`.
Existiert ein benötigtes Label nicht im Repo, kommentiere das am Issue statt
zu raten — erfinde keine Label-IDs.
+12
View File
@@ -0,0 +1,12 @@
# Normalize line endings independent of core.autocrlf.
* text=auto
# Maven wrapper: POSIX shell script must stay LF, even on Windows checkouts.
mvnw text eol=lf
*.sh text eol=lf
# Windows batch wrapper needs CRLF.
mvnw.cmd text eol=crlf
# Binaries: never convert.
*.jar binary
+9
View File
@@ -37,3 +37,12 @@ Since `apex-chart.ts` renders into light DOM (`createRenderRoot()` returns `this
**Styling**: `src/main/resources/META-INF/resources/styles.css` is the one project-level stylesheet (loaded via `@StyleSheet("styles.css")` in `Application.java`). It defines `--dialect-*` design tokens (Dialect design system: primary orange `#E86C00`, cool-gray background, card radius/shadow) and aliases them onto Aura's own CSS custom properties (`--aura-accent-color-*`, `--aura-background-color-*`, `--aura-orange`, `--aura-yellow`) rather than fighting the theme. Aura tokens use OKLCH + relative-color syntax and accept plain hex overrides. When restyling, prefer extending this alias layer over hardcoding new colors in components.
UI copy/data (chart labels, notifications) is in German.
## AI-Autofix Regeln
- Nur Issues mit Label `ai-ready` bearbeiten.
- Branch-Namensschema: `ai/issue-<nr>-<kurz-slug>`.
- Kein Fix ohne grüne Tests. Test-Befehl: `<dein Testkommando>`.
- Bei Unklarheit / Scope > ~200 Zeilen Diff: NICHT fixen,
stattdessen Issue kommentieren ("needs human") und Label `ai-blocked` setzen.
- PR-Beschreibung MUSS `Closes #<nr>` enthalten.
- Keine Änderungen an <kritische Pfade, z.B. build config, Migrations> ohne Freigabe.
+61
View File
@@ -0,0 +1,61 @@
#!/usr/bin/env bash
set -euo pipefail
source .env
REPO_DIR="$HOME/codebase/chart-app" # Haupt-Klon
BASE_BRANCH="main"
TEST_CMD="./mvnw test" # z.B. ./gradlew test
MAX_ISSUES=5 # pro Durchlauf, damit du nicht davonläufst
POLL_INTERVAL=120 # Sekunden zwischen Polls (0 = einmal laufen)
cd "$REPO_DIR"
process_next() {
git -C "$REPO_DIR" fetch origin "$BASE_BRANCH" --quiet
git -C "$REPO_DIR" checkout "$BASE_BRANCH" --quiet
git -C "$REPO_DIR" pull --quiet
# 1) Nächstes Issue holen (Sub-Agent, minimaler Output)
local out
out=$(claude -p "Nutze den Sub-Agent 'next-issue'. Gib NUR dessen Rueckgabezeile aus (ISSUE=<nr> oder ISSUE=NONE), keinen weiteren Text." \
--allowedTools "Agent,mcp__gitea__list_issues,mcp__gitea__issue_read" \
--output-format text)
local nr
nr=$(echo "$out" | grep -oE 'ISSUE=[0-9NONE]+' | cut -d= -f2)
if [[ "$nr" == "NONE" || -z "$nr" ]]; then
echo "Keine offenen ai-ready Issues."
return 1
fi
echo ">>> Bearbeite Issue #$nr"
local wt="../wt-issue-$nr"
local branch="ai/issue-$nr"
# 2) Isolierter Worktree + Branch
git worktree add -b "$branch" "$wt" "$BASE_BRANCH" --quiet
# 3) Worker im Worktree ausführen (autonom)
(
cd "$wt"
claude -p "/fix-issue $nr" \
--allowedTools "Bash($TEST_CMD),Bash(git *),Edit,Read,Write,Grep,Glob,mcp__gitea__issue_read,mcp__gitea__issue_write,mcp__gitea__label_read,mcp__gitea__pull_request_write" \
--output-format text
) || echo "!!! Worker für #$nr mit Fehler beendet"
# 4) Aufräumen
git worktree remove "$wt" --force || true
return 0
}
# --- Hauptschleife ---
while true; do
count=0
while (( count < MAX_ISSUES )); do
if process_next; then ((count++)); else break; fi
done
echo "Durchlauf fertig ($count Issues)."
(( POLL_INTERVAL == 0 )) && break
sleep "$POLL_INTERVAL"
done