diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json
deleted file mode 100644
index 64d1f9f..0000000
--- a/.claude-plugin/plugin.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "name": "workos-authkit-installer",
- "version": "1.0.0",
- "description": "WorkOS AuthKit integration skills for multiple frameworks",
- "author": {
- "name": "WorkOS",
- "url": "https://workos.com"
- },
- "homepage": "https://workos.com/docs/user-management/authkit",
- "repository": "https://github.com/workos/authkit-installer",
- "license": "MIT",
- "keywords": ["workos", "authkit", "authentication", "installer", "install"]
-}
diff --git a/CLAUDE.md b/CLAUDE.md
index 1bf1b3a..c97a167 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -47,3 +47,28 @@ pnpm typecheck # Type check
1. Create `src/commands/{resource}.ts` + `{resource}.spec.ts` (follow patterns in `organization.ts`)
2. Register in `src/bin.ts` and update `src/utils/help-json.ts` command registry
3. Include JSON mode tests in spec file
+
+## Do / Don't
+
+**Do:**
+
+- Follow the adapter pattern (`CLI`, `Dashboard`, `Headless`) in `src/integrations/` when adding framework installers
+- Use `InstallerEventEmitter` for state machine events -- see existing adapters for examples
+- Add both human and JSON output modes -- check `OutputMode` usage in `src/bin.ts`
+- Follow existing command patterns in `src/commands/organization.ts` when adding resource commands
+- Write `.spec.ts` tests alongside every command file
+
+**Don't:**
+
+- Use Node-specific sync APIs (crypto, fs sync) unless necessary
+- Use npm or yarn -- pnpm only
+- Skip JSON mode tests in spec files
+- Forget to wire up new frameworks in `src/run.ts` switch statement
+
+## PR Checklist
+
+- [ ] `pnpm build` passes
+- [ ] `pnpm test` passes
+- [ ] `pnpm typecheck` passes
+- [ ] Conventional Commit message format used (`feat:`, `fix:`, `feat!:` for breaking)
+- [ ] New commands include JSON mode support and tests
diff --git a/package.json b/package.json
index 4ae286c..62fd29a 100644
--- a/package.json
+++ b/package.json
@@ -26,8 +26,6 @@
},
"files": [
"dist",
- ".claude-plugin",
- "skills",
"package.json",
"README.md"
],
@@ -43,6 +41,7 @@
"@clack/prompts": "1.0.1",
"@napi-rs/keyring": "^1.2.0",
"@workos-inc/node": "^8.7.0",
+ "@workos/skills": "0.2.2",
"chalk": "^5.6.2",
"diff": "^8.0.3",
"fast-glob": "^3.3.3",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 27c9fae..8cc1e31 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -26,6 +26,9 @@ importers:
'@workos-inc/node':
specifier: ^8.7.0
version: 8.7.0
+ '@workos/skills':
+ specifier: 0.2.2
+ version: 0.2.2
chalk:
specifier: ^5.6.2
version: 5.6.2
@@ -1592,6 +1595,9 @@ packages:
resolution: {integrity: sha512-43HfXSR2Ez7M4ixpebuYVZzZf3gauh5jvv9lYnePg/x0XZMN2hjpEV3FD1LQX1vfMbqQ5gON3DN+/gH2rITm3A==}
engines: {node: '>=20.15.0'}
+ '@workos/skills@0.2.2':
+ resolution: {integrity: sha512-jO4HuI4seyAjoBwfl2bTQe5FXE5ir1nyJ5+RkYG4yhpIvsIThBJkAoYJwdhRhFynzJAYuQIb7v6E7a2zBto7ww==}
+
abort-controller@3.0.0:
resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
engines: {node: '>=6.5'}
@@ -3821,6 +3827,10 @@ snapshots:
iron-webcrypto: 2.0.0
jose: 6.1.3
+ '@workos/skills@0.2.2':
+ dependencies:
+ yaml: 2.8.2
+
abort-controller@3.0.0:
dependencies:
event-target-shim: 5.0.1
diff --git a/skills/workos-authkit-base/SKILL.md b/skills/workos-authkit-base/SKILL.md
deleted file mode 100644
index 9f0a854..0000000
--- a/skills/workos-authkit-base/SKILL.md
+++ /dev/null
@@ -1,123 +0,0 @@
----
-name: workos-authkit-base
-description: Architectural reference for WorkOS AuthKit integrations. Fetch README first for implementation details.
----
-
-# WorkOS AuthKit Base Template
-
-## First Action: Fetch README
-
-Before any implementation, fetch the framework-specific README:
-
-```
-WebFetch: {sdk-package-name} README from npmjs.com or GitHub
-```
-
-README is the source of truth for: install commands, imports, API usage, code patterns.
-
-## Task Structure (Required)
-
-| Phase | Task | Blocked By | Purpose |
-| ----- | --------- | ------------------ | --------------------------------- |
-| 1 | preflight | - | Verify env vars, detect framework |
-| 2 | install | preflight | Install SDK package |
-| 3 | callback | install | Create OAuth callback route |
-| 4 | provider | install | Setup auth context/middleware |
-| 5 | ui | callback, provider | Add sign-in/out UI |
-| 6 | verify | ui | Build confirmation |
-
-## Decision Trees
-
-### Package Manager Detection
-
-```
-pnpm-lock.yaml? → pnpm
-yarn.lock? → yarn
-bun.lockb? → bun
-else → npm
-```
-
-### Provider vs Middleware
-
-```
-Client-side framework? → AuthKitProvider wraps app
-Server-side framework? → Middleware handles sessions
-Hybrid (Next.js)? → Both may be needed
-```
-
-### Callback Route Location
-
-Extract path from `WORKOS_REDIRECT_URI` → create route at that exact path.
-
-## Environment Variables
-
-| Variable | Purpose | When Required |
-| ------------------------ | ------------------------------ | ------------- |
-| `WORKOS_API_KEY` | Server authentication | Server SDKs |
-| `WORKOS_CLIENT_ID` | Client identification | All SDKs |
-| `WORKOS_REDIRECT_URI` | OAuth callback URL | Server SDKs |
-| `WORKOS_COOKIE_PASSWORD` | Session encryption (32+ chars) | Server SDKs |
-
-Note: Some frameworks use prefixed variants (e.g., `NEXT_PUBLIC_*`). Check README.
-
-## Verification Checklists
-
-### After Install
-
-- [ ] SDK package installed in node_modules
-- [ ] No install errors in output
-
-### After Callback Route
-
-- [ ] Route file exists at path matching `WORKOS_REDIRECT_URI`
-- [ ] Imports SDK callback handler (not custom OAuth)
-
-### After Provider/Middleware
-
-- [ ] Provider wraps entire app (client-side)
-- [ ] Middleware configured in correct location (server-side)
-
-### After UI
-
-- [ ] Home page shows conditional auth state
-- [ ] Uses SDK functions for sign-in/out URLs
-
-### Final Verification
-
-- [ ] Build completes with exit code 0
-- [ ] No import resolution errors
-
-## Error Recovery
-
-### Module not found
-
-- [ ] Verify install completed successfully
-- [ ] Verify SDK exists in node_modules
-- [ ] Re-run install if missing
-
-### Build import errors
-
-- [ ] Delete `node_modules`, reinstall
-- [ ] Verify package.json has SDK dependency
-
-### Invalid redirect URI
-
-- [ ] Compare route path to `WORKOS_REDIRECT_URI`
-- [ ] Paths must match exactly
-
-### Cookie password error
-
-- [ ] Verify `WORKOS_COOKIE_PASSWORD` is 32+ characters
-- [ ] Generate new: `openssl rand -base64 32`
-
-### Auth state not persisting
-
-- [ ] Verify provider wraps entire app
-- [ ] Check middleware is in correct location
-
-## Critical Rules
-
-1. **Install SDK before writing imports** - never create import statements for uninstalled packages
-2. **Use SDK functions** - never construct OAuth URLs manually
-3. **Follow README patterns** - SDK APIs change between versions
-4. **Extract callback path from env** - don't hardcode `/auth/callback`
diff --git a/skills/workos-authkit-nextjs/SKILL.md b/skills/workos-authkit-nextjs/SKILL.md
deleted file mode 100644
index d091224..0000000
--- a/skills/workos-authkit-nextjs/SKILL.md
+++ /dev/null
@@ -1,247 +0,0 @@
----
-name: workos-authkit-nextjs
-description: Integrate WorkOS AuthKit with Next.js App Router (13+). Server-side rendering required.
----
-
-# WorkOS AuthKit for Next.js
-
-## Step 1: Fetch SDK Documentation (BLOCKING)
-
-**STOP. Do not proceed until complete.**
-
-WebFetch: `https://raw.githubusercontent.com/workos/authkit-nextjs/main/README.md`
-
-The README is the source of truth. If this skill conflicts with README, follow README.
-
-## Step 2: Pre-Flight Validation
-
-### Project Structure
-
-- Confirm `next.config.js` or `next.config.mjs` exists
-- Confirm `package.json` contains `"next"` dependency
-
-### Environment Variables
-
-Check `.env.local` for:
-
-- `WORKOS_API_KEY` - starts with `sk_`
-- `WORKOS_CLIENT_ID` - starts with `client_`
-- `NEXT_PUBLIC_WORKOS_REDIRECT_URI` - valid callback URL
-- `WORKOS_COOKIE_PASSWORD` - 32+ characters
-
-## Step 3: Install SDK
-
-Detect package manager, install SDK package from README.
-
-**Verify:** SDK package exists in node_modules before continuing.
-
-## Step 4: Locate the app/ directory (BLOCKING)
-
-**STOP. Do this before creating any files.**
-
-Determine where the `app/` directory lives:
-
-```bash
-# Check for src/app/ first, then root app/
-ls src/app/ 2>/dev/null && echo "APP_DIR=src" || (ls app/ 2>/dev/null && echo "APP_DIR=root")
-```
-
-Set `APP_DIR` for all subsequent steps. All middleware/proxy files MUST be created in `APP_DIR`:
-
-- If `APP_DIR=src` → create files in `src/` (e.g., `src/proxy.ts`)
-- If `APP_DIR=root` → create files at project root (e.g., `proxy.ts`)
-
-Next.js only discovers middleware/proxy files in the parent directory of `app/`. A file at the wrong level is **silently ignored** — no error, just doesn't run.
-
-## Step 5: Version Detection (Decision Tree)
-
-Read Next.js version from `package.json`:
-
-```
-Next.js version?
- |
- +-- 16+ --> Create {APP_DIR}/proxy.ts
- |
- +-- 15 --> Create {APP_DIR}/middleware.ts (cookies() is async)
- |
- +-- 13-14 --> Create {APP_DIR}/middleware.ts (cookies() is sync)
-```
-
-**Next.js 16+ proxy.ts:** `proxy.ts` is the preferred convention. `middleware.ts` still works but shows a deprecation warning. Next.js 16 throws **error E900** if both files exist at the same level.
-
-**Next.js 15+ async note:** All route handlers and middleware accessing cookies must be async and properly await cookie operations. This is a breaking change from Next.js 14.
-
-Middleware/proxy code: See README for `authkitMiddleware()` export pattern.
-
-### Existing Middleware (IMPORTANT)
-
-If `middleware.ts` already exists with custom logic (rate limiting, logging, headers, etc.), use the **`authkit()` composable function** instead of `authkitMiddleware`.
-
-**Pattern for composing with existing middleware:**
-
-```typescript
-import { NextRequest, NextResponse } from 'next/server';
-import { authkit, handleAuthkitHeaders } from '@workos-inc/authkit-nextjs';
-
-export default async function middleware(request: NextRequest) {
- // 1. Get auth session and headers from AuthKit
- const { session, headers, authorizationUrl } = await authkit(request);
- const { pathname } = request.nextUrl;
-
- // 2. === YOUR EXISTING MIDDLEWARE LOGIC ===
- // Rate limiting, logging, custom headers, etc.
- const rateLimitResult = checkRateLimit(request);
- if (!rateLimitResult.allowed) {
- return new NextResponse('Too Many Requests', { status: 429 });
- }
-
- // 3. Protect routes - redirect to auth if needed
- if (pathname.startsWith('/dashboard') && !session.user && authorizationUrl) {
- return handleAuthkitHeaders(request, headers, { redirect: authorizationUrl });
- }
-
- // 4. Continue with AuthKit headers properly handled
- return handleAuthkitHeaders(request, headers);
-}
-```
-
-**Key functions:**
-
-- `authkit(request)` - Returns `{ session, headers, authorizationUrl }` for composition
-- `handleAuthkitHeaders(request, headers, options?)` - Ensures AuthKit headers pass through correctly
-- For rewrites, use `partitionAuthkitHeaders()` and `applyResponseHeaders()` (see README)
-
-**Critical:** Always return via `handleAuthkitHeaders()` to ensure `withAuth()` works in pages.
-
-## Step 6: Create Callback Route
-
-Parse `NEXT_PUBLIC_WORKOS_REDIRECT_URI` to determine route path:
-
-```
-URI path --> Route location (use APP_DIR from Step 4)
-/auth/callback --> {APP_DIR}/app/auth/callback/route.ts
-/callback --> {APP_DIR}/app/callback/route.ts
-```
-
-Use `handleAuth()` from SDK. Do not write custom OAuth logic.
-
-**CRITICAL for Next.js 15+:** The route handler MUST be async and properly await handleAuth():
-
-```typescript
-// CORRECT - Next.js 15+ requires async route handlers
-export const GET = handleAuth();
-
-// If handleAuth returns a function, ensure it's awaited in request context
-```
-
-Check README for exact usage. If build fails with "cookies outside request scope", the handler is likely missing async/await.
-
-## Step 7: Provider Setup (REQUIRED)
-
-**CRITICAL:** You MUST wrap the app in `AuthKitProvider` in `app/layout.tsx`.
-
-This is required for:
-
-- Client-side auth state via `useAuth()` hook
-- Consistent auth UX across client/server boundaries
-- Proper migration from Auth0 (which uses client-side auth)
-
-```tsx
-// app/layout.tsx
-import { AuthKitProvider } from '@workos-inc/authkit-nextjs/components';
-
-export default function RootLayout({ children }: { children: React.ReactNode }) {
- return (
-
-
- {children}
-
-
- );
-}
-```
-
-**Do NOT skip this step** even if using server-side auth patterns elsewhere.
-
-## Step 8: UI Integration
-
-Add auth UI to `app/page.tsx` using SDK functions. See README for auth helper usage (`withAuth`/`getUser`, `getSignInUrl`, `signOut`).
-
-**Note:** The SDK renamed `getUser` to `withAuth` in newer versions. Use whichever function the installed SDK version exports — do NOT rename existing working imports.
-
-## Verification Checklist (ALL MUST PASS)
-
-Run these commands to confirm integration. **Do not mark complete until all pass:**
-
-```bash
-# 1. Check middleware/proxy exists (one should match)
-ls proxy.ts middleware.ts src/proxy.ts src/middleware.ts 2>/dev/null
-
-# 2. CRITICAL: Check AuthKitProvider is in layout (REQUIRED)
-grep "AuthKitProvider" app/layout.tsx || echo "FAIL: AuthKitProvider missing from layout"
-
-# 3. Check callback route exists
-find app -name "route.ts" -path "*/callback/*"
-
-# 4. Build succeeds
-npm run build
-```
-
-**If check #2 fails:** Go back to Step 6 and add AuthKitProvider. This is not optional.
-
-## Error Recovery
-
-### "cookies was called outside a request scope" (Next.js 15+)
-
-**Most common cause:** Route handler not properly async or missing await.
-
-Fix for callback route:
-
-1. Check that `handleAuth()` is exported directly: `export const GET = handleAuth();`
-2. If using custom wrapper, ensure it's `async` and awaits any cookie operations
-3. Verify authkit-nextjs SDK version supports Next.js 15+ (check README for compatibility)
-4. **Never** call `cookies()` at module level - only inside request handlers
-
-This error causes OAuth codes to expire ("invalid_grant"), so fix the handler first.
-
-### "middleware.ts not found"
-
-- Check: File at project root or `src/`, not inside `app/`
-- Check: Filename matches Next.js version (proxy.ts for 16+, middleware.ts for 13-15)
-
-### "Both middleware file and proxy file are detected" (Next.js 16+)
-
-- Next.js 16 throws error E900 if both `middleware.ts` and `proxy.ts` exist
-- Delete `middleware.ts` and use only `proxy.ts`
-- If `middleware.ts` has custom logic, migrate it into `proxy.ts`
-
-### "withAuth route not covered by middleware" but middleware/proxy file exists
-
-- **Most common cause:** File is at the wrong level. Next.js only discovers middleware/proxy files in the parent directory of `app/`. For `src/app/` projects, the file must be in `src/`, not at the project root.
-- Check: Is `app/` at `src/app/`? Then middleware/proxy must be at `src/middleware.ts` or `src/proxy.ts`
-- Check: Matcher config must include the route path being accessed
-
-### "Cannot use getUser in client component"
-
-- Check: Component has no `'use client'` directive, or
-- Check: Move auth logic to server component/API route
-
-### "Module not found" for SDK import
-
-- Check: SDK installed before writing imports
-- Check: SDK package directory exists in node_modules
-
-### "withAuth route not covered by middleware"
-
-- Check: Middleware/proxy file exists at correct location
-- Check: Matcher config includes the route path
-
-### Build fails after AuthKitProvider
-
-- Check: Import path matches what README specifies (root export vs `/components` subpath)
-- Check: No client/server boundary violations
-
-### NEXT*PUBLIC* prefix issues
-
-- Client components need `NEXT_PUBLIC_*` prefix
-- Server components use plain env var names
diff --git a/skills/workos-authkit-react-router/SKILL.md b/skills/workos-authkit-react-router/SKILL.md
deleted file mode 100644
index 91f6e39..0000000
--- a/skills/workos-authkit-react-router/SKILL.md
+++ /dev/null
@@ -1,117 +0,0 @@
----
-name: workos-authkit-react-router
-description: Integrate WorkOS AuthKit with React Router applications. Supports v6 and v7 (Framework, Data, Declarative modes). Use when project uses react-router, react-router-dom, or mentions React Router authentication.
----
-
-# WorkOS AuthKit for React Router
-
-## Decision Tree
-
-```
-1. Fetch README (BLOCKING)
-2. Detect router mode
-3. Follow README for that mode
-4. Verify with checklist below
-```
-
-## Phase 1: Fetch SDK Documentation (BLOCKING)
-
-**STOP - Do not write any code until this completes.**
-
-WebFetch: `https://raw.githubusercontent.com/workos/authkit-react-router/main/README.md`
-
-The README is the source of truth. If this skill conflicts with README, **follow the README**.
-
-## Phase 2: Detect Router Mode
-
-| Mode | Detection Signal | Key Indicator |
-| -------------- | ------------------------------- | ------------------------- |
-| v7 Framework | `react-router.config.ts` exists | Routes in `app/routes/` |
-| v7 Data | `createBrowserRouter` in source | Loaders in route config |
-| v7 Declarative | `` component | Routes as JSX, no loaders |
-| v6 | package.json version `"6.x"` | Similar to v7 Declarative |
-
-**Detection order:**
-
-1. Check for `react-router.config.ts` (Framework mode)
-2. Grep for `createBrowserRouter` (Data mode)
-3. Check package.json version (v6 vs v7)
-4. Default to Declarative if v7 with ``
-
-## Phase 3: Follow README
-
-Based on detected mode, apply the corresponding README section. The README contains current API signatures and code patterns.
-
-## Critical Distinctions
-
-### authLoader vs authkitLoader
-
-| Function | Purpose | Where to use |
-| --------------- | ------------------------- | ---------------------- |
-| `authLoader` | OAuth callback handler | Callback route ONLY |
-| `authkitLoader` | Fetch user data in routes | Any route needing auth |
-
-**Common mistake:** Using `authkitLoader` for callback route. Use `authLoader()`.
-
-### Root Route Requirement
-
-Auth loader MUST be on root route for child routes to access auth context.
-
-**Wrong:** Auth loader only on `/dashboard`
-**Right:** Auth loader on `/` (root), children inherit context
-
-## Environment Variables
-
-Required in `.env` or `.env.local`:
-
-- `WORKOS_API_KEY` - starts with `sk_`
-- `WORKOS_CLIENT_ID` - starts with `client_`
-- `WORKOS_REDIRECT_URI` - full URL (e.g., `http://localhost:3000/auth/callback`)
-- `WORKOS_COOKIE_PASSWORD` - 32+ chars (server modes only)
-
-## Verification Checklist (ALL MUST PASS)
-
-Run these commands to confirm integration. **Do not mark complete until all pass:**
-
-```bash
-# 1. Check SDK installed
-ls node_modules/@workos-inc/authkit-react-router 2>/dev/null || echo "FAIL: SDK not installed"
-
-# 2. Check callback route exists and matches WORKOS_REDIRECT_URI
-grep -r "authLoader\|handleCallbackRoute" src/ app/ 2>/dev/null
-
-# 3. Check auth loader/provider on root route
-grep -r "authkitLoader\|AuthKitProvider" src/ app/ 2>/dev/null
-
-# 4. Build succeeds
-npm run build
-```
-
-**If check #2 fails:** Callback route path must match WORKOS_REDIRECT_URI exactly. Use authLoader (not authkitLoader) for the callback route.
-
-## Error Recovery
-
-### "loader is not a function"
-
-**Cause:** Using loader pattern in Declarative/v6 mode
-**Fix:** Declarative/v6 modes use `AuthKitProvider` + `useAuth` hook, not loaders
-
-### Auth state not available in child routes
-
-**Cause:** Auth loader missing from root route
-**Fix:** Add `authkitLoader` (or `AuthKitProvider`) to root route so children inherit context
-
-### useAuth returns undefined
-
-**Cause:** Missing `AuthKitProvider` wrapper
-**Fix:** Wrap app with `AuthKitProvider` (required for Declarative/v6 modes)
-
-### Callback route 404
-
-**Cause:** Route path mismatch with `WORKOS_REDIRECT_URI`
-**Fix:** Extract exact path from env var, create route at that path
-
-### "Module not found" for SDK
-
-**Cause:** SDK not installed
-**Fix:** Install SDK, wait for completion, verify `node_modules` before writing imports
diff --git a/skills/workos-authkit-react/SKILL.md b/skills/workos-authkit-react/SKILL.md
deleted file mode 100644
index bc699a2..0000000
--- a/skills/workos-authkit-react/SKILL.md
+++ /dev/null
@@ -1,100 +0,0 @@
----
-name: workos-authkit-react
-description: Integrate WorkOS AuthKit with React single-page applications. Client-side only authentication. Use when the project is a React SPA without Next.js or React Router.
----
-
-# WorkOS AuthKit for React (SPA)
-
-## Decision Tree
-
-```
-START
- │
- ├─► Fetch README (BLOCKING)
- │ raw.githubusercontent.com/workos/authkit-react/main/README.md
- │ README is source of truth. Stop if fetch fails.
- │
- ├─► Detect Build Tool
- │ ├─ vite.config.ts exists? → Vite
- │ └─ otherwise → Create React App
- │
- ├─► Set Env Var Prefix
- │ ├─ Vite → VITE_WORKOS_CLIENT_ID
- │ └─ CRA → REACT_APP_WORKOS_CLIENT_ID
- │
- └─► Implement per README
-```
-
-## Critical: Build Tool Detection
-
-| Marker File | Build Tool | Env Prefix | Access Pattern |
-| ------------------------- | ---------- | ------------ | ------------------------- |
-| `vite.config.ts` | Vite | `VITE_` | `import.meta.env.VITE_*` |
-| `craco.config.js` or none | CRA | `REACT_APP_` | `process.env.REACT_APP_*` |
-
-**Wrong prefix = undefined values at runtime.** This is the #1 integration failure.
-
-## Key Clarification: No Callback Route
-
-The React SDK handles OAuth callbacks **internally** via AuthKitProvider.
-
-- No server-side callback route needed
-- SDK intercepts redirect URI client-side
-- Token exchange happens automatically
-
-Just ensure redirect URI env var matches WorkOS Dashboard exactly.
-
-## Required Environment Variables
-
-```
-{PREFIX}WORKOS_CLIENT_ID=client_...
-{PREFIX}WORKOS_REDIRECT_URI=http://localhost:5173/callback
-```
-
-No `WORKOS_API_KEY` needed. Client-side only SDK.
-
-## Verification Checklist (ALL MUST PASS)
-
-Run these commands to confirm integration. **Do not mark complete until all pass:**
-
-```bash
-# 1. Check env var prefix matches build tool
-grep -E "VITE_WORKOS_CLIENT_ID|REACT_APP_WORKOS_CLIENT_ID" .env .env.local 2>/dev/null
-
-# 2. Check AuthKitProvider wraps app root
-grep "AuthKitProvider" src/main.tsx src/index.tsx 2>/dev/null || echo "FAIL: AuthKitProvider missing"
-
-# 3. Check no server framework present (wrong skill if found)
-grep -E '"next"|"react-router"' package.json && echo "WARN: Server framework detected"
-
-# 4. Build succeeds
-pnpm build
-```
-
-**If check #2 fails:** AuthKitProvider must wrap the app root in main.tsx/index.tsx. This is required for useAuth() to work.
-
-## Error Recovery
-
-### "clientId is required"
-
-**Cause:** Env var inaccessible (wrong prefix)
-
-Check: Does prefix match build tool? Vite needs `VITE_`, CRA needs `REACT_APP_`.
-
-### Auth state lost on refresh
-
-**Cause:** Token persistence issue
-
-Check: Browser dev tools → Application → Local Storage. SDK stores tokens here automatically.
-
-### useAuth returns undefined
-
-**Cause:** Component outside provider tree
-
-Check: Entry file (`main.tsx` or `index.tsx`) wraps `` in ``.
-
-### Callback redirect fails
-
-**Cause:** URI mismatch
-
-Check: Env var redirect URI exactly matches WorkOS Dashboard → Redirects configuration.
diff --git a/skills/workos-authkit-sveltekit/SKILL.md b/skills/workos-authkit-sveltekit/SKILL.md
deleted file mode 100644
index 9722d49..0000000
--- a/skills/workos-authkit-sveltekit/SKILL.md
+++ /dev/null
@@ -1,208 +0,0 @@
----
-name: workos-authkit-sveltekit
-description: Integrate WorkOS AuthKit with SvelteKit. Server-side authentication with hooks and file-based routing.
----
-
-# WorkOS AuthKit for SvelteKit
-
-## Step 1: Fetch SDK Documentation (BLOCKING)
-
-**STOP. Do not proceed until complete.**
-
-WebFetch: `https://raw.githubusercontent.com/workos/authkit-sveltekit/main/README.md`
-
-The README is the source of truth. If this skill conflicts with README, follow README.
-
-## Step 2: Pre-Flight Validation
-
-### Project Structure
-
-- Confirm `svelte.config.js` (or `svelte.config.ts`) exists
-- Confirm `package.json` contains `@sveltejs/kit` dependency
-- Confirm `src/routes/` directory exists
-
-### Environment Variables
-
-Check `.env` or `.env.local` for:
-
-- `WORKOS_API_KEY` - starts with `sk_`
-- `WORKOS_CLIENT_ID` - starts with `client_`
-- `WORKOS_REDIRECT_URI` - valid callback URL
-- `WORKOS_COOKIE_PASSWORD` - 32+ characters
-
-SvelteKit uses `$env/static/private` and `$env/dynamic/private` natively. The agent should write env vars to `.env` (SvelteKit's default) or `.env.local`.
-
-## Step 2b: Partial Install Recovery
-
-Before installing the SDK, check if a previous AuthKit attempt already exists:
-
-1. Check if `@workos/authkit-sveltekit` is already in `package.json`
-2. Check for incomplete setup signals:
- - `src/hooks.server.ts` has commented-out `authkitHandle` import or exports a passthrough handle
- - `src/routes/+layout.server.ts` has TODO comments about loading the session
- - No callback `+server.ts` route exists in `src/routes/`
- - No `WORKOS_COOKIE_PASSWORD` in `.env`
-3. If partial install detected:
- - Do NOT reinstall the SDK (it's already there)
- - Read existing files to understand what's done vs missing
- - Complete the integration by filling gaps rather than starting fresh
- - The most common gap is the missing callback route — create it
- - Wire up `authkitHandle` in hooks.server.ts properly (use `sequence()` if other hooks exist)
- - Complete the layout load function
- - Ensure `WORKOS_COOKIE_PASSWORD` is set in `.env`
-
-## Step 2c: Existing Auth System Detection
-
-Check for existing authentication before integrating:
-
-```
-package.json has 'lucia'? → Lucia v3 session auth
-package.json has '@auth0/auth0-spa-js'? → Auth0 SPA auth
-package.json has '@auth/sveltekit'? → Auth.js SvelteKit
-src/hooks.server.ts handles cookies? → Custom session middleware
-```
-
-If existing auth detected (Lucia is most common in SvelteKit):
-
-- Do NOT remove or disable the existing auth system
-- Use `sequence()` from `@sveltejs/kit/hooks` to compose handles:
-
- ```typescript
- import { sequence } from '@sveltejs/kit/hooks';
- import { authkitHandle } from '@workos/authkit-sveltekit';
-
- // Keep existing handle, compose with AuthKit
- export const handle = sequence(authkitHandle, existingHandle);
- ```
-
-- AuthKit handle should come FIRST in `sequence()` so it runs before other middleware
-- Create separate WorkOS routes if `/login` or `/callback` are already taken (e.g., use `/auth/callback`)
-- Ensure existing auth routes, form actions, and session cookies continue to work unchanged
-- Document in code comments how to migrate fully to WorkOS AuthKit later
-
-## Step 3: Install SDK
-
-Detect package manager, install SDK package from README.
-
-```
-pnpm-lock.yaml? → pnpm add @workos/authkit-sveltekit
-yarn.lock? → yarn add @workos/authkit-sveltekit
-bun.lockb? → bun add @workos/authkit-sveltekit
-else → npm install @workos/authkit-sveltekit
-```
-
-**Verify:** SDK package exists in node_modules before continuing.
-
-## Step 4: Configure Server Hooks
-
-SvelteKit uses `src/hooks.server.ts` for server-side middleware. This is where the AuthKit handler is registered.
-
-Create or update `src/hooks.server.ts` with the authkit handle function from the README.
-
-### Existing Hooks (IMPORTANT)
-
-If `src/hooks.server.ts` already exists with custom logic, use SvelteKit's `sequence()` helper to compose hooks:
-
-```typescript
-import { sequence } from '@sveltejs/kit/hooks';
-import { authkitHandle } from '@workos/authkit-sveltekit'; // Check README for exact export
-
-export const handle = sequence(authkitHandle, yourExistingHandle);
-```
-
-Check README for the exact export name and usage pattern.
-
-## Step 5: Create Callback Route
-
-Parse `WORKOS_REDIRECT_URI` to determine route path:
-
-```
-URI path --> Route location
-/callback --> src/routes/callback/+server.ts
-/auth/callback --> src/routes/auth/callback/+server.ts
-```
-
-Use the SDK's callback handler from the README. Do not write custom OAuth logic.
-
-**Critical:** SvelteKit uses `+server.ts` for API routes, not `+page.server.ts`.
-
-## Step 6: Layout Setup
-
-Update `src/routes/+layout.server.ts` to load the auth session and pass it to all pages.
-
-Check README for the exact pattern — typically a `load` function that returns the user session from locals.
-
-```typescript
-// src/routes/+layout.server.ts
-import type { LayoutServerLoad } from './$types';
-
-export const load: LayoutServerLoad = async (event) => {
- // Check README for exact API — session is typically on event.locals
- return {
- user: event.locals.user, // or similar from README
- };
-};
-```
-
-## Step 7: UI Integration
-
-Add auth UI to `src/routes/+page.svelte` using the session data from the layout.
-
-- Show user info when authenticated
-- Show sign-in link/button when not authenticated
-- Add sign-out functionality
-
-Check README for sign-in URL generation and sign-out patterns.
-
-## Verification Checklist (ALL MUST PASS)
-
-Run these commands to confirm integration. **Do not mark complete until all pass:**
-
-```bash
-# 1. Check hooks.server.ts exists and has authkit
-grep -i "workos\|authkit" src/hooks.server.ts || echo "FAIL: authkit missing from hooks.server.ts"
-
-# 2. Check callback route exists
-find src/routes -name "+server.ts" -path "*/callback/*"
-
-# 3. Check layout loads auth session
-grep -i "user\|auth\|session" src/routes/+layout.server.ts || echo "FAIL: auth session missing from layout"
-
-# 4. Build succeeds
-pnpm build || npm run build
-```
-
-## Error Recovery
-
-### "Cannot find module '@workos/authkit-sveltekit'"
-
-- Check: SDK installed before writing imports
-- Check: SDK package directory exists in node_modules
-- Re-run install if missing
-
-### hooks.server.ts not taking effect
-
-- Check: File is at `src/hooks.server.ts`, not `src/hooks.ts` or elsewhere
-- Check: Named export is `handle` (SvelteKit requirement)
-- Check: If using `sequence()`, all handles are properly composed
-
-### Callback route not found (404)
-
-- Check: File uses `+server.ts` (not `+page.server.ts`)
-- Check: Route path matches `WORKOS_REDIRECT_URI` path exactly
-- Check: Exports `GET` handler (SvelteKit convention)
-
-### "locals" type errors
-
-- Check: App.Locals interface is augmented in `src/app.d.ts`
-- Check README for TypeScript setup instructions
-
-### Cookie password error
-
-- Verify `WORKOS_COOKIE_PASSWORD` is 32+ characters
-- Generate new: `openssl rand -base64 32`
-
-### Auth state not available in pages
-
-- Check: `+layout.server.ts` load function returns user data
-- Check: Pages access data via `export let data` (Svelte 4) or `$page.data` (Svelte 5)
diff --git a/skills/workos-authkit-tanstack-start/SKILL.md b/skills/workos-authkit-tanstack-start/SKILL.md
deleted file mode 100644
index c814016..0000000
--- a/skills/workos-authkit-tanstack-start/SKILL.md
+++ /dev/null
@@ -1,314 +0,0 @@
----
-name: workos-authkit-tanstack-start
-description: Integrate WorkOS AuthKit with TanStack Start applications. Full-stack TypeScript with server functions. Use when project uses TanStack Start, @tanstack/start, or vinxi.
----
-
-# WorkOS AuthKit for TanStack Start
-
-## Decision Tree
-
-```
-1. Fetch README (BLOCKING)
- ├── Extract package name from install command
- └── README is source of truth for ALL code patterns
-
-2. Detect directory structure
- ├── src/ (TanStack Start v1.132+, default)
- └── app/ (legacy vinxi-based projects)
-
-3. Follow README install/setup exactly
- └── Do not invent commands or patterns
-```
-
-## Fetch SDK Documentation (BLOCKING)
-
-**STOP - Do not proceed until complete.**
-
-WebFetch: `https://raw.githubusercontent.com/workos/authkit-tanstack-start/main/README.md`
-
-From README, extract:
-
-1. Package name: `@workos/authkit-tanstack-react-start`
-2. Use that exact name for all imports
-
-**README overrides this skill if conflict.**
-
-## Pre-Flight Checklist
-
-- [ ] README fetched and package name extracted
-- [ ] `@tanstack/start` or `@tanstack/react-start` in package.json
-- [ ] Identify directory structure: `src/` (modern) or `app/` (legacy)
-- [ ] Environment variables set (see below)
-
-## Directory Structure Detection
-
-**Modern TanStack Start (v1.132+)** uses `src/`:
-
-```
-src/
-├── start.ts # Middleware config (CRITICAL)
-├── router.tsx # Router setup
-├── routes/
-│ ├── __root.tsx # Root layout
-│ ├── api.auth.callback.tsx # OAuth callback (flat route)
-│ └── ...
-```
-
-**Legacy (vinxi-based)** uses `app/`:
-
-```
-app/
-├── start.ts or router.tsx
-├── routes/
-│ └── api/auth/callback.tsx # OAuth callback (nested route)
-```
-
-**Detection:**
-
-```bash
-ls src/routes 2>/dev/null && echo "Modern (src/)" || echo "Legacy (app/)"
-```
-
-## Environment Variables
-
-| Variable | Format | Required |
-| ------------------------ | ------------ | -------- |
-| `WORKOS_API_KEY` | `sk_...` | Yes |
-| `WORKOS_CLIENT_ID` | `client_...` | Yes |
-| `WORKOS_REDIRECT_URI` | Full URL | Yes |
-| `WORKOS_COOKIE_PASSWORD` | 32+ chars | Yes |
-
-Generate password if missing: `openssl rand -base64 32`
-
-Default redirect URI: `http://localhost:3000/api/auth/callback`
-
-## Middleware Configuration (CRITICAL)
-
-**authkitMiddleware MUST be configured or auth will fail silently.**
-
-**WARNING: Do NOT add middleware to `createRouter()` in `router.tsx` or `app.tsx`. That is TanStack Router (client-side only). Server middleware belongs in `start.ts` using `requestMiddleware`.**
-
-### If `start.ts` already exists
-
-Read the existing file first. Add `authkitMiddleware` to the existing `requestMiddleware` array (or create the array if missing). Preserve the existing export style. Do not rewrite the file from scratch.
-
-### If `start.ts` does not exist
-
-Create `src/start.ts` (or `app/start.ts` for legacy) using `createStart`:
-
-```typescript
-import { createStart } from '@tanstack/react-start';
-import { authkitMiddleware } from '@workos/authkit-tanstack-react-start';
-
-export const startInstance = createStart(() => ({
- requestMiddleware: [authkitMiddleware()],
-}));
-```
-
-**Two things matter here:**
-
-1. **Named export `startInstance`** — the build plugin generates `import type { startInstance }` from this file. A `default` export will cause a build error.
-2. **`createStart` takes a function** returning the options object, not the options directly. `createStart({ ... })` will fail.
-
-**WARNING: Do NOT add middleware to `createRouter()` in `router.tsx` or `app.tsx`. That is TanStack Router (client-side only). Server middleware belongs in `start.ts` using `requestMiddleware`.**
-
-## Callback Route (CRITICAL)
-
-Path must match `WORKOS_REDIRECT_URI`. For `/api/auth/callback`:
-
-**Modern (flat routes):** `src/routes/api.auth.callback.tsx`
-**Legacy (nested routes):** `app/routes/api/auth/callback.tsx`
-
-```typescript
-import { createFileRoute } from '@tanstack/react-router';
-import { handleCallbackRoute } from '@workos/authkit-tanstack-react-start';
-
-export const Route = createFileRoute('/api/auth/callback')({
- server: {
- handlers: {
- GET: handleCallbackRoute(),
- },
- },
-});
-```
-
-**Key points:**
-
-- Use `handleCallbackRoute()` - do not write custom OAuth logic
-- Route path string must match the URI path exactly
-- This is a server-only route (no component needed)
-
-## Protected Routes
-
-Use `getAuth()` in route loaders to check authentication:
-
-```typescript
-import { createFileRoute, redirect } from '@tanstack/react-router';
-import { getAuth, getSignInUrl } from '@workos/authkit-tanstack-react-start';
-
-export const Route = createFileRoute('/dashboard')({
- loader: async () => {
- const { user } = await getAuth();
- if (!user) {
- const signInUrl = await getSignInUrl();
- throw redirect({ href: signInUrl });
- }
- return { user };
- },
- component: Dashboard,
-});
-```
-
-## Sign Out Route
-
-```typescript
-import { createFileRoute, redirect } from '@tanstack/react-router';
-import { signOut } from '@workos/authkit-tanstack-react-start';
-
-export const Route = createFileRoute('/signout')({
- loader: async () => {
- await signOut();
- throw redirect({ href: '/' });
- },
-});
-```
-
-## Client-Side Hooks (Optional)
-
-Only needed if you want reactive auth state in components.
-
-**1. Add AuthKitProvider to root:**
-
-```typescript
-// src/routes/__root.tsx
-import { AuthKitProvider } from '@workos/authkit-tanstack-react-start/client';
-
-function RootComponent() {
- return (
-
-
-
- );
-}
-```
-
-**2. Use hooks in components:**
-
-```typescript
-import { useAuth } from '@workos/authkit-tanstack-react-start/client';
-
-function Profile() {
- const { user, isLoading } = useAuth();
- // ...
-}
-```
-
-**Note:** Server-side `getAuth()` is preferred for most use cases.
-
-## Finalize (REQUIRED before declaring success)
-
-After creating/editing all files, run these steps in order. Skipping them is the most common cause of build failures.
-
-### 1. Regenerate the route tree
-
-Adding new route files (callback, signout, etc.) makes the existing `routeTree.gen.ts` stale. The build will fail with type errors about missing routes until it is regenerated.
-
-```bash
-pnpm build 2>/dev/null || npx tsr generate
-```
-
-The build itself triggers route tree regeneration. If it fails for other reasons, use `tsr generate` directly.
-
-### 2. Ensure Vite type declarations exist
-
-TanStack Start projects import CSS with `import styles from './styles.css?url'`. Without Vite's type declarations, TypeScript will error on these imports. Check if `src/vite-env.d.ts` (or `app/vite-env.d.ts`) exists — if not, create it now (before attempting the build):
-
-```typescript
-///
-```
-
-### 3. Verify the build
-
-```bash
-pnpm build
-```
-
-Do not skip this step. If the build fails, fix the errors before finishing. Common causes:
-
-- Stale route tree → re-run step 1
-- Missing Vite types → re-run step 2
-- Wrong import paths → check package name is `@workos/authkit-tanstack-react-start`
-
-## Verification Checklist (ALL MUST PASS)
-
-Run these commands to confirm integration. **Do not mark complete until all pass:**
-
-```bash
-# 1. Check authkitMiddleware is configured
-grep -r "authkitMiddleware" src/ app/ 2>/dev/null || echo "FAIL: Middleware not configured"
-
-# 2. Check callback route exists
-find src/routes app/routes -name "*callback*" 2>/dev/null
-
-# 3. Check environment variables
-grep -c "WORKOS_" .env 2>/dev/null || echo "FAIL: No env vars found"
-
-# 4. Build succeeds
-pnpm build
-```
-
-**If check #1 fails:** authkitMiddleware must be in src/start.ts (or app/start.ts for legacy) requestMiddleware array. Auth will fail silently without it.
-
-## Error Recovery
-
-### "AuthKit middleware is not configured"
-
-**Cause:** `authkitMiddleware()` not in start.ts
-**Fix:** Create/update `src/start.ts` with middleware config
-**Verify:** `grep -r "authkitMiddleware" src/`
-
-### "Module not found" for SDK
-
-**Cause:** Wrong package name or not installed
-**Fix:** `pnpm add @workos/authkit-tanstack-react-start`
-**Verify:** `ls node_modules/@workos/authkit-tanstack-react-start`
-
-### Callback 404
-
-**Cause:** Route file path doesn't match WORKOS_REDIRECT_URI
-**Fix:**
-
-- URI `/api/auth/callback` → file `src/routes/api.auth.callback.tsx` (flat) or `app/routes/api/auth/callback.tsx` (nested)
-- Route path string in `createFileRoute()` must match exactly
-
-### getAuth returns undefined user
-
-**Cause:** Middleware not configured or not running
-**Fix:** Ensure `authkitMiddleware()` is in start.ts requestMiddleware array
-
-### "Cookie password too short"
-
-**Cause:** WORKOS_COOKIE_PASSWORD < 32 chars
-**Fix:** `openssl rand -base64 32`, update .env
-
-### Build fails with route type errors
-
-**Cause:** Route tree not regenerated after adding routes
-**Fix:** `pnpm dev` to regenerate `routeTree.gen.ts`
-
-## SDK Exports Reference
-
-**Server (main export):**
-
-- `authkitMiddleware()` - Request middleware
-- `handleCallbackRoute()` - OAuth callback handler
-- `getAuth()` - Get current session
-- `signOut()` - Sign out user
-- `getSignInUrl()` / `getSignUpUrl()` - Auth URLs
-- `switchToOrganization()` - Change org context
-
-**Client (`/client` subpath):**
-
-- `AuthKitProvider` - Context provider
-- `useAuth()` - Auth state hook
-- `useAccessToken()` - Token management
diff --git a/skills/workos-authkit-vanilla-js/SKILL.md b/skills/workos-authkit-vanilla-js/SKILL.md
deleted file mode 100644
index a6f8d79..0000000
--- a/skills/workos-authkit-vanilla-js/SKILL.md
+++ /dev/null
@@ -1,92 +0,0 @@
----
-name: workos-authkit-vanilla-js
-description: Integrate WorkOS AuthKit with vanilla JavaScript applications. No framework required, browser-only. Use when project is plain HTML/JS, doesn't use React/Vue/etc, or mentions vanilla JavaScript authentication.
----
-
-# WorkOS AuthKit for Vanilla JavaScript
-
-## Decision Tree
-
-### Step 1: Fetch README (BLOCKING)
-
-WebFetch: `https://raw.githubusercontent.com/workos/authkit-js/main/README.md`
-
-**README is source of truth.** If this skill conflicts, follow README.
-
-### Step 2: Detect Project Type
-
-```
-Has package.json with build tool (Vite, webpack, Parcel)?
- YES -> Bundled project (npm install)
- NO -> CDN/Static project (script tag)
-```
-
-### Step 3: Follow README Installation
-
-- **Bundled**: Use package manager install from README
-- **CDN**: Use unpkg script tag from README
-
-### Step 4: Implement Per README
-
-Follow README examples for:
-
-- Client initialization
-- Sign in/out handlers
-- User state management
-
-## Critical API Quirk
-
-`createClient()` is **async** - returns a Promise, not a client directly.
-
-```javascript
-// CORRECT
-const authkit = await createClient(clientId);
-```
-
-## Verification Checklist (ALL MUST PASS)
-
-Run these commands to confirm integration. **Do not mark complete until all pass:**
-
-```bash
-# 1. Check SDK is available (bundled or CDN)
-grep -r "createClient\|WorkOS" src/ *.html 2>/dev/null || echo "FAIL: SDK not found"
-
-# 2. Check createClient uses await
-grep -rn "await createClient" src/ *.js *.html 2>/dev/null || echo "FAIL: createClient must be awaited"
-
-# 3. Check sign-in is on user gesture (click handler)
-grep -rn "signIn\|sign_in" src/ *.js *.html 2>/dev/null
-
-# 4. Build succeeds (bundled projects only)
-pnpm build 2>/dev/null || echo "CDN project — verify manually in browser"
-```
-
-**If check #2 fails:** createClient() is async and must be awaited. Using it without await returns a Promise, not a client.
-
-## Environment Variables
-
-**Bundled projects only:**
-
-- Vite: `VITE_WORKOS_CLIENT_ID`
-- Webpack: `REACT_APP_WORKOS_CLIENT_ID` or custom
-- No `WORKOS_API_KEY` needed (client-side SDK)
-
-## Error Recovery
-
-| Error | Cause | Fix |
-| -------------------------------- | ------------------- | ------------------------------------------------------ |
-| `WorkOS is not defined` | CDN not loaded | Add script to `` before your code |
-| `createClient is not a function` | Wrong import | npm: check import path; CDN: use `WorkOS.createClient` |
-| `clientId is required` | Undefined env var | Check env prefix matches build tool |
-| CORS errors | `file://` protocol | Use local dev server (`npx serve`) |
-| Popup blocked | Not user gesture | Call `signIn()` only from click handler |
-| Auth state lost | Token not persisted | Check localStorage in dev tools |
-
-## Task Flow
-
-1. **preflight**: Fetch README, detect project type, verify env vars
-2. **install**: Add SDK per project type
-3. **callback**: SDK handles internally (no server route needed)
-4. **provider**: Initialize client with `await createClient()`
-5. **ui**: Add auth buttons and state display
-6. **verify**: Build (if bundled), check console
diff --git a/skills/workos-dotnet/SKILL.md b/skills/workos-dotnet/SKILL.md
deleted file mode 100644
index d9342cc..0000000
--- a/skills/workos-dotnet/SKILL.md
+++ /dev/null
@@ -1,163 +0,0 @@
----
-name: workos-dotnet
-description: Integrate WorkOS AuthKit with .NET (ASP.NET Core). Backend authentication with DI registration, auth endpoints, and appsettings configuration.
----
-
-# WorkOS AuthKit for .NET (ASP.NET Core)
-
-## Step 1: Fetch SDK Documentation (BLOCKING)
-
-**STOP. Do not proceed until complete.**
-
-WebFetch: `https://raw.githubusercontent.com/workos/workos-dotnet/main/README.md`
-
-The README is the source of truth for SDK API usage. If this skill conflicts with README, follow README.
-
-## Step 2: Pre-Flight Validation
-
-### Project Structure
-
-- Confirm a `*.csproj` file exists in the project root
-- Detect project style:
- - **Minimal API** (modern): `Program.cs` with `WebApplication.CreateBuilder()` — .NET 6+
- - **Startup pattern** (older): `Startup.cs` with `ConfigureServices()` / `Configure()` — .NET 5 and earlier
-
-This detection determines WHERE to register WorkOS services and middleware.
-
-### Environment Variables
-
-Check `appsettings.Development.json` for:
-
-- `WORKOS_API_KEY` — starts with `sk_`
-- `WORKOS_CLIENT_ID` — starts with `client_`
-
-## Step 3: Install SDK
-
-```bash
-dotnet add package WorkOS.net
-```
-
-**Verify:** Check the `*.csproj` file contains a `",
- "ClientId": "",
- "RedirectUri": "http://localhost:5000/auth/callback"
- }
-}
-```
-
-Use the actual credential values provided in the environment context.
-
-**Important:** Do NOT put secrets in `appsettings.json` (committed to git). Use `appsettings.Development.json` (gitignored) or `dotnet user-secrets`.
-
-## Step 7: Verification
-
-Run these checks — **do not mark complete until all pass:**
-
-```bash
-# 1. Check WorkOS.net is in csproj
-grep -i "WorkOS" *.csproj
-
-# 2. Check auth endpoints exist
-grep -r "auth/login\|auth/callback\|auth/logout" *.cs
-
-# 3. Build succeeds
-dotnet build
-```
-
-**If build fails:** Read the error output carefully. Common issues:
-
-- Missing `using` statements for WorkOS namespaces
-- Incorrect DI registration order
-- Missing session/cookie middleware registration
-
-## Error Recovery
-
-### "dotnet: command not found"
-
-- .NET SDK is not installed. Inform the user to install from https://dotnet.microsoft.com/download
-
-### NuGet restore failures
-
-- Check internet connectivity
-- Try `dotnet restore` explicitly before `dotnet build`
-
-### "No project file found"
-
-- Ensure you're in the correct directory with a `*.csproj` file
-
-### Build errors after integration
-
-- Check that all `using` statements are correct
-- Verify DI registration order (services before middleware)
-- Ensure `app.UseSession()` is called before mapping auth endpoints
diff --git a/skills/workos-elixir/SKILL.md b/skills/workos-elixir/SKILL.md
deleted file mode 100644
index b54ddd4..0000000
--- a/skills/workos-elixir/SKILL.md
+++ /dev/null
@@ -1,231 +0,0 @@
----
-name: workos-elixir
-description: Integrate WorkOS AuthKit with Elixir/Phoenix applications. Server-side authentication with Phoenix controllers and routes.
----
-
-# WorkOS AuthKit for Elixir (Phoenix)
-
-## Step 1: Fetch SDK Documentation (BLOCKING)
-
-**STOP. Do not proceed until complete.**
-
-WebFetch: `https://raw.githubusercontent.com/workos/workos-elixir/main/README.md`
-
-The README is the source of truth for SDK API usage. If this skill conflicts with README, follow README.
-
-## Step 2: Pre-Flight Validation
-
-### Project Structure
-
-- Confirm `mix.exs` exists
-- Read `mix.exs` to extract the app name (look for `app: :my_app` in `project/0`)
-- Confirm `lib/{app}_web/router.ex` exists (Phoenix project marker)
-- Confirm `config/runtime.exs` exists
-
-### Determine App Name
-
-The app name from `mix.exs` determines all file paths. For example, if `app: :my_app`:
-
-- Web module: `lib/my_app_web/`
-- Router: `lib/my_app_web/router.ex`
-- Controllers: `lib/my_app_web/controllers/`
-
-### Environment Variables
-
-Check `.env.local` for:
-
-- `WORKOS_API_KEY` - starts with `sk_`
-- `WORKOS_CLIENT_ID` - starts with `client_`
-
-## Step 2b: Partial Install Recovery
-
-Before creating new files, check if a previous AuthKit attempt exists:
-
-1. Check if `:workos` is already in `mix.exs` dependencies
-2. Check for incomplete auth code — AuthController exists but has TODO stubs, 501 responses, or missing callback/sign_out functions
-3. If partial install detected:
- - Do NOT re-add the SDK dependency (it's already there)
- - Do NOT re-run `mix deps.get` if deps are already fetched
- - Read existing auth files to understand what's done vs missing
- - Complete the integration by filling gaps (controller methods, routes)
- - Preserve any working code — only fix what's broken
- - Check for missing `/auth/callback` route (most common gap)
-
-## Step 2c: Existing Auth System Detection
-
-Check for existing authentication before integrating:
-
-```
-mix.exs has ':ueberauth'? → Ueberauth auth
-mix.exs has ':pow'? → Pow auth
-mix.exs has ':guardian'? → Guardian JWT auth
-mix.exs has ':phx_gen_auth'? → Phoenix generated auth
-config/*.exs has 'Ueberauth' config? → Ueberauth configured
-router.ex has '/:provider' wildcard auth routes? → Ueberauth routes
-```
-
-If existing auth detected:
-
-- Do NOT remove or disable it
-- Add WorkOS AuthKit alongside the existing system
-- If Ueberauth is configured, be careful of `/:provider` wildcard routes — use a specific scope like `/auth/workos` to avoid conflicts
-- Reuse existing session infrastructure if compatible
-- Create separate route paths for WorkOS auth
-- Ensure existing auth routes continue to work unchanged
-- Document in code comments how to migrate fully to WorkOS later
-
-## Step 3: Install SDK
-
-Add the `workos` package to `mix.exs` dependencies:
-
-```elixir
-defp deps do
- [
- # ... existing deps
- {:workos, "~> 1.0"}
- ]
-end
-```
-
-Then run:
-
-```bash
-mix deps.get
-```
-
-**Verify:** Check that `mix deps.get` completed successfully (exit code 0).
-
-## Step 4: Configure WorkOS
-
-Add WorkOS configuration to `config/runtime.exs`:
-
-```elixir
-config :workos,
- api_key: System.get_env("WORKOS_API_KEY"),
- client_id: System.get_env("WORKOS_CLIENT_ID")
-```
-
-This ensures credentials are loaded from environment variables at runtime, not compiled into the release.
-
-## Step 5: Create Auth Controller
-
-### Prerequisite: Verify `{AppName}Web` module exists
-
-The controller uses `use {AppName}Web, :controller`. Confirm `lib/{app}_web.ex` exists and defines the `:controller` macro. If it doesn't exist (minimal Phoenix projects may lack it), create it:
-
-```elixir
-defmodule {AppName}Web do
- def controller do
- quote do
- use Phoenix.Controller, formats: [:html, :json]
- import Plug.Conn
- end
- end
-
- defmacro __using__(which) when is_atom(which) do
- apply(__MODULE__, which, [])
- end
-end
-```
-
-### Create controller
-
-Create `lib/{app}_web/controllers/auth_controller.ex`:
-
-```elixir
-defmodule {AppName}Web.AuthController do
- use {AppName}Web, :controller
-
- def sign_in(conn, _params) do
- client_id = Application.get_env(:workos, :client_id)
- redirect_uri = "http://localhost:4000/auth/callback"
-
- authorization_url = WorkOS.UserManagement.get_authorization_url(%{
- provider: "authkit",
- client_id: client_id,
- redirect_uri: redirect_uri
- })
-
- case authorization_url do
- {:ok, url} -> redirect(conn, external: url)
- {:error, reason} -> conn |> put_status(500) |> text("Auth error: #{inspect(reason)}")
- end
- end
-
- def callback(conn, %{"code" => code}) do
- client_id = Application.get_env(:workos, :client_id)
-
- case WorkOS.UserManagement.authenticate_with_code(%{
- code: code,
- client_id: client_id
- }) do
- {:ok, auth_response} ->
- conn
- |> put_session(:user, auth_response.user)
- |> redirect(to: "/")
-
- {:error, reason} ->
- conn |> put_status(401) |> text("Authentication failed: #{inspect(reason)}")
- end
- end
-
- def sign_out(conn, _params) do
- conn
- |> clear_session()
- |> redirect(to: "/")
- end
-end
-```
-
-**IMPORTANT:** Adapt the module name and API calls based on the README. The WorkOS Elixir SDK API may differ from the pseudocode above. Always follow the README for exact function names, parameter shapes, and return types.
-
-## Step 6: Add Routes
-
-Add auth routes to `lib/{app}_web/router.ex`. Add these routes inside or outside the existing pipeline scope as appropriate:
-
-```elixir
-scope "/auth", {AppName}Web do
- pipe_through :browser
-
- get "/sign-in", AuthController, :sign_in
- get "/callback", AuthController, :callback
- post "/sign-out", AuthController, :sign_out
-end
-```
-
-## Step 7: Verification
-
-Run the following to confirm the integration compiles:
-
-```bash
-mix compile
-```
-
-**If compilation fails:**
-
-1. Read the error message carefully
-2. Check that the WorkOS SDK module names match what's in the README
-3. Verify the app name is consistent across all files
-4. Fix the issue and re-run `mix compile`
-
-## Error Recovery
-
-### "could not compile dependency :workos"
-
-- Check Elixir version compatibility (1.15+ recommended)
-- Try `mix deps.clean workos && mix deps.get`
-
-### "module WorkOS.UserManagement is not available"
-
-- The SDK API may use different module paths — re-read the README
-- Check if the SDK uses `WorkOS.SSO` or another module instead
-
-### "undefined function" in controller
-
-- Verify `use {AppName}Web, :controller` is correct
-- Check that the SDK functions match the README exactly
-
-### Route conflicts
-
-- Check existing routes in router.ex for `/auth` prefix conflicts
-- Adjust the scope path if needed (e.g., `/workos-auth`)
diff --git a/skills/workos-go/SKILL.md b/skills/workos-go/SKILL.md
deleted file mode 100644
index 6d1616c..0000000
--- a/skills/workos-go/SKILL.md
+++ /dev/null
@@ -1,226 +0,0 @@
----
-name: workos-go
-description: Integrate WorkOS AuthKit with Go applications. Supports Gin and stdlib net/http.
----
-
-# WorkOS AuthKit for Go
-
-## Step 1: Fetch SDK Documentation (BLOCKING)
-
-**STOP. Do not proceed until complete.**
-
-WebFetch: `https://raw.githubusercontent.com/workos/workos-go/main/README.md`
-
-The README is the source of truth for SDK API usage. If this skill conflicts with README, follow README.
-
-## Step 2: Pre-Flight Validation
-
-### Project Structure
-
-- Confirm `go.mod` exists in the project root
-- Confirm Go module is initialized (module path declared in `go.mod`)
-
-### Environment Variables
-
-Check `.env` for:
-
-- `WORKOS_API_KEY` - starts with `sk_`
-- `WORKOS_CLIENT_ID` - starts with `client_`
-- `WORKOS_REDIRECT_URI` - valid callback URL (e.g., `http://localhost:8080/auth/callback`)
-
-### Framework Detection
-
-Read `go.mod` to detect web framework:
-
-```
-go.mod contains github.com/gin-gonic/gin?
- |
- +-- Yes --> Use Gin router patterns
- |
- +-- No --> Use stdlib net/http patterns
-```
-
-## Step 2b: Partial Install Recovery
-
-Before creating new files, check if a previous AuthKit attempt exists:
-
-1. Check if `github.com/workos/workos-go` is already in `go.mod`
-2. Check for incomplete auth code — files that import WorkOS packages but have non-functional handlers (TODO comments, 501 responses, empty handler bodies)
-3. If partial install detected:
- - Do NOT re-run `go get` (the module is already there)
- - Read existing auth files to understand what's done vs missing
- - Complete the integration by filling gaps rather than starting fresh
- - Preserve any working code — only fix what's broken
- - If `usermanagement.SetAPIKey()` is already called in `init()`, don't call it again
- - Always run `go mod tidy` after changes to keep `go.sum` consistent
-
-## Step 2c: Existing Auth System Detection
-
-Check for existing authentication before integrating:
-
-```
-*.go files have 'jwt' or 'JWT'? → Custom JWT auth
-*.go files have 'oauth2'? → OAuth2 middleware
-*.go files have 'authMiddleware'? → Custom auth middleware
-go.mod has 'golang.org/x/oauth2'? → OAuth2 package
-go.mod has 'github.com/coreos/go-oidc'? → OIDC auth
-```
-
-If existing auth detected:
-
-- Do NOT remove or disable it
-- Add WorkOS AuthKit alongside the existing system
-- Create separate route paths for WorkOS auth (e.g., `/auth/workos/login` if `/auth/login` is taken)
-- Match handler signatures to the detected framework (Gin `*gin.Context` vs stdlib `http.ResponseWriter, *http.Request`)
-- Ensure existing auth middleware continues to work on its routes
-- Document in code comments how to migrate fully to WorkOS later
-
-## Step 3: Install SDK
-
-Run:
-
-```bash
-go get github.com/workos/workos-go/v4
-```
-
-**Verify:** Check that `go.mod` now contains `github.com/workos/workos-go/v4`. Both `go.mod` and `go.sum` will be modified — this is expected.
-
-## Step 4: Configure Authentication
-
-### 4a: Create Auth Handler File
-
-Create an auth handler file. Respect existing project structure:
-
-- If `internal/` directory exists, create `internal/auth/handlers.go`
-- If `handlers/` directory exists, create `handlers/auth.go`
-- Otherwise, create `auth/handlers.go`
-
-The file must:
-
-- Declare a package matching the directory name
-- Import `github.com/workos/workos-go/v4` packages as needed
-- Read env vars with `os.Getenv("WORKOS_API_KEY")`, `os.Getenv("WORKOS_CLIENT_ID")`, `os.Getenv("WORKOS_REDIRECT_URI")`
-
-### 4b: Implement Handlers
-
-Implement these three handlers following the redirect-based auth flow from the README:
-
-**Login handler** (`/auth/login`):
-
-- Get the authorization URL from WorkOS using `usermanagement.GetAuthorizationURL()`
-- Set `Provider` to the string `"authkit"` (it's a plain string, not a constant)
-- Include `ClientID` and `RedirectURI` from env vars
-- Redirect the user to the returned URL
-
-**Callback handler** (`/auth/callback`):
-
-- Extract the `code` query parameter from the redirect
-- Call `usermanagement.AuthenticateWithCode()` with the code and `ClientID`
-- Store user info in session/cookie (or return as JSON for API-first apps)
-- Redirect to homepage or return user data
-
-**Logout handler** (`/auth/logout`):
-
-- Clear session data
-- Redirect to homepage
-
-**CRITICAL:** Use idiomatic Go error handling throughout:
-
-```go
-result, err := someFunction()
-if err != nil {
- http.Error(w, "Error message", http.StatusInternalServerError)
- return
-}
-```
-
-### 4c: Wire Handlers into Router
-
-#### If using Gin:
-
-```go
-r := gin.Default()
-r.GET("/auth/login", handleLogin)
-r.GET("/auth/callback", handleCallback)
-r.GET("/auth/logout", handleLogout)
-```
-
-#### If using stdlib net/http:
-
-```go
-http.HandleFunc("/auth/login", handleLogin)
-http.HandleFunc("/auth/callback", handleCallback)
-http.HandleFunc("/auth/logout", handleLogout)
-```
-
-Wire these routes into the existing router setup in `main.go` or wherever routes are defined. Do NOT replace existing routes — add alongside them.
-
-### 4d: Initialize WorkOS Client
-
-In the appropriate init location (package-level `init()` or `main()`), initialize the WorkOS client:
-
-```go
-import "github.com/workos/workos-go/v4/pkg/usermanagement"
-
-func init() {
- usermanagement.SetAPIKey(os.Getenv("WORKOS_API_KEY"))
-}
-```
-
-Follow the README for the exact initialization pattern — it may differ from above.
-
-## Step 5: Environment Setup
-
-The `.env` file should already contain the required variables (written by the installer). Verify it contains:
-
-```
-WORKOS_API_KEY=sk_...
-WORKOS_CLIENT_ID=client_...
-WORKOS_REDIRECT_URI=http://localhost:8080/auth/callback
-```
-
-**Note for production:** Go does not have a built-in .env convention. In production, set real OS environment variables. The `.env` file is for development only. If using a `.env` loader like `github.com/joho/godotenv`, the agent may install it and add `godotenv.Load()` to `main()`.
-
-## Step 6: Verification
-
-Run these commands. **Do not mark complete until all pass:**
-
-```bash
-# 1. Go module is tidy
-go mod tidy
-
-# 2. Build succeeds
-go build ./...
-
-# 3. Vet passes (catches common mistakes)
-go vet ./...
-```
-
-If build fails:
-
-- Check import paths match the SDK version in `go.mod`
-- Ensure all new files have correct package declarations
-- Run `go mod tidy` to resolve dependency issues
-
-## Error Recovery
-
-### "cannot find module providing package github.com/workos/workos-go/v4/..."
-
-- Run `go mod tidy` to sync dependencies
-- Check that `go get` completed successfully
-- Verify the import path matches exactly (v4 suffix required)
-
-### "undefined: usermanagement.SetAPIKey" or similar
-
-- SDK API may have changed — refer to the fetched README
-- Check the correct subpackage import path
-
-### Build fails with type errors
-
-- Ensure handler function signatures match the framework (Gin uses `*gin.Context`, stdlib uses `http.ResponseWriter, *http.Request`)
-- Check that error return values are handled
-
-### "package X is not in std"
-
-- Run `go mod tidy` after adding new imports
-- Ensure `go get` was run before writing import statements
diff --git a/skills/workos-kotlin/SKILL.md b/skills/workos-kotlin/SKILL.md
deleted file mode 100644
index 394d59a..0000000
--- a/skills/workos-kotlin/SKILL.md
+++ /dev/null
@@ -1,195 +0,0 @@
----
-name: workos-kotlin
-description: Integrate WorkOS AuthKit with Kotlin/Spring Boot. Backend authentication with Gradle.
----
-
-# WorkOS AuthKit for Kotlin (Spring Boot)
-
-## Step 1: Fetch SDK Documentation (BLOCKING)
-
-**STOP. Do not proceed until complete.**
-
-WebFetch: `https://raw.githubusercontent.com/workos/workos-kotlin/main/README.md`
-
-The README is the source of truth. If this skill conflicts with README, follow README.
-
-## Step 2: Pre-Flight Validation
-
-### Project Structure
-
-- Confirm `build.gradle.kts` exists (Kotlin DSL) or `build.gradle` (Groovy DSL)
-- Confirm Spring Boot plugin is present (`org.springframework.boot`)
-- Detect Gradle wrapper: check if `./gradlew` exists
-
-### Gradle Wrapper
-
-```bash
-# If gradlew exists, ensure it's executable
-if [ -f ./gradlew ]; then chmod +x ./gradlew; fi
-```
-
-Use `./gradlew` if wrapper exists, otherwise fall back to `gradle`.
-
-### Environment Variables
-
-Check `application.properties` or `application.yml` for:
-
-- `workos.api-key` or `WORKOS_API_KEY`
-- `workos.client-id` or `WORKOS_CLIENT_ID`
-
-## Step 2b: Partial Install Recovery
-
-Before creating new files, check if a previous AuthKit attempt exists:
-
-1. Check if `workos-kotlin` is already in `build.gradle.kts` dependencies
-2. Check for incomplete auth code — WorkOS imported/instantiated but no controller with login/callback endpoints
-3. If partial install detected:
- - Do NOT re-add the SDK dependency (it's already there)
- - Read existing source files to understand what's done vs missing
- - Complete the integration by filling gaps (controller, config bean, routes)
- - Preserve any working code — only fix what's broken
- - Check for a missing `/auth/callback` endpoint (most common gap)
-
-## Step 2c: Existing Auth System Detection
-
-Check for existing authentication before integrating:
-
-```
-build.gradle.kts has 'spring-boot-starter-security'? → Spring Security
-*.kt files have 'SecurityFilterChain'? → Security filter config
-*.kt files have 'formLogin'? → Form-based auth
-*.kt files have 'oauth2Login'? → OAuth2 auth
-*.kt files have 'httpBasic'? → Basic auth
-```
-
-If existing auth detected:
-
-- Do NOT remove or disable it
-- Add WorkOS AuthKit alongside the existing system
-- If Spring Security is configured, ensure WorkOS auth routes are permitted through the security filter chain (add `.requestMatchers("/auth/workos/**").permitAll()`)
-- Create separate route paths for WorkOS auth (e.g., `/auth/workos/login` if `/login` is taken)
-- Ensure existing auth routes continue to work unchanged
-- Document in code comments how to migrate fully to WorkOS later
-
-## Step 3: Install SDK
-
-Add the WorkOS Kotlin SDK dependency to `build.gradle.kts`:
-
-```kotlin
-dependencies {
- implementation("com.workos:workos-kotlin:4.18.1")
- // ... existing dependencies
-}
-```
-
-Check the README for the latest version number — use the version from the README if it differs from above.
-
-**JVM target**: Ensure `jvmTarget` in `build.gradle.kts` matches the JDK on the system. Check with `java -version`. Common values: `"17"`, `"21"`. If `kotlin { jvmToolchain(...) }` is set, ensure it matches too.
-
-**Verify:** Run `./gradlew dependencies` or `gradle dependencies` to confirm the dependency resolves.
-
-## Step 4: Configure Authentication
-
-### 4a: Application Properties
-
-Add WorkOS configuration to `src/main/resources/application.properties`:
-
-```properties
-workos.api-key=${WORKOS_API_KEY}
-workos.client-id=${WORKOS_CLIENT_ID}
-workos.redirect-uri=http://localhost:8080/auth/callback
-```
-
-Or if the project uses `application.yml`, add the equivalent YAML.
-
-### 4b: Create WorkOS Configuration Bean
-
-Create a configuration class that initializes the WorkOS client:
-
-```kotlin
-@Configuration
-class WorkOSConfig {
- @Value("\${workos.api-key}")
- lateinit var apiKey: String
-
- @Bean
- fun workos(): WorkOS = WorkOS(apiKey)
-}
-```
-
-Adapt based on the SDK README — the exact client initialization may vary.
-
-### 4c: Create Auth Controller
-
-Create a Spring `@RestController` with these endpoints:
-
-1. **GET /auth/login** — Redirect user to WorkOS AuthKit hosted login
- - Use `workos.userManagement.getAuthorizationUrl()` — this returns a URL string
- - Parameters: `clientId`, `redirectUri`, `provider = "authkit"`
- - The method uses a builder pattern: `.provider("authkit").redirectUri(uri).build()`
-
-2. **GET /auth/callback** — Exchange authorization code for user profile
- - Extract `code` query parameter
- - Call `workos.userManagement.authenticateWithCode()` with the code and clientId
- - Store user session (use Spring's `HttpSession`)
- - Redirect to home page
-
-3. **GET /auth/logout** — Clear session and redirect
- - Invalidate `HttpSession`
- - Redirect to home page or WorkOS logout URL
-
-**Follow the README for exact API method names and parameters.**
-
-## Step 5: Session Management
-
-Use Spring's built-in `HttpSession` for session management:
-
-- Store user profile in session after callback
-- Check session in protected routes
-- Clear session on logout
-
-If Spring Security is already configured, integrate with the existing security filter chain rather than replacing it.
-
-## Step 6: Verification
-
-Run the build to verify everything compiles:
-
-```bash
-./gradlew build
-```
-
-**If build fails:**
-
-- Check dependency resolution: `./gradlew dependencies | grep workos`
-- Check for missing imports in the auth controller
-- Verify application.properties syntax
-- Gradle builds can be slow (30-60s) — be patient
-
-### Checklist
-
-- [ ] WorkOS SDK dependency in build.gradle.kts
-- [ ] Application properties configured
-- [ ] Auth controller with login, callback, logout endpoints
-- [ ] Build succeeds (`./gradlew build`)
-
-## Error Recovery
-
-### Dependency resolution failure
-
-- Check Maven Central is accessible
-- Verify the artifact coordinates match README exactly
-- Ensure `mavenCentral()` is in the `repositories` block of build.gradle.kts
-
-### "Could not resolve com.workos:workos-kotlin"
-
-- The package may use a different group ID — check README
-- Ensure repositories block includes `mavenCentral()`
-
-### Build fails with missing Spring Boot annotations
-
-- Verify `org.springframework.boot` plugin is applied
-- Check Spring Boot starter dependencies are present
-
-### Gradle wrapper permission denied
-
-- Run `chmod +x ./gradlew` before building
diff --git a/skills/workos-management/SKILL.md b/skills/workos-management/SKILL.md
deleted file mode 100644
index 4d9a605..0000000
--- a/skills/workos-management/SKILL.md
+++ /dev/null
@@ -1,250 +0,0 @@
----
-name: workos-management
-description: Manage WorkOS resources (orgs, users, roles, SSO, directories, webhooks, audit logs) via CLI. Use when configuring RBAC, onboarding orgs/users, debugging SSO/DSync, or managing WorkOS settings.
----
-
-# WorkOS Management Commands
-
-Use these commands to manage WorkOS resources directly from the terminal. The CLI must be authenticated via `workos auth login` or `WORKOS_API_KEY` env var.
-
-All commands support `--json` for structured output. Use `--json` when you need to parse output (e.g., extract an ID).
-
-## Quick Reference
-
-| Task | Command |
-| ---------------------- | ---------------------------------------------------------------------------- |
-| List organizations | `workos organization list` |
-| Create organization | `workos organization create "Acme Corp" acme.com:verified` |
-| List users | `workos user list --email=alice@acme.com` |
-| Create permission | `workos permission create --slug=read-users --name="Read Users"` |
-| Create role | `workos role create --slug=admin --name=Admin` |
-| Assign perms to role | `workos role set-permissions admin --permissions=read-users,write-users` |
-| Create org-scoped role | `workos role create --slug=admin --name=Admin --org=org_xxx` |
-| Add user to org | `workos membership create --org=org_xxx --user=user_xxx` |
-| Send invitation | `workos invitation send --email=alice@acme.com --org=org_xxx` |
-| Revoke session | `workos session revoke ` |
-| Add redirect URI | `workos config redirect add http://localhost:3000/callback` |
-| Add CORS origin | `workos config cors add http://localhost:3000` |
-| Set homepage URL | `workos config homepage-url set http://localhost:3000` |
-| Create webhook | `workos webhook create --url=https://example.com/hook --events=user.created` |
-| List SSO connections | `workos connection list --org=org_xxx` |
-| List directories | `workos directory list` |
-| Toggle feature flag | `workos feature-flag enable my-flag` |
-| Store a secret | `workos vault create --name=api-secret --value=sk_xxx --org=org_xxx` |
-| Generate portal link | `workos portal generate-link --intent=sso --org=org_xxx` |
-| Seed environment | `workos seed --file=workos-seed.yml` |
-| Debug SSO | `workos debug-sso conn_xxx` |
-| Debug directory sync | `workos debug-sync directory_xxx` |
-| Set up an org | `workos setup-org "Acme Corp" --domain=acme.com --roles=admin,viewer` |
-| Onboard a user | `workos onboard-user alice@acme.com --org=org_xxx --role=admin` |
-
-## Workflows
-
-### Setting up RBAC
-
-When you see permission checks in the codebase (e.g., `hasPermission('read-users')`), create the matching WorkOS resources:
-
-```bash
-workos permission create --slug=read-users --name="Read Users"
-workos permission create --slug=write-users --name="Write Users"
-workos role create --slug=admin --name=Admin
-workos role set-permissions admin --permissions=read-users,write-users
-workos role create --slug=viewer --name=Viewer
-workos role set-permissions viewer --permissions=read-users
-```
-
-For organization-scoped roles, add `--org=org_xxx` to role commands.
-
-### Organization Onboarding
-
-One-shot setup with the compound command:
-
-```bash
-workos setup-org "Acme Corp" --domain=acme.com --roles=admin,viewer
-```
-
-Or step by step:
-
-```bash
-ORG_ID=$(workos organization create "Acme Corp" --json | jq -r '.data.id')
-workos org-domain create acme.com --org=$ORG_ID
-workos role create --slug=admin --name=Admin --org=$ORG_ID
-workos portal generate-link --intent=sso --org=$ORG_ID
-```
-
-### User Onboarding
-
-```bash
-workos onboard-user alice@acme.com --org=org_xxx --role=admin
-```
-
-Or step by step:
-
-```bash
-workos invitation send --email=alice@acme.com --org=org_xxx --role=admin
-workos membership create --org=org_xxx --user=user_xxx --role=admin
-```
-
-### Local Development Setup
-
-Configure WorkOS for local development:
-
-```bash
-workos config redirect add http://localhost:3000/callback
-workos config cors add http://localhost:3000
-workos config homepage-url set http://localhost:3000
-```
-
-### Environment Seeding
-
-Create a `workos-seed.yml` file in your repo:
-
-```yaml
-permissions:
- - name: 'Read Users'
- slug: 'read-users'
- - name: 'Write Users'
- slug: 'write-users'
-
-roles:
- - name: 'Admin'
- slug: 'admin'
- permissions: ['read-users', 'write-users']
- - name: 'Viewer'
- slug: 'viewer'
- permissions: ['read-users']
-
-organizations:
- - name: 'Test Org'
- domains: ['test.com']
-
-config:
- redirect_uris: ['http://localhost:3000/callback']
- cors_origins: ['http://localhost:3000']
- homepage_url: 'http://localhost:3000'
-```
-
-Then run:
-
-```bash
-workos seed --file=workos-seed.yml # Create resources
-workos seed --clean # Tear down seeded resources
-```
-
-### Debugging SSO
-
-```bash
-workos debug-sso conn_xxx
-```
-
-Shows: connection type/state, organization binding, recent auth events, and common issues (inactive connection, org mismatch).
-
-### Debugging Directory Sync
-
-```bash
-workos debug-sync directory_xxx
-```
-
-Shows: directory type/state, user/group counts, recent sync events, and stall detection.
-
-### Webhook Management
-
-```bash
-workos webhook list
-workos webhook create --url=https://example.com/hook --events=user.created,dsync.user.created
-workos webhook delete we_xxx
-```
-
-### Audit Logs
-
-```bash
-workos audit-log create-event --org=org_xxx --action=user.login --actor-type=user --actor-id=user_xxx
-workos audit-log list-actions
-workos audit-log get-schema user.login
-workos audit-log export --org=org_xxx --range-start=2024-01-01 --range-end=2024-02-01
-workos audit-log get-retention --org=org_xxx
-```
-
-## Using --json for Structured Output
-
-All commands support `--json` for machine-readable output. Use this when you need to extract values:
-
-```bash
-# Get an organization ID
-workos organization list --json | jq '.data[0].id'
-
-# Get a connection's state
-workos connection get conn_xxx --json | jq '.state'
-
-# List all role slugs
-workos role list --json | jq '.data[].slug'
-
-# Chain commands: create org then add domain
-ORG_ID=$(workos organization create "Acme" --json | jq -r '.data.id')
-workos org-domain create acme.com --org=$ORG_ID
-```
-
-JSON output format:
-
-- **List commands**: `{ "data": [...], "listMetadata": { "before": null, "after": "cursor" } }`
-- **Get commands**: Raw object (no wrapper)
-- **Create/Update/Delete**: `{ "status": "ok", "message": "...", "data": {...} }`
-- **Errors**: `{ "error": { "code": "...", "message": "..." } }` on stderr
-
-## Command Reference
-
-### Resource Commands
-
-| Command | Subcommands |
-| --------------------- | ----------------------------------------------------------------------------------------------------- |
-| `workos organization` | `list`, `get`, `create`, `update`, `delete` |
-| `workos user` | `list`, `get`, `update`, `delete` |
-| `workos role` | `list`, `get`, `create`, `update`, `delete`, `set-permissions`, `add-permission`, `remove-permission` |
-| `workos permission` | `list`, `get`, `create`, `update`, `delete` |
-| `workos membership` | `list`, `get`, `create`, `update`, `delete`, `deactivate`, `reactivate` |
-| `workos invitation` | `list`, `get`, `send`, `revoke`, `resend` |
-| `workos session` | `list`, `revoke` |
-| `workos connection` | `list`, `get`, `delete` |
-| `workos directory` | `list`, `get`, `delete`, `list-users`, `list-groups` |
-| `workos event` | `list` (requires `--events` flag) |
-| `workos audit-log` | `create-event`, `export`, `list-actions`, `get-schema`, `create-schema`, `get-retention` |
-| `workos feature-flag` | `list`, `get`, `enable`, `disable`, `add-target`, `remove-target` |
-| `workos webhook` | `list`, `create`, `delete` |
-| `workos config` | `redirect add`, `cors add`, `homepage-url set` |
-| `workos portal` | `generate-link` |
-| `workos vault` | `list`, `get`, `get-by-name`, `create`, `update`, `delete`, `describe`, `list-versions` |
-| `workos api-key` | `list`, `create`, `validate`, `delete` |
-| `workos org-domain` | `get`, `create`, `verify`, `delete` |
-
-### Workflow Commands
-
-| Command | Purpose |
-| ----------------------------- | ------------------------------------------- |
-| `workos seed --file=` | Declarative resource provisioning from YAML |
-| `workos seed --clean` | Tear down seeded resources |
-| `workos setup-org ` | One-shot org onboarding |
-| `workos onboard-user ` | Send invitation + optional wait |
-| `workos debug-sso ` | SSO connection diagnostics |
-| `workos debug-sync ` | Directory sync diagnostics |
-
-### Common Flags
-
-| Flag | Purpose | Scope |
-| ------------------------------------------- | ------------------------ | --------------------------------------------------- |
-| `--json` | Structured JSON output | All commands |
-| `--api-key` | Override API key | Resource commands |
-| `--org` | Organization scope | role, membership, invitation, api-key, feature-flag |
-| `--force` | Skip confirmation prompt | connection delete, directory delete |
-| `--limit`, `--before`, `--after`, `--order` | Pagination | All list commands |
-
-## Dashboard-Only Operations
-
-These CANNOT be done from the CLI — tell the user to visit the WorkOS Dashboard:
-
-- **Enable/disable auth methods** — Dashboard > Authentication
-- **Configure session lifetime** — Dashboard > Authentication > Sessions
-- **Set up social login providers** (Google, GitHub, etc.) — Dashboard > Authentication > Social
-- **Create feature flags** — Dashboard > Feature Flags (toggle/target operations work via CLI)
-- **Configure branding** (logos, colors) — Dashboard > Branding
-- **Set up email templates** — Dashboard > Email
-- **Manage billing/plan** — Dashboard > Settings > Billing
diff --git a/skills/workos-node/SKILL.md b/skills/workos-node/SKILL.md
deleted file mode 100644
index 50b720b..0000000
--- a/skills/workos-node/SKILL.md
+++ /dev/null
@@ -1,197 +0,0 @@
----
-name: workos-node
-description: Integrate WorkOS AuthKit with Node.js backend applications. Adapts to Express, Fastify, Hono, Koa, or vanilla Node.js http. Server-side authentication with redirect-based OAuth flow.
----
-
-# WorkOS AuthKit for Node.js
-
-## Step 1: Fetch SDK Documentation (BLOCKING)
-
-**STOP - Do not proceed until complete.**
-
-WebFetch: `https://raw.githubusercontent.com/workos/workos-node/main/README.md`
-
-Also fetch the AuthKit quickstart for reference:
-WebFetch: `https://workos.com/docs/authkit/vanilla/nodejs`
-
-README is the source of truth for all SDK patterns. **README overrides this skill if conflict.**
-
-## Step 2: Detect Framework & Project Structure
-
-```
-package.json has 'express'? → Express
-package.json has 'fastify'? → Fastify
-package.json has 'hono'? → Hono
-package.json has 'koa'? → Koa
-None of the above? → Vanilla Node.js http (use Express quickstart pattern)
-
-tsconfig.json exists? → TypeScript (.ts files)
-"type": "module" in package.json? → ESM (import/export)
-else → CJS (require/module.exports)
-```
-
-Detect entry point: `src/index.ts`, `src/app.ts`, `app.js`, `server.js`, `index.js`
-
-Detect package manager: `pnpm-lock.yaml` → `yarn.lock` → `bun.lockb` → npm
-
-**Adapt all subsequent steps to the detected framework and module system.**
-
-## Step 2b: Partial Install Recovery
-
-Before creating new files, check if a previous AuthKit attempt exists:
-
-1. Check if `@workos-inc/node` is already in `package.json`
-2. Check for incomplete auth files — routes/handlers that import `@workos-inc/node` but are non-functional (TODO comments, 501 responses, empty handlers)
-3. If partial install detected:
- - Do NOT reinstall the SDK (it's already there)
- - Read existing auth files to understand what's done vs missing
- - Complete the integration by filling gaps rather than starting fresh
- - Preserve any working code — only fix what's broken
- - Check for a missing `/callback` route (most common gap)
-
-## Step 2c: Existing Auth System Detection
-
-Check for existing authentication before integrating:
-
-```
-package.json has 'passport'? → Passport.js auth
-package.json has 'express-openid-connect'? → Auth0 / OIDC
-package.json has 'express-session'? → Session-based auth may exist
-*.js/*.ts files have 'jsonwebtoken'? → JWT-based auth
-```
-
-If existing auth detected:
-
-- Do NOT remove or disable it
-- Add WorkOS AuthKit alongside the existing system
-- If `express-session` is already configured, reuse it for WorkOS session storage (don't create a second session middleware)
-- Create separate route paths for WorkOS auth (e.g., `/auth/workos/login` if `/login` is taken)
-- Ensure existing auth routes continue to work unchanged
-- Document in code comments how to migrate fully to WorkOS later
-
-## Step 3: Install SDK
-
-```
-pnpm-lock.yaml → pnpm add @workos-inc/node dotenv cookie-parser
-yarn.lock → yarn add @workos-inc/node dotenv cookie-parser
-bun.lockb → bun add @workos-inc/node dotenv cookie-parser
-else → npm install @workos-inc/node dotenv cookie-parser
-```
-
-For TypeScript, also install types: `pnpm add -D @types/cookie-parser`
-
-**Verify:** `@workos-inc/node` in package.json dependencies
-
-## Step 4: Initialize WorkOS Client
-
-Adapt to detected module system (ESM vs CJS):
-
-**ESM/TypeScript:**
-
-```typescript
-import { WorkOS } from '@workos-inc/node';
-const workos = new WorkOS(process.env.WORKOS_API_KEY, {
- clientId: process.env.WORKOS_CLIENT_ID,
-});
-```
-
-**CJS:**
-
-```javascript
-const { WorkOS } = require('@workos-inc/node');
-const workos = new WorkOS(process.env.WORKOS_API_KEY, {
- clientId: process.env.WORKOS_CLIENT_ID,
-});
-```
-
-## Step 5: Integrate Authentication
-
-### If Express
-
-Follow the quickstart pattern:
-
-1. **`/login` route** — call `workos.userManagement.getAuthorizationUrl({ provider: 'authkit', redirectUri: ..., clientId: ... })`, redirect
-2. **`/callback` route** — call `workos.userManagement.authenticateWithCode({ code, clientId })`, store session via sealed session or express-session
-3. **`/logout` route** — clear session cookie, redirect
-4. **Cookie middleware** — `app.use(cookieParser())`
-5. **Session-aware home route** — read session, display user info
-
-**Session handling options (pick one):**
-
-- **Sealed sessions** (recommended, from quickstart): use `sealSession: true` in authenticateWithCode, store sealed cookie, use `loadSealedSession` for verification
-- **express-session**: install `express-session`, configure middleware before routes, store user in `req.session`
-
-### If Fastify
-
-1. Register `@fastify/cookie` plugin
-2. Create `/login`, `/callback`, `/logout` routes using Fastify route syntax
-3. Use `reply.redirect()` for redirects
-4. Store session in signed cookie
-
-### If Hono
-
-1. Create `/login`, `/callback`, `/logout` routes using Hono router
-2. Use `c.redirect()` for redirects
-3. Use Hono's cookie helpers for session
-
-### If Koa
-
-1. Install `koa-router` if not present
-2. Create auth routes on router
-3. Use `ctx.redirect()` for redirects
-4. Use `koa-session` for session management
-
-### If Vanilla Node.js (no framework detected)
-
-Install Express and follow the Express pattern above. This matches the official quickstart.
-
-## Step 6: Environment Setup
-
-Create `.env` if it doesn't exist. Do NOT overwrite existing values:
-
-```
-WORKOS_API_KEY=sk_...
-WORKOS_CLIENT_ID=client_...
-WORKOS_REDIRECT_URI=http://localhost:3000/callback
-WORKOS_COOKIE_PASSWORD=
-```
-
-Ensure `.env` is in `.gitignore`.
-
-## Step 7: Verification
-
-**TypeScript:** `npx tsc --noEmit`
-**JavaScript:** `node --check `
-
-### Checklist
-
-- [ ] SDK installed (`@workos-inc/node` in package.json)
-- [ ] WorkOS client initialized
-- [ ] Login route redirects to AuthKit
-- [ ] Callback route exchanges code for user
-- [ ] Logout route clears session
-- [ ] `.env` has required variables
-- [ ] Build/syntax check passes
-
-## Error Recovery
-
-### Module not found: @workos-inc/node
-
-Re-run install for detected package manager.
-
-### Session not persisting
-
-If using express-session: ensure middleware registered BEFORE routes.
-If using sealed sessions: ensure cookie is being set with correct options (httpOnly, secure in prod, sameSite: 'lax').
-
-### Callback returns 404
-
-Route path must match WORKOS_REDIRECT_URI exactly.
-
-### ESM/CJS mismatch
-
-Check `"type"` field in package.json — `"module"` = ESM (import/export), absent = CJS (require).
-
-### TypeScript errors
-
-Install missing types: `@types/express`, `@types/cookie-parser`, `@types/express-session`.
diff --git a/skills/workos-php-laravel/SKILL.md b/skills/workos-php-laravel/SKILL.md
deleted file mode 100644
index 0b6055e..0000000
--- a/skills/workos-php-laravel/SKILL.md
+++ /dev/null
@@ -1,182 +0,0 @@
----
-name: workos-php-laravel
-description: Integrate WorkOS AuthKit with Laravel applications. Uses the dedicated workos-php-laravel SDK with service provider, middleware, and config publishing.
----
-
-# WorkOS AuthKit for Laravel
-
-## Step 1: Fetch SDK Documentation (BLOCKING)
-
-**STOP. Do not proceed until complete.**
-
-WebFetch: `https://raw.githubusercontent.com/workos/workos-php-laravel/main/README.md`
-
-The README is the source of truth. If this skill conflicts with README, follow README.
-
-## Step 2: Pre-Flight Validation
-
-### Project Structure
-
-- Confirm `artisan` file exists at project root
-- Confirm `composer.json` contains `laravel/framework` dependency
-- Confirm `app/` and `routes/` directories exist
-
-### Environment Variables
-
-Check `.env` for:
-
-- `WORKOS_API_KEY` - starts with `sk_`
-- `WORKOS_CLIENT_ID` - starts with `client_`
-- `WORKOS_REDIRECT_URI` - valid callback URL (e.g., `http://localhost:8000/auth/callback`)
-
-If `.env` exists but is missing these variables, append them. If `.env` doesn't exist, copy `.env.example` and add them.
-
-## Step 2b: Partial Install Recovery
-
-Before creating new files, check if a previous AuthKit attempt exists:
-
-1. Check if `workos/workos-php-laravel` is already in `composer.json`
-2. Check if `config/workos.php` exists but no auth controller or routes are wired
-3. If partial install detected:
- - Do NOT reinstall the SDK (it's already there)
- - Do NOT re-publish config if `config/workos.php` already exists
- - Read existing files to understand what's done vs missing
- - Complete the integration by filling gaps (controller, routes, middleware)
- - Preserve any working code — only fix what's broken
- - Check for missing auth controller or routes (most common gap)
-
-## Step 2c: Existing Auth System Detection
-
-Check for existing authentication before integrating:
-
-```
-composer.json has 'laravel/breeze'? → Breeze auth scaffolding
-composer.json has 'laravel/jetstream'? → Jetstream auth
-composer.json has 'laravel/fortify'? → Fortify auth backend
-app/Http/Controllers/Auth/ exists? → Auth controllers present
-routes/auth.php exists? → Auth routes file
-```
-
-If existing auth detected:
-
-- Do NOT remove or disable it
-- Add WorkOS AuthKit alongside the existing system
-- If Laravel session is already configured, reuse it for WorkOS
-- Create separate route paths for WorkOS auth (e.g., `/auth/workos/login` if `/login` is taken)
-- Ensure existing auth routes continue to work unchanged
-- Document in code comments how to migrate fully to WorkOS later
-
-## Step 3: Install SDK
-
-```bash
-composer require workos/workos-php-laravel
-```
-
-**Verify:** Check `composer.json` contains `workos/workos-php-laravel` in require section before continuing.
-
-## Step 4: Publish Configuration
-
-```bash
-php artisan vendor:publish --provider="WorkOS\Laravel\WorkOSServiceProvider"
-```
-
-This creates `config/workos.php`. Verify the file exists after publishing.
-
-If the artisan command fails, check README for the correct provider class name — it may differ.
-
-## Step 5: Configure Environment
-
-Ensure `.env` contains:
-
-```
-WORKOS_API_KEY=sk_...
-WORKOS_CLIENT_ID=client_...
-WORKOS_REDIRECT_URI=http://localhost:8000/auth/callback
-```
-
-Also ensure `config/workos.php` reads these env vars correctly. Check README for exact config structure.
-
-## Step 6: Create Auth Controller
-
-Create `app/Http/Controllers/AuthController.php` with methods for:
-
-- `login()` — Redirect to WorkOS AuthKit authorization URL
-- `callback()` — Handle OAuth callback, exchange code for user profile
-- `logout()` — Clear session and redirect
-
-Use SDK methods from README. Do NOT construct OAuth URLs manually.
-
-## Step 7: Add Routes
-
-Add to `routes/web.php`:
-
-```php
-use App\Http\Controllers\AuthController;
-
-Route::get('/login', [AuthController::class, 'login'])->name('login');
-Route::get('/auth/callback', [AuthController::class, 'callback']);
-Route::get('/logout', [AuthController::class, 'logout'])->name('logout');
-```
-
-Ensure the callback route path matches `WORKOS_REDIRECT_URI`.
-
-## Step 8: Add Middleware (if applicable)
-
-Check README for any authentication middleware the SDK provides. If available:
-
-1. Register middleware in `app/Http/Kernel.php` or `bootstrap/app.php` (Laravel 11+)
-2. Apply to routes that require authentication
-
-For Laravel 11+, middleware is registered in `bootstrap/app.php` instead of `Kernel.php`.
-
-## Step 9: Add UI Integration
-
-Update the home page or dashboard view to show:
-
-- Sign in link when user is not authenticated
-- User info and sign out link when authenticated
-
-Use Blade directives or SDK helpers from README.
-
-## Verification Checklist (ALL MUST PASS)
-
-```bash
-# 1. Config file exists
-ls config/workos.php
-
-# 2. Controller exists
-ls app/Http/Controllers/AuthController.php
-
-# 3. Routes registered
-php artisan route:list | grep -E "login|callback|logout"
-
-# 4. SDK installed
-composer show workos/workos-php-laravel
-
-# 5. Lint check
-php -l app/Http/Controllers/AuthController.php
-```
-
-## Error Recovery
-
-### "Class WorkOS\Laravel\WorkOSServiceProvider not found"
-
-- Verify `composer require` completed successfully
-- Run `composer dump-autoload`
-- Check `vendor/workos/` directory exists
-
-### "Route not defined"
-
-- Verify routes are in `routes/web.php`
-- Run `php artisan route:clear && php artisan route:cache`
-
-### Config not loading
-
-- Verify `config/workos.php` exists
-- Run `php artisan config:clear`
-- Check `.env` variables match config keys
-
-### Middleware issues (Laravel 11+)
-
-- Laravel 11 removed `Kernel.php` — register middleware in `bootstrap/app.php`
-- Check README for Laravel version-specific instructions
diff --git a/skills/workos-php/SKILL.md b/skills/workos-php/SKILL.md
deleted file mode 100644
index 10f61e9..0000000
--- a/skills/workos-php/SKILL.md
+++ /dev/null
@@ -1,160 +0,0 @@
----
-name: workos-php
-description: Integrate WorkOS AuthKit with generic PHP applications. Uses the workos-php SDK directly with standalone auth endpoint files.
----
-
-# WorkOS AuthKit for PHP
-
-## Step 1: Fetch SDK Documentation (BLOCKING)
-
-**STOP. Do not proceed until complete.**
-
-WebFetch: `https://raw.githubusercontent.com/workos/workos-php/main/README.md`
-
-The README is the source of truth. If this skill conflicts with README, follow README.
-
-## Step 2: Pre-Flight Validation
-
-### Project Structure
-
-- Confirm `composer.json` exists at project root
-- If `composer.json` doesn't exist, create a minimal one with `composer init --no-interaction`
-
-### Environment Variables
-
-Check for `.env` file with:
-
-- `WORKOS_API_KEY` - starts with `sk_`
-- `WORKOS_CLIENT_ID` - starts with `client_`
-- `WORKOS_REDIRECT_URI` - valid callback URL (e.g., `http://localhost:8000/callback.php`)
-
-If `.env` doesn't exist, create it with the required variables.
-
-## Step 2b: Partial Install Recovery
-
-Before creating new files, check if a previous AuthKit attempt exists:
-
-1. Check if `workos/workos-php` is already in `composer.json`
-2. Check for incomplete auth files — `login.php` or `callback.php` that import WorkOS but are non-functional (TODO comments, 501 responses, empty handlers)
-3. If partial install detected:
- - Do NOT reinstall the SDK (it's already there)
- - Read existing auth files to understand what's done vs missing
- - Complete the integration by filling gaps rather than starting fresh
- - Preserve any working code — only fix what's broken
- - Check for a missing `callback.php` (most common gap)
-
-## Step 2c: Existing Auth System Detection
-
-Check for existing authentication before integrating:
-
-```
-*.php files have 'session_start()' + '$_SESSION'? → Native PHP session auth
-*.php files have 'password_verify'? → Password-based auth
-*.php files have form POST to '/login'? → Form-based auth
-composer.json has auth libraries? → Third-party auth
-```
-
-If existing auth detected:
-
-- Do NOT remove or disable it
-- Add WorkOS AuthKit alongside the existing system
-- If `session_start()` is already used, reuse the session for WorkOS (don't create a second session mechanism)
-- Create separate file paths for WorkOS auth (e.g., `workos-login.php` if `login.php` is taken)
-- Ensure existing auth routes continue to work unchanged
-- Document in code comments how to migrate fully to WorkOS later
-
-## Step 3: Install SDK
-
-```bash
-composer require workos/workos-php
-```
-
-**Verify:** Check `composer.json` contains `workos/workos-php` in require section.
-
-Also install a dotenv library if not present:
-
-```bash
-composer require vlucas/phpdotenv
-```
-
-## Step 4: Create Bootstrap File
-
-Create a bootstrap or config file (e.g., `config.php` or `bootstrap.php`) that:
-
-1. Requires Composer autoloader: `require_once __DIR__ . '/vendor/autoload.php';`
-2. Loads `.env` using phpdotenv
-3. Initializes the WorkOS SDK client with API key
-
-Use SDK initialization from README. Do NOT hardcode credentials.
-
-## Step 5: Create Auth Endpoint Files
-
-### `login.php`
-
-- Initialize WorkOS client (include bootstrap)
-- Generate authorization URL using SDK
-- Redirect user to WorkOS AuthKit
-
-### `callback.php`
-
-- Initialize WorkOS client (include bootstrap)
-- Exchange authorization code from `$_GET['code']` for user profile using SDK
-- Start session, store user data
-- Redirect to home/dashboard
-
-### `logout.php`
-
-- Destroy session
-- Redirect to home page
-
-Use SDK methods from README for all WorkOS API calls. Do NOT construct OAuth URLs manually.
-
-## Step 6: Create Home Page
-
-Create or update `index.php` to show:
-
-- Sign in link (`login.php`) when no session
-- User info and sign out link (`logout.php`) when session exists
-
-## Verification Checklist (ALL MUST PASS)
-
-```bash
-# 1. SDK installed
-composer show workos/workos-php
-
-# 2. Auth files exist
-ls login.php callback.php logout.php
-
-# 3. No syntax errors
-php -l login.php
-php -l callback.php
-php -l logout.php
-php -l index.php
-
-# 4. Autoloader exists
-ls vendor/autoload.php
-```
-
-## Error Recovery
-
-### "Class WorkOS\WorkOS not found"
-
-- Verify `composer require` completed successfully
-- Check `vendor/autoload.php` is required in bootstrap
-- Run `composer dump-autoload`
-
-### Session issues
-
-- Ensure `session_start()` is called before any session access
-- Check PHP session configuration (`session.save_path`)
-
-### Redirect URI mismatch
-
-- Compare callback file path to `WORKOS_REDIRECT_URI` in `.env`
-- URLs must match exactly (including trailing slash)
-
-### Environment variables not loading
-
-- Verify `.env` file exists in project root
-- Verify phpdotenv is installed and loaded in bootstrap
-- Check file permissions on `.env`
diff --git a/skills/workos-python/SKILL.md b/skills/workos-python/SKILL.md
deleted file mode 100644
index ad3828c..0000000
--- a/skills/workos-python/SKILL.md
+++ /dev/null
@@ -1,193 +0,0 @@
----
-name: workos-python
-description: Integrate WorkOS AuthKit with Python applications. Adapts to Django, Flask, FastAPI, or vanilla Python. Server-side authentication with redirect-based OAuth flow.
----
-
-# WorkOS AuthKit for Python
-
-## Step 1: Fetch SDK Documentation (BLOCKING)
-
-**STOP. Do not proceed until complete.**
-
-WebFetch: `https://raw.githubusercontent.com/workos/workos-python/main/README.md`
-
-Also fetch the AuthKit quickstart for reference:
-WebFetch: `https://workos.com/docs/authkit/vanilla/python`
-
-The README is the source of truth for SDK API usage. If this skill conflicts with README, follow README.
-
-## Step 2: Detect Framework
-
-Examine the project to determine which Python web framework is in use:
-
-```
-manage.py exists? → Django
- settings.py has django imports? → Confirmed Django
-
-Gemfile/requirements has 'fastapi'? → FastAPI
- main.py has FastAPI() instance? → Confirmed FastAPI
-
-requirements has 'flask'? → Flask
- server.py/app.py has Flask() instance? → Confirmed Flask
-
-None of the above? → Vanilla Python (use Flask quickstart pattern)
-```
-
-**Adapt all subsequent steps to the detected framework.** Do not force one framework onto another.
-
-## Step 2b: Partial Install Recovery
-
-Before creating new files, check if a previous AuthKit attempt exists:
-
-1. Check if `workos` is already in `requirements.txt` or `pyproject.toml`
-2. Check for incomplete auth files — files that import `workos` but have non-functional routes (TODO comments, commented-out code, empty handlers)
-3. If partial install detected:
- - Do NOT reinstall the SDK (it's already there)
- - Read existing auth files to understand what's done vs missing
- - Complete the integration by filling gaps rather than starting fresh
- - Preserve any working code — only fix what's broken
- - Check for a missing `/callback` route (most common gap)
-
-## Step 2c: Existing Auth System Detection
-
-Check for existing authentication before integrating:
-
-```
-requirements.txt has 'flask-login'? → Flask-Login auth
-requirements.txt has 'authlib'? → OAuth/OIDC auth (e.g., Auth0)
-requirements.txt has 'django-allauth'? → Django allauth
-manage.py exists + 'django.contrib.auth'? → Django built-in auth
-*.py files have 'flask_login'? → Flask-Login in use
-```
-
-If existing auth detected:
-
-- Do NOT remove or disable it
-- Add WorkOS AuthKit alongside the existing system
-- If `flask-login` is present, use Flask-Login's session infrastructure (`login_user()`) for WorkOS auth too, rather than raw session management
-- Create separate route paths for WorkOS auth (e.g., `/auth/workos/login` if `/login` is taken)
-- Ensure existing auth routes continue to work unchanged
-- Document in code comments how to migrate fully to WorkOS later
-
-## Step 3: Pre-Flight Validation
-
-### Package Manager Detection
-
-```
-uv.lock exists? → uv add
-pyproject.toml has [tool.poetry]? → poetry add
-Pipfile exists? → pipenv install
-requirements.txt exists? → pip install (+ append to requirements.txt)
-else → pip install
-```
-
-### Environment Variables
-
-Check `.env` for:
-
-- `WORKOS_API_KEY` - starts with `sk_`
-- `WORKOS_CLIENT_ID` - starts with `client_`
-
-## Step 4: Install SDK
-
-Install using the detected package manager:
-
-```bash
-# uv
-uv add workos python-dotenv
-
-# poetry
-poetry add workos python-dotenv
-
-# pip
-pip install workos python-dotenv
-```
-
-If using `requirements.txt`, also append `workos` and `python-dotenv` to it.
-
-**Verify:** `python -c "import workos; print('OK')"`
-
-## Step 5: Integrate Authentication
-
-### If Django
-
-1. **Configure settings.py** — add `import os` + `from dotenv import load_dotenv` + `load_dotenv()` at top. Add `WORKOS_API_KEY` and `WORKOS_CLIENT_ID` from `os.environ.get()`.
-2. **Create auth views** — create `auth_views.py` (or add to existing views):
- - `login_view`: call SDK's `get_authorization_url()` with `provider='authkit'`, redirect
- - `callback_view`: call `authenticate_with_code()` with the code param, store user in `request.session`
- - `logout_view`: flush session, redirect
-3. **Add URL patterns** — add `auth/login/`, `auth/callback/`, `auth/logout/` to `urls.py`
-4. **Update templates** — add login/logout links using `{% url %}` tags
-
-### If Flask
-
-Follow the quickstart pattern exactly:
-
-1. **Initialize WorkOS client** in `server.py` / `app.py`:
- ```python
- from workos import WorkOSClient
- workos = WorkOSClient(api_key=os.getenv("WORKOS_API_KEY"), client_id=os.getenv("WORKOS_CLIENT_ID"))
- ```
-2. **Create `/login` route** — call `workos.user_management.get_authorization_url(provider="authkit", redirect_uri="...")`, redirect
-3. **Create `/callback` route** — call `workos.user_management.authenticate_with_code(code=code)`, set session cookie
-4. **Create `/logout` route** — clear session, redirect
-5. **Update home route** — show user info if session exists
-
-### If FastAPI
-
-1. **Initialize WorkOS client** in main app file
-2. **Create `/login` endpoint** — generate auth URL, return `RedirectResponse`
-3. **Create `/callback` endpoint** — exchange code, store in session/cookie
-4. **Create `/logout` endpoint** — clear session
-5. Use `Depends()` for auth middleware on protected routes
-
-### If Vanilla Python (no framework detected)
-
-Install Flask and follow the Flask pattern above. This matches the official quickstart.
-
-## Step 6: Environment Setup
-
-Create/update `.env` with WorkOS credentials. Do NOT overwrite existing values.
-
-```
-WORKOS_API_KEY=sk_...
-WORKOS_CLIENT_ID=client_...
-```
-
-## Step 7: Verification Checklist
-
-```bash
-# 1. SDK importable
-python -c "import workos; print('OK')"
-
-# 2. Credentials configured
-python -c "
-from dotenv import load_dotenv; import os; load_dotenv()
-assert os.environ.get('WORKOS_API_KEY','').startswith('sk_'), 'Missing WORKOS_API_KEY'
-assert os.environ.get('WORKOS_CLIENT_ID','').startswith('client_'), 'Missing WORKOS_CLIENT_ID'
-print('Credentials OK')
-"
-
-# 3. Framework-specific check
-# Django: python manage.py check
-# Flask: python -m py_compile server.py
-# FastAPI: python -m py_compile main.py
-```
-
-## Error Recovery
-
-### "ModuleNotFoundError: No module named 'workos'"
-
-Re-run the install command for the detected package manager.
-
-### Django: "CSRF verification failed"
-
-Auth callback receives GET requests from WorkOS. Ensure callback view uses GET, not POST. Or add `@csrf_exempt`.
-
-### Flask: Session not persisting
-
-Ensure `app.secret_key` is set (required for Flask sessions).
-
-### Virtual environment not active
-
-Check for `.venv/`, `venv/`, or poetry-managed environments. Activate before running install.
diff --git a/skills/workos-ruby/SKILL.md b/skills/workos-ruby/SKILL.md
deleted file mode 100644
index b150e24..0000000
--- a/skills/workos-ruby/SKILL.md
+++ /dev/null
@@ -1,198 +0,0 @@
----
-name: workos-ruby
-description: Integrate WorkOS AuthKit with Ruby applications. Adapts to Rails, Sinatra, or vanilla Ruby. Server-side authentication with redirect-based OAuth flow.
----
-
-# WorkOS AuthKit for Ruby
-
-## Step 1: Fetch SDK Documentation (BLOCKING)
-
-**STOP — Do not proceed until this fetch is complete.**
-
-WebFetch: `https://raw.githubusercontent.com/workos/workos-ruby/main/README.md`
-
-Also fetch the AuthKit quickstart for reference:
-WebFetch: `https://workos.com/docs/authkit/vanilla/ruby`
-
-The README is the **source of truth** for gem API usage. If this skill conflicts with the README, **follow the README**.
-
-## Step 2: Detect Framework
-
-Examine the project to determine which Ruby web framework is in use:
-
-```
-config/routes.rb exists? → Rails
- Gemfile has 'rails' gem? → Confirmed Rails
-
-Gemfile has 'sinatra' gem? → Sinatra
- server.rb/app.rb has Sinatra routes? → Confirmed Sinatra
-
-None of the above? → Vanilla Ruby (use Sinatra quickstart pattern)
-```
-
-**Adapt all subsequent steps to the detected framework.** Do not force Rails on a Sinatra project or vice versa.
-
-## Step 2b: Partial Install Recovery
-
-Before creating new files, check if a previous AuthKit attempt exists:
-
-1. Check if `workos` is already in `Gemfile`
-2. Check for incomplete auth files — files that `require "workos"` but have non-functional routes (TODO comments, 501 responses, empty handlers)
-3. If partial install detected:
- - Do NOT reinstall the gem (it's already there)
- - Read existing auth files to understand what's done vs missing
- - Complete the integration by filling gaps rather than starting fresh
- - Preserve any working code — only fix what's broken
- - Run `bundle install` (not `bundle update`) to avoid unexpected gem upgrades
-
-## Step 2c: Existing Auth System Detection
-
-Check for existing authentication before integrating:
-
-```
-Gemfile has 'devise'? → Devise auth (uses Warden)
-Gemfile has 'warden'? → Warden auth
-Gemfile has 'omniauth'? → OmniAuth (OAuth/OIDC)
-*.rb files have 'Warden'? → Warden middleware in use
-config/initializers has devise.rb? → Devise configured
-```
-
-If existing auth detected:
-
-- Do NOT remove or disable it
-- Add WorkOS AuthKit alongside the existing system
-- If Devise is present, Devise uses Warden under the hood — integrate WorkOS at the Warden strategy level if possible
-- Create separate route paths for WorkOS auth (e.g., `/auth/workos/login` if `/login` is taken)
-- Ensure Rack middleware ordering is correct (WorkOS session middleware must not conflict)
-- Ensure existing auth routes continue to work unchanged
-- Document in code comments how to migrate fully to WorkOS later
-
-## Step 3: Install WorkOS Gem
-
-```bash
-bundle add workos
-```
-
-If `dotenv` is not in the Gemfile:
-
-```bash
-# Rails
-bundle add dotenv-rails --group development,test
-
-# Sinatra / other
-bundle add dotenv
-```
-
-**Verify:** `bundle show workos`
-
-## Step 4: Integrate Authentication
-
-### If Rails
-
-1. **Create initializer** — `config/initializers/workos.rb`:
-
- ```ruby
- WorkOS.configure do |config|
- config.api_key = ENV.fetch("WORKOS_API_KEY")
- config.client_id = ENV.fetch("WORKOS_CLIENT_ID")
- end
- ```
-
-2. **Create AuthController** — `app/controllers/auth_controller.rb`:
- - `login` action: call `WorkOS::UserManagement.get_authorization_url(provider: "authkit", redirect_uri: ...)`, redirect
- - `callback` action: call `WorkOS::UserManagement.authenticate_with_code(code: params[:code])`, store user in session
- - `logout` action: clear session, redirect
-
-3. **Add routes** to `config/routes.rb`:
-
- ```ruby
- get "/auth/login", to: "auth#login"
- get "/auth/callback", to: "auth#callback"
- get "/auth/logout", to: "auth#logout"
- ```
-
-4. **Add current_user helper** to `ApplicationController` (optional):
-
- ```ruby
- helper_method :current_user
- def current_user
- @current_user ||= session[:user] && JSON.parse(session[:user])
- end
- ```
-
-5. **Verify:** `bundle exec rails routes | grep auth`
-
-### If Sinatra
-
-Follow the quickstart pattern exactly:
-
-1. **Configure WorkOS** in `server.rb`:
-
- ```ruby
- require "dotenv/load"
- require "workos"
- require "sinatra"
-
- WorkOS.configure do |config|
- config.key = ENV["WORKOS_API_KEY"]
- end
- ```
-
-2. **Create `/login` route** — call `WorkOS::UserManagement.authorization_url(provider: "authkit", client_id: ..., redirect_uri: ...)`, redirect
-
-3. **Create `/callback` route** — call `WorkOS::UserManagement.authenticate_with_code(client_id: ..., code: ...)`, store in session cookie
-
-4. **Create `/logout` route** — clear session cookie, redirect
-
-5. **Update home route** — read session, show user info if present
-
-6. **Verify:** `ruby -c server.rb`
-
-### If Vanilla Ruby (no framework detected)
-
-Install Sinatra and follow the Sinatra pattern above. This matches the official quickstart.
-
-## Step 5: Environment Setup
-
-Create/update `.env` with WorkOS credentials. Do NOT overwrite existing values.
-
-```
-WORKOS_API_KEY=sk_...
-WORKOS_CLIENT_ID=client_...
-```
-
-## Step 6: Verification
-
-### Rails
-
-```bash
-bundle show workos
-bundle exec rails routes | grep auth
-grep WORKOS .env
-```
-
-### Sinatra
-
-```bash
-bundle show workos
-ruby -c server.rb
-grep WORKOS .env
-```
-
-## Error Recovery
-
-### "uninitialized constant WorkOS"
-
-Gem not loaded. Verify `bundle show workos` succeeds. For Rails, ensure initializer exists. For Sinatra, ensure `require "workos"` is at top of server file.
-
-### "NoMethodError" on WorkOS methods
-
-SDK API may differ from this skill. Re-read the README (Step 1) and use exact method names.
-
-### Routes not working (Rails)
-
-Run `bundle exec rails routes | grep auth`. Verify routes are inside `Rails.application.routes.draw` block.
-
-### Session not persisting (Sinatra)
-
-Enable sessions: `enable :sessions` in server.rb, or use `rack-session` gem.
diff --git a/src/commands/install-skill.ts b/src/commands/install-skill.ts
index f475778..ca33401 100644
--- a/src/commands/install-skill.ts
+++ b/src/commands/install-skill.ts
@@ -3,7 +3,7 @@ import { join } from 'path';
import { existsSync } from 'fs';
import { mkdir, copyFile, readdir } from 'fs/promises';
import chalk from 'chalk';
-import { getPackageRoot } from '../utils/paths.js';
+import { getSkillsDir as getSkillsPackageDir } from '@workos/skills';
export interface AgentConfig {
name: string;
@@ -47,7 +47,7 @@ export interface InstallSkillOptions {
}
export function getSkillsDir(): string {
- return join(getPackageRoot(import.meta.url), 'skills');
+ return getSkillsPackageDir();
}
export async function discoverSkills(skillsDir: string): Promise {
diff --git a/src/integrations/dotnet/index.ts b/src/integrations/dotnet/index.ts
index 76b87ab..bc7a744 100644
--- a/src/integrations/dotnet/index.ts
+++ b/src/integrations/dotnet/index.ts
@@ -9,6 +9,7 @@ import { INSTALLER_INTERACTION_EVENT_NAME } from '../../lib/constants.js';
import { initializeAgent, runAgent } from '../../lib/agent-interface.js';
import { autoConfigureWorkOSEnvironment } from '../../lib/workos-management.js';
import { validateInstallation } from '../../lib/validation/index.js';
+import { getReference } from '@workos/skills';
export const config: FrameworkConfig = {
metadata: {
@@ -94,6 +95,7 @@ export async function run(options: InstallerOptions): Promise {
// Build prompt — credentials are passed via prompt context since .NET doesn't use .env.local
const skillName = config.metadata.skillName!;
const redirectUri = options.redirectUri || 'http://localhost:5000/auth/callback';
+ const refContent = await getReference(skillName);
const prompt = `You are integrating WorkOS AuthKit into this ASP.NET Core application.
@@ -106,24 +108,17 @@ export async function run(options: InstallerOptions): Promise {
## Environment
The following WorkOS credentials should be configured in appsettings.Development.json:
-- WORKOS_API_KEY: ${apiKey || '(not provided)'}
-- WORKOS_CLIENT_ID: ${clientId}
+- WORKOS_API_KEY: (configured)
+- WORKOS_CLIENT_ID: (configured)
- WORKOS_REDIRECT_URI: ${redirectUri}
-## Your Task
+## Integration Instructions
-Use the \`${skillName}\` skill to integrate WorkOS AuthKit into this application.
-
-The skill contains step-by-step instructions including:
-1. Fetching the SDK documentation
-2. Installing the WorkOS.net NuGet package
-3. Configuring DI registration
-4. Creating authentication endpoints
-5. Setting up appsettings configuration
+${refContent}
Report your progress using [STATUS] prefixes.
-Begin by invoking the ${skillName} skill.`;
+Begin integration now.`;
const agent = await initializeAgent(
{
diff --git a/src/integrations/elixir/index.ts b/src/integrations/elixir/index.ts
index ea55f34..34c97ea 100644
--- a/src/integrations/elixir/index.ts
+++ b/src/integrations/elixir/index.ts
@@ -8,6 +8,7 @@ import { INSTALLER_INTERACTION_EVENT_NAME } from '../../lib/constants.js';
import { getOrAskForWorkOSCredentials } from '../../utils/clack-utils.js';
import { initializeAgent, runAgent } from '../../lib/agent-interface.js';
import { writeEnvLocal } from '../../lib/env-writer.js';
+import { getReference } from '@workos/skills';
export const config: FrameworkConfig = {
metadata: {
@@ -96,7 +97,7 @@ export async function run(options: InstallerOptions): Promise {
}
// Build Elixir-specific prompt
- const integrationPrompt = buildElixirPrompt();
+ const integrationPrompt = await buildElixirPrompt();
// Initialize and run agent
const agent = await initializeAgent(
@@ -148,7 +149,9 @@ export async function run(options: InstallerOptions): Promise {
return lines.join('\n');
}
-function buildElixirPrompt(): string {
+async function buildElixirPrompt(): Promise {
+ const refContent = await getReference('workos-elixir');
+
return `You are integrating WorkOS AuthKit into this Elixir/Phoenix application.
## Project Context
@@ -165,19 +168,11 @@ The following environment variables have been configured in .env.local:
Note: For Elixir/Phoenix, these should be read via System.get_env() in config/runtime.exs rather than from .env.local directly.
-## Your Task
-
-Use the \`workos-elixir\` skill to integrate WorkOS AuthKit into this application.
+## Integration Instructions
-The skill contains step-by-step instructions including:
-1. Fetching the SDK documentation
-2. Validating the Phoenix project structure
-3. Installing the workos Hex package
-4. Configuring WorkOS in runtime.exs
-5. Creating auth controller and routes
-6. Verification with mix compile
+${refContent}
Report your progress using [STATUS] prefixes.
-Begin by invoking the workos-elixir skill.`;
+Begin integration now.`;
}
diff --git a/src/integrations/go/index.ts b/src/integrations/go/index.ts
index ce8d206..7776946 100644
--- a/src/integrations/go/index.ts
+++ b/src/integrations/go/index.ts
@@ -12,6 +12,7 @@ import { getOrAskForWorkOSCredentials } from '../../utils/clack-utils.js';
import { autoConfigureWorkOSEnvironment } from '../../lib/workos-management.js';
import { validateInstallation } from '../../lib/validation/index.js';
import { parseEnvFile } from '../../utils/env-parser.js';
+import { getReference } from '@workos/skills';
/** Default port for Go HTTP servers */
const GO_DEFAULT_PORT = 8080;
@@ -164,6 +165,7 @@ export async function run(options: InstallerOptions): Promise {
additionalLines.length > 0 ? '\n' + additionalLines.map((line) => `- ${line}`).join('\n') : '';
const skillName = config.metadata.skillName!;
+ const refContent = await getReference(skillName);
const integrationPrompt = `You are integrating WorkOS AuthKit into this ${config.metadata.name} application.
## Project Context
@@ -178,21 +180,13 @@ The following environment variables have been configured in .env:
- WORKOS_CLIENT_ID
- WORKOS_REDIRECT_URI
-## Your Task
+## Integration Instructions
-Use the \`${skillName}\` skill to integrate WorkOS AuthKit into this application.
-
-The skill contains step-by-step instructions including:
-1. Fetching the SDK documentation
-2. Installing the SDK
-3. Detecting Gin vs stdlib
-4. Creating authentication handlers
-5. Wiring handlers into the router
-6. Verification with go build and go vet
+${refContent}
Report your progress using [STATUS] prefixes.
-Begin by invoking the ${skillName} skill.`;
+Begin integration now.`;
// Initialize and run agent
const agent = await initializeAgent(
diff --git a/src/integrations/no-skill-tool.spec.ts b/src/integrations/no-skill-tool.spec.ts
new file mode 100644
index 0000000..19750d5
--- /dev/null
+++ b/src/integrations/no-skill-tool.spec.ts
@@ -0,0 +1,40 @@
+import { describe, it, expect } from 'vitest';
+import { readFileSync, readdirSync } from 'fs';
+import { join } from 'path';
+
+const integrationsDir = join(import.meta.dirname, '.');
+
+/**
+ * Guard against regressions where integration prompts reference the Skill tool.
+ * All integrations should inject reference content from @workos/skills directly,
+ * not tell the agent to invoke a skill.
+ */
+describe('no Skill tool references in integrations', () => {
+ const integrationDirs = readdirSync(integrationsDir, { withFileTypes: true })
+ .filter((d) => d.isDirectory())
+ .map((d) => d.name);
+
+ for (const dir of integrationDirs) {
+ const indexPath = join(integrationsDir, dir, 'index.ts');
+ let content: string;
+ try {
+ content = readFileSync(indexPath, 'utf-8');
+ } catch {
+ continue; // skip dirs without index.ts
+ }
+
+ it(`${dir}/index.ts should not tell agent to invoke a skill`, () => {
+ expect(content).not.toMatch(/Begin by invoking.*skill/i);
+ expect(content).not.toMatch(/Use the (?:`|\\`)\$\{.*\}(?:`|\\`) skill to integrate/i);
+ });
+ }
+});
+
+describe('allowedTools does not include Skill', () => {
+ it('agent-interface.ts should not list Skill in allowedTools', () => {
+ const content = readFileSync(join(import.meta.dirname, '..', 'lib', 'agent-interface.ts'), 'utf-8');
+ const match = content.match(/allowedTools:\s*\[([^\]]+)\]/);
+ expect(match).toBeTruthy();
+ expect(match![1]).not.toContain("'Skill'");
+ });
+});
diff --git a/src/integrations/python/index.ts b/src/integrations/python/index.ts
index 00ebe76..07a7cc4 100644
--- a/src/integrations/python/index.ts
+++ b/src/integrations/python/index.ts
@@ -7,6 +7,7 @@ import { enableDebugLogs } from '../../utils/debug.js';
import { analytics } from '../../utils/analytics.js';
import { INSTALLER_INTERACTION_EVENT_NAME } from '../../lib/constants.js';
import { parseEnvFile } from '../../utils/env-parser.js';
+import { getReference } from '@workos/skills';
/**
* Detect which Python package manager the project uses.
@@ -160,12 +161,13 @@ export const config: FrameworkConfig = {
/**
* Build the agent prompt for Python/Django integration.
*/
-function buildPythonPrompt(frameworkContext: Record): string {
+async function buildPythonPrompt(frameworkContext: Record): Promise {
const contextLines = ['- Framework: Python (Django)'];
if (frameworkContext.packageManager) contextLines.push(`- Package manager: ${frameworkContext.packageManager}`);
if (frameworkContext.installCommand) contextLines.push(`- Install command: ${frameworkContext.installCommand}`);
const skillName = config.metadata.skillName!;
+ const refContent = await getReference(skillName);
return `You are integrating WorkOS AuthKit into this Python/Django application.
@@ -179,21 +181,13 @@ The following environment variables have been configured in .env:
- WORKOS_API_KEY
- WORKOS_CLIENT_ID
-## Your Task
+## Integration Instructions
-Use the \`${skillName}\` skill to integrate WorkOS AuthKit into this application.
-
-The skill contains step-by-step instructions including:
-1. Fetching the SDK documentation
-2. Installing the SDK and python-dotenv
-3. Configuring Django settings
-4. Creating authentication views
-5. Setting up URL routing
-6. Adding authentication UI
+${refContent}
Report your progress using [STATUS] prefixes.
-Begin by invoking the ${skillName} skill.`;
+Begin integration now.`;
}
/**
@@ -234,7 +228,7 @@ export async function run(options: InstallerOptions): Promise {
});
// Build Python-specific prompt
- const prompt = buildPythonPrompt(frameworkContext);
+ const prompt = await buildPythonPrompt(frameworkContext);
// Initialize and run agent directly (bypass runAgentInstaller)
const { initializeAgent, runAgent } = await import('../../lib/agent-interface.js');
diff --git a/src/integrations/ruby/index.ts b/src/integrations/ruby/index.ts
index bbd4c70..a453ecd 100644
--- a/src/integrations/ruby/index.ts
+++ b/src/integrations/ruby/index.ts
@@ -8,6 +8,7 @@ import { INSTALLER_INTERACTION_EVENT_NAME } from '../../lib/constants.js';
import { initializeAgent, runAgent } from '../../lib/agent-interface.js';
import { getOrAskForWorkOSCredentials } from '../../utils/clack-utils.js';
import { autoConfigureWorkOSEnvironment } from '../../lib/workos-management.js';
+import { getReference } from '@workos/skills';
export const config: FrameworkConfig = {
metadata: {
@@ -77,7 +78,10 @@ export async function run(options: InstallerOptions): Promise {
});
// Get WorkOS credentials
- const { apiKey, clientId } = await getOrAskForWorkOSCredentials(options, config.environment.requiresApiKey);
+ const { apiKey, clientId: _clientId } = await getOrAskForWorkOSCredentials(
+ options,
+ config.environment.requiresApiKey,
+ );
// Auto-configure WorkOS environment (redirect URI, CORS, homepage) if not already done
const callerHandledConfig = Boolean(options.apiKey || options.clientId);
@@ -91,6 +95,7 @@ export async function run(options: InstallerOptions): Promise {
// Build prompt for the agent
const redirectUri = options.redirectUri || 'http://localhost:3000/auth/callback';
+ const refContent = await getReference('workos-ruby');
const prompt = `You are integrating WorkOS AuthKit into this Ruby on Rails application.
## Project Context
@@ -100,25 +105,18 @@ export async function run(options: InstallerOptions): Promise {
## Environment
-The following environment variables should be configured in a .env file:
-- WORKOS_API_KEY=${apiKey ? '(provided)' : '(not set)'}
-- WORKOS_CLIENT_ID=${clientId || '(not set)'}
+The following environment variables are needed (create a .env file if one does not exist):
+- WORKOS_API_KEY
+- WORKOS_CLIENT_ID
- WORKOS_REDIRECT_URI=${redirectUri}
-## Your Task
-
-Use the \`workos-ruby\` skill to integrate WorkOS AuthKit into this application.
+## Integration Instructions
-The skill contains step-by-step instructions including:
-1. Fetching the SDK documentation
-2. Installing the WorkOS Ruby gem
-3. Creating the WorkOS initializer
-4. Creating the AuthController with login, callback, and logout
-5. Adding authentication routes
+${refContent}
Report your progress using [STATUS] prefixes.
-Begin by invoking the workos-ruby skill.`;
+Begin integration now.`;
// Initialize and run agent
const agent = await initializeAgent(
diff --git a/src/lib/agent-interface.ts b/src/lib/agent-interface.ts
index 557438c..29b8d75 100644
--- a/src/lib/agent-interface.ts
+++ b/src/lib/agent-interface.ts
@@ -3,7 +3,8 @@
* Uses Claude Agent SDK directly with WorkOS MCP server
*/
-import { getPackageRoot } from '../utils/paths.js';
+import { dirname } from 'path';
+import { getSkillsDir as getSkillsPackageDir } from '@workos/skills';
import { debug, logInfo, logWarn, logError, initLogFile, getLogFilePath } from '../utils/debug.js';
import type { InstallerOptions } from '../utils/types.js';
import { analytics } from '../utils/analytics.js';
@@ -451,7 +452,7 @@ export async function initializeAgent(config: AgentConfig, options: InstallerOpt
},
},
model: getConfig().model,
- allowedTools: ['Skill', 'Read', 'Write', 'Edit', 'Bash', 'Glob', 'Grep', 'WebFetch'],
+ allowedTools: ['Read', 'Write', 'Edit', 'Bash', 'Glob', 'Grep', 'WebFetch'],
sdkEnv,
};
@@ -575,8 +576,9 @@ export async function runAgent(
await currentTurnDone;
};
- // Load plugin with bundled skills
- const pluginPath = getPackageRoot(import.meta.url);
+ // Load plugin from @workos/skills package
+
+ const pluginPath = dirname(getSkillsPackageDir());
logInfo('Loading plugin from:', pluginPath);
const response = query({
diff --git a/src/lib/agent-runner.ts b/src/lib/agent-runner.ts
index b554d73..be4dad6 100644
--- a/src/lib/agent-runner.ts
+++ b/src/lib/agent-runner.ts
@@ -1,3 +1,4 @@
+import { getReference } from '@workos/skills';
import { SPINNER_MESSAGE, type FrameworkConfig } from './framework-config.js';
import { validateInstallation, quickCheckValidateAndFormat } from './validation/index.js';
import type { InstallerOptions } from '../utils/types.js';
@@ -93,7 +94,7 @@ export async function runAgentInstaller(config: FrameworkConfig, options: Instal
});
// Build integration prompt (credentials are already in .env.local)
- const integrationPrompt = buildIntegrationPrompt(
+ const integrationPrompt = await buildIntegrationPrompt(
config,
{
frameworkVersion: frameworkVersion || 'latest',
@@ -205,17 +206,17 @@ export async function runAgentInstaller(config: FrameworkConfig, options: Instal
/**
* Build the integration prompt for the agent.
- * Uses skill-based approach where agent invokes framework-specific skill.
+ * Reads reference content from @workos/skills and injects it directly into the prompt.
* Note: Credentials are pre-written to .env.local, so not included in prompt.
*/
-function buildIntegrationPrompt(
+async function buildIntegrationPrompt(
config: FrameworkConfig,
context: {
frameworkVersion: string;
typescript: boolean;
},
frameworkContext: Record,
-): string {
+): Promise {
const additionalLines = config.prompts.getAdditionalContextLines
? config.prompts.getAdditionalContextLines(frameworkContext)
: [];
@@ -228,9 +229,19 @@ function buildIntegrationPrompt(
throw new Error(`Framework ${config.metadata.name} missing skillName in config`);
}
- // Next.js uses NEXT_PUBLIC_ prefix for redirect URI
- const redirectUriEnvVar =
- config.metadata.integration === 'nextjs' ? 'NEXT_PUBLIC_WORKOS_REDIRECT_URI' : 'WORKOS_REDIRECT_URI';
+ // Read reference content from @workos/skills package
+ // Load both the base template (task structure, decision trees, error recovery)
+ // and the framework-specific reference (step-by-step instructions)
+ const [baseContent, refContent] = await Promise.all([getReference('workos-authkit-base'), getReference(skillName)]);
+
+ // Build env var list dynamically based on what was actually configured
+ const envVars = [
+ ...(config.environment.requiresApiKey ? ['WORKOS_API_KEY'] : []),
+ 'WORKOS_CLIENT_ID',
+ config.metadata.integration === 'nextjs' ? 'NEXT_PUBLIC_WORKOS_REDIRECT_URI' : 'WORKOS_REDIRECT_URI',
+ 'WORKOS_COOKIE_PASSWORD',
+ ];
+ const envVarList = envVars.map((v) => `- ${v}`).join('\n');
return `You are integrating WorkOS AuthKit into this ${config.metadata.name} application.
@@ -242,25 +253,19 @@ function buildIntegrationPrompt(
## Environment
The following environment variables have been configured in .env.local:
-- WORKOS_API_KEY
-- WORKOS_CLIENT_ID
-- ${redirectUriEnvVar}
-- WORKOS_COOKIE_PASSWORD
+${envVarList}
+
+## General Guidelines
-## Your Task
+${baseContent}
-Use the \`${skillName}\` skill to integrate WorkOS AuthKit into this application.
+## Integration Instructions
-The skill contains step-by-step instructions including:
-1. Fetching the SDK documentation
-2. Installing the SDK
-3. Creating the callback route
-4. Setting up middleware/auth handling
-5. Adding authentication UI to the home page
+${refContent}
Report your progress using [STATUS] prefixes.
-Begin by invoking the ${skillName} skill.`;
+Begin integration now.`;
}
function buildCompletionSummary(config: FrameworkConfig, changes: string[], nextSteps: string[]): string {