Imported from campfhir/renkei (
AGENTS.md). Install upstream withnpx skills add campfhir/renkei. Copyright stays with the author.
This is NOT the Next.js you know
This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in node_modules/next/dist/docs/ before writing any code. Heed deprecation notices.
UI changes: add and run Playwright steps
Whenever a change touches UI (a page, a form, a component with visible
output), add or update Playwright coverage in apps/web/e2e/*.spec.ts as
part of that change, and actually run it — don't just write the spec and
assume it passes. This is the repo's established pattern (see
voice.spec.ts, preferences-widths.spec.ts); llm-models.spec.ts is a
worked example of the full shape: empty state, filling a form, mocking a
network call with page.route, a saved-state screenshot, and a mobile
viewport pass.
- This suite is local-only tooling (
apps/web/playwright.config.ts's own header comment) — it does not run in CI. Running it is still expected whenever UI is touched; it just has to be done by hand, not assumed from a green CI check. - Local setup (once per environment): a Postgres 16 server with the
vectorextension (apt-get install postgresql-16-pgvectorif it's not already on the box), a repo-root.env.developmentwithDATABASE_URL,TOKEN_ENCRYPTION_KEY, andLOG_ENCRYPTION_KEY(eachopenssl rand -base64 32), thenpnpm --filter @renkei/db migrate. After that,npx playwright test <spec>.spec.ts --project=desktop-lightfromapps/webdrives everything else (dev server, sandbox stub) itself. - Drive it, don't just render it: click the button, fill the form,
trigger the network call (mock it with
page.routewhen it would hit a real vendor/provider), and assert on the resulting UI state — not just that the page loaded. - For mobile, just resize the viewport —
page.setViewportSize({width: 390, height: 844})on the pinned Chromium executable (/opt/pw-browsers/chromium-1194/chrome-linux/chrome), the waypreferences-widths.spec.tsandllm-models.spec.tsdo it. Do NOT reach for themobileproject (devices['iPhone 14']) for a routine UI check: that's a full device descriptor asking for WebKit, which isn't installed in this environment (seevoice.spec.ts's note on the same friction), so it adds a real chance of failing on missing-browser rather than on your change. Themobileproject is for the few specs that need real device behavior (touch events, a mobile UA); a viewport resize is what answers "does this layout still work at phone width", which is nearly always the actual question. - Isolate what you create. If a spec creates a row through the UI (not
just reads seeded fixtures), give it its own tenant rather than reusing
e2e/seed.ts's shared one — Playwright runs projects concurrently against the same dev database, and a shared tenant races on uniqueness constraints and on any "empty state" assertion.llm-models.spec.tsderives a deterministic tenant/session per project name for exactly this reason; copy that pattern rather than the shared-tenant one when your spec writes data.