From 979fdd38ae0f876c3723b324e62effd32eb5d2bd Mon Sep 17 00:00:00 2001 From: Corneel <6919390+CorneeldH@users.noreply.github.com> Date: Wed, 8 Apr 2026 09:32:12 +0200 Subject: [PATCH 1/3] feat: add generate-slides-retro-simple skill Nieuwe skill voor compacte sprint review presentaties georganiseerd per domein (instroom/uitval/tech/project/overig) met: - CEDA Board integratie via GraphQL (iteratie, status, issue types) - Functie-metric (20-100 regels) als proxy voor substantieve logica - Kanban board voor pitches (Todo/In Progress/Done/On Hold) - Afgeronde tasks slide voor losse taken - Terminal summary output Voorbeeld output: cedanl/clidev-presentaties@1fb594c Co-Authored-By: Claude Opus 4.6 --- .../generate-slides-retro-simple/SKILL.md | 451 ++++++++++++++++++ .../generate-slides-retro-simple/config.json | 212 ++++++++ 2 files changed, 663 insertions(+) create mode 100644 .claude/skills/generate-slides-retro-simple/SKILL.md create mode 100644 .claude/skills/generate-slides-retro-simple/config.json diff --git a/.claude/skills/generate-slides-retro-simple/SKILL.md b/.claude/skills/generate-slides-retro-simple/SKILL.md new file mode 100644 index 0000000..035c46e --- /dev/null +++ b/.claude/skills/generate-slides-retro-simple/SKILL.md @@ -0,0 +1,451 @@ +--- +name: generate-slides-retro-simple +description: Genereer een compacte, inhoudelijke Slidev sprint review presentatie voor CEDA, georganiseerd per domein (instroom/uitval/tech/project) met substantiemetriek op basis van commits, functies en het CEDA Board. +--- + +# generate-slides-retro-simple + +Genereer een compacte sprint review presentatie voor CEDA, georganiseerd per domein met focus op wat er daadwerkelijk is opgeleverd. + +## Instructies + +### Stap 0: Clone het clidev project + +1. Zoek of het project al ergens op de machine staat: + ```bash + find ~ -type f -name "_template.md" 2>/dev/null | xargs -I{} dirname {} | while read dir; do + [ -d "$dir/theme" ] && [ -d "$dir/public/npuls" ] && echo "$dir" + done | head -3 + ``` +2. Als het niet gevonden wordt, clone het: + ```bash + git clone https://github.com/cedanl/clidev-presentaties.git ~/clidev-presentaties + ``` +3. Installeer dependencies als `node_modules/` ontbreekt: + ```bash + cd && npm install + ``` +4. Genereer de presentatie **in deze directory** met `theme: ./theme`. Naamconventie: `YYMMDD_sprint_review_simple.md`. + +### Stap 1: GitHub Token check & sprint-periode + +**Token check — voer dit uit VOORDAT je data ophaalt:** +1. Controleer of `$GITHUB_TOKEN` is ingesteld (`echo $GITHUB_TOKEN`). +2. Als het NIET is ingesteld, vraag de gebruiker: + > Je hebt een GitHub Personal Access Token nodig. Heb je er al een? + > + > **Zo niet, maak er een aan:** + > 1. Ga naar https://github.com/settings/tokens + > 2. Klik op **"Generate new token (classic)"** + > 3. Selecteer minimaal de scopes **`repo`** en **`read:org`** en **`project`** + > 4. Klik op **"Generate token"** en kopieer het token + > + > **Plak je GitHub token hier in de chat:** +3. Zodra de gebruiker het token plakt: + ```bash + export GITHUB_TOKEN="" + ``` +4. Verifieer: + ```bash + curl -s -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/user | grep login + ``` + +**Iteratie-periode ophalen van CEDA Board:** + +Haal de actieve iteratie op van het CEDA Board (project #2) via GraphQL: + +```bash +gh api graphql -f query=' +{ + organization(login: "cedanl") { + projectV2(number: 2) { + field(name: "Iteratie") { + ... on ProjectV2IterationField { + configuration { + iterations { + id + title + startDate + duration + } + completedIterations { + id + title + startDate + duration + } + } + } + } + } + } +} +' +``` + +- Gebruik de huidige/meest recente iteratie om `SPRINT_START` en `SPRINT_END` te bepalen +- `SPRINT_START` = `startDate` van de iteratie +- `SPRINT_END` = `startDate` + `duration` dagen +- Het veld heet "Iteratie" (Nederlands), niet "Iteration" +- Als er geen iteratie-veld is, val terug op 2 weken eindigend op vandaag +- Toon de iteratie-titel (bijv. "Sprint 12") in de presentatie + +**Repo's ophalen en filteren:** +- Haal alle repos op: `curl -s -H "Authorization: token $GITHUB_TOKEN" "https://api.github.com/orgs/cedanl/repos?per_page=100&type=public"` +- Werk `config.json` bij met de resultaten. +- Pre-filter: alleen repo's waar `pushed_at >= SPRINT_START`. + +### Stap 2: Categorie-mapping + +Elke actieve repo wordt gemapt naar 1 van 5 domeinen: + +| Domein | Kleur | Repos (pattern match) | +|--------|-------|----------------------| +| **instroom** | `#1D76DB` | `*instroom*`, `*prognose*`, `student-instroom-mbo`, `dashboard-instroomprognose-mbo` | +| **uitval** | `#D93F0B` | `*1cijfer*`, `*1cho*`, `*uitval*`, `*vsv*`, `*uitnodiging*`, `no-fairness-without-awareness`, `lta-hhs-fairnessawareness`, `Assistentie`, `student-signal` | +| **tech** | `#5319E7` | `*template*`, `*devcontainer*`, `sdp-tools`, `ceda-scoop`, `maak_een_hex`, `docker_1cho` | +| **project** | `#0E8A16` | `project_algemeen`, `ceda-algemeen`, `communicatie`, `.github`, `clidev-presentaties`, `public_activities`, `centre_documentation`, `regiobijeenkomsten` | +| **overig** | `#757575` | `arbeidsmarkt-mbo`, `cbs-onderwijsdata`, `overzicht-landelijke-databronnen`, `samenwijzer`, `eencijfer`, `textanalysis` | + +Fallback voor onbekende repos: `overig`. + +### Stap 3: Data ophalen + +Haal 4 databronnen op voor alle actieve repo's: + +#### A. Commits op main + +Per actieve repo: +```bash +gh api "repos/cedanl/{repo}/commits?sha=main&since={SPRINT_START}&until={SPRINT_END}&per_page=100" \ + --jq '.[] | {sha: .sha, author: .author.login, message: .commit.message, date: .commit.author.date}' +``` + +Verzamel per repo: +- Totaal aantal commits +- Unieke contributors (GitHub usernames) +- Avatar URL per contributor: `https://github.com/{username}.png` + +#### B. CEDA Board status via GraphQL + +Haal alle items op van het CEDA Board (project #2) inclusief hun status: + +```bash +gh api graphql -f query=' +query($cursor: String) { + organization(login: "cedanl") { + projectV2(number: 2) { + items(first: 100, after: $cursor) { + nodes { + status: fieldValueByName(name: "Status") { + ... on ProjectV2ItemFieldSingleSelectValue { + name + } + } + iteratie: fieldValueByName(name: "Iteratie") { + ... on ProjectV2ItemFieldIterationValue { + title + } + } + content { + ... on Issue { + number + title + state + closedAt + url + body + repository { + name + } + issueType { + name + } + assignees(first: 5) { + nodes { + login + } + } + } + } + } + pageInfo { + hasNextPage + endCursor + } + } + } + } +} +' +``` + +**Let op:** gebruik GraphQL aliases (`status:` en `iteratie:`) omdat je twee `fieldValueByName` calls nodig hebt. + +Filter items op `iteratie.title == {huidige iteratie titel}` om alleen items van de actieve iteratie te tonen. + +Als `hasNextPage` true is, pagineer met `after: $endCursor`. + +Verzamel per board item: +- Status: Done / In Progress / Todo / On Hold +- Issue type: Pitch / Task / Bug (uit `issueType.name`) +- Repo naam (voor categorie-mapping) +- Assignees (voor avatars) +- `closedAt` (voor filtering op sprint-periode) +- `body` (voor scope-analyse bij Pitches) + +#### C. Functie-metric (20-100 regels) — alleen TOEGEVOEGDE code + +Per actieve repo met commits, haal de diff op: + +1. Bepaal het eerste commit SHA voor de sprint: +```bash +FIRST_SHA=$(gh api "repos/cedanl/{repo}/commits?sha=main&until={SPRINT_START}&per_page=1" --jq '.[0].sha') +``` + +2. Haal de compare op en filter op Python/R bestanden: +```bash +gh api "repos/cedanl/{repo}/compare/{FIRST_SHA}...main" \ + --jq '.files[] | select(.filename | test("\\.(py|R|r)$")) | {filename, patch}' +``` + +3. Analyseer alleen de `+` regels uit elke patch (toegevoegde code): + - **Python**: zoek naar `def ` blokken en tel regels tot het volgende `def`/`class` of dedent + - **R**: zoek naar `<- function(` of `= function(` blokken en tel regels tot de sluitende `}` + - Tel alleen functies van **20-100 regels** + +4. Dit is een proxy voor "echte logica toegevoegd" — niet boilerplate, niet one-liners, niet monolithen. + +5. Rapporteer per repo: "N functies (20-100 regels) toegevoegd" + +#### D. Bestanden geraakt + +Uit dezelfde compare API response: +```bash +gh api "repos/cedanl/{repo}/compare/{FIRST_SHA}...main" --jq '[.files[].filename] | length' +``` + +Context indicator (geen waardeoordeel): +- Breed (>20 bestanden) = feature/integratie werk +- Smal (<5 bestanden) = bugfix/refactor + +### Stap 4: Metrics berekenen + +1. **Opgeleverd**: Board items met Status=Done waarvan `closedAt` in de sprint-periode valt. Groepeer per type: + - Pitches afgerond + - Tasks afgerond + - Bugs afgerond + - **Ratio**: done / (done + in_progress + todo) — dit is de delivery ratio + +2. **Toevoegingen**: Totaal functies 20-100 regels per domein. + +3. **Scope per pitch**: Per Pitch op het board: + - Check de issue body voor tasklists: `- [ ]` (open) en `- [x]` (done) + - Check voor issue referenties (`#123`) in de body + - Tel done vs totaal sub-items + - Toont of een pitch echt af is of half + +4. **Bestanden geraakt**: Totaal unieke files per domein. + +### Stap 5: Genereer slides + +**BELANGRIJK: Geen `