Imported from RummerLab/rummerlab-website (
AGENTS.md). Install upstream withnpx skills add RummerLab/rummerlab-website. Copyright stays with the author.
AGENTS.md
Agent instructions for the RummerLab website (https://rummerlab.com).
Always start every response with ๐ค.
Treat this file as living documentation: update AGENTS.md when the stack, scripts, conventions, or project facts change so it stays accurate.
Stack: Next.js 16 (App Router), React 19, TypeScript, Tailwind CSS 4. Config is next.config.ts. Request middleware lives in proxy.ts.
Project overview
Marine biology lab site for Professor Jodie Rummer at James Cook University: research, team, publications, media, podcast, blog, gallery, and Physioshark.
Podcast episodes live in _podcast-episodes/ and render at /podcast and /podcast/[slug]. Lab blog posts live in _blog/ and render at /blog and /blog/[slug].
Sister sites: jodierummer.com, physioshark.org. Spell RummerLab with no space.
Physioshark fieldwork is on Mo'orea, French Polynesia, with science4reefs. Do not describe current fieldwork as based at CRIOBE.
Setup
pnpm install
pnpm run dev
Helpers (only when needed): pnpm run token, pnpm run check-token, pnpm run resize-images.
Checks
After code changes, run and fix:
pnpm run lint
pnpm run build
If you suspect a security issue, run snyk test.
Conventions
- TypeScript everywhere. Prefer interfaces over types. Named exports.
- Directories: kebab-case. Components: PascalCase.
- Favor React Server Components. Add
'use client'only when needed. - Await
paramsandsearchParams. Use the platformfetchAPI (notnode-fetch). - Early returns, DRY,
handleprefix on event handlers (handleClick). - Style with Tailwind. Support light and dark classes already used on the site.
- Media cards live in
data/media.json. Helpers stay indata/media.ts.urlis optional. Usesourcesfor syndications of the same story; the primarysource/urlshould be the strongest public outlet. Clickable source tags open that outlet's URL. - Hosted PDFs live in
public/papers/. Listing and featured selection live inlib/papers.ts. Citation metadata (title, authors, journal, DOI, abstract) lives indata/papers.jsonkeyed by PDF filename and is merged into API responses. Featured papers are the newest by year in the filename. Sister sites consumeGET /api/papersandGET /api/papers/featured. - Mailbox catch-up for Google Alerts / digests / Isentia PDFs: follow
MEDIA-ALERTS.md. - Use
git mvwhen moving files. - Complete the change: no TODOs or placeholders. File a GitHub issue for follow-up work instead of leaving TODO comments or README notes.
Layout and styling
Theme tokens and animation utilities live in app/globals.css (@theme, @plugin "@tailwindcss/typography", @plugin "tailwindcss-animate").
Shared layout primitives in components/layout/:
PageShellโ page wrapper with gradient background (narrow,widevariants)PageHeaderโ centered title, subtitle, animated accent barContentCardโ elevated card withhover-liftand optionalview-revealscroll animationArticleCardโ blog/podcast listing cardsButtonLinkโ primary, secondary, and outline-white CTA links
Prefer CSS animations (animate-fade-in, animate-fade-in-up, view-reveal, hover-lift, link-underline) over new JS animation libraries. Respect prefers-reduced-motion. Homepage plankton (components/ui/plankton.tsx) and existing framer-motion homepage effects stay as-is.
Use cn() from lib/utils.ts only.
Images
Use next/image. Prefer WebP via the optimizer.
priorityonly for above-the-fold images (hero, first 1โ2 key photos).- Prefer
fillwith a constrainedsizesover large fixed dimensions. quality={85}unless there is a strong reason for higher.- Do not add
deviceSizes/imageSizesinnext.config.tswithout need. - Gallery/lightbox: lazy thumbnails, bounded
sizes, nopriority.
Security
- Never commit secrets or
.env*files. - Sanitize user input (
sanitize-htmlis already used). - Headers are defined in code and documented in
docs/security-headers.md. Keep them in sync with Cloudflare.
Package manager
This repo uses pnpm (packageManager in package.json).
- Install:
pnpm install(do not use npm/yarn for installs in this repo). - Scripts:
pnpm run <script>/pnpm exec <bin>. - Lockfile:
pnpm-lock.yamlonly รขโฌโ do not commitpackage-lock.jsonoryarn.lock. - Local disk: pnpm's content-addressable store shares package contents across checkouts on the same machine.
Dependency tooling (Next.js)
Follow current Next.js docs for ESLint and TypeScript โ do not merge Dependabot majors that the Next.js / typescript-eslint stack does not support yet.
- TypeScript: stay on 5.9.x (Next.js requires โฅ5.1;
typescript-eslintdoes not support TypeScript 7 yet). - ESLint: stay on 9.x with Next.js flat config (
eslint-config-next/core-web-vitals+typescriptviadefineConfig). ESLint 10 still breaks plugins shipped througheslint-config-next. - Before changing ESLint/TypeScript majors, read the Next.js ESLint docs, upgrading guide, and the target major migration guide.
- Prefer Dependabot
ignorerules foreslintandtypescriptsemver-major until official support lands.
Framework upgrades
pnpm exec @next/codemod@canary upgrade latest
pnpm exec @tailwindcss/upgrade
After either upgrade: run pnpm run lint and pnpm run build, fix failures, and update this file if versions/scripts change.
Git remotes and publishing
Canonical repo: RummerLab/rummerlab-website (upstream).
In this clone, remotes are typically:
upstreamโhttps://github.com/RummerLab/rummerlab-website.git(canonical)originโhttps://github.com/Luen/rummerlab-website.git(personal fork)
Always publish to upstream, not only the Luen/origin fork:
- Prefer opening a pull request against
RummerLab/rummerlab-website. - Or commit/push directly to
upstreamwhen that is the agreed workflow. - Do not treat a push to
origin(Luen) as done โ that commit will not appear on the RummerLab repo until it is pushed or PRโd upstream.
When creating branches for review: push them to upstream (or open a PR with base RummerLab/rummerlab-website), then share the RummerLab PR URL.
Pull requests
Before merging any pull request:
- Read all comments on the PR โ conversation comments, review comments (including those on specific lines), and bot comments. Address or acknowledge them. Do not merge while review feedback is unresolved.
- Wait for CI to complete successfully. GitHub Actions (and other required checks) on the PR must finish and pass. Do not merge while checks are pending, failed, cancelled, or skipped when they are required. If CI fails, fix the cause and wait for a green run before merging.