Planverfolgung über das lokale Kanban
Das Kanban existiert, damit Claude-Sitzungen über verschiedene Projekte und verschiedene Tage hinweg den Planstatus zwischen den Sitzungen lebendig halten können: Pläne beanspruchen, sie durch Status bewegen, Notizen hinterlassen. Mehrere Claude- Instanzen können sich ein Board teilen — gruppiere deine Arbeit immer unter einem Projekt-Slug, damit Pläne aus verschiedenen Repos nicht kollidieren.
Wenn du an einem nicht-trivialen Plan in einem Projekt auf einer Maschine arbeitest, auf der das Kanban läuft, solltest du während der Arbeit mit ihm sprechen.
Das Board
Quelle: https://github.com/hechtch/kanban — eine Angular-SPA plus eine Go-API über SQLite. Es läuft lokal; es gibt keine gehostete Instanz.
git clone https://github.com/hechtch/kanban.git
cd kanban
make container-build && make container-run # CONTAINER_RUNTIME=podman wenn du podman verwendest
make container-run veröffentlicht -p 8000:8000 und mountet
~/.kanban/data für die Persistenz, sodass ein einzelner Container sowohl die
UI als auch die API auf Port 8000 bereitstellt.
| Modus | UI für den Menschen | Agenten-API-Basis |
|---|---|---|
Container (make container-run) | http://localhost:8000/board | http://localhost:8000/api/agent |
Dev (make run) | http://localhost:4200/board | http://localhost:8000/api/agent |
Die Agenten-API ist in beiden Modi auf Port 8000 — nur der UI-Link für den Menschen
unterscheidet sich, weil make run den Angular-Dev-Server separat auf 4200 bereitstellt.
Verwende den UI-Link des Containers auf 8000, es sei denn, du weißt, dass der Benutzer
make run ausführt.
Wenn der Benutzer es woanders bereitgestellt hat (hinter einem Reverse-Proxy, einem
anderen veröffentlichten Port), wird er dir die Basis-URL nennen — nimm seine über den
Standardwert und behalte das Suffix /api/agent bei.
Läuft es?
KB=http://localhost:8000/api/agent
curl -sS http://localhost:8000/api/health
# {"status":"ok"}
Wenn das fehlschlägt, läuft das Kanban nicht. Starte es nicht selbst —
es schreibt in ~/.kanban/data/kanban.db und ein zweiter Prozess, der um diese
DB kämpft, ist schlimmer als keine Verfolgung. Sage dem Benutzer, dass es nicht läuft,
biete die make container-run-Zeile oben an und fahre mit der eigentlichen Arbeit
unverfolgt fort.
Kanonische Spezifikation — lies dies für alle Endpunkt-Details
Die API liefert eine vollständige OpenAPI 3.1-Spezifikation, die aus den typisierten Go- Handlern generiert wird. Sie ist die Quelle der Wahrheit für Pfade, Anfrage-/Antwortformate, Statuscodes und Validierungsregeln — im Zweifelsfall rufe sie ab, anstatt zu raten oder sich auf veraltete Dokumentation zu verlassen:
- Spezifikation (JSON):
http://localhost:8000/api/openapi.json - Spezifikation (YAML):
http://localhost:8000/api/openapi.yaml - Swagger UI (für Menschen):
http://localhost:8000/api/docs
Der Rest dieser Datei gibt dir den Agenten-Workflow (Slugs, Konventionen, Rezepte), damit du die API nicht von Grund auf neu lernen musst. Für Endpunktspezifika, die hier nicht abgedeckt sind, lies die Spezifikation.
Antworten enthalten ein $schema-URL-Feld, das auf das JSON-Schema der Antwort
verweist (Huma-Konvention). Ignoriere es, es sei denn, du validierst Antworten
gegen das Schema.
Die Plan-Datei-Konvention, die dieser Skill voraussetzt
Das Board verfolgt Pläne, und ein Plan ist eine Markdown-Datei im Repo:
plans/<thema>.md— eine Datei pro diskretem, laufendem Plan, die das Warum und Was beschreibt. Verwende Kontrollkästchen (- [ ]/- [x]) für umsetzbare Aufgaben und verfeinere sie direkt, während die Arbeit fortschreitet.plans/done/<thema>.md— wohin die Datei verschoben wird, sobald die Arbeit ausgeliefert oder aufgegeben wurde, mit einem kurzen "Ausgeliefert in — "-Header oben.CHANGELOG.md— das öffentliche "Was hat sich geändert", gepaart mitplans/done/das das Warum trägt.
Wenn ein Repo dieses Layout noch nicht verwendet, erstelle plans/ und füge die
Datei ein, bevor du sie auf dem Board beanspruchst — die Slug-Regel unten hängt
vom Dateinamen ab.
Die Slug-Regel
Alles ist über Slug geschlüsselt, niemals über eine numerische ID. Speichere niemals
eine task.id in deinen Prompts oder deinem Code.
- Plan-Slug = der Plan-Dateiname minus
.md, kleingeschrieben.plans/fotoimport.md→fotoimport. - Projekt-Slug = der Repo- oder Initiativname in Kebab-Schreibweise.
~/projects/fotoorganizer→fotoorganizer. (Für ein Projekt namens "Foto Organizer" leitet der Server automatischfotoorganizeraus dem Namen ab; du kannst auch einen expliziten Slug übergeben.) - Form (serverseitig erzwungen):
^[a-z0-9]([a-z0-9-]*[a-z0-9])?$. Schlechte Slugs geben400zurück. Kleinbuchstaben, Bindestriche zwischen Wörtern, keine Unterstriche oder Großbuchstaben.
Der Aufgabenkörper IST der Plan
Wenn du einen Plan zum ersten Mal beanspruchst, sende den Plan-Markdown als body-
Feld. Die Kanban-Datenbank ist von diesem Moment an maßgeblich — synchronisiere
Änderungen während des Flugs nicht zurück in die Datei. Die Datei plans/<slug>.md auf
der Festplatte ist der Samen (einmal verwendet); plans/done/<slug>.md ist die
Archiv-Schnappschuss, den du schreibst, wenn die Arbeit ausgeliefert wird.
Wenn du später erneut PUT mit einem neuen body ausführst, gewinnt deine Version.
Menschen können auch Tippfehler in der gerenderten Ansicht unter /task/<task_id>
in der UI korrigieren; beide Bearbeitungen landen in derselben Spalte.
Einen Plan zu beanspruchen macht ihn zu "Claudes"
Es gibt kein zu setzendes Bearbeiterfeld. Das Board leitet es ab: Eine Aufgabe, die
einen plan_slug trägt — genau das, was PUT /plans/<slug> erstellt — wird unter
Claude im Seitenleisten-Bearbeiterfilter angezeigt und erhält einen Claude-Chip
auf der Karte. Aufgaben, die der Mensch von Hand erstellt hat, haben keinen plan_slug
und bleiben unter dir.
Einen Plan über diese API zu beanspruchen ist also eine sichtbare Handlung. Beanspruche nicht die Arbeit, die der Mensch selbst erledigt, nur um eine Notiz darauf zu hinterlassen.
Status
Fünf Board-Spalten, festgelegt:
todo → doing → blocked → awaiting_merge → done
Plus backlog (außerhalb des Boards, optionaler 6.).
blocked— Arbeit kann nicht fortgesetzt werden; erkläre warum in einer Notiz.awaiting_merge— Code ist geschrieben und gepusht, wartet auf einen PR, der gemerged wird, oder eine manuelle Zusammenführung. Anders alsdone, weil die Arbeit noch nicht ausgeliefert ist.- Wechsle zu
doneerst, wenn der Branch tatsächlich in den Hauptzweig gemerged wurde. Keine automatische Überführung.
'waiting' ist kein gültiger Status — er wurde in einer Migration in 'blocked'
umbenannt.
Git-Branch
Pläne (und alle Aufgaben) können ein git_branch-Feld tragen — den Branch, auf dem
die Arbeit stattfindet. Setze es, wenn du einen Feature-Branch erstellst, damit der
Mensch es auf der Karte sehen kann:
curl -sS -X PUT $KB/plans/fotoimport \
-H 'Content-Type: application/json' \
-d '{"git_branch":"feat/fotoimport"}'
Lösche mit {"git_branch": null}. Der Branch wird als monospace Chip auf der Karte
angezeigt.
Vorgeschlagenes Modell und Aufwand
Jede Aufgabe kann ein model und einen effort tragen — ein Hinweis für denjenigen
Agenten, der die Arbeit als nächstes aufnimmt. Der Mensch setzt diese aus dem Ticket
(oder du kannst es, wenn du das Gewicht eines Plans kennst), und sie werden als
fable / xhigh-Chip auf der Karte angezeigt. Halte sie ein: Wenn du einen Plan
fortsetzt, dessen Aufgabe sonnet / high sagt, ist das die Stufe, die der Besitzer
dafür ausgeben will; ein fable / xhigh-Audit-Plan will das große Modell mit
hohem Aufwand.
curl -sS -X PUT $KB/plans/sicherheitsaudit \
-H 'Content-Type: application/json' \
-d '{"model":"fable","effort":"xhigh"}'
modelist eine freie Kurzform —fable,opus,sonnet,haikusind die Hausmarken; der Server wandelt in Kleinbuchstaben um und kürzt, und lehnt alles über 40 Zeichen ab.effortmuss einer vonlow,medium,high,xhigh,maxsein (die Reasoning-Effort-Stufen von Claude Code); alles andere gibt eine422.- Beide sind optional und unabhängig; lösche mit
null. Fehlend bedeutet "keine Präferenz — verwende die Sitzungsvoreinstellung".
Projekte: Archivieren und Standard-Tags
Ein Projekt trägt zwei Felder zusätzlich zu Name/Farbe, beide setzbar beim
selben PUT $KB/projects/<slug>-Upsert:
-
archived— das Projekt ist abgeschlossen. Seine Pläne fallen aus der Seitenleiste und vom Board (zusammengefaltet in einem "archivierten" Abschnitt, den der Mensch aufklappen kann), aber nichts wird gelöscht und jeder Endpunkt gibt sie weiterhin zurück. Setze es, wenn die Arbeit eines Projekts ausgeliefert wurde:curl -sS -X PUT $KB/projects/fotoorganizer \ -H 'Content-Type: application/json' -d '{"archived":true}' -
tags— taggt jede Aufgabe im Projekt. Der Server führt sie beim Lesen in dietagsjeder Aufgabe zusammen, sodass ein Plan unter einem Projekt, das mit["infra"]getaggt ist, alsinfragetaggt zurückkommt, ohne jemals einzeln getaggt worden zu sein. Ersetzt die gesamte Menge, wie Aufgaben-Tags:curl -sS -X PUT $KB/projects/fotoorganizer \ -H 'Content-Type: application/json' -d '{"tags":["medien","infra"]}'Da die Zusammenführung beim Lesen erfolgt, entfernt das Löschen eines Tags aus dem Projekt es sofort aus jeder Aufgabe. Setze kein Projekt-Tag einzeln auf seine Aufgaben — der Server entfernt geerbte Tags aus der eigenen Menge einer Aufgabe, also würdest du nur einen No-Op schreiben.
Workflow pro Sitzung
KB=http://localhost:8000/api/agent
# 1. Stelle sicher, dass dein Projekt existiert (idempotent — 201 beim ersten Mal, 200 danach).
curl -sS -X PUT $KB/projects/fotoorganizer \
-H 'Content-Type: application/json' \
-d '{"name":"Foto Organizer","color":"#d4654a"}'
# 2. Beanspruche den Plan + sende seinen aktuellen Body + setze ihn unter dein Projekt.
# Erster PUT erstellt mit status=todo; spätere PUTs patchen.
BODY=$(jq -Rs . < plans/fotoimport.md)
curl -sS -X PUT $KB/plans/fotoimport \
-H 'Content-Type: application/json' \
-d "{\"title\":\"Foto Import\",\"project_slug\":\"fotoorganizer\",\"body\":$BODY}"
# 3. Erstelle einen Feature-Branch und teile ihn dem Kanban mit.
git checkout -b feat/fotoimport
curl -sS -X PUT $KB/plans/fotoimport \
-H 'Content-Type: application/json' \
-d '{"git_branch":"feat/fotoimport"}'
# 4. Wechsle zu doing mit einer Notiz. Status-PUTs sind idempotent — gleicher Status
# ohne Notiz ist ein No-Op; mit Notiz wird ein Aktivitätseintrag geschrieben.
curl -sS -X PUT $KB/plans/fotoimport/status \
-H 'Content-Type: application/json' \
-d '{"status":"doing","note":"Phase 2 gestartet"}'
# 5. Hinterlasse Notizen während der Arbeit (günstiger als ein Statuswechsel).
curl -sS -X POST $KB/plans/fotoimport/notes \
-H 'Content-Type: application/json' \
-d '{"text":"Phase 2 abgeschlossen; führe Tests durch"}'
# 6. Wenn der PR offen ist, verschiebe zu awaiting_merge.
curl -sS -X PUT $KB/plans/fotoimport/status \
-H 'Content-Type: application/json' \
-d '{"status":"awaiting_merge","note":"PR #123 offen"}'
# 7. Sobald gemerged, wechsle zu done und archiviere die Datei.
curl -sS -X PUT $KB/plans/fotoimport/status \
-H 'Content-Type: application/json' \
-d '{"status":"done","note":"gemerged in v0.3.0"}'
# dann `git mv plans/fotoimport.md plans/done/fotoimport.md`
Erwähne den UI-Link des Menschen, wenn du gerade einen Plan erstellt oder verschoben hast —
http://localhost:8000/board (oder :4200 im Entwicklermodus).
Regeln und Fallstricke
- Status-Enum ist festgelegt:
todo,doing,blocked,awaiting_merge,done,backlog. Erfinde keine neuen. - Unbekanntes
project_sluggibt422 unknown project_slug "X"zurück — erstelle das Projekt vor der Zuweisung. Keine automatische, stille Erstellung. project_slug: ""löscht das Projekt, äquivalent zuproject_id: null.- Upsert ist echter Upsert —
PUT /plans/:slugmit{}ist dein "beanspruchen falls abwesend, patchen falls vorhanden"-Aufruf. Erneutes Ausführen dupliziert nicht; nur der erste Aufruf schreibt einencreate-Aktivitätseintrag. - Gleichstatus-Status-PUT ist ein No-Op, es sei denn, du übergibst eine
note. Nutze dies zu deinem Vorteil — du kannst sicher wiederholen. - Aktivitätslog ist append-only und sichtbar unter
$KB/plans/<slug>/activity. Verwende Notizen, um Brotkrumen zu hinterlassen ("Phase 2 abgeschlossen; starte Phase 3"), anstatt im Body zu erzählen. - Der Body ist Markdown, gerendert unter
/task/<task_id>in der UI. Verwende Standard-Markdown: Überschriften, Listen (einschließlich- [ ]/- [x]), Codeblöcke, Links. Tabellen und Blockzitate werden ebenfalls gerendert.
Wann man sich nicht darum kümmern sollte
- Einmalige Fehlerbehebungen, Refactorings, Dokumentationsanpassungen. Das Kanban verfolgt Pläne — mehrstufige Initiativen, die sich über Sitzungen erstrecken oder bedeutungsvollen Kontext tragen. Einzel-Commits brauchen kein Ticket.
- Wenn das Kanban-Repo selbst das Projekt ist, an dem du arbeitest, dokumentiert es seine eigenen
Konventionen in seiner
CLAUDE.md— lies diese stattdessen und ignoriere diese Datei. - Wenn der Health-Check fehlschlägt, läuft das Board nicht. Versuche nicht, es zu starten; fahre einfach fort und informiere den Benutzer.