Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .changeset/fix-stale-agent-docs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
---
11 changes: 5 additions & 6 deletions .claude/skills/clerk-monorepo/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ description: >-

# Working in the clerk/javascript monorepo

This is Clerk's JavaScript SDK monorepo: 24 packages (22 published `@clerk/*` plus the private
`@clerk/msw` and `@clerk/swingset`) managed with pnpm
This is Clerk's JavaScript SDK monorepo: the `@clerk/*` packages under `packages/`, managed with pnpm
workspaces and Turborepo. Read this before building, testing, committing, or touching anything
under `packages/`.

Expand All @@ -27,7 +26,7 @@ The order matters more than the commands. Do them in sequence:
1. **Node `>=24.15.0`** (pinned in `.nvmrc`). `nvm use` if you have nvm. Wrong Node version is the
single most common cause of cryptic "cannot find module @clerk/..." build errors.
2. **`corepack enable`** before installing. The `preinstall` hook runs `only-allow pnpm`; npm/yarn
are hard-blocked. Corepack pins the right pnpm (`>=10.33.0`).
are hard-blocked. Corepack pins the right pnpm (`engines` in `package.json`).
Comment thread
alexcarpenter marked this conversation as resolved.
Resolved
3. **`pnpm install` from the repo root** (never a subdirectory). It is a workspace; installing from
a package dir leaves cross-package links broken.
4. **`pnpm build`** before anything else. Packages depend on each other's built `dist/` + `.d.ts`.
Expand All @@ -39,7 +38,7 @@ Full sequence, the 11 footguns, and the internal integration-test / 1Password se

## Package map: where does X live?

The ~10 packages people touch most. Full 25-package table, the dependency pyramid, and the complete
The ~10 packages people touch most. How to list every package, the dependency pyramid, and the complete
"change X, touch Y" routing are in [`references/package-map.md`](references/package-map.md).

| Package | You change it when... |
Expand Down Expand Up @@ -143,8 +142,8 @@ see [`references/setup-and-footguns.md`](references/setup-and-footguns.md) and `

Each rule below restates `AGENTS.md`; the parenthetical is how it is enforced.

- **pnpm only, Node `>=24.15`, pnpm `>=10.33`.** (`preinstall` blocks npm/yarn; `engines` in
`package.json`.)
- **pnpm only, at the Node and pnpm versions in `engines` in `package.json`.** (`preinstall` blocks
npm/yarn.)
- **Every PR needs a changeset.** Write the file directly; the `pnpm changeset` /
`pnpm changeset:empty` scripts are interactive prompts an agent cannot drive. A changeset is a
changelog entry for users upgrading, not a summary of the diff. See
Expand Down
55 changes: 16 additions & 39 deletions .claude/skills/clerk-monorepo/references/package-map.md
Original file line number Diff line number Diff line change
@@ -1,48 +1,25 @@
# Package map

The 25 active, git-tracked packages, the dependency shape, and the full "change X, touch Y" routing.
`SKILL.md` has the short version (the ~10 packages people touch most).

> The authoritative package list is the set of `packages/*/package.json` files tracked in git. The
> `packages/` directory can also hold leftover build artifacts from **removed** packages (e.g.
> `types`, `remix`, `themes`, `elements`, `agent-toolkit`, `dev-cli`) that contain only build output
> (`dist/`, `node_modules/`, `.turbo/`) and no `package.json`. Those are not active packages and are
> not valid commit scopes.
Every package, the dependency shape, and the full "change X, touch Y" routing. `SKILL.md` has the
short version (the ~10 packages people touch most).

## All packages

Categories: **foundational** (depended on by most others), **browser-runtime** (ships to the
browser directly), **adapter** (framework SDK), **ui/i18n**, **tooling**. The "BC" column marks the
two packages whose runtime is pushed into apps pinned to older SDKs, so they carry the strict
backwards-compatibility contract (see `breaking-changes.md`).
The package list is the set of git-tracked `packages/*/package.json` files. Most have a
`description` saying what the package is, and `"private": true` marks the ones that never publish:

```bash
for f in $(git ls-files 'packages/*/package.json' | awk -F/ 'NF==3'); do
node -p "const p = require('./$f'); p.name + (p.private ? ' (private)' : '') + ': ' + (p.description ?? '')"
done
```

The `packages/` directory can also hold leftover build artifacts from **removed** packages (e.g.
`types`, `remix`, `themes`, `elements`) with no `package.json`. Those are not active packages and are
not valid commit scopes.

| Package | Category | BC | Purpose |
| ------------------------------- | --------------- | --- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `@clerk/shared` | foundational | | Internal utilities used by all SDKs (storage, events, React helpers). Hosts the shared types as `@clerk/shared/types`. Most-depended-on package. |
| `@clerk/backend` | foundational | | Backend API REST client, JWT verification, webhook helpers. Used by every server adapter. |
| `@clerk/clerk-js` | browser-runtime | ⚠️ | The browser runtime (script tag). Backwards-compat sensitive. |
| `@clerk/ui` | ui | ⚠️ | React components for the hosted sign-in / sign-up flows (`packages/ui/src/components`). Consumed by the react/astro/vue/chrome-extension adapters. Backwards-compat sensitive. |
| `@clerk/mosaic` | ui | | Experimental next-generation React components. Public ESM package (`UserButton` + `styles.css`). Ships unstyled, accessible primitives (dialog, menu, popover, ...) internally under `src/primitives/`. Reads Clerk context from the host SDK via `@clerk/shared`. |
| `@clerk/react` | adapter (core) | | React hooks and context (`useAuth`, `useUser`, `useOrganization`, ...). Shared by the React-based adapters. |
| `@clerk/nextjs` | adapter | | Next.js SDK: middleware, route handlers, server components. |
| `@clerk/express` | adapter | | Express middleware and server helpers. |
| `@clerk/fastify` | adapter | | Fastify plugin. |
| `@clerk/hono` | adapter | | Hono SDK (edge / serverless). |
| `@clerk/astro` | adapter | | Astro integration (components + server utilities). |
| `@clerk/nuxt` | adapter | | Nuxt module (Vue). |
| `@clerk/vue` | adapter | | Vue 3 composables and components. |
| `@clerk/react-router` | adapter | | React Router v7 SDK. |
| `@clerk/tanstack-react-start` | adapter | | TanStack React Start SDK. |
| `@clerk/expo` | adapter | | React Native / Expo SDK. |
| `@clerk/expo-native-components` | adapter | | Native components (`AuthView`, `UserButton`, `UserProfileView`) and the native module for Expo, built on clerk-ios / clerk-android. Optional companion to `@clerk/expo`. |
| `@clerk/expo-passkeys` | adapter | | Passkeys companion library for Expo. |
| `@clerk/chrome-extension` | browser-runtime | | SDK for Chrome extension contexts. |
| `@clerk/localizations` | ui/i18n | | Translation strings for the UI components. Consumed by `ui`. |
| `@clerk/testing` | tooling | | E2E test helpers for consumers (Playwright + Cypress). |
| `@clerk/msw` | tooling | | MSW request handlers for mocking the Clerk API in tests. Private (not published). |
| `@clerk/swingset` | tooling | | Component explorer for `@clerk/mosaic`. Private (not published). |
| `@clerk/upgrade` | tooling | | CLI codemod tool for upgrading consumers between SDK versions. |
| `@clerk/eslint-plugin` | tooling | | ESLint plugin enforcing Clerk patterns across JavaScript frameworks (lint rules shipped to apps). Published. |
Only `@clerk/clerk-js` and `@clerk/ui` carry the strict backwards-compatibility contract: their
runtime is pushed into apps pinned to older SDKs (see `breaking-changes.md`).

Tests: `pnpm turbo test --filter=@clerk/<name>` (or `pnpm --filter @clerk/<name> test` after a
build). Most packages use vitest; `@clerk/backend` runs a multi-runtime suite (node + edge +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ integration-test setup. The short happy path is in `SKILL.md`; this is the full
`Cannot find module '@clerk/shared'` or missing-type errors downstream.
2. **`corepack enable`** before installing. `package.json` has `preinstall: only-allow pnpm`, so
npm and yarn are blocked outright. Corepack reads `packageManager` and uses the pinned pnpm
(`>=10.33.0`). Without it you may run a mismatched global pnpm.
(`engines` in `package.json`). Without it you may run a mismatched global pnpm.
3. **`git clone` and `cd` into the repo root.**
4. **`pnpm install` from the root.** This is a pnpm workspace; the root install links all packages
together. Installing from a package subdirectory leaves workspace links broken. First install
Expand Down
58 changes: 19 additions & 39 deletions .cursor/commands/cmt.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
description: v7 - Generate commit message from chat changes
description: v8 - Generate commit message from chat changes
(note to LLMs: increment version when you make changes to this file)
---

Expand All @@ -9,16 +9,11 @@ Generate a commit message for changes in this chat. **Do not commit or push** (s

---

## ⚙️ REPO-SPECIFIC CONFIGURATION
## Scopes and types

> **Edit this section when using in a new repository.**
The scope is required. Valid scopes: any `packages/*` short name, the same name with `clerk-` removed (`clerk-js` or `js`), or `repo`, `release`, `e2e`, `ci`, `*`. Source of truth: `commitlint.config.ts`.

### Valid Scopes

Scopes must match package/app names. No scope is also valid. Invalid scope = commitlint rejection.

- **Packages:** astro, backend, chrome-extension, clerk-js, elements, expo, expo-passkeys, express, fastify, localizations, nextjs, nuxt, react, react-router, remix, shared, tanstack-react-start, testing, themes, types, ui, upgrade, vue
- **Other:** docs, repo, release, e2e, \*
Only the PR title is linted, and it becomes the squash commit, so the title format matters most.

---

Expand All @@ -33,31 +28,17 @@ Scopes must match package/app names. No scope is also valid. Invalid scope = com

## Valid Types

**Types (REQUIRED - ALWAYS FIRST):** feat | fix | build | chore | ci | perf | refactor | revert | style | test

## FORMAT - READ THIS CAREFULLY

**CRITICAL: Type is MANDATORY and ALWAYS comes FIRST**

```
type(scope): description ← CORRECT: type first, scope optional
type: description ← CORRECT: type without scope
```
feat | fix | docs | build | chore | ci | perf | refactor | revert | style | test

**WRONG FORMATS:**
## Format

```
docs: description ← WRONG: "docs" is a SCOPE, not a type!
scope: description ← WRONG: missing type!
type(scope): description ← CORRECT
type: description ← WRONG: scope is required
scope: description ← WRONG: missing type
```

**If working with docs:**

```
feat(docs): add new guide ← CORRECT
chore(docs): update readme ← CORRECT
docs: something ← WRONG
```
`docs` is a type, not a scope: `docs(repo): update contributing guide`.

## Process

Expand All @@ -75,7 +56,7 @@ docs: something ← WRONG

Then **STOP and wait** for response.

6. Generate commit message (TYPE FIRST, then optional scope in parentheses)
6. Generate commit message (type first, then the scope in parentheses)
7. If "stage" present → run `git add` on affected files (only chat-mentioned files unless "all" flag present)

## Format Rules
Expand All @@ -84,9 +65,8 @@ docs: something ← WRONG
type(scope): description
```

- **TYPE IS REQUIRED** - one of: feat, fix, build, chore, ci, perf, refactor, revert, style, test
- **SCOPE IS OPTIONAL** - if present, wrap in parentheses after type
- All lowercase, ≤72 chars
- Type and scope are both required
- ≤72 chars
- Title = "what it does", body = "why"
- Be specific (use domain terms from conversation, not generic words)
- No filler: avoid "update", "changes", "code" when meaningless
Expand Down Expand Up @@ -121,7 +101,7 @@ Why:
## Examples

```
feat(api): add rate limiting to auth endpoints
feat(backend): add rate limiting to auth endpoints

Why:
DDoS attacks on /api/sign-in caused production degradation.
Expand All @@ -136,21 +116,21 @@ May need IP allowlist for trusted services (CLERK-5678).
```

```
chore(docs): fix typo in authentication guide
docs(nextjs): fix typo in the middleware README

Why:
Users reported confusion from misspelling.
```

```
ci: consolidate test job into checks to speed up pipeline
ci(repo): consolidate test job into checks to speed up pipeline

Why:
Reduce CI overhead by running tests in same job as lint/type checks.
```

```
feat(docs): document commitlint scope validation system
docs(repo): document commitlint scope validation system

Why:
Added clear documentation to help contributors understand scope requirements.
Expand All @@ -159,9 +139,9 @@ Added clear documentation to help contributors understand scope requirements.
## Remember

- Important:Do not add unnecessary new lines or paragraphs to sentences. Let the editor wrap lines as needed.
- **TYPE FIRST, ALWAYS** - never start with a scope
- **TYPE FIRST, ALWAYS**, then the scope in parentheses
- **NEVER COMMIT OR PUSH**
- Type is REQUIRED, scope is optional
- Type and scope are both required
- **Always explain WHY changes were made** - what problem was being solved, what issues were identified, what motivated the change
- **Provide enough context** - someone reading the commit in 2 years should understand the reasoning without access to the conversation
- Only ask questions for high-impact changes
Expand Down
13 changes: 4 additions & 9 deletions .cursor/rules/clerk-js-ui.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -164,15 +164,10 @@ const errorMessage = translateError(apiError);
### Card Pattern
```tsx
const MyCard = () => (
<Card>
<Card.Root>
<Card.Header>
<Card.Title>Title</Card.Title>
</Card.Header>
<Card.Content>Content</Card.Content>
<Card.Footer>Footer</Card.Footer>
</Card.Root>
</Card>
<Card.Root>
<Card.Content>Content</Card.Content>
<Card.Footer>Footer</Card.Footer>
</Card.Root>
);
```

Expand Down
Loading
Loading