# Les 13 — Externe APIs + Cursor + Vercel
## Docenttekst (Klas A — 3 uur, fysiek, demo-driven)

**Les:** 14 van 18
**Onderwerp:** Externe APIs + Cursor agents (Composer + Background) + Vercel preview deploys + GitHub Actions CI
**Duur:** 180 minuten
**Format:** Tim demonstreert klassikaal. Studenten kijken mee. Zelf bouwen = huiswerk.
**Demo-app:** Pokédex (PokéAPI, geen key, visueel) — nieuwe kleine app

---

## Hoe deze tekst werkt

- `[SLIDE X]` — klik naar slide X
- `[SCHERM: slides | cursor | terminal | browser | github | vercel]` — welk venster op de beamer
- **Vertel:** "..." — wat je zegt (mag eigen woorden)
- `*[stage direction]*` — instructie voor jezelf
- 💬 = verwachte studentenvraag

---

## VÓÓR DE LES — Setup (60 min)

### 1. Cursor versie checken

- Cursor moet `>=0.45` zijn voor Background Agents
- Pro account aktief (Tim's eigen) — Background Agents zitten daar in
- Test: `Cmd+Shift+P` → "Open Background Agent" zichtbaar in command palette
- Login bij Cursor cloud — eenmalige flow

### 2. Vercel + GitHub klaar

- Vercel account (Tim's eigen) — gekoppeld aan GitHub
- Test repo: maak vooraf 1 dummy-repo aan (om snel te kunnen demonstreren als demo crasht)
- Bookmark: vercel.com/dashboard, github.com/USER

### 3. Demo-app vooraf gemaakt (backup)

- Werkende `pokedex-demo` lokaal + op GitHub + op Vercel
- Als live coding faalt: switch hier naartoe, vertel "dit is hoe het er eindelijk uitziet"

### 4. Folder & terminal-tabs

- Werk-folder: `~/novi/novi-lessons/Les13-Cursor-Vercel-Deploy/live`
- 3 terminal tabs: project root, git-watcher (`watch git status`), Vercel CLI
- Cursor open met empty folder klaar
- Browser tabs vooraf open:
  - https://pokeapi.co/
  - https://vercel.com/dashboard
  - https://github.com (jouw user)
  - https://docs.cursor.com/background-agent (referentie)

### 5. Internet check

- Background Agents werken alleen met goede verbinding
- Vercel deploys ook
- Backup hotspot indien WiFi gisteren rare dingen deed

### 6. Backup screenshots

Heb klaar voor als demo faalt:
- Cursor Background Agent UI (run completed)
- GitHub PR met Vercel comment
- Vercel preview deploy
- GitHub Actions groene check
- Branch protection settings page

---

# HET SCRIPT — Lees mee tijdens de les

## BLOK 1 — Welkom + Terugblik (10 min)

`[SLIDE 1 — Title]` `[SCHERM: slides]`

**Vertel:** "Welkom bij les 14. Vandaag gaan we van localhost de wereld in. Externe APIs, Vercel, Cursor's coding agents, GitHub Actions CI. Heel hands-on."

`[SLIDE 2 — Terugblik]`

**Vertel:** "Lessen 11 t/m 13 gingen over AI: SDK, tools, agents. Alles draaide op jouw laptop. Dat was prima om te leren, maar in het echt deploy je iets en wil je dat anderen het kunnen gebruiken.

Vandaag drie dingen tegelijk. Een — externe APIs aanroepen. Geen LLM, gewoon data ophalen. Twee — die app naar Vercel. Drie — Cursor's twee agent-modes leren kennen en daarmee feature branches openen die automatisch preview-URLs krijgen op Vercel."

`[SLIDE 3 — Planning]`

**Vertel:** "Drie uur. Eerst 45 minuten theorie verdeeld over de drie onderwerpen. Daarna vier demos. Pauze rond minuut 90. Tot slot lesopdracht en huiswerk."

---

## BLOK 2 — Theorie Externe APIs (15 min)

`[SLIDE 4 — Wat is een externe API]`

**Vertel:** "Een externe API is een HTTP-endpoint van iemand anders. Je doet `fetch()`, je krijgt JSON. Klaar. Dat is het idee.

Drie smaken qua authenticatie. Geen key — PokéAPI en Open-Meteo bijvoorbeeld. Met key — Tavily, TMDB, de meeste paid APIs. OAuth — Google, GitHub user-data, dat is complexer.

In Next.js fetch je op twee plekken. Server-side, in een Server Component of API route. Of client-side, met `useEffect`. Server-side is bijna altijd beter voor initial data. Je key blijft veilig, het is gecached, en sneller."

`[SLIDE 5 — Code]`

**Vertel:** "Code voorbeeld. Server Component is `async`. Doe `fetch`, parse als JSON, return. Met `next: { revalidate: 3600 }` zegt je tegen Next.js: cache dit een uur. Eerste user triggert de fetch, de volgende honderd users krijgen de gecachte versie. Schaalbaar zonder dat je iets hoeft te doen.

💬 *Vraag: 'Wanneer client-side?'*

**Antwoord:** "Bij user-interactie. Een zoekbalk waar je live filtert — moet client-side, want de input verandert in de browser. Real-time updates, polling — client-side. Maar de eerste page-load: server-side."

---

## BLOK 3 — Theorie Cursor Agents (15 min)

`[SLIDE 6 — Composer vs Background]`

**Vertel:** "Cursor heeft TWEE soorten agents. Niet hetzelfde. Niet uitwisselbaar. Vandaag gaan we beide doen.

Composer. `Cmd+I`. Lokaal in je editor. Jij wacht, agent werkt, je ziet de diffs verschijnen. Je accepteert per file. Synchroon — je bent erbij. Dit is pair programming.

Background Agent. `Cmd+Shift+P` → 'Open Background Agent'. Runt in Cursor's cloud, niet jouw machine. Je geeft een prompt, gaat iets anders doen, komt terug. De agent maakt een branch, doet commits, opent een PR op GitHub. Asynchroon — je hoeft er niet bij te zijn.

Het verschil zit in waar je bent in je workflow. Composer voor exploreren, voor pair-programming, voor 'ik wil even meekijken'. Background Agent voor 'ik weet wat ik wil, voer maar uit terwijl ik vergader'."

💬 *Vraag: 'Kost Background Agent geld?'*

**Antwoord:** "Ja, zit in Cursor Pro. Twintig dollar per maand. Hobby-tier — gratis Cursor — heeft alleen Composer. Voor de huiswerk-opdracht: trial van Pro werkt prima, of vraag credits via Cursor support voor studenten."

💬 *Vraag: 'Hoe vergelijkt dit met Claude Code of OpenCode?'*

**Antwoord:** "Allemaal coding agents, allemaal goed. Cursor's Background Agent is uniek in dat-ie autonoom een PR opent — Claude Code en OpenCode draaien lokaal en doen geen PR-flow zelf. Het hangt af van je workflow. We zien beide in deze les."

---

## BLOK 4 — Theorie Vercel + CI (15 min)

`[SLIDE 7 — Vercel preview deploys]`

**Vertel:** "Vercel is hosting platform van de Next.js-makers. Voor Next.js apps de simpelste deploy ter wereld. Push naar GitHub, een minuut later: live.

Het magische zit in **preview deploys**. Elke branch krijgt automatisch een eigen URL. Niet alleen `main` — letterlijk elke. Push naar `feature/search` → `je-app-git-feature-search-user.vercel.app` is live. PR's krijgen een comment met de URL.

Waarom is dit zo krachtig? Background Agent maakt een PR — preview URL is direct klikbaar. Reviewer test de feature live, niet alleen code-diff. Stakeholders kunnen iets zien. Geen 'werkt op mijn laptop'-discussies meer.

Environments — drie scopes. Production = main. Preview = alle andere branches. Development = lokaal. Per env-variabele kies je waar-ie beschikbaar is."

`[SLIDE 8 — GitHub Actions CI]`

**Vertel:** "Last theory bit. GitHub Actions. Een script dat draait wanneer er iets gebeurt — push, PR, merge.

Minimaal voor dit vak: lint en build per PR. Eerst tien regels YAML, daarna heb je voor elke PR: lint draait, TypeScript build slaagt, anders rode X.

Waarom belangrijk? Background Agent kan typo's maken. CI vangt dat op voor je merget. Plus: 'werkte op mijn laptop' bestaat niet meer."

---

## BLOK 5 — Demo 1: Pokédex met Composer (30 min)

`[SLIDE 9 — Wat we bouwen]`

**Vertel:** "Tijd voor demo. We bouwen vandaag een Pokédex. PokéAPI heeft data van duizend Pokémon, geen key nodig, gratis. Vier features in totaal — twee met Composer nu, twee met Background Agent na de pauze."

`[SLIDE 10 — DEMO 1]` `[SCHERM: terminal + cursor]`

**Vertel:** "Klas, kijk mee. Vragen tussendoor mogen."

`*[Terminal:]*`

```bash
cd ~/novi/novi-lessons/Les13-Cursor-Vercel-Deploy
pnpm create next-app@latest pokedex \
  --typescript --tailwind --app --no-src-dir --import-alias "@/*"
cd pokedex
cursor .
```

`*[Cursor opens]*`

**Vertel:** "Cursor open. Nu Composer. Op Mac: `Cmd+I`. Op Windows: `Ctrl+I`."

`*[Cmd+I — Composer panel opens]*`

**Vertel:** "Composer is een tab in Cursor — niet hetzelfde als de gewone Chat. Composer kan meerdere files tegelijk wijzigen. Chat alleen één antwoord per keer."

`*[Type in Composer:]*`

> Bouw een Pokédex-startpagina op `app/page.tsx`. Haal de eerste 151 Pokémon op van `https://pokeapi.co/api/v2/pokemon?limit=151` als async Server Component. Toon in een grid van cards (Tailwind, 4 kolommen op desktop, 2 op tablet, 1 op mobile). Elke card: naam (capitalized), sprite van `https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/{id}.png`, en het Pokemon nummer (#001). Hover effect: card lichtjes vergroten en schaduw. Gebruik `next/image`. Voeg PokéAPI's sprite domain toe aan `next.config.ts`.

**Vertel:** "Klik 'Submit'. Composer denkt na. Je ziet diffs verschijnen — `app/page.tsx`, eventueel `next.config.ts`."

`*[Accept all diffs]*`

```bash
pnpm dev
```

`*[Open browser → localhost:3000]*`

**Vertel:** "Daar staan onze 151 Pokémon. Werkt out of the box."

💬 *Vraag: 'Hoe weet Composer welke files te wijzigen?'*

**Antwoord:** "Cursor heeft toegang tot je hele workspace. Composer ziet de file-structure, package.json, alles. Hij beslist zelf welke files relevant zijn voor de prompt. Soms vraagt hij om bevestiging — vooral bij nieuwe files."

`*[Tweede Composer prompt:]*`

> Voeg detail-pagina toe op `app/pokemon/[name]/page.tsx`. Toon: grote sprite van `https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/{id}.png`, de naam, types als gekleurde chips (gebruik officiële Pokemon type colors zoals fire = red, water = blue, etc), en stats (HP, Attack, Defense, Sp.Atk, Sp.Def, Speed) als progress bars die de waarde tonen. Voeg height + weight onderaan. Link de homepage-cards naar `/pokemon/{name}`.

`*[Accept diffs, refresh browser, klik op een card]*`

**Vertel:** "Detail-pagina werkt. Stats als balkjes. Types met kleurtjes. Composer heeft type-colors zelf gevonden — die zitten in zijn training data."

`*[Optioneel — als tijd:]*`

> De stats balkjes zijn te dun en de kleur is wat saai. Maak ze dikker en gebruik een paarse gradient.

**Vertel:** "Composer kan ook polish doen. Twee minuten later: betere UI. Dit is wat ik bedoelde met 'pair programming' — snel iteraten op visuals."

---

## BLOK 6 — Demo 2: Vercel deploy (15 min)

`[SLIDE 11 — DEMO 2]` `[SCHERM: terminal + github + vercel]`

**Vertel:** "App werkt lokaal. Nu de wereld in."

`*[Terminal:]*`

```bash
git init
git add .
git commit -m "Initial Pokédex with Composer"
git branch -M main
```

`*[Browser → github.com/new]*`

**Vertel:** "Nieuwe repo. Naam: pokedex. Public — geen secrets in onze code dus public mag. Géén README, géén license — Next.js heeft alles al."

`*[Klik 'Create repository']*`

```bash
git remote add origin https://github.com/JOUW-USER/pokedex.git
git push -u origin main
```

`*[Refresh GitHub — code is daar]*`

`*[Browser → vercel.com/dashboard]*` `[SCHERM: vercel]`

**Vertel:** "Vercel. Add New → Project. Import Git Repository. Kies pokedex."

`*[Op import-screen — alle defaults laten staan]*`

**Vertel:** "Vercel detecteert Next.js automatisch. Build command: `pnpm build`. Output directory: `.next`. Niks aanpassen. Klik Deploy."

`*[Wachten ~60-90s]*`

**Vertel:** "Tijdens het builden: dit is wat er gebeurt. Vercel pulled je code van GitHub, install dependencies, runt `pnpm build`. Output gaat naar hun CDN. Klaar.

`*[Build done — klik op URL]*`

**Vertel:** "Daar staat-ie. Productie URL. Live."

`*[Demonstreer: open URL op je telefoon — werkt]*`

**Vertel:** "Werkt op telefoon. Werkt overal. Internet."

`*[Terug naar Cursor — kleine wijziging:]*`

`*[Composer:]*` "Verander de h1 van 'Pokédex' naar 'Mijn Pokédex (Live!)'"

```bash
git add . && git commit -m "Update title" && git push
```

`*[Browser → Vercel dashboard]*`

**Vertel:** "Nieuwe deploy verschijnt direct. Wacht 30 seconden..."

`*[Refresh productie URL]*`

**Vertel:** "Nieuwe titel zichtbaar. Geen extra commando. Push naar main = deploy."

💬 *Vraag: 'En als de build faalt?'*

**Antwoord:** "Productie blijft op de laatste werkende versie. Vercel deployt alleen als build slaagt. Je krijgt mail dat de build mislukte, productie blijft online. Geen downtime."

---

## BLOK 7 — Pauze (15 min)

`[SLIDE 12 — Pauze]`

**Vertel:** "Pauze. Vijftien minuten."

`*[Tijdens pauze: open Cursor Background Agent flow alvast — zorg dat repo geconnect is]*`

---

## BLOK 8 — Demo 3: Background Agent (25 min)

`[SLIDE 13 — DEMO 3]` `[SCHERM: cursor + github + vercel]`

**Vertel:** "Nu de Background Agent. Dit is écht anders. Geen pair-programming meer — we delegeren."

`*[Cursor: Cmd+Shift+P]*`

**Vertel:** "Cmd+Shift+P opent command palette. Type 'Background Agent'."

`*[Select 'Open Background Agent']*`

**Vertel:** "Eerste keer: Cursor vraagt verbinding met je repo. Volg de flow — opent browser, OAuth met GitHub, Cursor mag in jouw cloud sandbox draaien."

`*[Connect flow]*`

**Vertel:** "Klaar. Nu de prompt. Belangrijk: SPECIFIEK zijn. De agent ziet ons niet. Hij krijgt alleen de prompt."

`*[Schrijf:]*`

> Maak een nieuwe branch `feature/search`. Voeg een controlled input toe bovenaan `app/page.tsx`. Wanneer gebruiker typt, filter de Pokémon-lijst case-insensitive op naam. Houd Tailwind-styling consistent met bestaande cards (rounded corners, padding p-4). Voeg een count toe rechtsboven: "X van 151 zichtbaar". Push de branch en open een PR met titel "Add search bar". PR body: korte beschrijving + screenshot suggestie.

`*[Submit]*`

**Vertel:** "Agent draait nu. Cursor toont je een panel waarin je kunt zien wat-ie doet — bestanden inlezen, edits maken, terminal commands."

`*[Wachten ~3-5 minuten. Tijdens wachten:]*`

**Vertel:** "Belangrijk om uit te leggen — terwijl deze agent draait, ben ik vrij om iets anders te doen. Lokaal coden, Composer gebruiken voor andere features, koffie halen. Dat is het voordeel.

Andere relevante punten. Agent draait in Cursor's sandbox — niet jouw laptop. Hij heeft toegang tot je repo, kan `pnpm install` doen, kan tests draaien, kan PR's openen. Maar hij heeft GEEN toegang tot jouw productie-secrets of services. Sandbox is geïsoleerd."

`*[Agent done — PR verschijnt op GitHub]*` `[SCHERM: github]`

**Vertel:** "Pull request op GitHub. Klik."

`*[PR open]*`

**Vertel:** "Vercel heeft een comment achtergelaten — preview URL. Klik."

`*[Browser → Vercel preview URL]*`

**Vertel:** "Live, op een ANDERE URL dan productie. Test zoekbalk."

`*[Type 'pika' — Pikachu blijft over]*`

**Vertel:** "Werkt. Search live op preview URL. Productie ongewijzigd."

`*[Terug naar GitHub PR — Files Changed tab]*`

**Vertel:** "Code-review. Agent heeft `app/page.tsx` aangepast, eventueel een nieuwe component gemaakt. Lees diff, check of het ok is."

`*[Eventueel: comment in PR]*`

**Vertel:** "Stel ik wil een wijziging — bv. 'voeg ook een clear-button toe'. Twee opties. Een: open de branch lokaal, Composer fix. Twee: nieuwe Background Agent prompt op deze branch. Voor demo doen we optie twee."

`*[Cursor → Background Agent → existing or new]*`

> Op de bestaande branch feature/search: voeg een 'X' clear-button toe rechts in de zoekinput die de input leegmaakt.

`*[Wacht 2-3 min, refresh PR, refresh preview URL]*`

**Vertel:** "Update zichtbaar. Klik X — input leeg. Werkt."

`*[Eventueel: merge]*`

**Vertel:** "Tevreden? Merge PR. Vercel productie-deploy start automatisch. Een minuut later: search live op productie."

💬 *Vraag: 'Wat als agent vastloopt?'*

**Antwoord:** "Twee opties. Pakje sluiten en opnieuw beginnen met betere prompt. Of: open de branch lokaal, kijk wat agent gedaan heeft, fix met Composer. De agent is geen blackbox — hij commit echt op een branch, je kunt erin kijken."

---

## BLOK 9 — Demo 4: GitHub Actions CI (15 min)

`[SLIDE 14 — DEMO 4]` `[SCHERM: cursor + github]`

**Vertel:** "Laatste demo. CI. Eén check per PR — lint + build."

`*[Cursor → Composer]*`

> Voeg een GitHub Actions workflow toe: `.github/workflows/ci.yml`. Runt op pull_request en push naar main. Steps: checkout, install pnpm 9, setup node 20 met pnpm cache, install dependencies met frozen lockfile, run lint, run build.

`*[Accept diffs]*`

`*[Terminal:]*`

```bash
git checkout -b chore/add-ci
git add .github/workflows/ci.yml
git commit -m "Add CI workflow"
git push -u origin chore/add-ci
```

`*[GitHub → openen PR]*` `[SCHERM: github]`

**Vertel:** "PR open. Klik tab 'Actions' — workflow draait. ~1-2 min."

`*[Wacht]*`

**Vertel:** "Groene check verschijnt. Merge PR. CI is nu live op elke toekomstige PR."

`*[Demo: failing CI]*`

**Vertel:** "Laat ik laten zien wat er gebeurt bij een fout."

`*[Cursor → Composer:]*`

> Maak een TypeScript fout in app/page.tsx. Verwijder een belangrijke import. Push naar een nieuwe branch chore/test-ci-fail.

```bash
git push -u origin chore/test-ci-fail
```

`*[GitHub → PR open → wait]*`

**Vertel:** "Rode X. Build faalt. Klik op de details — daar staat letterlijk wat mis is."

`*[Fix met Composer]*`

> Repareer de TypeScript-fout in app/page.tsx (voeg de import terug). Commit.

```bash
git push
```

`*[Wacht — groene check]*`

**Vertel:** "Fixed. CI groen. Merge mag nu."

`*[Branch protection toevoegen — kort]*` `[SCHERM: github settings]`

**Vertel:** "Tot slot — branch protection. Settings → Branches → Add rule. Branch pattern: main. Vink aan: require PR before merging. Require status checks: select onze CI workflow. Save.

Wat dit doet: niemand kan nog direct naar main pushen. Background Agents werken via PRs — dat blijft werken. PR moet groene CI hebben voor merge."

`*[Demo: probeer direct push naar main]*`

```bash
git checkout main && echo "test" >> README.md && git commit -am "direct" && git push
```

```
! [remote rejected] main -> main (protected branch hook declined)
```

**Vertel:** "Geblokkeerd. Goed."

---

## BLOK 10 — Composer vs Background reflectie (10 min)

`[SLIDE 15 — Wanneer welke]`

**Vertel:** "Twee tools, één keuze per taak. Wanneer welke?

Composer voor pair-programming. Snel feedback, jij stuurt, agent voert uit, jij accepteert per diff. Goed voor: exploreren, leren, refactors waar je wilt meekijken.

Background Agent voor delegatie. Specifieke feature, kun je niet bij zijn, parallel werken aan andere taken. Goed voor: PR-prep, parallel werken aan 3 features, terwijl-je-vergadert.

Risico's bij Background. Vage prompts = vage PR's. Specifiek zijn helpt. Agent kost credits — voor solo-projecten geen issue, voor teams kan oplopen.

Wat ik zelf doe: 80% Composer, 20% Background. Background voor de écht goed-gedefinieerde features die ik dan parallel laat draaien."

💬 *Vraag: 'Welke is beter voor onze eindopdracht?'*

**Antwoord:** "Beide. Ontwerpen + leren = Composer. Specifieke features uitwerken = Background. Voor de eindopdracht-pitch: laat zien dat je beide kunt — dat is een vaardigheid."

---

## BLOK 11 — Lesopdracht + Huiswerk (10 min)

`[SLIDE 16 — Lesopdracht + Huiswerk]`

**Vertel:** "Lesopdracht — in de les. Half uur. Je eigen Pokédex setuppen, één feature met Composer, push naar GitHub, deploy op Vercel. Aan het eind: jouw eigen productie-URL.

Huiswerk — voor volgende week. Vier dingen.

Een: feature toevoegen via Background Agent. Branch + PR + preview URL.

Twee: GitHub Actions CI workflow. Lint + build per PR.

Drie: branch protection op main. PR's verplicht, CI moet groen.

Vier: DEPLOY.md schrijven. URLs, prompt die je aan Background Agent gaf, reflectie over Composer vs Background, bewijs van CI (groen + rood voorbeeld), één observatie.

Bonus: tweede externe API, environment scoping, parallelle Background Agents.

Tien punten, voldoende is zes. Inleveren via Brightspace: repo URL + productie URL + DEPLOY.md."

---

## BLOK 12 — Afsluiting (5 min)

`[SLIDE 17 — Afsluiting]`

**Vertel:** "Wat hebben we vandaag gedaan. Externe APIs in Server Components. Cursor Composer voor synchrone werk. Cursor Background Agent voor async PR's. Vercel productie + preview per branch. GitHub Actions CI. Branch protection.

Volgende les: RAG en embeddings. Vector search met pgvector. We bouwen een tool die semantic search doet — handig om in een agent te plakken. Combo van les 13 en 15.

Daarna: performance + observability, eindopdracht-werkdagen, pitch.

Vragen?"

`*[Vragenronde — minstens 5 min over laten]*`

---

## NA DE LES — Wrap-up

- Push working `pokedex` repo naar GitHub als referentie voor studenten
- Brightspace: link naar referentie-repo + huiswerk-instructies
- Verzamel vragen die niet beantwoord — terug in Les 13 opening
- Voor Klas B (later): check of Cursor Pro licenties beschikbaar zijn voor studenten, anders Background Agent demo moeilijk

---

## Veelvoorkomende fouten tijdens live coding

| Fout | Oplossing |
|------|-----------|
| `next/image` PokéAPI domain error | Composer: "voeg images.remotePatterns toe in next.config.ts" |
| Cursor Composer onresponsive | Cmd+I opnieuw, of restart Cursor |
| Background Agent verbinding faalt | Logout/login Cursor cloud, refresh repo connection |
| Vercel deploy faalt: missing dep | `pnpm install` lokaal, commit lockfile, push |
| GitHub Actions: pnpm not found | Check `pnpm/action-setup@v3` versie in yml |
| Branch protection: kan eigen PR niet mergen | Tijdens demo: voeg jezelf toe als bypass user |
| Preview URL 404 | Wachten — eerste build duurt soms 2 min |
| Background Agent fixt verkeerde files | Te vage prompt — specifiek met file paths volgende keer |

---

## Mentale model voor de klas

Als studenten verward zijn over de Cursor agent-modes:

> **Composer** = jij pair-programt met AI. Synchroon. Cmd+I. Lokaal.
>
> **Background Agent** = jij delegeert aan AI. Async. Cmd+Shift+P. Cloud. Opent PR.

Belangrijkste regel voor Background Agent: prompts moeten zo specifiek zijn alsof je het aan een nieuwe junior junior dev op afstand uitlegt. Geen context-cues, geen "je weet wel".
