Files
Andrew ImmandGitHub ca414736ba telemetry: add agentName to anonymous metadata (#95586)
Add agentName to anonymous telemetry metadata

### What

Adds an agentName: string | null field to the anonymous telemetry
metadata block that accompanies every payload, alongside existing fields
like ciName, nextVersion, and isCI. The value is the detected AI coding
agent driving the process (e.g. claude, cursor, codex), or null when
none is detected.

### Why

We currently have no visibility into how much Next.js development
happens under AI coding agents. This field lets us understand that split
in the same anonymous way we already track other CLI usage.

### How

Agent detection via @vercel/detect-agent
- Vendored @vercel/detect-agent (from the Vercel CLI) into
`next/dist/compiled/@vercel/detect-agent` (new taskfile ncc task,
externals entry, and type declaration), matching how I *understand*
other third-party deps are bundled.
- The vendored detection method is async (it does a filesystem probe for
Devin in addition to env-var checks) and potentially slower than we'd
want for logging, so it's wrapped in a memoized helper:
`telemetry/agent-name.ts`. `getAgentName()` caches the promise from
`determineAgent()`: the first call runs detection once, concurrent
callers share that in-flight promise, and every later call resolves
against the already-settled result. The agent shouldn't change over the
process lifetime, so this is safe. Detection failures resolve to null so
telemetry never throws on this path.

Wiring into the payload
- `getAnonymousMeta()` is now async and includes `agentName: await
getAgentName()`. `storage.ts` awaits it on the send path (the record
method was thankfully already async).
- The NEXT_TELEMETRY_DEBUG=1 output now includes the meta block
alongside each event, so the full payload — including agentName — is
observable locally without sending anything. We didn't output this
before, so it was harder to debug these fields.

Consolidating agent detection
- There was a second, synchronous, hand-vendored copy of agent detection
(telemetry/detect-agent.ts) used only by the AGENTS.md/CLAUDE.md
auto-generation hook. It's been removed and that hook
(ensureAgentRulesForDev) now uses the same vendored `getAgentName()`.
Now we have a single source of truth and can easily get upstream changes
from the vercel CLI package. `ensureAgentRulesForDev` became async, its
only caller in start-server.ts was already in an async scope, so this is
easy.

### Testing

- NEXT_TELEMETRY_DEBUG=1 next build shows agentName in the payload meta
block next to ciName/nextVersion.
- Verified the memoized helper: agent present -> name; cleared env ->
null; repeated calls return the same promise instantly.
- agent-rules-auto-generate dev tests pass (agent-detected generates
files; cleared-env does not)
- next-server-nft trace snapshot updated: adds @vercel/detect-agent +
agent-name.js, removes detect-agent.js.
- ts, build, existing telemetry unit test, lint
2026-07-14 16:56:01 -07:00
..
…