# Les 2 — OpenCode Pro ## Lesstof — Rules, Worktrees & Scroll Animations **Vak:** AI-Assisted Development **Opleiding:** NOVI Hogeschool Utrecht **Onderwerp:** OpenCode Desktop professioneel inzetten met regels, config en parallel worktrees --- ## Inhoudsopgave 1. [OpenCode in 2026](#1-opencode-in-2026) 2. [TUI vs Desktop — welke kies je?](#2-tui-vs-desktop) 3. [Plan/Build/@explore + /init](#3-planbuildexplore--init) 4. [`AGENTS.md` — het officiële regelbestand](#4-agentsmd--het-officiele-regelbestand) 5. [`opencode.json` — config & permissies](#5-opencodejson--config--permissies) 6. [Plugins & `opencode-worktree`](#6-plugins--opencode-worktree) 7. [De scroll-animatie stack (Next.js 16)](#7-de-scroll-animatie-stack) 8. [Project setup van A tot Z](#8-project-setup-van-a-tot-z) 9. [Workflow patterns](#9-workflow-patterns) 10. [Bronnen](#10-bronnen) --- ## 1. OpenCode in 2026 OpenCode is een open-source AI coding-IDE. 60.000+ GitHub stars. Gemaakt door SST. Provider-agnostisch — werkt met OpenAI, Anthropic, Google, Groq, lokale modellen via Ollama, en meer. Vergelijkbaar concept als Cursor of Claude Code, maar: - **Open source** — geen vendor lock-in - **Provider-keuze** — niet vast aan één AI-bedrijf - **Script-vriendelijk** — perfect voor automation, CI/CD, plugins - **Twee smaken:** Desktop (UI) en TUI (terminal) ### Desktop App (vandaag onze keuze) Native app voor macOS, Windows, Linux. Download via https://opencode.ai/download. Layout (globaal): - **File tree** links — bestanden + folders, right-click voor acties - **Diff viewer** midden — visueel groen/rood met klik-accept/reject - **Chat panel** onder — prompts naar de agent - **Sessions sidebar** links — meerdere parallelle sessies (voor worktrees!) - **Ingebouwde terminal** — onderaan, optioneel ### TUI (terminal) ```bash npm i -g opencode-ai@latest opencode ``` Zelfde engine, zelfde commando's, zelfde plugins. Goed voor SSH, scripts, CI/CD. --- ## 2. TUI vs Desktop — Welke kies je? | Aspect | TUI | Desktop | |--------|-----|---------| | Leercurve | Steiler — alles via keyboard | Vlakker — visueel | | Diff review | Plain text inline | Visuele diff-viewer | | Files browsen | Via @-references | File tree zichtbaar | | Sessies parallel | Tmux / aparte terminals | Sessions sidebar | | SSH / headless servers | ✅ | ❌ (X-server nodig) | | Worktree plugin auto-spawn | ✅ (spawnt terminal) | ❌ (handmatige tab) | | Snel typen / muscle memory | ✅ | Ok, maar trager | | Scripted workflows | ✅ | Beperkt | ### Wanneer wel TUI? - **SSH-only servers** — geen X11 nodig - **CI/CD pipelines** — scripted invocaties - **Tmux fans** — past in je tmux setup - **Worktree power-users** — auto-terminal-spawn van de plugin ### Onze keuze voor deze les en eindopdracht: Desktop Sneller te leren, visueler, beter voor parallel-werken via Sessions sidebar. --- ## 3. Plan/Build/@explore + /init ### Plan vs Build mode OpenCode heeft twee modes — Tab om te wisselen. **Plan mode** is read-only. Tools: `read`, `grep`, `glob`, `webfetch`. Geen edits, geen shell commands. Goed voor brainstorm / verkenning. **Build mode** is default. Alle tools aan. Schrijft code, voert commands uit. Best practice: begin **altijd** in plan-mode. Laat het uitleggen wat het van plan is. Geef feedback. Pas dan Tab → build. ### Sub-agents Drie ingebouwde sub-agents: | Naam | Wat | Wanneer | |------|-----|---------| | `@explore` | Read-only verkenning | "Waar staat X?" "Wat is dit?" | | `@general` | Brede taak-agent | Default voor de meeste taken | | `@scout` | Gerichte zoekopdracht | "Vind alle plaatsen waar..." | Manuele aanroep: `@explore vind alle authenticatie code`. Primaire agent kan ze ook autonoom inschakelen. ### `/init` commando In de chat: `/init`. OpenCode scant je repo, stelt vragen, en genereert/update je `AGENTS.md`. Doe dit **als eerste actie** in elk nieuw project. Daarna kun je het bestand uitbreiden met jouw specifieke regels. ### Belangrijke keybinds (Desktop én TUI) | Shortcut | Actie | |----------|-------| | `Tab` | Wissel plan ↔ build | | `Enter` | Submit | | `Esc` | Cancel | | `Ctrl+X h` | Help (alle bindings) | | `Ctrl+D` | Exit (TUI) | Leader-key voor commando-specifieke bindings: `Ctrl+X`. Customizen via `~/.config/opencode/tui.json` of in Desktop settings. --- ## 4. `AGENTS.md` — Het officiële regelbestand `AGENTS.md` is markdown in je project-root die OpenCode automatisch in elke context laadt. Officieel format. Expliciet vergeleken in de docs met Cursor's `.cursorrules`. ### Twee locaties | Pad | Wanneer | |-----|---------| | `./AGENTS.md` | Per project (in repo, geversioneerd) | | `~/.config/opencode/AGENTS.md` | Globaal voor alle projecten | ### Externe regels referencen ```markdown # Stack rules @rules/styling.md @rules/security.md ``` OpenCode laadt deze lazy via z'n Read-tool — pas wanneer relevant. ### Voorbeeld voor scroll-animatie project ```markdown # Project Rules ## Why this stack High-end scroll storytelling site (Awwwards/FWA niveau). GSAP + Lenis = pro standaard — Apple, Stripe, OpenAI, Active Theory, Locomotive, Darkroom Engineering. Framer Motion is voor app UI, niet voor scroll storytelling. Kies GSAP voor timing-precisie + GPU-perf. ## Stack - Next.js 16 (App Router, TypeScript, Turbopack) - TailwindCSS voor styling - GSAP 3.15+ (incl. ScrollTrigger, SplitText) met `@gsap/react` - Lenis 1.3+ (`lenis/react`) voor smooth scroll ## Hard rules - Geen Framer Motion, react-spring, AOS - Animaties altijd in Client Components (`"use client"`) - ScrollTrigger registratie 1x per file - Animatie-code altijd binnen `useGSAP(() => {}, { scope: ref })` - Nooit `useEffect` voor GSAP code - Lenis sync: `gsap.ticker.add` met `autoRaf: false` - **Async params (Next 16):** altijd `await params` en `await searchParams` ## Patterns - Eén `` wrapper in `app/layout.tsx` - Refs i.p.v. globale selectors; scope animaties - Tailwind voor layout/typografie; GSAP voor transform/opacity - Geen `transition-*` Tailwind classes op geanimeerde elementen ## Done = - Geen hydration warnings - Werkt in React Strict Mode - `ScrollTrigger.refresh()` na dynamische content ``` **De `## Why this stack` sectie is cruciaal.** Hiermee snapt de agent *waarom* we deze keuzes maken — niet alleen *wat*. Resultaat: hij stelt op eigen initiatief geen Framer Motion meer voor, want hij begrijpt dat we voor scroll storytelling werken. ### Tips voor goede AGENTS.md - **Concreet, niet vaag.** "Gebruik clean code" werkt niet. "useGSAP alleen, geen useEffect" wel. - **Versie-pinning** voor libraries die snel veranderen. - **Definitie van klaar** — checkpoints die de agent zelf kan toetsen. - **Anti-patterns expliciet noemen** — "Geen Framer Motion" voorkomt veel discussie. --- ## 5. `opencode.json` — Config & Permissies ### Locaties | Pad | Scope | |-----|-------| | `./opencode.json` | Per project | | `~/.config/opencode/opencode.json` | Globaal | ### Basis voorbeeld ```json { "$schema": "https://opencode.ai/config.json", "model": "openai/gpt-4o-mini" } ``` Model formaat: `provider/model-id`. Voorbeelden: - `openai/gpt-4o-mini` - `openai/gpt-4o` - `anthropic/claude-sonnet-4` - `groq/llama-3.3-70b-versatile` ### Permissies ```json { "$schema": "https://opencode.ai/config.json", "permission": { "bash": { "*": "ask", "git *": "allow", "rm *": "deny" }, "edit": { "*": "deny", "app/**/*.tsx": "allow", "components/**": "allow" } } } ``` Drie levels: `allow`, `ask`, `deny`. Glob patterns voor bash commands en file paths. ### Plugin syntax (npm) ```json { "plugin": [ "@anthropic/some-plugin@1.0.0" ] } ``` OpenCode installeert plugins automatisch via Bun in `~/.cache/opencode/node_modules/` bij het opstarten. ### MCP servers (optioneel) ```json { "mcp": { "context7": { "type": "local", "command": "npx", "args": ["-y", "@upstash/context7-mcp"] } } } ``` Voor up-to-date library docs binnen je AI-context. Niet vereist voor deze les. --- ## 6. Plugins & `opencode-worktree` ### Wat is `opencode-worktree`? Plugin van **kdcokenny** (community maker, ook achter `ocx` en `opencode-workspace`). **Wat doet het?** Geeft de agent twee nieuwe tools: - `worktree_create` — maakt nieuwe branch + worktree-folder - `worktree_delete` — commit changes + cleanup **Worktree-locatie:** `~/.local/share/opencode/worktree///` ### Installatie via `ocx` ```bash # Eenmalig: ocx installeren curl -fsSL https://kdco.dev/ocx/install.sh | sh # Plugin toevoegen ocx add kdco/worktree --from https://registry.kdco.dev ``` Restart OpenCode na install. ### Verschil Desktop vs TUI | Actie | TUI | Desktop | |-------|-----|---------| | `worktree_create` aanroepen | ✅ | ✅ | | `worktree_delete` aanroepen | ✅ | ✅ | | **Auto nieuw terminal venster** | ✅ | ❌ | | Nieuwe context openen | Auto | Handmatig (Sessions sidebar) | In Desktop maakt de plugin de worktree, daarna open je hem zelf in een nieuwe Sessions tab. ### Workflow in Desktop 1. In je hoofd-Session: `Maak een worktree voor feature-hero.` 2. Plugin maakt worktree-folder 3. Klik **+ New Session** in sidebar 4. **Open Folder** → navigate naar de worktree-folder 5. Nu heb je 2 sessies parallel in sidebar — main + feature-hero 6. Klik tussen sessies om te wisselen ### Handmatig alternatief (zonder plugin) ```bash git worktree add ../mijn-repo-hero -b feature-hero ``` Dan handmatig nieuwe Session openen op die folder. ### Best practices - Eén opencode-instance per worktree-directory (gouden regel) - Niet wisselen tussen sessies van verschillende worktrees binnen één session-context (cwd-bug) - Branch name = folder name (makkelijker zoeken in `git worktree list`) - Cleanup na merge — niet stapelen --- ## 7. De scroll-animatie stack ### Next.js 16 (mei 2026) Uitgekomen oktober 2025. **Breaking changes ten opzichte van 15:** - **Async API's verplicht:** `cookies()`, `headers()`, `params`, `searchParams` zijn nu allemaal async. Altijd `await`: ```tsx // app/products/[id]/page.tsx export default async function Page({ params }: { params: Promise<{ id: string }> }) { const { id } = await params; // VERPLICHT in 16 return
{id}
; } ``` - **Turbopack is default** voor `dev` en `build`. Webpack alleen via opt-in. - **`middleware.ts` → `proxy.ts`** met nieuwe Node.js runtime. - **`revalidateTag` vereist 2e argument** (cacheLife profile). - **Node.js 20.9+** vereist (18 is dropped). ### Waarom GSAP + Lenis? Dit is **dé** stack voor scroll storytelling op pro-niveau. Niet "een" optie — de standaard. **Wie gebruikt dit?** - **Apple** — product pages met scroll-revealed content - **Stripe** — homepage en product pages - **OpenAI** marketing pages - **Awwwards / FWA winnaars** — vrijwel altijd GSAP - Pro studios: **Active Theory**, **Locomotive**, **Resn**, **Darkroom Engineering** (makers van Lenis) **Waarom niet Framer Motion?** - Framer Motion is uitstekend voor **app UI** — modals, page transitions, micro-interacties - Maar voor **scroll storytelling** (jouw eindopdracht): GSAP heeft betere timing-precisie en GPU-optimalisaties - Daarom: Framer Motion voor app-werk, GSAP voor scroll-werk **Andere voordelen:** - **GSAP sinds januari 2025: 100% gratis** onder de "no charge" license — incl. ScrollTrigger, SplitText, MorphSVG (vroeger premium) - **Lenis** integreert naadloos met ScrollTrigger via één RAF sync - Beide zijn **populair op v0 en Cursor** — AI's kennen de patterns goed Schrijf dit op in je `AGENTS.md` (sectie `## Why this stack`). Dan kiest je AI agent dezelfde keuzes om dezelfde redenen. ### Packages ```bash npm install gsap @gsap/react lenis ``` **Belangrijk:** - Pakket heet **`lenis`** (niet meer `@studio-freight/lenis`) - `@gsap/react` geeft je de officiele `useGSAP` hook ### De `useGSAP` hook Drop-in vervanger voor `useEffect`/`useLayoutEffect` voor GSAP code. Doet automatisch cleanup via `gsap.context()`. Werkt veilig met React Strict Mode en SSR. ```tsx "use client"; import { useRef } from "react"; import gsap from "gsap"; import { ScrollTrigger } from "gsap/ScrollTrigger"; import { useGSAP } from "@gsap/react"; gsap.registerPlugin(useGSAP, ScrollTrigger); export default function FadeIn() { const ref = useRef(null); useGSAP(() => { gsap.from(".fade-item", { opacity: 0, y: 60, duration: 1, stagger: 0.15, scrollTrigger: { trigger: ref.current, start: "top 80%", }, }); }, { scope: ref }); return (

Hello scroll

Ik fade in.

); } ``` ### Lenis sync met ScrollTrigger Zonder sync lopen GSAP en Lenis hun eigen requestAnimationFrame — animaties haperen. Officieel patroon: `autoRaf: false` op Lenis, GSAP's ticker drijft Lenis aan. ```tsx // components/SmoothScroll.tsx "use client"; import { ReactLenis, type LenisRef } from "lenis/react"; import { useEffect, useRef } from "react"; import gsap from "gsap"; import { ScrollTrigger } from "gsap/ScrollTrigger"; gsap.registerPlugin(ScrollTrigger); export default function SmoothScroll({ children }: { children: React.ReactNode }) { const lenisRef = useRef(null); useEffect(() => { function update(time: number) { lenisRef.current?.lenis?.raf(time * 1000); } gsap.ticker.add(update); gsap.ticker.lagSmoothing(0); return () => gsap.ticker.remove(update); }, []); return ( {children} ); } ``` In `app/layout.tsx`: ```tsx import SmoothScroll from "@/components/SmoothScroll"; import "./globals.css"; export default function RootLayout({ children }: { children: React.ReactNode }) { return ( {children} ); } ``` --- ## 8. Project setup van A tot Z ### Stap 1 — Next.js 16 project aanmaken ```bash npx create-next-app@latest scroll-site \ --typescript --tailwind --app --eslint --no-src-dir --turbopack cd scroll-site ``` ### Stap 2 — Animation dependencies ```bash npm install gsap @gsap/react lenis ``` ### Stap 3 — Git init + first commit ```bash git init git add . git commit -m "init: next 16 + gsap + lenis" ``` ### Stap 4 — `AGENTS.md` toevoegen Plak het voorbeeld uit sectie 4 in `AGENTS.md` in root. Pas aan op jouw project. ### Stap 5 — `opencode.json` toevoegen ```json { "$schema": "https://opencode.ai/config.json", "model": "openai/gpt-4o-mini", "permission": { "bash": { "*": "ask", "git *": "allow", "npm *": "allow", "rm *": "deny" } } } ``` ### Stap 6 — OpenCode Desktop starten Open OpenCode Desktop → File → Open Folder → `scroll-site`. In chat: `/init` om je AGENTS.md te valideren. ### Stap 7 — SmoothScroll wrapper bouwen Vraag in chat: > Bouw een SmoothScroll wrapper component volgens onze AGENTS.md. Plaats hem in `components/SmoothScroll.tsx` en wrap children in `app/layout.tsx`. Plan-mode → review → Tab → Build-mode. ### Stap 8 — Eerste worktree > Maak een worktree voor feature-hero en bouw daar een hero-sectie met een SplitText-reveal op scroll. Plugin maakt worktree → open nieuwe Sessions tab op die folder → agent bouwt. --- ## 9. Workflow patterns ### Pattern 1 — Plan eerst, dan Build Begin altijd in **plan-mode**. Laat de agent uitleggen wat het van plan is. Geef feedback. Pas dan Tab → build. ### Pattern 2 — Eén worktree per feature Werk niet alles in main. Een feature = een worktree = een branch. Makkelijk parallel + makkelijk reviewen via PR. ### Pattern 3 — `AGENTS.md` evolueert Loop je tegen iets aan dat steeds verkeerd gaat? Voeg toe aan AGENTS.md. Het is een levend document. ### Pattern 4 — `@explore` voor verkenning Nieuwe codebase of vergeten waar iets staat? `@explore` eerst, dan pas hoofd-agent inzetten. Spaart tokens en geeft jou betere context. ### Pattern 5 — Permissions matchen je risico Beginnersproject: `bash.*` op `ask`. Productie-werk: alleen specifieke folders editable. Schrijf permissions naar het werk dat je doet. ### Pattern 6 — Sessions sidebar = jouw parallel werk Eén Session = orchestrator (in main). Worktrees met aparte Sessions = workers. Orchestrator stuurt, workers bouwen. Klik tussen tabs. --- ## 10. Bronnen ### OpenCode officieel - Hoofdsite: https://opencode.ai - Download (Desktop): https://opencode.ai/download - Docs: https://opencode.ai/docs/ - Rules (`AGENTS.md`): https://opencode.ai/docs/rules/ - Config: https://opencode.ai/docs/config/ - Plugins: https://opencode.ai/docs/plugins/ - Agents (sub-agents): https://opencode.ai/docs/agents/ - Modes: https://opencode.ai/docs/modes/ - Commands: https://opencode.ai/docs/commands/ - Permissions: https://opencode.ai/docs/permissions/ - GitHub: https://github.com/sst/opencode - DeepWiki Desktop apps: https://deepwiki.com/sst/opencode/6.7-desktop-applications ### Plugin ecosystem - `opencode-worktree`: https://github.com/kdcokenny/opencode-worktree - `ocx` extension manager: https://github.com/kdcokenny/ocx - `opencode-workspace` (uitgebreidere variant): https://github.com/kdcokenny/opencode-workspace ### Next.js 16 - Blog post: https://nextjs.org/blog/next-16 - Upgrade guide: https://nextjs.org/docs/app/guides/upgrading/version-16 - create-next-app CLI: https://nextjs.org/docs/app/api-reference/cli/create-next-app ### GSAP - Docs v3: https://gsap.com/docs/v3/ - React guide (`useGSAP`): https://gsap.com/resources/React/ - License (sinds 2025 gratis): https://gsap.com/standard-license - ScrollTrigger: https://gsap.com/docs/v3/Plugins/ScrollTrigger/ - SplitText: https://gsap.com/docs/v3/Plugins/SplitText/ ### Lenis - GitHub: https://github.com/darkroomengineering/lenis - React README: https://github.com/darkroomengineering/lenis/blob/main/packages/react/README.md - Homepage: https://lenis.darkroom.engineering/ ### Combinaties / patterns - GSAP forum: Next 15/16 best practices: https://gsap.com/community/forums/topic/43831-what-are-the-best-practices-for-using-gsap-with-next-15-clientserver-components/ - Tutorial: Next.js + Lenis + GSAP: https://devdreaming.com/blogs/nextjs-smooth-scrolling-with-lenis-gsap ### Volgende les preview Les 3: **Introductie Cursor**. De commerciele tegenhanger van OpenCode. Cursor rules vs AGENTS.md, Composer mode, Tab-completion, @-references. Wanneer kies je welke tool?