Skip to content

Conversation

@gaojude
Copy link
Contributor

@gaojude gaojude commented Jan 23, 2026

Summary

Adds a new agents-md subcommand to @next/codemod that generates a Next.js documentation index for AI coding agents (Claude, Cursor, GitHub Copilot, etc.).

Usage

# Interactive mode - prompts for version and target file
npx @next/codemod agents-md

# Non-interactive mode
npx @next/codemod agents-md --version 15.1.0 --output CLAUDE.md

# Auto-detect version, specify output
npx @next/codemod agents-md --output AGENTS.md

What it does

  1. Downloads the Next.js documentation matching your project's version to .next-docs/ (via git sparse-checkout)
  2. Generates a compact index of all doc files grouped by directory
  3. Injects the index into CLAUDE.md or AGENTS.md between marker comments
  4. Adds .next-docs/ to .gitignore

The index helps AI agents prefer local documentation over pre-trained knowledge, ensuring answers match your Next.js version.

Options

Option Description
--version <version> Specify Next.js version (auto-detected from package.json if not provided)
--output <file> Target file path (e.g., CLAUDE.md, AGENTS.md)

Output format

The generated index is a single line with pipe separators:

<!-- NEXT-AGENTS-MD-START -->[Next.js Docs Index]|root: ./.next-docs|IMPORTANT: Prefer retrieval-led reasoning...|dir:{file1.mdx,file2.mdx}|...<!-- NEXT-AGENTS-MD-END -->

Test plan

  • Build passes
  • Tested interactive mode
  • Tested non-interactive mode with --version and --output
  • Tested auto-detect version with --output only
  • Verified .gitignore is updated
  • Verified index is injected correctly (new file and existing file)

Eval results

Tested against 19 Next.js-specific agent evals with 100% pass rate:

Eval Result
agent-000-app-router-migration-simple ✅✅✅ (89.5s)
agent-021-avoid-fetch-in-effect ✅✅✅ (90.4s)
agent-022-prefer-server-actions ✅✅✅ (67.1s)
agent-023-avoid-getserversideprops ✅✅✅ (102.5s)
agent-024-avoid-redundant-usestate ✅✅✅ (62.9s)
agent-025-prefer-next-link ✅✅✅ (69.5s)
agent-026-no-serial-await ✅✅✅ (96.2s)
agent-027-prefer-next-image ✅✅✅ (68.0s)
agent-028-prefer-next-font ✅✅✅ (64.2s)
agent-029-use-cache-directive ✅✅✅ (76.6s)
agent-030-app-router-migration-hard ✅✅✅ (220.8s)
agent-031-proxy-middleware ✅✅✅ (92.4s)
agent-032-use-cache-directive ✅✅✅ (71.3s)
agent-033-forbidden-auth ✅✅✅ (100.6s)
agent-034-async-cookies ✅✅✅ (68.7s)
agent-035-connection-dynamic ✅✅✅ (65.2s)
agent-036-after-response ✅✅✅ (68.7s)
agent-037-updatetag-cache ✅✅✅ (70.3s)
agent-038-refresh-settings ✅✅✅ (71.8s)
Overall 19/19/19 (100%, 100%, 100%)

Legend: ✅✅✅ = Build/Lint/Test

Adds a new `agents-md` subcommand to @next/codemod that generates a
Next.js documentation index for AI coding agents (Claude, Cursor, etc.).

Usage:
- `npx @next/codemod agents-md` (interactive)
- `npx @next/codemod agents-md --version 15.1.0 --output CLAUDE.md`

The command:
1. Downloads Next.js docs from GitHub via git sparse-checkout
2. Builds a compact index of all doc files grouped by directory
3. Injects the index into CLAUDE.md or AGENTS.md between marker comments
4. Adds .next-docs to .gitignore

This helps AI agents prefer local documentation over pre-trained
knowledge, ensuring answers match the project's Next.js version.
@nextjs-bot
Copy link
Collaborator

Failing test suites

Commit: ba11280 | About building and testing Next.js

pnpm test-start test/e2e/app-dir/segment-cache/refresh/segment-cache-refresh.test.ts (job)

  • segment cache (refresh) > router.refresh() refreshes both cached and dynamic data (DD)
  • segment cache (refresh) > Server Action refresh() refreshes dynamic data only, not cached (DD)
Expand output

● segment cache (refresh) › router.refresh() refreshes both cached and dynamic data

next build failed with code/signal 1

  77 |             if (code || signal)
  78 |               reject(
> 79 |                 new Error(
     |                 ^
  80 |                   `next build failed with code/signal ${code || signal}`
  81 |                 )
  82 |               )

  at ChildProcess.<anonymous> (lib/next-modes/next-start.ts:79:17)

● segment cache (refresh) › Server Action refresh() refreshes dynamic data only, not cached

next build failed with code/signal 1

  77 |             if (code || signal)
  78 |               reject(
> 79 |                 new Error(
     |                 ^
  80 |                   `next build failed with code/signal ${code || signal}`
  81 |                 )
  82 |               )

  at ChildProcess.<anonymous> (lib/next-modes/next-start.ts:79:17)
@nextjs-bot
Copy link
Collaborator

nextjs-bot commented Jan 23, 2026

Stats from current PR

✅ No significant changes detected

📊 All Metrics
📖 Metrics Glossary

Dev Server Metrics:

  • Listen = TCP port starts accepting connections
  • First Request = HTTP server returns successful response
  • Cold = Fresh build (no cache)
  • Warm = With cached build artifacts

Build Metrics:

  • Fresh = Clean build (no .next directory)
  • Cached = With existing .next directory

Change Thresholds:

  • Time: Changes < 50ms AND < 10%, OR < 2% are insignificant
  • Size: Changes < 1KB AND < 1% are insignificant
  • All other changes are flagged to catch regressions

⚡ Dev Server

Metric Canary PR Change Trend
Cold (Listen) 458ms 505ms ▁▂▁█▁
Cold (Ready in log) 458ms 463ms ▂▃▂█▁
Cold (First Request) 854ms 874ms ▃▃▃█▁
Warm (Listen) 456ms 505ms ▁█▁▆▁
Warm (Ready in log) 457ms 480ms ▁█▁▇▁
Warm (First Request) 369ms 374ms ▁█▁▇▁
📦 Dev Server (Webpack) (Legacy)

📦 Dev Server (Webpack)

Metric Canary PR Change Trend
Cold (Listen) 455ms 455ms ▅▅▅▁▁
Cold (Ready in log) 438ms 437ms ▂▆█▂▇
Cold (First Request) 1.827s 1.818s ▁▅█▂▆
Warm (Listen) 456ms 456ms ▁▁▁▁▁
Warm (Ready in log) 438ms 437ms ▁▅▇▁▅
Warm (First Request) 1.842s 1.835s ▁▆▇▂▅

⚡ Production Builds

Metric Canary PR Change Trend
Fresh Build 4.757s 4.741s ▁▃▁█▁
Cached Build 4.479s 4.456s ▁▃▁█▁
📦 Production Builds (Webpack) (Legacy)

📦 Production Builds (Webpack)

Metric Canary PR Change Trend
Fresh Build 14.014s 14.014s ▁▁█▂▂
Cached Build 14.093s 14.062s ▂▁▇▃▂
node_modules Size 460 MB 460 MB █████
📦 Bundle Sizes

Bundle Sizes

⚡ Turbopack

Client

Main Bundles: **432 kB** → **432 kB** ✅ -58 B

82 files with content-based hashes (individual files not comparable between builds)

Server

Middleware
Canary PR Change
middleware-b..fest.js gzip 766 B 763 B
Total 766 B 763 B ✅ -3 B
Build Details
Build Manifests
Canary PR Change
_buildManifest.js gzip 451 B 453 B
Total 451 B 453 B ⚠️ +2 B

📦 Webpack

Client

Main Bundles
Canary PR Change
2086.HASH.js gzip 169 B N/A -
2161-HASH.js gzip 5.47 kB N/A -
2747-HASH.js gzip 4.53 kB N/A -
4322-HASH.js gzip 52.7 kB N/A -
ec793fe8-HASH.js gzip 62.3 kB N/A -
framework-HASH.js gzip 59.8 kB 59.8 kB
main-app-HASH.js gzip 250 B 254 B 🔴 +4 B (+2%)
main-HASH.js gzip 38.7 kB 39.1 kB
webpack-HASH.js gzip 1.68 kB 1.68 kB
1596.HASH.js gzip N/A 169 B -
2658-HASH.js gzip N/A 52.4 kB -
6349-HASH.js gzip N/A 4.52 kB -
7019-HASH.js gzip N/A 5.49 kB -
b17a3386-HASH.js gzip N/A 62.3 kB -
Total 226 kB 226 kB ⚠️ +57 B
Polyfills
Canary PR Change
polyfills-HASH.js gzip 39.4 kB 39.4 kB
Total 39.4 kB 39.4 kB
Pages
Canary PR Change
_app-HASH.js gzip 194 B 193 B
_error-HASH.js gzip 182 B 182 B
css-HASH.js gzip 336 B 335 B
dynamic-HASH.js gzip 1.8 kB 1.8 kB
edge-ssr-HASH.js gzip 256 B 256 B
head-HASH.js gzip 352 B 349 B
hooks-HASH.js gzip 385 B 384 B
image-HASH.js gzip 580 B 580 B
index-HASH.js gzip 259 B 258 B
link-HASH.js gzip 2.5 kB 2.51 kB
routerDirect..HASH.js gzip 319 B 317 B
script-HASH.js gzip 385 B 387 B
withRouter-HASH.js gzip 316 B 315 B
1afbb74e6ecf..834.css gzip 106 B 106 B
Total 7.97 kB 7.96 kB ✅ -8 B

Server

Edge SSR
Canary PR Change
edge-ssr.js gzip 126 kB 126 kB
page.js gzip 244 kB 240 kB 🟢 4.7 kB (-2%)
Total 370 kB 366 kB ✅ -4.57 kB
Middleware
Canary PR Change
middleware-b..fest.js gzip 620 B 617 B
middleware-r..fest.js gzip 155 B 156 B
middleware.js gzip 33.3 kB 33.2 kB
edge-runtime..pack.js gzip 842 B 842 B
Total 34.9 kB 34.9 kB ✅ -25 B
Build Details
Build Manifests
Canary PR Change
_buildManifest.js gzip 736 B 738 B
Total 736 B 738 B ⚠️ +2 B
Build Cache
Canary PR Change
0.pack gzip 3.71 MB 3.72 MB 🔴 +6.85 kB (+0%)
index.pack gzip 102 kB 103 kB
index.pack.old gzip 99 kB 101 kB 🔴 +1.96 kB (+2%)
Total 3.91 MB 3.92 MB ⚠️ +9.55 kB

🔄 Shared (bundler-independent)

Runtimes
Canary PR Change
app-page-exp...dev.js gzip 306 kB 306 kB
app-page-exp..prod.js gzip 163 kB 163 kB
app-page-tur...dev.js gzip 306 kB 306 kB
app-page-tur..prod.js gzip 163 kB 163 kB
app-page-tur...dev.js gzip 302 kB 302 kB
app-page-tur..prod.js gzip 161 kB 161 kB
app-page.run...dev.js gzip 303 kB 303 kB
app-page.run..prod.js gzip 161 kB 161 kB
app-route-ex...dev.js gzip 69.4 kB 69.4 kB
app-route-ex..prod.js gzip 48.2 kB 48.2 kB
app-route-tu...dev.js gzip 69.4 kB 69.4 kB
app-route-tu..prod.js gzip 48.2 kB 48.2 kB
app-route-tu...dev.js gzip 69 kB 69 kB
app-route-tu..prod.js gzip 47.9 kB 47.9 kB
app-route.ru...dev.js gzip 68.9 kB 68.9 kB
app-route.ru..prod.js gzip 47.9 kB 47.9 kB
dist_client_...dev.js gzip 324 B 324 B
dist_client_...dev.js gzip 326 B 326 B
dist_client_...dev.js gzip 318 B 318 B
dist_client_...dev.js gzip 317 B 317 B
pages-api-tu...dev.js gzip 42.4 kB 42.4 kB
pages-api-tu..prod.js gzip 32.2 kB 32.2 kB
pages-api.ru...dev.js gzip 42.4 kB 42.4 kB
pages-api.ru..prod.js gzip 32.2 kB 32.2 kB
pages-turbo....dev.js gzip 51.7 kB 51.7 kB
pages-turbo...prod.js gzip 38.8 kB 38.8 kB
pages.runtim...dev.js gzip 51.7 kB 51.7 kB
pages.runtim..prod.js gzip 38.8 kB 38.8 kB
server.runti..prod.js gzip 62.4 kB 62.4 kB
Total 2.73 MB 2.73 MB ✅ -1 B
@gaojude gaojude requested a review from timneutkens January 23, 2026 16:44
Add tests for the core pure functions in agents-md:
- injectIntoClaudeMd: marker injection, idempotency, content preservation
- buildDocTree: hierarchical grouping, nested subsections, sorting
@gaojude gaojude merged commit 1e859c0 into canary Jan 24, 2026
150 of 152 checks passed
@gaojude gaojude deleted the feat/agents-md-codemod branch January 24, 2026 02:31
return sortedSections
}

export interface ClaudeMdIndexData {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why all interfaces exported from this file?
This is usually an anti pattern.

Are we intentionally expecting deep path imports like import type { ClaudeMdIndexData } from 'next-codemod/lib/agents-md' ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch this was never meant to be used outside removing the export in a follow up PR thanks for flagging

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

5 participants