Commit Graph

241 Commits

Author SHA1 Message Date
Nicolas Angelo 6c7a968e88 refactor(orgs): swap cli command from config to enable for cleaner enablement instructions 2026-05-05 15:39:28 -04:00
Railly Hugo c1f6afc82a Merge pull request #39 from clerk/railly/aie-930-clerk-billing-cli-sidebar
feat(billing): add agent-first CLI sidebar for programmatic billing config
2026-05-04 10:00:37 -05:00
Railly Hugo 8d58fb2760 Merge pull request #40 from clerk/railly/aie-931-clerk-orgs-cli-sidebar
feat(orgs): add agent-first CLI sidebar
2026-05-04 09:59:57 -05:00
Railly 0dafc45b9d fix(orgs): correct CLI endpoints in references after deeper router verification
- Replace deprecated /v1/saml_connections with /v1/enterprise_connections (modern path); note paid plan SAML feature gate
- Custom roles: use POST /v1/organization_roles to create (was wrongly POST /v1/role_sets/.../roles which only adds existing roles to a set)
- Custom permissions: show two-step flow (POST /v1/organization_permissions to create, then POST /v1/organization_roles/.../permissions/... to attach)
2026-05-01 17:27:54 -05:00
Railly 2d91575041 fix(orgs): use clerk api wrapper instead of raw BAPI in references
References now consistently show clerk api commands (agent-friendly wrapper) instead of raw BAPI URLs. Matches the SKILL.md Agent-first sidebar style.
2026-05-01 17:25:17 -05:00
Railly 3e5a416888 feat(orgs): add agent-first CLI sidebar
- New 'Agent-first: Programmatic org management' section showing:
  - Enable Organizations + settings via PLAPI Instance Config PATCH (organization_settings.enabled / max_allowed_memberships / domains_enabled / admin_delete_enabled)
  - Org CRUD via BAPI (POST/GET/PATCH/DELETE /v1/organizations)
  - Memberships CRUD (add/list/update role/remove)
  - Invitations (send/list/revoke)
- Update STOP callout: enable toggle is also doable via clerk config patch
- Update Quick Start step 1 to show both paths
- Note that org subscription/billing flows through clerk-billing skill
- Pointer to references/ for roles + SSO deep dives
2026-05-01 17:18:41 -05:00
Railly a831369a75 fix(billing): remove duplicate PricingTable setup from b2c-patterns reference
The 'Full Pricing Page Setup' snippet duplicated SKILL.md Pattern 1 (basic <PricingTable /> render). Strip it; references should expand on B2C-specific patterns, not repeat the basic intro.
2026-05-01 17:12:54 -05:00
Railly 695b81a81c fix(billing): show both Dashboard + CLI paths inline in references, no SKILL.md backref
Path-agnostic was too sterile. Restore dual-path mentions inline (Dashboard URL or clerk config patch) so references are self-contained, without looping the agent back to SKILL.md.
2026-05-01 17:01:55 -05:00
Railly 49f8593715 fix(billing): make references path-agnostic for plan/feature setup
References should expand patterns, not redirect back to SKILL.md or prescribe setup paths. Strip Dashboard/CLI path mentions from b2b-patterns and b2c-patterns; SKILL.md owns setup, references focus on plan-type invariants and pattern usage.
2026-05-01 16:52:45 -05:00
Railly f7d3ec8cd6 feat(billing): add CLI pointers in references for plan/feature creation
Brief 'or via clerk config patch, see SKILL.md → Agent-first' pointers added inline where references currently say 'create plans in Dashboard'. No duplication of the full sidebar — references stay focused on patterns, SKILL.md owns the CLI flow.
2026-05-01 16:42:28 -05:00
Railly 40cc1ba0c9 fix(billing): remove internal Linear ticket reference from skill content
Skills should be agnostic of internal Clerk team tooling. Strip the AIE-823 link and 'when the wrapper ships' future-state framing from the Notes block; keep only what works today.
2026-05-01 16:39:52 -05:00
Railly ca5e4a5e21 fix(billing): correct Enable Billing claim - it works via clerk config patch
- Update STOP callout to show two paths (Dashboard or clerk config patch with billing.user_enabled/organization_enabled)
- Update Quick Start step 1 to mention CLI alternative
- Add 'Enable Billing via CLI' subsection with PATCH example showing auto-creation of free_user/free_org default plans
- Remove stale 'Enable Billing toggle is Dashboard-only' caveat from Notes
- Note that top-level features manipulation and plan-feature attachments are fully supported via PLAPI billing config handler
2026-05-01 16:38:15 -05:00
Railly 6ac4e3a740 feat(billing): add agent-first CLI sidebar for programmatic billing config
- New 'Agent-first: Programmatic billing config' section showing clerk config pull/patch flow + raw clerk api PATCH for full control
- Update STOP callout to clarify CLI can edit plans/features once billing is enabled (Dashboard-only toggle remains for the master switch)
- Note that subscription lifecycle still flows through PricingTable + webhooks
- Reference AIE-823 for the future friendly wrapper swap

Closes AIE-930
2026-05-01 15:54:55 -05:00
Railly Hugo 9d32bf4b90 Merge pull request #28 from clerk/railly/aie-796-skills-add-clerk-billing-skill
feat(billing): add clerk-billing skill
2026-04-28 17:41:09 -05:00
Railly 4e86f5ef44 fix(billing): address review feedback - features-first, UserProfile, org: slugs
- Replace custom AccountBillingPage with <UserProfile /> (B2C), OrgBillingPage with <OrganizationProfile /> (B2B); built-in components own plan switching, cancellations, payment methods
- Use 'org:' slug prefix for org plan checks (has({ plan: 'org:team' })) to disambiguate from user plans in code
- Lead with has({ feature }) over has({ plan }) in Tiered Feature Gating examples; features can move between plans without code deploy
- Remove PricingTable Server Component claim (it is client-side)
- Remove 'metered usage' from core skill router (not shipped)
- Remove Free Plan Fallback section (incorrect concept)
- Strip Stripe leakage from non-setup contexts; keep setup mention and event-name mapping table
- Per-Seat -> Seat-based naming in core router and B2B section heading
- Dedupe seat-limit content between SKILL.md and b2b-patterns.md
- Remove confusing experimental-subpath/underscore notes
- Remove anti-tip about /billing/features 404
- Drop em dashes throughout
2026-04-28 15:58:44 -05:00
Railly Hugo c95ab9bd86 Merge pull request #34 from clerk/railly/skills-pixel-logo-and-cleanup
chore(readme): pixel logo + drop unused issue template
2026-04-27 17:17:52 -05:00
Railly b65b7f761c feat(readme): swap CDN logo for local pixel SVG
Replaces the hosted Clerk logo PNG with a pixel-art SVG bundled in the
repo. The new asset matches the agentic vibe of the skills repo and
removes the external CDN dependency in the README header.
2026-04-27 17:17:05 -05:00
Railly df266409a3 chore: remove unused issue template directory
Skill-request issue template has zero usage. Killing it to keep the
repo lean. Skills get added by maintainers based on actual demand
signal, not GitHub issues.
2026-04-27 17:13:13 -05:00
Railly 16fd490c90 fix(orgs): tighten Membership mode framing in the STOP block
The original line claimed picking the wrong mode causes PricingTable,
OrganizationSwitcher, and personal-account flows to "break silently" —
that overstates what actually happens. In Membership required mode,
signed-in users are routed through the choose-organization task and
personal accounts are disabled by design, not broken. Rewrote to
describe what each mode does and when to pick optional, without the
"break silently" framing.
2026-04-22 13:56:21 -05:00
Railly df56808fc0 fix(billing): reframe Membership-mode error signature row
The old row claimed "<PricingTable /> empty on B2C when Orgs are
enabled | Membership required mode disables personal accounts" — but
if Membership required is on, signed-in users are routed through
choose-organization and never land in a "user without active org"
state to begin with, so the empty-render framing was wrong.

What the Membership mode actually breaks for a billing app is B2C +
B2B coexistence: personal-plan subscriptions can't happen because
personal accounts are disabled by default (since 2025-08-22). Row
rewritten to describe that path specifically, not a PricingTable
render state.
2026-04-22 13:54:00 -05:00
Railly 40e0b7b8c9 fix(billing): add subscriptionItem.expired event, correct webhook env var
- Add subscriptionItem.expired to the event names table in SKILL.md
  and the catalog list in references/billing-webhooks.md so handlers
  can branch on it.

- Rename CLERK_WEBHOOK_SECRET to CLERK_WEBHOOK_SIGNING_SECRET in the
  3 places the skill referenced it (frontmatter compatibility, Error
  Signatures row, billing-webhooks.md Key Rules). The canonical env
  var read by verifyWebhook across all SDK packages is
  CLERK_WEBHOOK_SIGNING_SECRET; the shorter form never matched and
  would produce 'Missing webhook signing secret' at runtime.
2026-04-22 13:35:46 -05:00
Railly 26fc1c4cef refactor(billing): deduplicate SKILL.md, add task-routing table
SKILL.md had three overlapping tables covering the same errors (Error
Signatures, Debugging has() Failures, Common Pitfalls) and duplicated
the full 70-line webhook handler that already lives in
references/billing-webhooks.md. The main file carried maintenance weight
without earning it.

- Delete 'Debugging has() Failures' section — subsumed by Error Signatures
- Delete 'Common Pitfalls' table — subsumed by Error Signatures
- Trim 'Checkout Flows' — removed duplicate <PricingTable /> example
  already shown in §1
- Trim §9 webhook handler from 4 events + middleware snippet down to
  one anchoring event; point to references/billing-webhooks.md for the
  full template, TS types, middleware setup, and status table
- Add 'What Do You Need?' task-to-reference routing table mirroring
  clerk-nextjs-patterns / clerk-orgs convention, so agents know which
  reference to read for which concern without scrolling to the index

SKILL.md: 519 -> 450 lines. No information loss; everything pruned
had a canonical home in Error Signatures or references/.
2026-04-22 13:34:16 -05:00
Railly 50b54e10f5 fix(billing): reframe B2B from 'per-seat pricing' to 'seat-LIMIT plans'
The skill was using Stripe-style 'per-seat billing' language: 'Clerk
auto-increments seats per org member', 'Clerk manages per-seat pricing
internally', etc. That's not the Clerk Billing model.

Verified against clerk_go source + public docs:
- Default B2B billing = seat-LIMIT plans: each org plan has a fixed
  price and optional membership cap, enforced on invite/join
- To charge larger orgs more, tier plans by seat cap (starter 5 /
  team 10 / enterprise unlimited), not meter per member
- 'flag_per_seat_prices' does exist in clerk_go but is flag-gated and
  not GA, so it's out of scope for this skill

This aligns with /docs/guides/billing/seat-limit-plans.mdx. The
mislabel was the exact framing Dylan flagged in v1 review — worth
being precise about now that the rest is clean.

Updates:
- Description, references table, §6 key pattern, B2B vs B2C table, See Also
- b2b-patterns.md overview + renamed 'Per-Seat Billing' section to
  'Seat-Limit Plans' with accurate invariants and add-on requirement note
- Plan Naming table now labels the column 'Seat cap'; mentions
  Organization Plans tab + Seat-based toggle
- Eval 3 expected_output + assertions now require the skill to
  CORRECT the user's 'auto-incrementing seats' mental model
2026-04-22 13:34:16 -05:00
Railly 2e5055b0f4 fix(billing): correct wire-format object literals (commerce_* not billing_*)
Payload examples in billing-webhooks.md used 'billing_subscription',
'billing_payer', 'billing_subscription_item', 'billing_payment_attempt'
as the `object` field values. The real wire format uses 'commerce_*'
(verified against @clerk/backend/src/api/resources/JSON.ts and a live
GET /billing/plans returning "object":"commerce_plan").

Any agent writing `if (evt.data.object === 'billing_subscription')`
would never match a real webhook event — silent failure.

Added eval 4 assertion to catch this hallucination going forward.
2026-04-22 13:34:16 -05:00
Railly 77697195cd fix(billing): surface User Plans vs Organization Plans tab distinction
Three silent failure modes that weren't covered:

- Wrong-tab plan creation. Dashboard Billing → Plans has two tabs
  (User Plans / Organization Plans) with slugs scoped per tab, and
  plans can't be moved between tabs. Creating `pro` under Organization
  Plans and rendering default <PricingTable /> (for="user") produces
  an empty table with no error. Quick Start step 2 now calls out the
  tab match; both b2c-patterns.md and b2b-patterns.md mirror this.

- Membership required mode silently breaks B2C. If Organizations are
  enabled without `Membership optional`, personal accounts are disabled
  and <PricingTable /> excludes users with no active org — no console
  warning. b2c-patterns.md now opens with this prerequisite + the
  dashboard shortcut URL.

- Features are per-plan, not global. /billing/features 404s; features
  live inside each plan's edit page, and the same slug can be attached
  to multiple plans. Quick Start step 3 clarifies this; eval 6
  assertions updated accordingly.

Also added a compact "Dashboard shortcuts" table since every setup
action requires a Dashboard visit and shortcut URLs are more reliable
than click-path instructions.
2026-04-22 13:34:16 -05:00
Railly feaf4b84f1 fix(billing): document billing-disabled error + fix v7+ version note
Agents were writing <PricingTable /> without surfacing the Dashboard
prerequisite, leaving users stuck on the 'cannot_render_billing_disabled'
error with no diagnosis. The Clerk CLI and Backend API cannot toggle
billing today (clerk_go#18260 is the follow-up that will); Dashboard is
the only path.

Changes:
- STOP block at top of SKILL.md calling out Dashboard-only enablement
  with the exact deep link
- Quick Start step 1 references the error signature the user will hit
  if they skip it
- New 'Error Signatures' section with cannot_render_billing_disabled
  plus 5 other common symptoms mapped to root cause + fix
- Version note corrected from 'v6+ (Core 3)' to 'v7+ (Core 3)' —
  v6 is Core 2, billing there shipped under __unstable_* APIs
- Eval 1 and 9 assertions tightened: agent must surface the Dashboard
  link + error code, and must NOT claim the CLI/BAPI can enable billing
2026-04-22 13:34:16 -05:00
Railly ab4473a8e9 fix(billing): remove Stripe Billing hallucinations, align with docs
Clerk Billing is a separate product from Stripe Billing — Plans are not
synced to Stripe Products, PricingTable opens Clerk's in-app checkout
drawer (not Stripe Checkout), and per-seat pricing is managed internally
by Clerk with a single active SubscriptionItem per payer per Plan.

Also fixes:
- subscriptionItem.created removed (not a real event; catalog has 9 items)
- useSubscription import: drop __experimental_ prefix (subpath is the signal)
- PricingTable props: full list including for="organization" for B2B
- CheckoutButton section added (was missing entirely)
- Beta warning dropped from SKILL.md per review feedback
- Dev gateway surfaced so skill doesn't falsely require a Stripe account
- Eval assertions rewritten to catch the bad mental model instead of
  encoding it (e.g. evals 1, 3, 7, 9, 10, 11)
2026-04-22 13:34:16 -05:00
Railly 016da325ff fix(billing): correct webhook payload shape and useSubscription API
Code examples were destructuring fields that do not exist at the top
level of billing webhook payloads. Verified against the SDK types in
@clerk/backend (BillingSubscriptionWebhookEventJSON,
BillingSubscriptionItemWebhookEventJSON, BillingPayerJSON).

Webhook payload corrections (SKILL.md Pattern 9, billing-webhooks.md,
b2b-patterns.md):
- The subscribing entity lives at evt.data.payer with user_id? and
  organization_id? (not evt.data.user_id / evt.data.org_id)
- The subscription id is evt.data.id (not a separate subscription_id
  field)
- Plan slug is nested: evt.data.items[i].plan?.slug on subscription
  events, evt.data.plan?.slug on subscriptionItem events
- seats does not exist as a top-level field; derive seat count from
  items.length (one subscription item per seat)
- subscriptionItem events carry the item only; no subscription_id
  back-reference, so match by payer plus plan slug
- Payload reference now shows the actual nested schema with payer,
  items[], items[i].plan, payment_source_id, etc.

useSubscription hook corrections (SKILL.md Pattern 7, b2c-patterns.md):
- Import from @clerk/nextjs/experimental as __experimental_useSubscription
  (Billing is Beta, the hook is not yet exported from @clerk/nextjs)
- The return type uses isLoading, not isLoaded
- The renewal date is subscription.nextPayment?.date (a Date object),
  not subscription.currentPeriodEnd (which does not exist on
  BillingSubscriptionResource)

Event catalog corrections:
- Added subscriptionItem.created back to the setup list (10 items,
  not 9). It exists per the SDK types.
- Removed the incorrect "no subscriptionItem.created event" note.
- Added subscriptionItem.created row to the Clerk vs Stripe table.

Also:
- Removed duplicate clerk-setup entry in See Also.
2026-04-22 13:34:16 -05:00
Railly 792a3188ce refactor(skills): replace metadata.inputs with compatibility field
Standardizes the env var declaration across all skills to use the
`compatibility:` string field (matching clerk-webhooks, clerk-testing,
clerk-swift, clerk-android, clerk-expo-patterns) instead of the
nested metadata.inputs list.

Affected:
- clerk-billing (was already part of this PR)
- clerk-orgs
- clerk-backend-api
- clerk-chrome-extension-patterns
2026-04-22 13:34:16 -05:00
Railly b63769b71a fix(billing): correct webhook event catalog and add seats to updated handler
- Remove subscriptionItem.created (not a real Clerk event per docs)
- Remove subscription.canceled (cancellation fires as subscriptionItem.canceled)
- Add paymentAttempt.created / paymentAttempt.updated to the setup list
- Add explanatory note clarifying there is no subscription.canceled and
  no subscriptionItem.created event
- Relabel the canceled row in the SKILL.md event table to
  'Subscription item canceled' to match the actual event semantics
- Destructure seats from subscription.updated so B2B per-seat changes
  propagate to the database

Verified against clerk.com/docs/nextjs/guides/development/webhooks/billing.
2026-04-22 13:33:34 -05:00
Railly a19fd073a6 fix(billing): use has() and useSubscription() instead of sessionClaims
The SKILL.md Pattern 7 and b2c-patterns.md were teaching agents to read
sessionClaims.metadata.plan directly, which is not the supported path
per Clerk docs. Authorization should go through has({ plan }) and
display-only details through useSubscription().

- Replace sessionClaims lookups with has({ plan }) + useSubscription()
- Update eval 5 to assert the new pattern and explicitly reject
  sessionClaims.metadata.plan
- Resolves the contradiction where the skill taught sessionClaims but
  evals 2 and 6 penalized it
2026-04-22 13:33:34 -05:00
Railly 74bb401af8 test(billing): tighten assertions for evals 1, 4, 6
Replace correctness-focused assertions with discriminating ones that
target Clerk-specific knowledge:

- eval 1 (pricing): check for Beta warning, SDK version pinning,
  explicit Stripe-connection prerequisite, Plans-must-exist prereq,
  and negative assertions against @clerk/billing import and direct
  Stripe API calls.

- eval 4 (webhooks): verify the agent uses verifyWebhook from
  @clerk/nextjs/webhooks (not raw svix), uses camelCase event names
  like subscriptionItem.pastDue (not past_due), marks the webhook
  route public via createRouteMatcher, and uses async middleware
  callbacks.

- eval 6 (feature gating): verify the decision-rule explanation
  (feature vs plan), the Dashboard → Features slug-matching warning,
  and the billing-gates-permissions gotcha.

Measured delta in a local eval run (3 evals, single-run each):
100% pass rate with skill vs 68% without — +32pp differentiation,
up from +17pp with the previous correctness-based assertions.
2026-04-22 13:33:34 -05:00
Railly 47ceab4023 test(billing): migrate evals to agentskills.io assertions format
- Rename `expectations` → `assertions` per https://agentskills.io spec
- Add `files: []` field for consistency with new format
- Keep `scaffold` as a custom extension the eval runner uses to pick
  the starter template (nextjs-basic-auth from clerk-nextjs-patterns)
- Tighten individual assertions to be more specific and verifiable:
  exact import paths, exact method calls, concrete event names

12 evals, 64 total assertions. Ready for the new skill-creator eval
framework which expects the assertions-based format.
2026-04-22 13:33:34 -05:00
Railly b1cfe960b6 docs(readme): add clerk-billing to features table and examples 2026-04-22 13:33:34 -05:00
Railly 39247a43a5 chore(marketplace): register clerk-billing in features plugin 2026-04-22 13:33:34 -05:00
Railly 5b331e0e8c feat(router): route billing tasks to clerk-billing 2026-04-22 13:33:34 -05:00
Railly dd90f1bae4 feat(billing): add clerk-billing skill
Covers the Clerk Billing feature set:
- `<PricingTable />` component usage
- `has({ plan })` and `has({ feature })` gating (server + client)
- B2B per-seat billing with organizations
- Billing webhook event handling (subscription lifecycle)
- Upgrade/downgrade flows and debugging `has()` failures
- Core 3 syntax throughout (async middleware, auth.protect)

Structure:
- SKILL.md with 10 key patterns and common pitfalls table
- references/ with deep dives for b2c, b2b, components, webhooks
- evals/ with 12 evals covering recommendation + implementation tests

Addresses the measured gap where billing was recommended 6.3% of the
time without a dedicated skill vs 89.6% with one.
2026-04-22 13:33:34 -05:00
Railly Hugo f490910489 Merge pull request #31 from clerk/railly/aie-874-refresh-clerk-orgs-skill-accuracy-pass-progressive
refactor(orgs): accuracy + progressive disclosure pass
2026-04-22 13:32:05 -05:00
Railly 686f0667d3 fix(orgs): fifth sweep — modern signIn.sso + multi-SDK auth accessors
Two more residuals caught:

enterprise-sso.md — Custom Sign-In Flow:
- The example used signIn.authenticateWithRedirect() which still works
  but is the legacy path. Current enterprise-connections custom flow
  doc uses signIn.sso({ strategy, identifier, redirectUrl,
  redirectCallbackUrl }). Updated to the Core 3 canonical pattern with
  a small Core-2/legacy callout noting the older method still exists
  for backwards compat.
- Note: redirectUrlComplete -> redirectUrl, and new redirectCallbackUrl
  param for the additional-requirements case.

SKILL.md — §1 accessor note:
- Original line conflated "getAuth(event)" as covering Nuxt AND Astro
  server, but Astro uses context.locals.auth() (not getAuth). Split
  out per-SDK: auth(event) for Nuxt, context.locals.auth() for Astro,
  getAuth(req) for Express. Client accessors kept as useAuth (React)
  or composables (Vue/Nuxt).
2026-04-22 13:04:35 -05:00
Railly 093ca7682a fix(orgs): fourth sweep — TaskChooseOrganization SDK list + verifyToken reference
Two more residuals caught on a fourth cross-validation pass:

SKILL.md §6 (Session Task):
- Claim that TaskChooseOrganization "ships in @clerk/js-frontend" as
  an import. Package name is actually @clerk/clerk-js, and the JS
  Frontend SDK exposes the task UI via clerk.mountTaskChooseOrganization
  / unmountTaskChooseOrganization methods, not as a component import.
  Reworded to make the import-vs-mount distinction clear.

references/invitations.md framework-wrappers table:
- @clerk/backend row pointed at clerk.verifyToken (method-style) but
  verifyToken is a standalone top-level export from @clerk/backend,
  not a method on the client instance. Reworded accordingly.
2026-04-22 12:56:43 -05:00
Railly dfda71135a fix(orgs): final cross-validation sweep — 6 residual inaccuracies
Full sweep across all 4 reference files + SKILL.md against docs
reference pages + @clerk/backend + @clerk/astro + @clerk/nuxt
+ @clerk/express source.

Caught in this pass:

SKILL.md:
- Enterprise SSO short section still claimed "Requires domain
  verification (DNS TXT)". Reworded to reflect the real model:
  the SSO connection owns its domain directly, no separate Verified
  Domain required, the two features are mutually exclusive. Added
  JIT Provisioning as the real auto-join mechanism.

roles-permissions.md:
- org:sys_domains:manage description claimed coverage of
  "Enterprise SSO connections" which isn't in the docs. Tightened
  to only what docs explicitly confirm (Verified Domains).

invitations.md:
- createOrganizationInvitationBulk signature was wrong: skill had
  a single object with invitations: [...] inside, but the real
  method takes organizationId as a positional arg + a params array
  as the second arg. Agents following the old example would get a
  TypeScript error or a 400 from BAPI.
- Bulk endpoint rate limit corrected from 250/hr (same as single)
  to 50/hr (per the bulk-specific rate limit in the backend ref).
- Framework wrappers table had two wrong client retrievers:
  @clerk/astro/server used `clerk(context)` (invalid import) —
  real is `clerkClient(context)`. @clerk/nuxt/server used
  `useClerkClient(event)` — real is `clerkClient(event)`.
  Fixed auth-context accessors for both frameworks.

nextjs-patterns.md: verified clean against @clerk/nextjs/server
source (auth.protect overloads, createRouteMatcher, clerkMiddleware).
No changes needed.
2026-04-22 12:04:23 -05:00
Railly 3849a443cf fix(orgs): address review feedback on enterprise-sso + invitations refs
Applying feedback from PR review:

enterprise-sso.md:
- Configuration Flow rewritten. Removed DNS TXT record claim for
  Verified Domains (ownership is verified via email code inside the
  OrganizationSwitcher / OrganizationProfile flow, per the Verified
  Domains guide). Removed the conflation of SSO connection setup with
  Verified Domains — docs explicitly call out that the two features
  are mutually exclusive on the same domain.
- Added note that Dashboard is the only path today; flagged CLI as
  a future revisit once shipped.
- Verified Domains section reframed as "separate feature, short
  reference" pointing to the canonical doc.
- New section for JIT Provisioning — this is the actual mechanism
  that auto-joins SSO users to an org, not Verified Domains.
- Key Rules corrected: SSO connection owns its domain (no Verified
  Domain prerequisite); auto-join is JIT Provisioning.
- Dropped self-referential "this is where the skill used to
  hallucinate" wording per review.

invitations.md:
- Added framework-wrappers callout at top. Method signatures on
  clerk.organizations.* are identical across SDKs — only the
  client-retrieval wrapper differs. Table covers @clerk/nextjs,
  @clerk/backend, @clerk/astro/server, @clerk/nuxt/server,
  @clerk/express. Keeps @clerk/nextjs as default code flavor
  (consistent with clerk-billing precedent) while making the
  cross-SDK story discoverable, addressing the review comment
  on framework separation.
2026-04-22 11:58:33 -05:00
Railly baf7a954fc refactor(orgs): slim nextjs-patterns reference to org-specific content
Trim references/nextjs-patterns.md (146 -> 106 lines) by removing
content that already lives in the clerk-nextjs-patterns skill:

- File-naming note (proxy.ts vs middleware.ts) — lives in
  clerk-nextjs-patterns/references/middleware-strategies.md
- Generic createRouteMatcher intro — same place
- 401 vs 403 response policy — lives in
  clerk-nextjs-patterns/references/api-routes.md
- Generic server action shape — lives in
  clerk-nextjs-patterns/references/server-actions.md

Keep the org-specific adaptations:

- auth.protect({ role / permission }) in middleware
- orgSlug === params.slug URL safety invariant
- orgId-scoped DB writes in server actions
- getOrganizationMembershipList usage in an API route

Updated routing + references tables in SKILL.md to describe the
file's scope and point agents to clerk-nextjs-patterns for generic
Next.js patterns.
2026-04-20 18:45:40 -05:00
Railly f73966be81 refactor(orgs): accuracy + progressive disclosure pass
Brings clerk-orgs in line with the structure used by clerk-billing v2
and clerk-nextjs-patterns: progressive disclosure, compatibility
frontmatter, task-routing table, error signatures, dashboard shortcuts.

Content refinements (cross-referenced against clerk-docs reference
pages + the @clerk/backend + @clerk/shared types in clerk/javascript):

- Permission slugs aligned with the canonical System Permissions
  catalog at docs/guides/organizations/control-access/roles-and-permissions.mdx:
  org:sys_{memberships,profile,domains,billing}:{read,manage,delete}.
  The older table referenced non-canonical names that would not match
  a has() check at runtime.

- createOrganizationInvitation example now includes inviterUserId,
  which the Backend API reference lists as required for human-initiated
  invitations.

- Enterprise SSO example updated to access provider metadata via
  enterpriseAccounts[i].enterpriseConnection?.provider, matching the
  EnterpriseAccountConnection type definition. Direct .provider access
  on EnterpriseAccount returns undefined.

- getOrganizationInvitationList status enum updated to include all
  four documented values: pending, accepted, revoked, expired.

- Membership required vs Membership optional mode surfaced explicitly
  (default is required since Aug 22, 2025). This affects B2C + B2B
  coexistence and was a silent-failure mode worth calling out in the
  error signatures table.

Structural changes:

- SKILL.md 423 -> 350 lines. Framework-agnostic framing with
  @clerk/nextjs as the default code flavor and a pointer to other SDKs
  (@clerk/react, @clerk/astro, @clerk/vue, @clerk/expo, ...). Next.js
  middleware and redirect() patterns moved to references/nextjs-patterns.md.

- New references/: roles-permissions.md (120), invitations.md (137),
  enterprise-sso.md (108), nextjs-patterns.md (146). All under the 300-line
  threshold per skill-creator guidance.

- Frontmatter: inputs: array -> compatibility: string (matches
  clerk-billing pattern + skill-creator convention). Version 2.1.0 -> 3.0.0.

- New sections: STOP prerequisite block, Dashboard shortcuts table,
  Error Signatures table (seven rows), What Do You Need? routing table.

Evals:

- Eval 2 (RBAC): require canonical System Permission slugs.
- Eval 5 (SSO): require enterpriseConnection?.provider path.
- Eval 7 (invitations): require inviterUserId + full status enum.
- Eval 9 (new): cover the Membership mode prerequisite.
2026-04-20 18:23:08 -05:00
Railly Hugo 43d2211bec Merge pull request #26 from clerk/railly/remove-clerk-cli-readme
docs(readme): remove Clerk CLI install section
2026-04-06 18:44:07 -05:00
Railly 498ccf0229 docs(readme): remove Clerk CLI install section 2026-04-06 18:39:00 -05:00
Railly Hugo c4833f8b6b Merge pull request #25 from clerk/railly/aie-750-add-framework-patterns-restructure
feat: add 9 framework pattern skills + restructure into 4 categories
2026-04-06 18:37:28 -05:00
Railly 7e4ff9f833 fix(backend-api): add See Also section 2026-04-06 18:32:10 -05:00
Railly 932e2dd2c8 fix: add See Also to remaining 5 skills (orgs, backend-api, astro, expo, react-router) 2026-04-06 18:32:02 -05:00
Railly 7ad26358c7 fix: final review polish
- W1: rephrase clerk-setup cross-skill ref to avoid backtick path syntax
- W3: add See Also to 9 skills missing it (orgs, webhooks, backend-api,
  custom-ui, vue, astro, expo, chrome-extension, react-router)
- W4: add Android row to README Ask Your Agent table
- N4: testing demo repo URL → main branch instead of pinned commit
2026-04-06 18:31:35 -05:00