agentleFS
tazo90tazo90/next-openapi-gen/AGENTS.md

next-openapi-gen

AGENTS.md193 starsChanged 3 months agoMITView on GitHub

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.

We split this AGENTS.md into the rules it gives an agent

7 rules. About 0 are common, 5 are distinctive, and 2 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈5

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Prefer Oxc config to stay close to standard defaults and avoid large hand-maintained rule lists unless there is a clear repo-specific need.

    line 11
  2. Very specific:

    Prefer standard, concise module names over verbose create-* filenames when the exported symbol already carries the constructor/factory …

    line 13
  3. Distinctive:

    Prefer a single shared Zod schema per domain when practical instead of parallel DTO or duplicate inferred types.

    line 16
  4. Distinctive:

    Prefer committed workspace editor defaults when they make formatter, lint, and TypeScript SDK behavior consistent across contributors and …

    line 18
  5. Very specific:

    Prefer internal workspace package boundaries for core, CLI, init, and framework code when restructuring, while keeping …

    line 19
  6. Distinctive:

    Keep Vitest coverage exclusions minimal.

    line 21
  7. Distinctive:

    After a source restructure, prefer stable imports to concrete implementation files instead of keeping long-lived barrel re-export layers as …

    line 22

≈ “Common” is an estimate: at least 1 in 5 of the 36,368 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
AGENTS.md
<!-- BEGIN:nextjs-agent-rules -->

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.

<!-- END:nextjs-agent-rules -->

Learned User Preferences

  • Prefer Oxc config to stay close to standard defaults and avoid large hand-maintained rule lists unless there is a clear repo-specific need.
  • Prefer simpler, direct APIs over wrapper factories or overly clever abstraction layers when they do not add clear value. Preserve existing user-facing CLI/API behavior during internal refactors, and avoid adding new config or customization surface unless it is explicitly requested; when promoting experimental options to stable config, drop legacy experimental shims rather than keeping backward-compatibility aliases unless a deprecation window is explicitly requested. At app or API boundaries, prefer one client factory with direct method calls, inlining it when a call site uses it only once; for multipart uploads, prefer explicit @body schemas over the bodyless @contentType multipart/form-data binary-file fallback when richer typed forms are needed. Keep clientSdk a thin post-generate wrapper around an external generator rather than vendoring a client SDK product; leave custom OAuth/OIDC scheme objects in components / schemaFiles instead of growing JSDoc into a scheme DSL.
  • Prefer standard, concise module names over verbose create-* filenames when the exported symbol already carries the constructor/factory meaning.
  • Prefer .ts/.mts for tool and config files when the tool supports it, with proper typing over workarounds that drop type safety; keep inherently non-TS formats as-is (.json, .yaml, .editorconfig, .gitattributes, .gitignore, GitHub Actions workflow files); migrate remaining JavaScript-based configs where the toolchain supports typed configs cleanly (including release tooling and example apps).
  • Prefer openapi-gen as the forward-looking CLI/config naming and openapi-gen.config.ts as the TypeScript config format. init writes openapi-gen.config.ts with defineConfig by default and still writes JSON when --output ends in .json. Sample apps keep a mix of openapi-gen.config.ts / .mts / .json plus legacy next.openapi.json and next-openapi-gen so discovery and both binaries stay covered. Keep those legacy names working through a deprecation window instead of breaking existing apps immediately.
  • Prefer a single shared Zod schema per domain when practical instead of parallel DTO or duplicate inferred types; keep provider-specific mapping in the provider package.
  • Prefer package.json, VS Code tasks, and Turbo pipelines composed from plain pnpm and upstream CLIs over bespoke .mjs orchestrators, and avoid duplicate script entries such as :turbo variants that only mirror an existing command. For pnpm release-age issues, prefer pinning a slightly older package version over adding minimumReleaseAgeExclude.
  • Prefer committed workspace editor defaults when they make formatter, lint, and TypeScript SDK behavior consistent across contributors and agents.
  • Prefer internal workspace package boundaries for core, CLI, init, and framework code when restructuring, while keeping packages/next-openapi-gen as the public compatibility and install surface until an explicit publishing change is requested.
  • Keep automated tests for shared library behavior under the repo root tests/ directory with domain-aligned subfolders that mirror src/; put cross-cutting scenario or behavior checks into tests/**/regressions/ rather than leaving them flat at the root. Prefer checked-in project-style fixtures plus temp-copy harnesses for integration coverage over inline-generated temp app trees when realistic app structure matters; align integration coverage with documented JSDoc tags and README-backed examples where practical, and use real handler bodies in fixtures when testing implementation-driven inference. Prefer JSDoc tag names that match official OpenAPI field names, and keep aliases when renaming tags. Spread new generator features and annotations across apps/ sample projects with realistic domain-shaped APIs instead of concentrating demos in one app.
  • Keep Vitest coverage exclusions minimal; do not broadly exclude core source directories just to satisfy coverage thresholds.
  • After a source restructure, prefer stable imports to concrete implementation files instead of keeping long-lived barrel re-export layers as the primary layout.

Learned Workspace Facts

  • Shared TypeScript baselines in packages/typescript-config (base.json, nextjs.json, library.json) intentionally follow a stricter preset. Emitting workspace packages extend library.json (composite + isolatedDeclarations) and are wired with project references from the root tsconfig.json; pnpm typecheck:packages runs tsc -b.
  • Workspace editor defaults live in .vscode/; they point TypeScript at the workspace SDK and use the Oxc VS Code extension for formatting and fixes.
  • Git hooks are installed via simple-git-hooks from the root package.json; pre-commit runs lint-staged with Oxfmt/Oxlint using oxfmt.config.ts and oxlint.config.ts, and commit-msg runs commitlint. Root Ox configs ignore **/public/openapi.json; when only such generated JSON is staged, oxfmt can otherwise receive no paths, so lint-staged runs oxfmt with --no-error-on-unmatched-pattern (root package.json).
  • The workspace pins a Zod 3 compatibility catalog (and related apps) to the latest Zod 3 line; broad dependency major upgrades should not fold that track onto Zod 4. The AST Zod converter in packages/openapi-core/src/schema/zod/zod-converter.ts must handle Zod Mini (zod/mini, zod/v4/mini) functional APIs—z.extend, z.optional/z.nullable, .check(z.minLength(...))—via structural dispatch, not only chain forms; top-level z.extend on the z binding must not use the named-schema .extend pre-check. Shared nullability lives in nullability.ts; non-discriminated unions emit anyOf (not oneOf); z.undefined() union branches map to optional semantics.
  • Vitest coverage thresholds in vitest.config.ts coverageScopes are tiered: satellites (CLI, init, frameworks, Arazzo, Overlay, facade) are 99/95/99/99 for statements, branches, functions, and lines; openapi-core and the unscoped fallback are 95/92/95/95.
  • Integration generator fixtures live under tests/fixtures/projects/, and tests/helpers/test-project.ts provides temp-copy, template-materialization, and isolated-cwd helpers for running them; the next/app-router/core-flow fixture carries checked-in OpenAPI 3.0/3.1/3.2 templates plus upload routes covering schema-backed and bodyless multipart request bodies, and apps/next-app-next-config plus apps/next-app-zod serve as concrete 3.1/3.2 examples. Large-scale *-at-scale fixtures and app generated/ trees are produced by pnpm generate:scale-fixtures; regenerate instead of hand-editing generated route or schema files, and keep them committed because CI does not run generate:scale-fixtures on checkout, except apps/next-app-drizzle-zod scale output (src/app/api/generated/, src/schemas/generated/, src/db/schema.generated.ts), which stays gitignored because drizzle-zod@0.8.3 infers Zod 4 types that fail typecheck against that app's Zod 3 pin. TanStack/React Router scale routes from scripts/fixture-scale/routes.mts reference types via JSDoc only (no import type blocks), matching Next.js generated routes.
  • The repo now uses internal workspace packages for the generator split: packages/openapi-core, packages/openapi-cli, packages/openapi-init, packages/openapi-framework-next, packages/openapi-framework-tanstack, packages/openapi-framework-react-router, packages/openapi-framework-remix, packages/openapi-framework-sveltekit, packages/openapi-framework-nuxt, packages/openapi-framework-astro, packages/openapi-framework-hono, packages/openapi-framework-express, packages/openapi-arazzo, and packages/openapi-overlay, while packages/next-openapi-gen remains the public compatibility facade. Supported FrameworkKind values stay a closed enum: Next.js, TanStack, React Router, Remix, SvelteKit, Nuxt, Astro, Hono, and Express. Unknown framework.kind values error instead of falling back to Next.js. *-at-scale fixtures and bench matrix rows for the six newer stacks are a follow-up after their core-flow fixtures and sample apps. Keep Arazzo and Overlay as sibling packages rather than inlining them into core. Overlay 1.2 supports reusable components.actions plus $ref, $self, and optional targetFormat (openapi | asyncapi | arazzo); applyOverlay is format-agnostic, but the generator does not emit AsyncAPI documents. Published packages declare TypeScript >=5.9 <8; packages/openapi-core/src/shared/typescript-runtime.ts resolves the project-local compiler first with a bundled fallback, routes TS 5.9/6.x through classic lib/typescript.js, and TS 7.x through the native adapter in native-typescript-adapter.ts; the workspace catalog pins TypeScript 7.0.2 for baseline tsc and sample apps, while openapi-core and published next-openapi-gen use the typescript-classic catalog (npm:@typescript/typescript6@6.0.2) so classic compiler types and the bundled fallback stay on 6 and consumers on 5.9–6 are not hoisted onto 7.
  • Built-in docs UI template assets live under packages/openapi-init/templates/init/ui/{nextjs,tanstack,react-router,remix,sveltekit,nuxt,astro,hono,express}; packages/openapi-init/src/init/ui-registry.ts maps UI metadata to those template files, the published package includes the templates directory alongside dist, and docs-page scaffolding dispatches by framework instead of assuming Next-only output. Generate-time emission uses the same createDocsPage({ framework }) path for every supported kind; sample apps stay opted out so generate:apps does not overwrite hand-scaffolded docs pages.
  • apps/next-app-adapter is the only Next sample that should use adapterPath (pointing at a sibling next-openapi.adapter.mjs); apps/next-app-next-config wraps its next.config.ts with withNextOpenApi from next-openapi-gen/next and must stay adapterPath-free. apps/next-app-ts-config owns the clientSdk golden path: a typed config entry plus a thin env-gated openapi-generator-cli wrapper (GENERATE_CLIENT_SDK=1). Sample Next apps inherit shared @workspace/next-config (cacheComponents, partialPrefetching, agentRules: false so next dev does not write sample-app AGENTS.md/CLAUDE.md; experimental.useTypeScriptCli stays true because TypeScript 7 has no JavaScript compiler API).
  • packages/next-openapi-gen CLI bundling in tsup.config.ts must externalize non-workspace runtime dependencies; bundling CommonJS packages like commander into the ESM CLI breaks sample-app generate with Node's Dynamic require error. A committed bin wrapper at packages/next-openapi-gen/bin/cli.mjs delegates to the built CLI so the next-openapi-gen / openapi-gen commands resolve in clean checkouts before any workspace build runs. Playwright e2e (playwright.config.ts) prebuilds the CLI workspace graph with pnpm exec turbo run build --filter=next-openapi-gen... so internal packages have dist/ outputs, sets EXPOSE_TESTING_API=1 so experimental.exposeTestingApiInProductionBuild is on for measured next builds, and tests/e2e/instant-nav.spec.ts locks Cache Components instant navigation for next-app-drizzle-zod (see instant-nav.rig.md).
  • GitHub Actions CI is defined in .github/workflows/ci.yml (quality, build, unit, integration, coverage, parallelized E2E, typescript-compatibility matrix for TS 5.9.3/6/7, default-branch/workflow_dispatch); standard Linux jobs use pnpm exec turbo run for build and other tasks wired in turbo.json where applicable; .github/dependabot.yml maintains Actions dependencies; generator benchmarks use vitest.bench.config.ts (pnpm test:bench, pnpm test:bench:vitest under tests/bench), with a committed generator baseline at tests/bench/generator/baseline.json, CLI subprocess benchmarks under tests/bench/cli/, and workflow notes in docs/performance.md; test:bench:schema scopes discovery with --dir tests/bench/schema so Vitest does not duplicate benchmarks from .pnpm-store. The route-parse worker bench (tests/bench/generator/route-parse-worker.bench.ts) needs @babel/parser as a direct root devDependency because worker threads resolve modules from the workspace root.
  • OpenAPI generation writes .openapi-gen/manifest.json only when NODE_ENV !== "production"; it is dev-only metadata (for example config path, diagnostics, performance) and .openapi-gen/ stays gitignored. Generator disk cache is on by default via top-level cache: true (OPENAPI_GEN_CACHE=0/1 overrides); route fragments and input hashes reuse unchanged work across runs. Generator output must be deterministic across runs: paths are sorted by folder path, then file name, then HTTP method, so re-generating the spec does not create order-only diffs. Bodyless @contentType multipart/form-data routes without @body emit a required multipart body with a binary file field. Built-in auth presets emit default components.securitySchemes objects when a referenced scheme is missing (existing components / schemaFiles / templates win); @auth and @security treat comma as OR and semicolon as AND. Supported OpenAPI targets are 3.0, 3.1, 3.2, and experimental 3.3-preview; OpenAPI 4.0 is not supported, and unreleased 3.3.0 / 4.x fall back to 3.2.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

Reviews can't be read right now.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.