Eine fundierte Einführung in das KantaiKit-Flottensystem: warum es so gebaut ist, wie die Rollen (Emperor / Commander / Officer) zusammenspielen, wie die Pane-Verwaltung über die iTerm-API läuft, und wie Missionen mit Code- und QA-Review durchgearbeitet werden. Geschrieben von „Emperor Whitebeard” (Cihats Indie-Flotte) für seinen Bruder, der KantaiKit selbst einsetzen will.
KantaiKit ist eine Methode + ein leichtes Werkzeug-Set, um mehrere Claude-Code-Sessions wie eine kleine, sichtbare „Flotte” zu orchestrieren: ein Mensch (du) steuert oben, darunter arbeiten KI-Agenten an Projekten, jeder in seinem eigenen sichtbaren iTerm-Pane, das du beobachten, anstupsen und bei Hängern fortsetzen kannst.
Es gibt zwei Ebenen, die zusammen das ergeben, was später eine eigene App (das „Flagship”-Produkt) machen soll. Das hier ist die Zwischenlösung: nur iTerm-Panes + ein paar Shell-Skripte + Claude-Code-Skills. Kein Server, keine fremde Cloud.
Drei Dinge sind das Herz:
1. Eine klare Rollen-Hierarchie (Emperor → Commander → Officer), jeweils eine Claude-Session pro Rolle.
2. Pane-Verwaltung über die iTerm2-Python-API (das it2-CLI), damit eine Session eine andere lesen, anschreiben und überwachen kann.
3. Eine disziplinierte Missions-Pipeline (Alignment → Requirements → Mission Board → Umsetzung → Multi-Visor-Review → Closeout), abgeleitet aus Matt Pococks Vertical-Slice-/Grill-me-Ansatz und John Ousterhouts „deep modules”.
Wenn man Claude Code „einfach so” für ein größeres Projekt nutzt, passieren vier Dinge zuverlässig:
Task/Subagent auf, siehst du den Fortschritt nicht, kannst ihn nicht fortsetzen, und Limits/Stalls sind nicht diagnostizierbar.KantaiKit kombiniert bewusst drei Denkschulen:
| Vorteil | Wie KantaiKit es erreicht |
|---|---|
| Man baut das Richtige | Alignment-Interview + Mission Requirements zwingen zur Abstimmung, bevor Code entsteht. |
| Sichtbarkeit & Kontrolle | Jede echte Arbeit läuft in einem sichtbaren Pane, das du beobachten/fortsetzen kannst – nie in unsichtbaren Subagents. |
| Echtes Vier-Augen-Prinzip | Multi-Visor: ein Code Reviewer (mit Quellcode) UND ein QA Reviewer (ohne Quellcode, fährt die laufende App) prüfen unabhängig. Plus optional Codex als Cross-Modell-Reviewer. |
| Parallelität mit Überblick | Mehrere Divisionen/Officer laufen gleichzeitig; die Hierarchie + ein Watcher-Daemon halten den Überblick. |
| Kontext-Hygiene | Jeder Officer hat seinen eigenen Kontext – die Implementierungs-Details verstopfen nicht den Kontext des Commanders. |
| Kontinuierlicher Mehrwert | Vertical Slices + „Usefulness Checkpoints” sorgen dafür, dass nach jedem Schritt etwas Benutzbares da ist. |
| Compaction-fest | Alles Wichtige steht in Artefakten (Alignment Report, Mission Board, AGENTS.md) – nach einem Kontext-Reset liest die Session sich selbst wieder ein. |
Eine Claude-Code-Session pro Rolle. Die Hierarchie ist streng top-down: die obere Ebene liest den Zustand der unteren und reagiert; die untere meldet nichts aktiv „nach oben” (sie wird beobachtet).
Mensch (Developer)
│
▼
Emperor eine Session, cwd = Workspace-Root (z.B. ~/Developer/MeinZeug/)
│ überwacht ALLE Division Commander, routet deine Wünsche an die richtige Division
▼ beobachtet
Division Commander eine Session PRO Projekt, cwd = Projekt-Repo
│ besitzt die Missions-Pipeline, überwacht seine Officer, pflegt das Backlog
▼ beobachtet
Officer eine Session pro Missions-Aufgabe, sichtbares Pane
Sub-Rollen: Planner · Implementer · Code Reviewer · QA Reviewer · Merger
Emperor – die Flotten-Ebene. Sitzt im Workspace-Root, kennt alle Divisionen, leitet Intent an die richtige weiter, fängt flotten-weite Signale ab (z.B. „eine Division ist abgestürzt”, „eine wartet auf eine Entscheidung”). Trifft irreversible/flotten-weite Entscheidungen oder eskaliert sie an den Menschen.
Division Commander – die Projekt-Ebene. Eine pro aktivem Projekt, läuft im Repo des Projekts. Führt die Mission-Pipeline (siehe §4), zerlegt Arbeit in Aufgaben, schickt Officer los, sichert Fortschritt, sammelt aufgeschobene Punkte im Backlog (<Repo>/.kantai/Backlog.md). Der Commander schreibt nicht selbst Code – er definiert und überwacht.
Officer – die Arbeits-Ebene. Mission-gebundene Worker, jeder in einem sichtbaren iTerm-Split-Pane. Sub-Rollen mit strikter „Lane-Discipline”: - Planner – wählt fertige Aufgaben, klärt Reihenfolge/Parallelisierungs-Konflikte, brieft den Implementer. - Implementer – schreibt den Code, TDD red-green-refactor, übergibt mit striktem Handoff (erledigt / offen / Befehle-mit-Exit-Codes / Issues / Red-Green-Beweis). - Code Reviewer – liest Code, Tests/Lint/Konventionen, schlägt Findings vor, fixt nie selbst. - QA Reviewer – fährt die laufende App, liest keinen Code. - Merger – führt zusammen.
Die wichtigste Regel überhaupt: Echte Missions-Arbeit (Implementierung, Review) läuft IMMER in einem sichtbaren Officer-Pane, NIE in einem unsichtbaren Subagent. Grund: Du musst jeden Worker sehen, bei Hängern fortsetzen und Limits/Stalls diagnostizieren können. Das
Task/Subagent-Tool ist nur für kleine, read-only Unter-Aufgaben innerhalb einer Session erlaubt (eine breite Code-Suche, ein Datei-Scan) – niemals für trackbare Arbeit.
Jede Emperor-/Commander-Session bekommt einen stabilen Namen (in Cihats Flotte: Whitebeard-Piraten aus One Piece, z.B. Emperor Whitebeard, Commander Ace · DojoKame). Officer bleiben aufgaben-benannt (Projekt · Officer Implementer T8), weil sie temporär sind. Das macht die iTerm-Tab-/Pane-Liste auf einen Blick lesbar.
Das ist das technische Fundament: Wie kann eine Claude-Session eine andere Session starten, lesen, anschreiben und überwachen? Über die iTerm2-Python-API, angesprochen durch das it2-CLI (und einen direkten Fallback).
uv tool install it2 (legt it2 in ~/.local/bin/).it2-CLI + die fertigen Skripteit2 ist ein dünner Wrapper über das iterm2-Python-Paket (beide sprechen denselben lokalen Websocket zu iTerm2). Darüber liegt ein Set kleiner Shell-Skripte (im claude-code-pane-control-Skill):
SCRIPTS=~/.agents/skills/claude-code-pane-control/scripts
SID=$("$SCRIPTS/start-claude.sh") # splittet ein Pane, startet `claude`, gibt die Session-ID zurück
"$SCRIPTS/send-prompt.sh" "$SID" "Mach X …" # tippt Text + 0.3s + Enter (Paste-Workaround)
"$SCRIPTS/peek-pane.sh" "$SID" | tail -30 # liest den Bildschirm (entfernt NULL-Bytes + Leerzeilen-Padding)
"$SCRIPTS/answer-mc.sh" "$SID" 2 # wählt Option 2 in einem Multiple-Choice-Widget
"$SCRIPTS/answer-permission.sh" "$SID" no # beantwortet einen Permission-Prompt
"$SCRIPTS/rename-claude-chat.sh" "$SID" "Neuer Name" # /rename (setzt Chat- UND iTerm-Pane-Name)
"$SCRIPTS/stop-claude.sh" "$SID" # Escape (NIE 2x Ctrl+C – das beendet die Session!)Zum Officer-Spawnen gibt es spawn-officer-pane.sh --commander-pane <UUID> --name "…" --cwd <Repo>: es splittet ein Pane neben dem Commander, startet dort claude, und wartet, bis die TUI wirklich interaktiv ist (bis die 5h:-Statusleiste erscheint), bevor es die Pane-ID zurückgibt – so landet der Brief garantiert.
Keine Session darf je durch ein
it2-CLI-Versagen blockiert sein. Wenn das CLI zickt (split exit 1, hängt, Reconnect flaket unter Last), nutzt man die rohe API direkt:
D=~/.agents/skills/claude-code-pane-control/scripts/it2_direct.py
"$D" list # JSON: jede Session (id, name, title, tty)
"$D" prompt <VOLLE-UUID> "weiter …" # tippen + Enter
"$D" read <VOLLE-UUID> 40 # letzte 40 Bildschirm-ZeilenDas läuft unter it2s eigenem venv-Python (wo das iterm2-Paket installiert ist). Die ganze API-Oberfläche sind eigentlich nur drei Calls: Connection.async_create() → get_session_by_id(UUID) → async_send_text("…\r") / async_get_screen_contents().
Jedes Claude-Pane ist immer in genau einem Zustand. Man erkennt ihn am Bildschirminhalt:
| Zustand | Erkennung |
|---|---|
| IDLE | Inhalt ≥15s unverändert, kein Widget sichtbar → wartet auf den nächsten Prompt |
| BUSY | Inhalt ändert sich zwischen Polls → denkt/sucht/streamt/führt Tools aus |
| BLOCKED-MC | eingefrorener Inhalt + ☐-Kopfzeile + nummerierte Optionen + Fußzeile Enter to select · ↑/↓ to navigate · Esc to cancel |
| BLOCKED-PERMISSION | eingefroren + gestrichelter ╌╌╌-Divider + 3 Optionen (Yes / Yes-and-allow / No) + Fußzeile Esc to cancel · Tab to amend |
Wichtige Fallen (kosten sonst „Geister-tot”-Fehlalarme):
- Immer die VOLLE UUID verwenden (aus it2 session list --json, Key id) – ein 8-Zeichen-Präfix liefert beim Lesen still leeren Inhalt.
- Boot dauert 20–40s, nicht 5 – während des Bootens zeigt das Pane Scrollback, das wie „nie gestartet” aussieht. Liveness per Prozess prüfen (ps -t <tty>), nicht per Bildschirmtext.
- Dim-grauer Text nach ❯ ist eine Autocomplete-/Vorschlags-Anzeige, KEINE echte Eingabe und KEINE „angekommene Nachricht”. Echte Nachrichten stehen nur im Transkript-JSONL.
- Bei offenem MC-Widget nie frei-Text reinschicken (würde still die Default-Option bestätigen) – nur über answer-mc.sh eine konkrete Option wählen.
Damit eine obere Ebene merkt, dass unten etwas passiert, läuft pro Layer ein Hintergrund-Daemon (fleet-watch.sh, Standard-Intervall 10s), gestartet via kantai-fleet start-watcher. Er liest zyklisch den Zustand aller bewachten Panes und injiziert bei einem Trigger ein „Signal” direkt ins obere Pane (via it2 send) – Claude empfängt es als neue User-Nachricht.
Die fünf Trigger:
| Trigger | Bedeutung | Reaktion der oberen Ebene |
|---|---|---|
blocked-multiple-choice |
Pane wartet auf eine MC-Antwort | reinschauen, beantworten oder eskalieren |
blocked-permission |
Pane wartet auf eine Erlaubnis | reinschauen, ja/ja-und-erlauben/nein je Scope |
session-exited |
Pane lebt, aber keine Claude-TUI | erst verifizieren (peeken!), nur bei echtem Tod neu starten |
all-officers-idle |
alle Officer einer Mission gleichzeitig idle | Commander: Officer prüfen, nächsten anstoßen oder Mission schließen |
pane-died |
Pane-UUID lebt nicht mehr | re-spawnen oder aus der Watchlist nehmen |
Praktische Lehre aus dem Betrieb: verlass dich nicht nur auf injizierte Signale – die obere Ebene sollte bei jedem ihrer eigenen Ticks aktiv den Zustand abfragen (den Layer File dumpen), denn injizierte Signale können verloren gehen, wenn das Ziel-Pane gerade selbst arbeitet. Aktives Polling ist die zuverlässige Absicherung.
Pro Ebene eine JSON-Datei:
- Emperor: ~/.kantai/emperor.fleet.json
- Commander: <Repo>/.kantai/commander.fleet.json
Inhalt: owner (das Pane selbst) + watchedSessions[] (je: label, paneID, kind/role, missionID, lastState, lastStateChangedAt, alive, snoozedUntil, snoozeReason …). Verwaltet wird das über das kantai-fleet-CLI (add-watched, remove-watched, snooze, start-watcher, watcher-status …) – alles mit langen, benannten Flags (--label "…"), atomare Writes, Lock pro Datei. Mit Snooze unterdrückt man Signale einer Session für eine Zeit (z.B. wenn ein Pane bewusst auf eine Mensch-Entscheidung wartet).
Initial Input (Idee, Bug, Feedback, Screenshot, Test-Eindruck vom Handy)
▼
Alignment Interview Commander ↔ Mensch, EINE Frage nach der anderen, je mit Empfehlung
▼ (Seiten-Schleifen: Research / Prototype)
Alignment Report (Roh-Gespräch verdichtet zu: gelöste Entscheidungen + offene Fragen + Roadmap)
▼
Mission Requirements PRD-Synthese: Mission-Ziel, Problem, Lösung, „Als X will ich Y, damit Z",
▼ Implementation/Testing-Decisions, Out-of-Scope. NUR Synthese, keine neue Discovery.
Mission Board Aufgaben-DAG (T1 → T2 → …), pro Task: Vertical Slice + Required Context Packet
▼ + Acceptance Criteria + Expected Proof + Parallelisierungs-Konflikte
+ „Usefulness Checkpoint" (was kann der Mensch danach benutzen?)
▼
Pro Task: Officer Planner → Officer Implementer → Code Reviewer → [QA Reviewer]
▼
Closeout (Backlog gruppieren, nächste Mission vorschlagen)
Disziplin-Regeln, auf die es ankommt: - Nur das Alignment-Interview bringt viele Fragen in den Chat. Ab Mission Requirements schreibt der Commander, der Mensch reviewt Artefakte. - Vertical Slice = der kleinste durchgehende, benutzbare/testbare Mehrwert. Kein horizontales Schneiden. - Jede Implementation Decision muss auf eine Alignment-Entscheidung zurückführbar sein – sonst ist es eine still eingeschmuggelte neue Entscheidung (zurück zum Menschen). - Validation Contract / Acceptance Criteria + Expected Proof stehen vor dem Code fest. - Jeder logische Change braucht BEWEIS, nicht Annahme – ein Red-Green-Test, eine grüne Suite oder eine reale App-Beobachtung. „Sollte passen” zählt nicht.
Das Review ist in zwei getrennte Officer-Rollen aufgeteilt, sequenziell:
| Rolle | Quellcode-Zugriff? | Was sie tut | Lane-Discipline |
|---|---|---|---|
| Code Reviewer | Ja | Tests, Type-Check, Lint, Konventions-Compliance, Refactor-Kandidaten. Lädt projektspezifische *-pro-Skills je Diff. Darf Codex parallel als Cross-Modell-Review aufrufen. |
liest Code, schreibt Findings, fixt nie |
| QA Reviewer | Nein | Startet die laufende App (Simulator/Mac/lokaler Port), fährt sie wie ein Nutzer – via macos-peekaboo (native Apps) oder browser-use (Web). Läuft dokumentierte User-Flows ab, vergleicht Mockup vs Implementierung, achtet auf Empty/Error-States, Dark-Mode, Accessibility, abgeschnittene Buttons usw. |
fährt die App, schreibt Findings, liest nie Quellcode |
Warum getrennt? Weil es zwei verschiedene Fehlerklassen sind: der Code Reviewer findet, was im Code falsch ist; der QA Reviewer findet, was der Nutzer erlebt (was im Code unsichtbar ist – Layout, Keyboard verdeckt das Feld, fehlende Bestätigung bei Löschen …). Ein Agent mit beiden „Hüten” hätte einen blinden Fleck. Reihenfolge: erst Code Reviewer (billiger, fängt Offensichtliches), dann QA Reviewer (teurer, braucht App-Start).
Welche Visoren pro Mission: Backend → Code Reviewer Pflicht, QA optional. Reine UI → beide Pflicht. Doku/Refactor → oft nur Code Reviewer. Beide melden ihre Findings (Severity-getaggt: High/Medium/Low) an den Commander, nie direkt an den Menschen. High-Findings gehen als „Punch-List” zurück an den Implementer (Runde N+1), bis PASS.
Konkretes Beispiel aus dem echten Betrieb (heute): Für eine Website mit DSGVO-Personendaten hat ein Commander den Schutz-Mechanismus (client-seitige Argon2-Verschlüsselung) gebaut. Code Reviewer: PASS (echte Krypto-KAT, 12 distinkte IVs, 0 Klartext, fail-closed Build). QA Reviewer: PASS_WITH_GAPS – fand ein
<head>-Metadaten-Leck (Titel/Description verrieten ohne Passwort eine Inhalts-Zusammenfassung). Das war im Code unauffällig, aber im laufenden Ergebnis sichtbar. Genau dafür ist der getrennte QA-Visor da.
KantaiKit nutzt optional das Codex-Plugin (OpenAI) als zweite Modell-Familie – vor allem beim Code Reviewer als paralleler Cross-Review (Findings vergleichen; Widerspruch → Commander synthetisiert). Beim QA Reviewer geht das nicht (Codex kann peekaboo/browser-use nicht fahren). Regel: vor dem ersten Codex-Call den codex-plugin-reliability-Skill laden, nie --background.
uv tool install it2, die claude-code-pane-control + kantai-fleet Skripte/Skills bereitlegen..kantai/-Ordner anlegen, eine Claude-Session als Division Commander dort starten. (Für den Anfang reicht eine Ebene – kein Emperor nötig, solange du nur 1 Projekt hast.).kantai//KantaiKit/-Ordner).kantai-fleet start-watcher), damit der Commander gemeldet bekommt, wenn ein Officer idle/blockiert ist – plus eigener Backstop-Poll.Tipp: Die wichtigsten Projekt-Regeln (Konventionen, Build-Befehle, „nie X tun”) gehören in die AGENTS.md des Repos – sie wird automatisch geladen und überlebt jede Compaction.
Das hier ist die Zwischenlösung: iTerm-Panes + Skills + Shell-Skripte, komplett lokal, kein Server, keine Cloud. Das finale KantaiKit-Produkt soll dieses Substrat später durch eine native macOS-„Flagship”-App + Multi-Plattform-Client ersetzen (Layer File → DB-Schema, Panes → verwaltete Sessions, Reaktions-Handler → Mission Scheduler). Die Zwischenlösung probt aber bereits jedes Muster, jede Rolle und jede Grenze, die das Produkt brauchen wird – die App ist dann ein Port, kein Redesign.
Bekannte Stolpersteine aus dem echten Betrieb (alle in diesem Dokument erwähnt): volle UUIDs statt Präfixe, Boot dauert 20–40s, Dim-Text ≠ echte Eingabe, MC-Widget nie frei-Text, injizierte Signale nicht blind vertrauen (aktiv pollen), session-exited immer erst per Peek verifizieren bevor man neu startet.
Ein Skill ist nichts Magisches: eine Markdown-Datei (SKILL.md) mit YAML-Frontmatter plus Anleitungstext. Claude Code lädt sie automatisch, sobald das description-Feld zur aktuellen Aufgabe passt. So sieht der Kopf aus:
---
name: kantai-fleet # kebab-case, eindeutig
description: "Primitive skill for KantaiKit's iTerm-fleet … Triggers – 'kantai-fleet add-watched', 'snooze', 'start-watcher', 'Layer File' …"
metadata:
keywords: "kantai-fleet, fleet-watch.sh, start-watcher, layer file, watchlist, snooze, trigger"
disable-model-invocation: false # true = nur manuell via /skill-name, kein Auto-Load
---
# Titel
… die eigentliche Anleitung (knapp, ein Konzept = eine Anweisung) …Wesentlich:
- Das description-Feld entscheidet das Auto-Laden. Es muss die Trigger-Situationen + Stichwörter klar nennen („load when the user asks X”, „triggers: …“). Schlecht beschriebene Skills laden nie.
- disable-model-invocation: true → der Skill lädt NICHT automatisch, nur per /skill-name. Für seltene/teure Skills.
- Ablageort: ~/.agents/skills/<name>/SKILL.md. Es gibt einen Symlink ~/.claude/skills → .agents/skills; immer über den .agents/-Pfad editieren, nie den Symlink anfassen.
- Ein Skill-Ordner kann mehr haben: scripts/ (Shell/Python, die der Skill aufruft), references/, assets/.
- Neue Skills baust du mit dem skill-creator-Skill. Leitsatz: keep it simple, don’t over-engineer – lieber ein knapper, treffsicher beschriebener Skill als ein 500-Zeilen-Monster.
Primitive (das Fundament – Pane-Steuerung + Flotte):
| Skill-Datei | Was reingehört |
|---|---|
kantai-fleet/SKILL.md |
Der Loop-Daemon fleet-watch.sh + das kantai-fleet-CLI (add-watched, remove-watched, snooze, start-watcher, watcher-status) + der Layer-File-Vertrag (JSON-Struktur, atomare Writes, Lock) + die fünf Trigger + wie ein Signal ins obere Pane injiziert wird. scripts/: fleet-watch.sh, spawn-officer-pane.sh. |
claude-code-pane-control/SKILL.md |
Das 4-Zustands-Modell (IDLE/BUSY/BLOCKED-MC/BLOCKED-PERMISSION), die Capture-Gotchas (volle UUID, Boot 20-40s, Dim-Text-Falle, NULL-Bytes), die MC-/Permission-Widget-Rezepte, der it2/it2_direct.py-Fallback. scripts/: start-claude.sh, peek-pane.sh, send-prompt.sh, answer-mc.sh, answer-permission.sh, rename-claude-chat.sh, stop-claude.sh, it2_direct.py. |
iterm-pane-organization/SKILL.md |
Tab-/Pane-Layout, die Eine-Projekt-pro-Tab-Naming-Policy, Sessions verschieben/zusammenführen, und die Snapshot/Restore-Crash-Recovery (Panes nach iTerm-Absturz wiederherstellen). |
Rollen (das Verhalten je Ebene):
| Skill-Datei | Was reingehört |
|---|---|
kantaikit-architecture/SKILL.md |
Die Big-Picture-Lookup: Vokabular, Topologie, die 5 Trigger, das Multi-Visor-Muster, das Layer-File-Schema, die Skill-Map. Lädt man, wenn man „wie hängt X mit Y zusammen” fragt. |
kantaikit-emperor/SKILL.md |
Emperor-Verantwortlichkeiten + Reaktions-Handler für die 4 Trigger, manueller Snooze/Unsnooze-Workflow, Flotten-Routing, Morning-Briefing-Stil. Lädt automatisch, wenn cwd der Workspace-Root ist. |
kantaikit-division-commander/SKILL.md |
Commander-Verantwortlichkeiten + die Mission-Pipeline (Alignment → Requirements → Board → Officer-Runs → Multi-Visor → Closeout) + Watchlist + Backlog + Officer-Spawning. Lädt automatisch, wenn cwd ein Repo mit .kantai/-Ordner ist. |
kantaikit-officer-implementer/SKILL.md |
Implementer-Lane: TDD red-green, projektspezifische *-pro-Skills je Diff, striktes Handoff-Format (erledigt / offen / Befehle-mit-Exit-Codes / Issues / Red-Green-Beweis). |
kantaikit-officer-code-reviewer/SKILL.md |
Code-Reviewer-Lane: Tests/Lint/Konventionen, Refactor-Kandidaten, optional Codex-Cross-Review. Liest Code, fixt nie. |
kantaikit-officer-qa-reviewer/SKILL.md |
QA-Reviewer-Lane: laufende App fahren (peekaboo/browser-use), User-Flows ablaufen, Mockup-Vergleich, Severity-Findings, Handoff-Format. Liest keinen Code. |
kantaikit-officer-planner/SKILL.md, kantaikit-officer-merger/SKILL.md |
Planner: fertige Tasks wählen, Reihenfolge/Konflikte, Implementer briefen. Merger: zusammenführen. |
Support (werden je Phase dazugeladen):
| Skill | Wofür |
|---|---|
grill-me |
Das Alignment-Interview (eine Frage nach der anderen, mit Empfehlung). |
tdd |
Red-green-refactor für den Implementer. |
codex-plugin-reliability |
Vor JEDEM ersten Codex-Call laden (nie --background, Stall-Recovery). |
claude-notify |
ntfy-Push aufs iPhone (Task fertig / Entscheidung nötig / Fehler). |
tailshare |
Lokale Dateien als HTTPS-Links teilen (damit man sie vom Handy öffnen kann). |
app-dev-context, swiftui-pro, swift-testing-pro, swift-concurrency-pro, … |
Projektspezifische Style-Guides, vom Code Reviewer/Implementer je nach Diff geladen. |
skill-creator |
Neue Skills anlegen. |
checkpoint |
Session-Zustand sichern/wiederherstellen („wo waren wir?“). |
kantai-fleet – das Flotten-Primitiv. Liefert zwei Dinge. (1) Den Daemon fleet-watch.sh: eine Bash-Schleife, die alle ~10s den Layer-File liest, jedes bewachte Pane peekt, den Zustand per 4-State-Modell klassifiziert und bei einem Trigger ein Signal via it2 send ins owner-Pane injiziert (mit 60s-Cooldown pro Trigger, damit derselbe Trigger nicht im nächsten Tick erneut feuert). (2) Das kantai-fleet-CLI als dünnen Dispatcher über den Layer-File: start-watcher / stop-watcher / watcher-status, add-watched / remove-watched, snooze / unsnooze. Zwei Betriebs-Gotchas (live gelernt): Der Daemon hält Watchlist + Snoozes im Speicher – nach add-watched oder snooze den Daemon neu starten, sonst greift die Änderung nicht oder wird beim nächsten Write überschrieben. Und nach einem Restart kann das PID-File ausbleiben (Race), obwohl der Daemon läuft – dann echo <pid> > ~/.kantai/<layer>.json.watcher.pid, damit watcher-status ihn wieder findet.
claude-code-pane-control – ein Pane fahren. Das Herz: das 4-Zustands-Modell (IDLE/BUSY/BLOCKED-MC/BLOCKED-PERMISSION) erkennt man an Bildschirm-Strukturen, NICHT an den (ständig wechselnden) Spinner-Verben. Die Skripte (peek-pane.sh, send-prompt.sh, answer-mc.sh, answer-permission.sh, rename-claude-chat.sh) plus der it2_direct.py-Fallback für CLI-Aussetzer. Widget-Bedienung: im MC-Widget mit ↓ (\x1b[B) k-mal zur Ziel-Option, dann \r; für eine Frei-Antwort erst zur „Type something.”-Zeile, dann Text tippen (NICHT vorher Enter – das bricht die Frage ab). Zwei harness-direkte Slash-Commands (/rename, /remote-control) wirken auch, während das Pane BUSY ist. Capture-Fallen, die „Pane ist tot”-Fehlalarme erzeugen: immer die VOLLE UUID (Präfix liefert still leer), Boot dauert 20-40s, dim-grauer Text nach ❯ ist ein Vorschlag (keine echte Eingabe), it2 session capture braucht NULL-Byte-Stripping.
kantaikit-division-commander – der Projekt-Motor. Definiert die ganze Pipeline + welche Phase welches Artefakt produziert (Alignment Report → Mission Requirements → Mission Board), die grill-me-Disziplin im Alignment (eine Frage, eine Empfehlung; erst recherchieren), die Vertical-Slice-Zerlegung mit „Usefulness Checkpoints”, das Officer-Spawning (spawn → add-watched → briefen → beobachten → Multi-Visor → Closeout), das Backlog, und die Decision-Authority: leicht-reversible/risikoarme Calls trifft der Commander selbst + loggt eine Begründung; nur irreversible-architektonisch-UND-unersetzliche Calls werden eskaliert (Anti-Pattern: „Open Question:
kantaikit-officer-code-reviewer + -qa-reviewer – das Multi-Visor-Paar. Code Reviewer hat Quellcode-Zugriff: Tests/Lint/Type-Check, Konventions-Compliance, Refactor-Kandidaten, optional Codex-Cross-Review (zwei Modell-Familien vergleichen). QA Reviewer hat keinen Quellcode-Zugriff: startet die laufende App und fährt sie wie ein Nutzer (peekaboo nativ / browser-use Web), läuft User-Flows ab, vergleicht Mockup, achtet auf Empty/Error-States, Dark-Mode, Accessibility. iOS-Gotcha: die Software-Tastatur MUSS sichtbar sein (Cmd+K), wenn ein Flow ein TextField berührt – sonst rutschen „Keyboard verdeckt das Feld”-Bugs durch. Beide melden severity-getaggte Findings (High/Medium/Low) an den Commander, fixen nie selbst.
kantaikit-emperor – die Flotten-Ebene. Überwacht alle Commander (eine Ebene über dem Commander, gleicher kantai-fleet-Mechanismus), routet deinen Intent an die richtige Division, behandelt die Trigger (blocked-MC / blocked-permission / session-exited / pane-died) der Commander, verwaltet Snoozes, schreibt Morning-Briefings. Macht keine Missions-Arbeit selbst.
Disziplin-Helfer: grill-me (Interview-Technik), tdd (red-green-refactor, das der Implementer fährt), codex-plugin-reliability (immer VOR dem ersten Codex-Call laden, nie --background, Stall-Recovery-Leiter).
AGENTS.md / CLAUDE.md (die Projekt-Regeln)Pro Repo eine AGENTS.md mit den verbindlichen Projekt-Regeln (Konventionen, Build-/Test-Befehle, „nie X tun”, Decision-Authority – was darf der Commander selbst, was eskaliert er). Die CLAUDE.md ist meist nur ein Pointer (@AGENTS.md). Beides wird automatisch in den Kontext geladen und ist deshalb der Ort für alles, was auch nach einer Compaction noch gelten muss.
Vererbung: AGENTS.md/CLAUDE.md vererben von oben nach unten – eine AGENTS.md im Workspace-Root gilt für alle Projekte darunter, jedes Projekt ergänzt seine eigene. (Achtung: settings.json vererbt NICHT, siehe 9.3.)
.kantai/-Ordner (der Laufzeit-Zustand)Pro Division ein .kantai/-Ordner im Repo:
- commander.fleet.json – der Layer File (welche Officer-Panes werden bewacht, ihr Zustand). Reiner Laufzeit-Zustand mit session-spezifischen Pane-IDs → gitignored, nicht committen.
- Backlog.md – aufgeschobene Punkte (Developer-Feedback, Refactor-Kandidaten, Minor-Findings).
- optional Hooks/ (z.B. PostWorktreeCreate.sh).
Der Emperor-Layer-File liegt zentral unter ~/.kantai/emperor.fleet.json. Daneben im ~/.kantai/-Ordner: commander-names.md (Namens-Registry) + fleet-roster.md (Divisions-Liste fürs Routing).
settings.json (Permissions, Model, Hooks)Zwei Ebenen werden geladen + gemerged: user-level ~/.claude/settings.json + project-level <repo>/.claude/settings.json. Wichtig: settings.json vererbt NICHT von Parent-Ordnern (anders als AGENTS.md). Strategie: gemeinsame Permissions/Model/StatusLine ins user-level; nur projektspezifisches (Sprache, MCP-Server, Hooks) ins project-level.
Hier konfiguriert man u.a.:
- Permissions – was darf die KI ohne Nachfrage (Bash(...), Skill, Read/Edit, etc.). Generisches "Skill" erlaubt alle Skills.
- Hooks – automatische Aktionen bei Events (z.B. Auto-Format nach jedem Edit, PreCompact-Skript). Das ist der Weg für „mach immer X, wenn Y” – der Harness führt es aus, nicht die KI.
- StatusLine, Model.
~/.agents/skills/kantai-fleet/scripts/ → fleet-watch.sh (der Daemon), spawn-officer-pane.sh.~/.agents/skills/claude-code-pane-control/scripts/ → peek-pane.sh, send-prompt.sh, answer-mc.sh, rename-claude-chat.sh, it2_direct.py, …CLI-Konvention: nur lange, benannte Flags (--label "…", --pane-id <UUID>), Pflicht-Flags brechen mit klarer Fehlermeldung, Enums werden gegen Allowlist geprüft, UUIDs format-gecheckt, Writes atomar.
1. Setup: iTerm Python API an · `uv tool install it2` · Skills + Skripte bereit
2. Division anlegen: <Repo>/.kantai/ + <Repo>/AGENTS.md (Regeln) anlegen
3. Commander starten: Claude-Session im Repo öffnen → lädt kantaikit-division-commander automatisch
4. Watcher an: `kantai-fleet start-watcher --layer-file <Repo>/.kantai/commander.fleet.json`
5. Mission: Alignment-Interview → Requirements → Mission Board (Markdown-Artefakte)
6. Officer spawnen: `spawn-officer-pane.sh --commander-pane <UUID> --name "… Officer Implementer T1" --cwd <Repo>`
7. Registrieren: `kantai-fleet add-watched --layer-file … --kind officer --role implementer --pane-id <UUID>`
8. Briefen: `send-prompt.sh <Officer-UUID> "<Task-Brief>"`
9. Überwachen: Watcher meldet idle/blockiert ins Commander-Pane (+ eigener Backstop-Poll!)
10. Review: Code Reviewer + (QA Reviewer) als weitere Officer-Panes, Findings → Implementer
11. Closeout: Officer schließen, Watcher stoppen, Backlog/Checkpoint aktualisieren
Wenn mehrere Projekte parallel laufen, kommt oben ein Emperor (Session im Workspace-Root, lädt kantaikit-emperor) drauf, der die Commander mit demselben kantai-fleet-Mechanismus überwacht – nur eine Ebene höher.
fleet-watch-Daemon für all-officers-idle – dieser Trigger feuert für die Commander-Ebene unzuverlässig (ein hängender Auto-Cooldown). Jeder Commander braucht einen eigenen Backstop-Poll (zwei Divisionen haben das heute unabhängig bestätigt). Aktives Zustands-Polling ist die zuverlässige Absicherung; injizierte Signale sind nur die Kür.session-exited immer erst per Peek verifizieren, nie blind claude neu starten – ein offenes MC-Widget wird leicht als „tot” fehlerkannt; ein blinder Neustart zerstört eine lebende Session.Das ist der Schlüssel, wie die ganze Konfiguration versioniert + getrackt wird, obwohl es viele einzelne Projekte gibt.
Das Prinzip: mindestens EIN Umbrella, das alles enthält. Der Workspace ist ein Umbrella-Git-Repo (bei Cihat ~/Developer/Indie), das jedes Projekt als Git-Submodul einhängt. Jedes Submodul ist sein eigenes vollwertiges Repo mit eigenem Remote – aber das Umbrella „kennt” sie alle (es trackt pro Submodul einen Gitlink, also den exakt eingecheckten Commit-Stand). Dadurch hast du einen Ort, an dem du committen + tracken kannst: das Umbrella.
~/Developer/Indie/ ← UMBRELLA-Repo (eigenes git), Emperor-cwd
├── AGENTS.md ← workspace-weite Regeln (hier committet + getrackt)
├── CLAUDE.md ← nur @AGENTS.md-Pointer
├── Commercial/ConsumerApps/
│ ├── DojoKame/ ← Submodul = eigenes Repo (Commander-cwd)
│ │ ├── AGENTS.md ← projekt-spezifische Regeln (im Submodul committet)
│ │ ├── .kantai/ ← commander.fleet.json (gitignored), Backlog.md
│ │ ├── Doku/ ← (DojoKame ist selbst ein Umbrella: Sub-Submodul)
│ │ └── Recherche/ ← weiteres Sub-Submodul
│ └── ImmersiveTokyo/ ← weiteres Submodul
└── …
Zwei Umbrella-Ebenen. (1) Das Top-Umbrella (Indie) enthält ALLE Projekte – das ist das „wenigstens eine, das alles enthält”. (2) Manche Projekte sind selbst Umbrellas (z.B. DojoKame mit Doku/ + Recherche/, oder Timing mit App/ + vielen Sub-Repos). Beide Ebenen funktionieren gleich: das äußere Repo trackt das innere als Submodul.
Wo welche AGENTS.md lebt + wie sie vererbt:
- Umbrella-AGENTS.md (Workspace-Root) = die workspace-weiten Regeln, die JEDES Projekt erbt. Wird im Umbrella-Repo committet + getrackt.
- Submodul-AGENTS.md (pro Projekt) = projekt-spezifische Regeln. Wird IM Submodul committet.
- CLAUDE.md/AGENTS.md vererben top-down: ein Agent im Submodul lädt erst die Umbrella-Regeln, dann die Projekt-Regeln. (Achtung: settings.json vererbt NICHT – siehe 9.3.)
Wie das zur Flotte passt:
- Der Emperor sitzt im Umbrella-Root (cwd = ~/Developer/Indie) – von dort sieht/erreicht er alle Submodule.
- Jeder Division Commander sitzt in seinem Submodul (cwd = das Projekt-Repo).
- Die .kantai/commander.fleet.json (Laufzeit-Zustand mit Pane-IDs) wird gitignored – sie gehört nicht ins Repo. Die dauerhaften Dinge (AGENTS.md, Backlog.md, Mission-Boards/Requirements als Markdown) werden dagegen committet + getrackt, jeweils im Repo der passenden Ebene.
Der Git-Workflow (so wird eine AGENTS.md-Änderung getrackt):
1. Änderung im Submodul machen (z.B. DojoKame/AGENTS.md editieren) → im Submodul committen + pushen (eigenes Repo, eigener Remote).
2. Dadurch zeigt der Gitlink im Umbrella auf einen neuen Commit → im Umbrella den Submodul-Pointer-Bump committen + pushen.
3. Workspace-weite Regeln (Top-AGENTS.md) editierst du direkt im Umbrella und committest dort.
So ist auf jeder Ebene alles versioniert: die Projekt-Regeln im Projekt, die Flotten-/Workspace-Regeln + die exakten Submodul-Stände im Umbrella. Ein neues Projekt hängst du mit git submodule add <remote-url> <pfad> ins Umbrella (genau so wurde z.B. ImmersiveTokyo/JapanTournee2026 aufgenommen).
Praxis-Hinweise: Push-Matrix beachten (private Repos/Forgejo frei pushen, public Repos nur mit Freigabe). Ein „untracked embedded repo” im Umbrella (
git statuszeigt es als??statt als Gitlink) heißt: das Projekt liegt zwar im Ordner, ist aber noch NICHT als Submodul registriert – danngit submodule addnachholen, damit es getrackt wird.
Das Namensschema ist One Piece: die Indie-Flotte sind die Whitebeard-Piraten, die Timing-Flotte die Rothaar-Piraten (Shanks). Namen sind stabil pro Division – stirbt ein Pane und wird neu gespawnt, bekommt es denselben Namen. Registry-Dateien: ~/.kantai/commander-names.md + ~/.kantai/fleet-roster.md.
cwd des Emperors: ~/Developer/Indie/. Eine Division = ein Projekt.
| Commander | Division | Projekt |
|---|---|---|
| Whitebeard | (Emperor) | die ganze Indie-Flotte |
| Marco | KantaiKit | das Fleet-Tooling selbst |
| Ace | DojoKame | Japanisch-Lern-App |
| Jozu | SpotCrown | Social-Spotting-Spiel |
| Vista | EasyMeal | Ernährungs-App (Sonderfall: Developerin ist Samiye, nicht Cihat) |
| Blamenco | SiteKit | Swift-Static-Site-Generator (1.0.0 fertig) |
| Rakuyo | Iminomy | „Bedeutungs-Währung”-App |
| Namur | Japan2026 | Reisetagebuch |
| Blenheim | TranslateKit | KI-Übersetzung |
| Curiel | FreemiumKit | IAP-SDK |
| Kingdew | LageMagazin | Content |
| Haruta | LageDerGesetze | Politik-App |
| Atmos | Jihanki | Automaten-/Schließfach-Finder (Japan) |
| Jiru | WWDCNotes | WWDC-Notizen |
| Fossa | DengonKit | Projekt |
| Izo | VocalKit | Podcast-/Audio-Tooling (AppStore Tagebuch) |
| Squard | JapanTournee2026 | Reisebegleiter-Website (Chor „Der Flügel”) |
| Whitey Bay | ImmersiveTokyo | visionOS 3D-180°-Video-App (Apple Vision Pro) |
Reihenfolge der canon-Ränge: Marco (1.), Ace (2.), Jozu (3.), Thatch (4., übersprungen – stirbt früh im canon), Vista (5.), Blamenco (6.), Rakuyo (7.), Namur (8.) … danach Blenheim, Curiel, Kingdew, Haruta, Atmos, Jiru, Fossa, Izo (bis 16. Rang). Sind die 16 canon-Namen vergeben, ziehen neue Divisionen aus den verbündeten Kapitänen der Whitebeard-Allianz: Squard, dann Whitey Bay, dann Doma, McGuy, Andre, Ramba …
Timing ist Cihats Hauptarbeit (eigenes Repo, NICHT unter Indie) und läuft als eigene Flotte mit Shanks-rotem Akzent (#C8102E). Besonderheit: drei parallele Checkouts desselben Repos, je eine Commander-Identität:
| Rolle | Name | Checkout |
|---|---|---|
| Emperor | Shanks | das Timing-Fleet global |
| Division Commander | Beckman (BEC) |
~/Developer/Timing (primär / Integration) |
| Division Commander | Lucky Roux (ROU) |
~/Developer/Timing-Spare |
| Division Commander | Yasopp (YAS) |
~/Developer/Timing-Clone |
Praktisch fährt Timing aktuell einen Commander (Beckman im primären Checkout), der die drei Checkouts kennt und Officer in den jeweils freien hineinschickt, wenn parallele Arbeit einen anderen Branch braucht. Die Branch-Isolation zwischen den Checkouts ist heilig: niemals im falschen Checkout den Branch wechseln (das stört andere Sessions).
Dieser Abschnitt ist so geschrieben, dass ein anderer Claude-Code-Agent auf einem anderen Mac das System von Grund auf aufsetzen kann. Reihenfolge:
uv (brew install uv).uv tool install it2 → it2 liegt in ~/.local/bin/. Ersten it2-Aufruf machen → iTerm-Erlaubnis-Dialog einmal akzeptieren.tailshare-Server, ntfy-Server (für Push).Zwei Wege:
- Kopieren (empfohlen): den ganzen Baum ~/.agents/skills/ von der Referenz-Maschine übernehmen – mindestens kantai-fleet/, claude-code-pane-control/, iterm-pane-organization/, kantaikit-architecture/, kantaikit-emperor/, kantaikit-division-commander/, kantaikit-officer-* sowie die Support-Skills (grill-me, tdd, codex-plugin-reliability, claude-notify, tailshare, skill-creator). Jeder Ordner enthält SKILL.md + ggf. scripts/. Den Symlink ~/.claude/skills → ~/.agents/skills anlegen.
- Neu erstellen: ist die Referenz nicht verfügbar, schreibt ein fähiger Agent jede SKILL.md aus der Spezifikation in §8 dieses Dokuments (Frontmatter + beschriebener Inhalt). Die Skripte rekonstruiert er aus ihrem dokumentierten Verhalten:
- it2_direct.py – das 3-Call-Skelett steht in §3.3 (Connection.async_create → get_session_by_id(UUID) → async_send_text("…\r") / async_get_screen_contents()), plus die Subcommands list/prompt/run/send/read. Shebang = it2s venv-Python (head -1 "$(which it2)").
- peek-pane.sh – it2 session capture <UUID> + NULL-Bytes strippen (tr -d '\0') + trailing-Leerzeilen ignorieren.
- send-prompt.sh – Text via it2 send tippen, 0.3s warten, dann \r (Paste-Workaround).
- answer-mc.sh / answer-permission.sh – im Widget mit ↓ (\x1b[B) zur Ziel-Option navigieren, dann \r. Volle UUIDs, nie Präfixe.
- rename-claude-chat.sh – sendet /rename <name> (harness-direkt, läuft auch während BUSY).
- spawn-officer-pane.sh – splittet ein Pane neben --commander-pane, startet claude im --cwd, pollt auf die 5h:-Statusleiste, bevor es die UUID zurückgibt.
- fleet-watch.sh – eine Bash-Schleife (Default 10s): liest den Layer-File (JSON), peekt jedes bewachte Pane, klassifiziert den Zustand per 4-State-Modell (§3.4), und feuert bei einem Trigger ein Signal via it2 send ins owner-Pane (mit 60s-Cooldown pro Trigger). Plus das kantai-fleet-CLI (add-watched/remove-watched/snooze/start-watcher/stop-watcher/watcher-status) als dünner Dispatcher über den Layer-File (atomare Writes, mkdir-Lock).
~/.claude/settings.json (user-level): Permissions (Bash(...), Skill, Read/Edit), Model, StatusLine. (Projekt-settings.json nur für Projektspezifisches; vererbt nicht von oben.)~/.kantai/ anlegen: leeres emperor.fleet.json (vom CLI initialisiert), commander-names.md + fleet-roster.md (Namens-Registry – eigenes Thema wählen, z.B. eine andere Crew).<Repo>/AGENTS.md (Projekt-Regeln, Build-/Test-Befehle, Decision-Authority) + <Repo>/CLAUDE.md (@AGENTS.md) + <Repo>/.kantai/ (für commander.fleet.json, Backlog.md; .kantai/commander.fleet.json gitignoren).Dem Fluss aus §9.5 folgen: Commander-Session im Repo starten → kantai-fleet start-watcher → Mission-Pipeline (Alignment → Requirements → Mission Board) → Officer spawnen + add-watched + briefen → Multi-Visor-Review → Closeout. Bei mehreren Projekten oben einen Emperor im Workspace-Root.
Eine eigene Namens-Crew wählen (Cihat nutzt Whitebeard-/Shanks-Piraten, siehe §10). In ~/.kantai/commander-names.md Emperor- + Commander-Namen registrieren; stabil pro Division halten.
Die zwei wichtigsten Lehren gleich von Anfang an einbauen (§9.6): (1) Jeder Commander braucht einen eigenen Backstop-Poll – dem
all-officers-idle-Daemon-Trigger nicht allein vertrauen. (2)session-exitedimmer erst per Peek verifizieren, nie blind neu starten. Und: echte Arbeit IMMER in sichtbaren Officer-Panes, nie in Subagents.
Fragen? Cihat kennt das System im Alltagsbetrieb und kann konkrete Skript-Pfade + Beispiele zeigen. Maßgebliche Quellen: Skills unter ~/.agents/skills/kantaikit-*, ~/.agents/skills/kantai-fleet, ~/.agents/skills/claude-code-pane-control; Konfiguration in <Repo>/AGENTS.md, <Repo>/.kantai/ und ~/.claude/settings.json; Namens-Registry in ~/.kantai/commander-names.md + fleet-roster.md.