# Kanban — Spec & Architektur **Datei:** `/Users/robinchoice/dev/kanban/index.html` (eine Datei, kein Build) **Server:** `/Users/robinchoice/dev/kanban/server.sh` — static-file server aus `~` auf Port 8765 **Aufruf:** `http://localhost:8765/dev/kanban/index.html` (Server muss laufen für MD-Viewer; sonst funktioniert das Board trotzdem) **State:** Browser `localStorage` --- ## Zweck Single Source of Truth für alle laufenden Projekte. Self-contained HTML mit Kanban-Methodik (3 Spalten, Expedite-Swimlane, Class of Service, WIP-Limits, Little's Law, Monte Carlo). Visualisiert das Ringsystem von Robin (Ring 0–3, vier Workspace-Gruppen, ~16 Boards). --- ## Layout ``` ┌──────────────┬──────────────────────────────────────┬──────────────┐ │ SIDEBAR │ MAIN (Overview / Board / Analytics) │ IDEEN │ │ links │ │ rechts │ │ │ │ │ │ Gruppen │ • Header (Titel, Goal, Pills) │ • Input │ │ + Boards │ • Tabs │ • Filter │ │ + Aktionen │ • View-Body │ • Liste │ │ 210 px │ flex:1 │ 280 px │ └──────────────┴──────────────────────────────────────┴──────────────┘ ``` Banner oben (rot/amber) wenn auf `file://` statt `localhost:8765` — mit Switch-Button. --- ## Drei Views (Tabs in der Reihenfolge: Overview · Board · Analytics) ### Overview (Default) Hero-Block + 5 Sektionen, alle Felder editierbar: | Element | Quelle | Edit | |---|---|---| | Hero-Icon (96×96, rounded) | `overview.icon` (path) | bei Bild-Fail Emoji-Fallback in Board-Farbe | | Hero-Name | `board.name` | im Board-Header editierbar | | Hero-Tagline (lila, kursiv) | `overview.tagline` | Click + tippen | | Hero-Description (2-3 Sätze) | `overview.description` | Click + tippen | | Badges: Ring, Gruppe, Typ | live + `overview.type` | type editierbar | | Launch-Cards Grid | `overview.launches[]` | **Single-Click öffnet URL** (oder MD-Viewer wenn `.md`). **Doppelklick auf Text editiert.** `×` löscht. | | Was bisher geschah | `overview.summary` | Click + tippen | | Tech-Stack | `overview.stack[]` | Pill mit `×`, `+ Tech` Input | | Hosting · IDs · Pfade | `overview.info[]` | Label + Value editierbar, Copy-Btn, `×`, `+ Zeile` | | 🔒 Secrets · Keys | `overview.secrets[]` | Label + Value editierbar, masked-Toggle (Auge), Copy-Btn, `×`, `+ Secret` | | ⌘ Quick-Commands | `overview.commands[]` | Label + Cmd editierbar, Copy-Btn, `×`, `+ Command` | ### Board 3-Spalten-Kanban + Expedite-Swimlane darüber. | Spalte | Farbe | WIP-Limit | |---|---|---| | Ready | amber | — | | In Progress | blau | per Board (Pill im Header editierbar) | | Done | grün | — | **Expedite-Swimlane:** horizontale Reihe über dem Board mit 3 Zonen (deckungsgleich mit Spalten). Tasks mit `cos:'expedite'` erscheinen NUR in der Zone, nicht im normalen col-body. Drag zwischen Zonen behält Expedite. Drag in col-body demotet. Drag von col-body in Zone promoted. **Karten-Aktionen** (sichtbar bei Hover, oben rechts): - ⚑ Blocker togglen (`task.blocked`) — Karte rot - ↗ Promote-to-Board — öffnet Add-Board-Modal mit Task-Titel vorbelegt - × Löschen **Auto-Aging:** Karte > SLE-Tage in einer Spalte → roter Glow + "ÜBERFÄLLIG"-Label. Done-Karten werden nicht alt gezeigt. **Add-Card:** `+ Karte…` Input am Spalten-Ende. Enter fügt hinzu, Esc blurt. ### Analytics | KPI | Berechnung | Farbe | |---|---|---| | WIP | `count(wip)` gegen `wipLimit` | rot/amber/blau | | Cycle Time ⌀ | `WIP / Throughput × 7` (Tage) | blau | | Queue ETA | `(WIP+Ready) / Throughput × 7` (Tage bis Queue leer) | teal | | Flow Efficiency | `WIP / (WIP+Ready) × 100%` | grün/amber/rot | | Remaining | `WIP + Ready` | neutral | **Throughput-Quelle:** automatisch `realThroughput()` aus Done-Cards der letzten 14 Tage (mit `task.doneAt`). Fallback `board.throughput` wenn keine History. Status-Pill ("↻ Real" grün vs. "⊘ Statisch" grau). **Monte Carlo:** 8.000 Runs, Varianz ±60%, gibt P50/P75/P85/P95 Wochen + Datum. Live-Input für Throughput-Override. **Active Blockers:** alle Tasks mit `task.blocked === true`. **SLE:** vergleicht Cycle Time mit `board.sle.days`. --- ## Sidebar (links) Gruppen-Sections, dynamisch aus `GROUPS` + `BOARDS` gerendert. Meta-Gruppe (Ring 0) ist visuell hervorgehoben (lila Gradient, Glow, `◉`-Bullet). | Element | Verhalten | |---|---| | Gruppen-Section | Drop-Zone für Board-Drag (board.group ändern) | | Gruppen-Header (`s-group`) | draggable — Reihenfolge der Gruppen ändern (persistiert in `kanban_groups`) | | Nav-Item (Board) | Klick = aktivieren; draggable in andere Gruppe oder vor andere Nav-Items (Reihenfolge in `kanban_board_order`) | | Ring-Badge (R0/R1p/R1w/R2/R3/?) | Klick togglet durch Ring-Werte | | Badge (Count) | `remaining(b)` mit Color-Code (rot=Blocker, blau=WIP, grau=neutral) | | `×` (nur user-erstellt) | löscht das Board | **Unten:** - `+ Board` → Modal: Name, Goal, Gruppe (oder + Neue Gruppe), Farb-Picker (8 Optionen) - `+ Gruppe` → `prompt()` für Namen; leere Gruppen werden gezeigt - `↺ Reset` → aktuelles Board auf DEFAULTS zurück; bei user-erstellten Boards: löschen --- ## Ideen-Pinnwand (rechts) | Element | Verhalten | |---|---| | Input + Enter | neue Idee am Anfang einfügen, Tag aus aktivem Filter | | Filter-Buttons (Alle/Projekt/Erkenntnis/Später) | filtern Liste + setzen Default-Tag | | Idee-Card | hover-Buttons: `→` (Promote-Modal) und `✕` (löschen); **draggable** auf col-body → erstellt Task | | Drop-Zonen (erscheinen beim Card-Drag aus Board) | 📂 Projekt / 💡 Erkenntnis / 🕒 Später / ○ ohne Label — droppen entfernt Task aus Board und legt Idee an | **Seed:** 35 Ideen (v1=20 Projekt, v2=15 Erkenntnis, v3=+16 aus _archive). Versionierung via `kanban_ideas_seeded` Key. --- ## Datenmodell ### Task ```js { t: 'Titel', // required blocked: true, // optional — Karte rot, ⚑ aktiv cos: 'expedite' | 'fixed', // optional — Class of Service movedAt: 1779580800000, // Timestamp letzter Spaltenwechsel (für Aging) doneAt: 1779580800000, // Timestamp bei Wechsel nach Done (für Throughput) age: 14, // optional — manuell überschriebenes Aging (rare) note: 'Notiz', // optional — graue Sub-Zeile } ``` ### Board ```js { name: 'Döner-App', goal: 'Beschreibung', group: 'Code', // Sidebar-Gruppe color: '#f87171', // Dot-Farbe ring: '0' | '1p' | '1w' | '2' | '3' | '?', wipLimit: 3, // editierbar via Pill throughput: 2, // editierbar via Pill (Fallback wenn keine Done-History) sle: { days: 14, p: 85 }, // days editierbar via Pill cols: [ { id: 'ready', label: 'Ready', tasks: [...] }, { id: 'wip', label: 'In Progress', tasks: [...] }, { id: 'done', label: 'Done', tasks: [...] }, ], focus: 'Fixstern-Text', // editierbar im Header overview: { // optional icon: 'assets/...png', tagline: '...', description: '...', summary: '...', type: 'ios-app' | 'web' | 'meta' | ..., launches: [{label, sub, url, icon}], stack: ['...'], info: [{label, value}], secrets: [{label, value, masked}], commands: [{label, cmd}], }, userCreated: true, // nur bei UI-erstellten Boards } ``` ### Idea ```js { id: 1013, text: '...', tag: 'projekt' | 'erkenntnis' | 'spaeter', // optional created: '17.05.' | 'archive/...' | 'journal/...', } ``` ### State-Keys in localStorage | Key | Inhalt | |---|---| | `kanban_v2` | `{[boardId]: {cols, focus, [overrides], [userCreated-Meta]}}` | | `kanban_groups` | `['Meta','Code',...]` | | `kanban_board_order` | `{[group]: [id1, id2, ...]}` | | `kanban_ideas` | `[Idea, ...]` | | `kanban_ideas_seeded` | `'v3'` | --- ## Default-Boards | ID | Name | Gruppe | Ring | |---|---|---|---| | ringsystem | Ringsystem | Meta | 0 | | kanban | Kanban (dieses Board) | Meta | 0 | | doener | Döner-App | Code | 3 | | musichub | Music Hub | Code | 1w | | openclaw | OpenClaw / Rob | Code | 1w | | docpilot | docpilot | Code | 1w | | k4 | K4 Digital — PM-Mandat | Beruflich | 1w | | branding | Branding & Außendarstellung | Beruflich | 1w | | psk | PSK I Zertifizierung | Beruflich | 1w | | eu | Einzelunternehmen | Beruflich | 1w | | pleasance | Pleasance | Web | 3 | | mdim | mydrugismusic Website | Web | 3 | | privat | Haushalt & Leben | Privat | 1p | | degoogle | De-Google / FOSS Migration | Privat | 1p | | bibliothek | Bibliothek-Pipeline | Privat | 1p | | aikb | AI Engineering KB | Privat | 1w | **Overview gefüllt für:** doener, kanban, ringsystem. Andere: nur Skeleton (Pilot-Modus). --- ## Tool-Agnostik | Datei | Status | |---|---| | `~/.claude/AGENTS.md` | kanonisch | | `~/.claude/CLAUDE.md` | Symlink → AGENTS.md | | `~/dev/personal-vault/AGENTS.md` | kanonisch | | `~/dev/personal-vault/CLAUDE.md` | Symlink → AGENTS.md | | `~/dev/robin-work/AGENTS.md` | kanonisch | | `~/dev/robin-work/CLAUDE.md` | Symlink → AGENTS.md | **Backup:** `~/.claude/CLAUDE.md.bak` (alte Datei vor der Symlink-Migration) Skills tool-agnostisch über `~/.skills/{name}.md` mit Symlinks aus tool-spezifischen Verzeichnissen (Claude: `~/.claude/skills/{name}/SKILL.md`; OpenCode: `~/.config/opencode/commands/{name}.md`). --- ## Local-Server ``` ~/dev/kanban/server.sh ``` Startet `python3 -m http.server 8765 --bind 127.0.0.1` aus `~/`. - Aufruf: `~/dev/kanban/server.sh` (Vordergrund) oder `nohup ~/dev/kanban/server.sh &` (Hintergrund persist) - Stop: `pkill -f "http.server 8765"` - Logs: `/tmp/kanban-server.log` (wenn via nohup gestartet) Benötigt nur für **MD-Viewer** und localhost-URLs. Board-Funktion funktioniert auch ohne Server unter `file://`. Aber dann erscheint ein Warn-Banner oben. --- ## MD-Viewer Klick auf Launch-Card mit `.md`-URL → Modal mit gerendertem Markdown. Mini-Parser inline: Headings (h1-h3), Bold, Italic, inline Code, Code-Blocks, Listen (ul/ol), Tables, Blockquotes, Hr, Links. Fallback wenn `fetch()` scheitert (CORS): Anleitung mit drei Optionen (Extension / Server / Tab). --- ## Wichtige JS-Funktionen ### Render | Funktion | Beschreibung | |---|---| | `show(id)` | Board wechseln | | `setView(v)` | Tab-Switch (overview/board/analytics) | | `renderOverview(id)` | Hero + 5 Sektionen | | `renderBoard(id)` | Swimlane + 3 Spalten + col-add-input | | `renderAnalytics(id)` | KPIs, Flow, Monte Carlo, Blockers, SLE | | `renderSidebar()` | Gruppen + Boards | | `renderIdeas()` | gefilterte Ideen mit Drag-Attrs | | `initBadges()` | Alias renderSidebar | | `renderMarkdown(src)` | Mini-MD-Parser | ### State | Funktion | Beschreibung | |---|---| | `loadState()` / `saveState()` | BOARDS persist mit Override-Logik für Defaults | | `loadGroups()` / `saveGroups()` | + Migration: `Meta` vorne einfügen wenn fehlend | | `loadBoardOrder()` / `saveBoardOrder()` | per-Group-Order | | `loadIdeas()` / `saveIdeas()` | + Seeding | | `migrateCols(b)` | 5→3-Spalten-Migration | | `getBoardsForGroup(g)` | geordnete Board-IDs | ### Mutations (Board) | Funktion | Beschreibung | |---|---| | `addCard(boardId, colId, text)` | mit `movedAt` + ggf. `doneAt` | | `deleteCard(boardId, colId, idx)` | | | `toggleBlocker(boardId, colId, idx)` | `task.blocked` | | `saveBoardSetting(key, el, min, max)` | wipLimit/throughput/sleDays | | `saveBoardName()` / `saveBoardGoal()` | Header-Edit | | `saveFocus()` | Fokus-Text im Header | | `resetCurrentBoard()` | Default-Reset oder User-Board-Delete | | `deleteBoard(id, e)` | nur user-erstellt | | `cycleRing(boardId, e)` | togglet durch Ring-Werte | | `promoteToBoard(boardId, colId, idx)` | Task → neues Board | ### Mutations (Overview) | Funktion | Beschreibung | |---|---| | `updateOvFromEl(el)` | aus data-section/idx/prop | | `addOvRow(section)` | leere Zeile für info/secrets/launches/commands | | `addOvPill(section, value)` | für stack | | `deleteOvRow(section, idx)` | | | `enableEdit(el)` | Launch-Card-Felder Doppelklick aktiviert | | `toggleSecretBtn(btn)` | masked toggle | | `copyText(t, btn)` / `copyFromBtn(btn)` | Clipboard mit visual feedback | ### Mutations (Ideen) | Funktion | Beschreibung | |---|---| | `addIdea()` / `deleteIdea(idx)` | | | `filterIdeas(tag)` | + setzt Default-Tag | | `openPromote(idx)` / `confirmPromote()` / `closePromote()` | Modal Idee→Task | ### Add-Board-Modal | Funktion | Beschreibung | |---|---| | `showAddBoard()` / `closeAddBoard()` | | | `selectAbColor(c, el)` | Farb-Picker | | `confirmAddBoard()` | + Promote-Source-Handling | | `showAddGroup()` | prompt()-Dialog | ### DnD | Funktion | Beschreibung | |---|---| | `onDragStart/End` (Cards) | + `showIdeaDropZones(on)` | | `onDragOver/Drop` (col-body) | demotet expedite, handelt auch Ideen-Drops | | `onDragOverExp/onDropToExpCol` | promoted expedite | | `onBoardDragStart/End` | Board-Drag in Sidebar | | `onGroupDragOver/Drop` | Board → Gruppe | | `onNavItemDragOver/Drop` | Board-Reorder innerhalb Gruppe | | `onIdeaDragStart/End` | Idee aus Pinnwand | | `onGroupHeaderDragStart/End` | Gruppe-Reorder | | `onGroupSectionDragOver/Drop` | Gruppe-Drop-Target | | `onIdeaZoneDragOver` / `onDropToIdeas` | Card → Idee | | `onLaunchClick(e, card)` | Launch-Card öffnet URL/MD | ### Helper | Funktion | Beschreibung | |---|---| | `escapeHtml(s)` | HTML-Escape | | `liveAge(task)` | aus `movedAt` | | `ageClass(days)` | fresh/ok/warn/old | | `colCount(b, id)` | tasks.length | | `remaining(b)` | ready + wip | | `hasBlocker(b)` | any task.blocked | | `monteCarlo(left, tp, runs)` | {p50,p75,p85,p95} | | `realThroughput(b, days)` | aus Done-History | | `openMD(url)` / `closeMD()` / `openMdExternal()` | MD-Viewer | | `enableEdit(el)` | Launch-Card-Edit-Modus aktivieren | ### Globals ```js let curId = 'doener'; let curView = 'overview'; // default let BOARDS = {}; // runtime, mutiert let IDEAS = []; let GROUPS = ['Meta','Code',...]; let BOARD_ORDER = {}; let dragSrc = null; // {boardId, colId, idx} bei Card-Drag im Board let dragBoard = null; // boardId bei Sidebar-Drag let dragIdea = null; // idx bei Ideen-Drag let dragGroup = null; // group bei Gruppe-Drag let promoteSource = null; // {boardId, colId, idx} beim Task→Board let abSelColor = '#7c6af7'; let promoteIdx = null; let mdCurrentUrl = null; ``` --- ## CSS-Variablen (Theme) ``` --bg:#0d0d0f, --surface:#16161a, --surface2:#1e1e24, --surface3:#26262e --border:#2a2a35, --border2:#353545 --text:#e8e8f0, --text-muted:#6b6b80, --text-dim:#4a4a5a --accent:#7c6af7 (lila), --accent-soft:#2d2550 --green:#4ade80, --amber:#fbbf24, --red:#f87171, --blue:#60a5fa --teal:#2dd4bf, --purple:#c084fc, --orange:#fb923c --sidebar-w:210px, --col-w:240px ``` Color-of-State Konvention: - **Ready** = amber - **In Progress** = blau - **Done** = grün - **Blocked** = rot (Border + Background-Tint) - **Expedite** = rot (border-left + Swimlane-Background) - **Fixed Date** = amber (border-left) - **Aging > SLE** = roter Glow --- ## Test-Checkliste (für externe Tester-Agents) ### Layout & Navigation - [ ] Sidebar links: alle 5 Gruppen sichtbar (Meta · Code · Beruflich · Web · Privat) - [ ] Meta-Gruppe: lila Gradient mit `◉`-Bullet - [ ] Klick auf jedes Board lädt korrektes Layout, Header zeigt Name, Goal, Pills (WIP-Limit/TP/SLE), Fokus-Stern - [ ] Tab-Reihenfolge: Overview · Board · Analytics - [ ] Default-Tab beim Start: Overview - [ ] Banner oben wenn auf `file://` (nicht localhost:8765) ### Boards - [ ] `+ Board` öffnet Modal mit Name (Pflicht), Goal, Gruppe-Select (+ "Neue Gruppe…"), Farb-Picker (8 Farben) - [ ] User-Board zeigt `×` bei Hover (Default-Boards nicht) - [ ] `+ Gruppe` legt leere Gruppe an (sichtbar mit "Leer — Board hinzufügen" Placeholder) - [ ] Board-Drag in andere Gruppe → Group-Wechsel persistent - [ ] Board-Drag auf konkretes Nav-Item → Reihenfolge innerhalb Gruppe persistent - [ ] Gruppe-Header draggable → Gruppen-Reihenfolge ändert - [ ] Ring-Badge (R0/R1p/R1w/R2/R3) togglet bei Klick durch alle Werte - [ ] `↺ Reset`: bei Default-Board Spalten reset, bei User-Board Löschen-Confirm - [ ] Board-Name + Goal per Klick im Header editierbar (Enter speichert, Esc revert) ### Settings (Pills im Header) - [ ] WIP-Limit Pill editierbar (1-20) - [ ] Throughput Pill editierbar (0.5-30, Dezimalen erlaubt) - [ ] SLE-Tage Pill editierbar (1-180) - [ ] Alle drei persistent nach Reload ### Karten (Board-View) - [ ] `+ Karte…` Input: Enter fügt hinzu, Esc blurt - [ ] Hover-Buttons: ⚑ togglet blocked (Karte rot), ↗ öffnet Promote-Modal, × löscht - [ ] Drag col-body → col-body: verschiebt + setzt `movedAt` - [ ] Drag col-body → exp-zone: verschiebt + setzt cos=expedite - [ ] Drag exp-zone → exp-zone: verschiebt + bleibt expedite - [ ] Drag exp-zone → col-body: demotet (cos entfernt) - [ ] Drag in `done` setzt zusätzlich `doneAt` - [ ] Karte > SLE-Tage in Spalte (außer done): rot leuchtender Glow + "ÜBERFÄLLIG"-Label - [ ] Drag Card → eine der vier Ideen-Drop-Zonen (rechte Sidebar): erstellt Idee, entfernt Card ### Promote-to-Board - [ ] ↗ auf Karte öffnet Modal mit Name = Task-Titel - [ ] Hint zeigt Quell-Board und -Spalte korrekt - [ ] Gruppe + Farbe vorbelegt mit Quell-Board - [ ] Confirm → neues User-Board, Task aus Quelle entfernt - [ ] Cancel → kein Board angelegt, Quell-Task bleibt ### Overview - [ ] Hero-Block: Icon (oder Emoji-Fallback in Board-Farbe), Name, Tagline, Description, Badge-Reihe (Ring/Gruppe/Typ) - [ ] Tagline + Description + Type per Single-Click editierbar (Click + tippen) - [ ] Launch-Cards: **Single-Click öffnet URL** (oder MD-Viewer bei .md-URL); **Doppelklick auf Text aktiviert Edit-Modus** - [ ] `× Entfernen` löscht Launch-Card - [ ] `+ Launch-Card` fügt leere Card hinzu - [ ] Was bisher geschah: per Click editierbar - [ ] Tech-Stack-Pills: `×` löscht, `+ Tech` Input fügt hinzu - [ ] Info-Rows: Label + Value editierbar, Copy-Btn (✓ Feedback), `×` löscht, `+ Zeile` fügt hinzu - [ ] Secrets: Label + Value editierbar, Auge-Toggle (masked persistent), Copy-Btn, `×`, `+ Secret` - [ ] Quick-Commands: Label + Cmd editierbar, Copy-Btn, `×`, `+ Command` ### MD-Viewer - [ ] Voraussetzung: Aufruf via `http://localhost:8765/dev/kanban/index.html` (Server läuft) - [ ] Klick auf `.md`-Launch-Card öffnet Modal mit gerendertem Markdown (Headings, Code, Tables, Listen) - [ ] `↗ Tab` öffnet Roh-Inhalt in neuer Tab - [ ] `× Schließen` oder Klick auf Overlay schließt Modal - [ ] Bei `file://`-Aufruf: Fallback-Anleitung erscheint mit drei Optionen ### Analytics - [ ] Tab-Wechsel ohne State-Verlust - [ ] WIP-KPI färbt rot bei `> wipLimit`, amber bei `= wipLimit`, blau sonst - [ ] Cycle Time, Queue ETA, Flow Efficiency mathematisch plausibel (siehe Spec oben) - [ ] Monte Carlo Throughput-Input updated Live - [ ] Status-Pill grün "↻ Real" wenn Done-Cards mit doneAt < 14d existieren, sonst grau "⊘ Statisch" - [ ] Active Blockers Panel listet alle Tasks mit `blocked:true` - [ ] Flow Distribution: 3 Balken (Ready/WIP/Done) korrekt skaliert ### Ideen - [ ] Input + Enter fügt Idee am Anfang ein - [ ] Filter-Buttons: ändern Anzeige UND Default-Tag für neue Ideen - [ ] Hover-Buttons: `→` Promote-Modal (Spalten-Default = erste verfügbare, nie 'backlog'), `✕` löscht - [ ] Drag Idee in col-body → Task entsteht, Idee verschwindet - [ ] Drag funktioniert nur auf col-body, nicht in exp-zone ### Persistenz - [ ] Reload behält: Boards, Spalten-States, Fokus, Ideen, Gruppen, Group-Order, alle Overrides (name/goal/wipLimit/tp/sle/overview) - [ ] `localStorage.clear()` + Reload → alle Defaults zurück inkl. Seed-Ideen v3 - [ ] Alte 5-Spalten-States werden via `migrateCols` zu 3-Spalten konsolidiert ### Tool-Agnostik - [ ] `~/.claude/CLAUDE.md` ist Symlink auf `AGENTS.md` - [ ] `~/.claude/CLAUDE.md.bak` enthält den alten Inhalt vor Migration - [ ] Ringsystem-Board zeigt alle relevanten MD-Files als Launch-Cards mit korrekten http://localhost:8765-URLs --- ## Bekannte Einschränkungen - Karten-Sortierung INNERHALB einer Spalte nicht möglich (immer append) - Card-Edit (Titel/Note ändern) nicht möglich — nur löschen + neu - Gruppen können nicht umbenannt oder gelöscht werden - Kein Card-Detail-View (kein Comments, Attachments, History) - Kein Export - Keine Tastatur-Shortcuts - localStorage nicht synchronisiert — pro Browser/Gerät separat - Keine Undo-Funktion - CFD-Chart noch nicht implementiert (Ready-Task) - Throughput-History akkumuliert sich erst über Zeit — bei frischem Start fallback auf statischen Wert --- ## Datei-Struktur ``` /Users/robinchoice/dev/kanban/ ├── index.html # Die gesamte App ├── SPEC.md # Diese Datei ├── server.sh # Local HTTP Server (chmod +x) └── assets/ └── doener.png # App-Icon (kopiert aus ~/dev/doener-app/iOS/.../AppIcon.appiconset/icon-1024.png) ``` --- ## Setup (für neue Session / anderen Agent) ```bash # 1. Server starten (für MD-Viewer) nohup ~/dev/kanban/server.sh > /tmp/kanban-server.log 2>&1 & # 2. Im Browser öffnen open http://localhost:8765/dev/kanban/index.html # 3. Stop wenn nötig pkill -f "http.server 8765" ``` Wenn Server nicht laufen soll: einfach `open ~/dev/kanban/index.html` — Board funktioniert, aber MD-Viewer-Modal zeigt Fallback-Anleitung statt gerenderter Inhalte.