diff --git a/.agents/skills/clerk-backend-api/SKILL.md b/.agents/skills/clerk-backend-api/SKILL.md
new file mode 100644
index 0000000..5a3bbfc
--- /dev/null
+++ b/.agents/skills/clerk-backend-api/SKILL.md
@@ -0,0 +1,426 @@
+---
+name: clerk-backend-api
+description: "Clerk Backend REST API explorer and executor. Browse tags, inspect endpoint schemas, and execute authenticated requests. Use when listing users, managing organizations, or calling any Clerk API endpoint."
+allowed-tools: Bash, Read, Grep, Skill, WebFetch
+license: MIT
+compatibility: Requires CLERK_SECRET_KEY (sk_*) for Backend API calls.
+---
+
+## Options context
+
+User Prompt: $ARGUMENTS
+
+## CRITICAL: Mandatory checks before EVERY write request
+
+Before ANY POST / PATCH / PUT / DELETE, you MUST do ALL of the following in your response:
+
+1. **Check CLERK_SECRET_KEY** — verify it is set:
+ ```bash
+ echo $CLERK_SECRET_KEY | head -c 10
+ ```
+ If empty, stop and ask the user. Do not proceed without a valid key.
+
+2. **Check CLERK_BAPI_SCOPES** — run:
+ ```bash
+ echo $CLERK_BAPI_SCOPES
+ ```
+ Inspect the output. If scopes are missing or do not include the required write permission, tell the user: *"This is a write operation and your current scopes may not allow it. Rerun with --admin to bypass?"* Do NOT attempt the request and fail — ask first.
+
+3. **For DELETE requests:** warn explicitly that the action is **IRREVERSIBLE** and list exactly what data will be permanently destroyed (user record, all sessions, all memberships, all associated data). Require explicit confirmation before proceeding. This warning is MANDATORY — never skip it.
+
+4. **For metadata operations:** always explain which metadata type is being used and why (see Metadata types section below).
+
+---
+
+## FAST PATH: Common operations (use directly, no spec fetching needed)
+
+For the operations below, skip spec fetching and execute immediately using these exact templates. Substitute `$CLERK_SECRET_KEY`, `$USER_ID`, `$ORG_ID`, `$EMAIL` as needed from the user's context.
+
+### Create organization + invite member (two-step)
+
+```bash
+# Step 1 — Create organization
+ORG=$(curl -s -X POST "https://api.clerk.com/v1/organizations" \
+ -H "Authorization: Bearer $CLERK_SECRET_KEY" \
+ -H "Content-Type: application/json" \
+ -d "{\"name\": \"Acme Corp\", \"created_by\": \"$USER_ID\"}")
+echo "$ORG" | python3 -c "import sys,json; d=json.load(sys.stdin); print(json.dumps(d, indent=2))"
+
+# Step 2 — Extract org ID
+ORG_ID=$(echo "$ORG" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")
+
+# Step 3 — Invite member with role
+curl -s -X POST "https://api.clerk.com/v1/organizations/${ORG_ID}/invitations" \
+ -H "Authorization: Bearer $CLERK_SECRET_KEY" \
+ -H "Content-Type: application/json" \
+ -d "{\"email_address\": \"user@example.com\", \"role\": \"org:admin\"}" \
+ | python3 -c "import sys,json; print(json.dumps(json.load(sys.stdin), indent=2))"
+```
+
+**Roles:** use `"org:admin"` or `"org:member"` (always prefix with `org:`).
+
+### SDK equivalent (for Next.js / TypeScript projects with `@clerk/nextjs` or `@clerk/backend`)
+
+```typescript
+import { clerkClient } from '@clerk/nextjs/server'
+// OR if using @clerk/backend directly:
+// import { createClerkClient } from '@clerk/backend'
+// const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY })
+
+// Step 1: Create organization
+const org = await clerkClient.organizations.createOrganization({
+ name: 'Acme Corp',
+ createdBy: userId, // required — the ID of the user creating the org
+})
+
+// Step 2: Invite member to the org
+const invitation = await clerkClient.organizations.createOrganizationInvitation({
+ organizationId: org.id,
+ emailAddress: 'user@example.com',
+ role: 'org:admin', // or 'org:member'
+})
+```
+
+### Update user metadata
+
+**Always explain the three metadata types before asking which to use:**
+
+| Type | Field | Readable by | Writable by | Use for |
+|------|-------|-------------|-------------|---------|
+| Public | `public_metadata` | Client + Server | **Server only** | Plan tier, roles, feature flags the frontend reads |
+| Private | `private_metadata` | **Server only** | **Server only** | Stripe IDs, compliance flags, internal identifiers |
+| Unsafe | `unsafe_metadata` | Client + Server | Client + Server | Ephemeral UI state, onboarding steps (client-writable — avoid sensitive data) |
+
+**For `plan: 'pro'` and `onboarded: true` — use `public_metadata`** (frontend-readable, server-writable):
+
+```bash
+curl -s -X PATCH "https://api.clerk.com/v1/users/${USER_ID}" \
+ -H "Authorization: Bearer $CLERK_SECRET_KEY" \
+ -H "Content-Type: application/json" \
+ -d '{"public_metadata": {"plan": "pro", "onboarded": true}}' \
+ | python3 -c "import sys,json; d=json.load(sys.stdin); print(f'Updated user {d[\"id\"]}: public_metadata={d.get(\"public_metadata\")}')"
+```
+
+**SDK equivalent:**
+
+```typescript
+import { clerkClient } from '@clerk/nextjs/server'
+// OR: import { createClerkClient } from '@clerk/backend'
+
+await clerkClient.users.updateUser(userId, {
+ publicMetadata: { plan: 'pro', onboarded: true }, // readable by client, writable server-only
+ // privateMetadata: { stripeId: 'cus_xxx' }, // server-only read AND write
+ // unsafeMetadata: { step: 'welcome' }, // client-writable, avoid sensitive data
+})
+```
+
+**Note:** REST API uses `snake_case` (`public_metadata`). SDK uses `camelCase` (`publicMetadata`).
+
+### List users (last 7 days)
+
+```bash
+curl -s "https://api.clerk.com/v1/users?limit=100&offset=0&order_by=-created_at&created_at=gt:$(date -d '7 days ago' +%s 2>/dev/null || date -v-7d +%s)000" \
+ -H "Authorization: Bearer $CLERK_SECRET_KEY" \
+ | python3 -c "
+import sys, json
+data = json.load(sys.stdin)
+if isinstance(data, list):
+ print(f'Found {len(data)} users:')
+ for u in data:
+ print(f' {u[\"id\"]}: {u.get(\"email_addresses\", [{}])[0].get(\"email_address\", \"no email\")}')
+else:
+ print(json.dumps(data, indent=2))
+"
+```
+
+### Delete user (confirm required)
+
+```bash
+# ONLY run after explicit user confirmation
+curl -s -X DELETE "https://api.clerk.com/v1/users/${USER_ID}" \
+ -H "Authorization: Bearer $CLERK_SECRET_KEY" \
+ | python3 -c "import sys,json; d=json.load(sys.stdin); print(f'Deleted: {d}')"
+```
+
+---
+
+## Clerk Backend API — Full Endpoint Reference
+
+Base URL: `https://api.clerk.com/v1`
+Auth: `Authorization: Bearer $CLERK_SECRET_KEY` on every request.
+
+### Users
+
+**List users**
+```
+GET /v1/users
+Query params: limit (max 500, default 10), offset, order_by (+/-created_at, +/-updated_at, +/-email_address, +/-web3wallet, +/-first_name, +/-last_name, +/-phone_number, +/-username, +/-last_active_at, +/-last_sign_in_at), email_address[], phone_number[], username[], web3wallet[], user_id[], query, created_at (ISO 8601 range: gt:TIMESTAMP or lt:TIMESTAMP in Unix ms)
+Returns: array of User objects
+```
+
+**Get user**
+```
+GET /v1/users/{user_id}
+Returns: User object
+```
+
+**Update user**
+```
+PATCH /v1/users/{user_id}
+Body (JSON, snake_case): { public_metadata, private_metadata, unsafe_metadata, first_name, last_name, username, ... }
+```
+
+**Delete user — IRREVERSIBLE**
+```
+DELETE /v1/users/{user_id}
+Destroys: user record, all sessions, all memberships, all associated data
+Returns: { id, object, deleted: true }
+```
+Always warn the user this is permanent and confirm before proceeding.
+
+### Organizations
+
+**Create organization**
+```
+POST /v1/organizations
+Body: { name: string, created_by: string (user_id), public_metadata?, private_metadata?, max_allowed_memberships? }
+Returns: Organization object with { id, name, slug, ... }
+```
+
+**List organizations**
+```
+GET /v1/organizations
+Query params: limit, offset, query, order_by
+```
+
+**Invite member**
+```
+POST /v1/organizations/{organization_id}/invitations
+Body: { email_address: string, role: string ("org:admin" or "org:member"), public_metadata?, private_metadata? }
+Returns: OrganizationInvitation object
+```
+
+---
+
+## How to execute requests
+
+**ALWAYS execute requests with direct `curl` commands.** Use the spec-extraction scripts (`api-specs-context.sh`, `extract-tags.js`, `extract-endpoint-detail.sh`) to discover endpoints, but make actual API calls with `curl`. Do NOT use `scripts/execute-request.sh` — it's a local dev helper, not for agent use.
+
+Template for GET requests:
+```bash
+curl -s "https://api.clerk.com/v1${PATH}${QUERY_STRING}" \
+ -H "Authorization: Bearer $CLERK_SECRET_KEY"
+```
+
+Template for POST/PATCH requests:
+```bash
+curl -s -X ${METHOD} "https://api.clerk.com/v1${PATH}" \
+ -H "Authorization: Bearer $CLERK_SECRET_KEY" \
+ -H "Content-Type: application/json" \
+ -d '${BODY_JSON}'
+```
+
+Template for DELETE requests:
+```bash
+curl -s -X DELETE "https://api.clerk.com/v1${PATH}" \
+ -H "Authorization: Bearer $CLERK_SECRET_KEY"
+```
+
+**After getting the response:** Parse and display it clearly. Use `python3 -c "import sys,json; data=json.load(sys.stdin); print(json.dumps(data, indent=2))"` to pretty-print JSON. Extract key fields (id, email, name, etc.) and summarize them for the user.
+
+---
+
+## API specs context
+
+Before doing anything outside the FAST PATH, fetch the available spec versions and tags by running:
+```bash
+bash scripts/api-specs-context.sh
+```
+
+Use the output to determine the latest version and available tags.
+
+**Caching:** If you already fetched the spec context earlier in this conversation, do NOT fetch it again. Reuse the version and tags from the previous call.
+
+---
+
+## Rules
+
+- For common operations (list users, create org, invite, update metadata, delete user): use the FAST PATH above — do NOT fetch specs first.
+- Always disregard endpoints/schemas related to `platform`.
+- Always confirm before performing write requests (POST/PUT/PATCH/DELETE).
+- For DELETE operations, always warn the user that the action is **irreversible** and mention what data will be lost (user record, sessions, memberships). This warning is MANDATORY — never skip it.
+- For write operations (POST/PUT/PATCH/DELETE), check `CLERK_BAPI_SCOPES` before attempting the request. If missing or insufficient, ask the user upfront. Do NOT attempt and fail — ask before executing. This check is MANDATORY.
+- For metadata operations, always explain all three types (public, private, unsafe) and recommend the appropriate one.
+- Pagination: always use `limit` + `offset` and mention that results may be paginated for large datasets.
+- Use direct curl commands for all API calls — never use `scripts/execute-request.sh`.
+
+---
+
+## Rate Limits & Gotchas
+
+### Rate Limits
+
+| Environment | Limit |
+|-------------|-------|
+| Production | 1,000 requests / 10 seconds |
+| Development | 100 requests / 10 seconds |
+| Single invitations | 100 / hour |
+| Bulk invitations | 25 / hour |
+| Org invitations | 250 / hour |
+| Frontend API sign-in creation | 5 / 10 seconds |
+| Frontend API sign-in attempts | 3 / 10 seconds |
+| List users max per page | 500 |
+
+`currentUser()` makes a real API call that counts against rate limits. Use `auth()` for just the session claims — it reads from the token without an API call.
+
+### Metadata Overwrites (Not Merges)
+
+`updateUser({ publicMetadata: { role: 'admin' } })` REPLACES all public metadata, not merges. To add a field without losing existing data: read first, spread, then write.
+
+Wrong:
+```typescript
+await clerkClient.users.updateUser(userId, { publicMetadata: { newField: 'value' } })
+```
+This DELETES all other `publicMetadata` fields.
+
+Right:
+```typescript
+const user = await clerkClient.users.getUser(userId)
+await clerkClient.users.updateUser(userId, {
+ publicMetadata: { ...user.publicMetadata, newField: 'value' },
+})
+```
+
+---
+
+## Modes
+
+Determine the active mode based on the user prompt in [Options context](#options-context):
+
+| Mode | Trigger | Behavior |
+|------|---------|----------|
+| `help` | Prompt is empty, or contains only `help` / `-h` / `--help` | Print usage examples (step 0) |
+| `browse` | Prompt is `tags`, or a tag name (e.g. `Users`) | List all tags or endpoints for a tag |
+| `execute` | Specific endpoint (e.g. `GET /users`) or natural language action (e.g. "get user john_doe") | Look up endpoint, execute request |
+| `detail` | Endpoint + `help` / `-h` / `--help` (e.g. `GET /users help`) | Show endpoint schema, don't execute |
+
+---
+
+## Your Task
+
+Use the **LATEST VERSION** from [API specs context](#api-specs-context) by default. If the user specifies a different version (e.g. `--version 2024-10-01`), use that version instead.
+
+Determine the active mode, then follow the applicable steps below.
+
+---
+
+### 0. Print usage
+
+**Modes:** `help` only — **Skip** for `browse`, `execute`, and `detail`.
+
+Print the following examples to the user verbatim:
+
+```
+Browse
+ /clerk-backend-api tags — list all tags
+ /clerk-backend-api Users — browse endpoints for the Users tag
+ /clerk-backend-api Users version 2025-11-10.yml — browse using a different version
+
+Execute
+ /clerk-backend-api GET /users — fetch all users
+ /clerk-backend-api get user john_doe — natural language works too
+ /clerk-backend-api POST /invitations — create an invitation
+
+Inspect
+ /clerk-backend-api GET /users help — show endpoint schema without executing
+ /clerk-backend-api POST /invitations -h — view request/response details
+
+Options
+ --admin — bypass scope restrictions for write/delete
+ --version [date], version [date] — use a specific spec version
+ --help, -h, help — inspect endpoint instead of executing
+```
+
+Stop here.
+
+---
+
+### 1. Fetch tags
+
+**Modes:** `browse` (when prompt is `tags` or no tag specified) — **Skip** for `help`, `execute`, and `detail`.
+
+If using a non-latest version, fetch tags for that version:
+```bash
+curl -s https://raw.githubusercontent.com/clerk/openapi-specs/main/bapi/${version_name} | node scripts/extract-tags.js
+```
+Otherwise, use the **TAGS** already in [API specs context](#api-specs-context).
+
+Share tags in a table and prompt the user to select a query.
+
+---
+
+### 2. Fetch tag endpoints
+
+**Modes:** `browse` (when a tag name is provided) — **Skip** for `help`, `execute`, and `detail`.
+
+Fetch all endpoints for the identified tag:
+```bash
+curl -s https://raw.githubusercontent.com/clerk/openapi-specs/main/bapi/${version_name} | bash scripts/extract-tag-endpoints.sh "${tag_name}"
+```
+
+Share the results (endpoints, schemas, parameters) with the user.
+
+---
+
+### 3. Fetch endpoint detail
+
+**Modes:** `execute`, `detail` — **Skip** for `help` and `browse`.
+
+For natural language prompts in `execute` mode, first check if the operation matches a FAST PATH entry above. If it does, skip this step and proceed directly to step 4 using the FAST PATH template.
+
+For other endpoints, identify the matching endpoint by searching the tags in context. Fetch tag endpoints if needed to resolve the exact path and method.
+
+Extract the full endpoint definition:
+```bash
+curl -s https://raw.githubusercontent.com/clerk/openapi-specs/main/bapi/${version_name} | bash scripts/extract-endpoint-detail.sh "${path}" "${method}"
+```
+- `${path}` — e.g. `/users/{user_id}`
+- `${method}` — lowercase, e.g. `get`
+
+**`detail` mode:** Share the endpoint definition and schemas with the user. Stop here.
+
+**`execute` mode:** Continue to step 4.
+
+---
+
+### 4. Execute request
+
+**Modes:** `execute` only.
+
+1. Run the **mandatory checks** from the CRITICAL section above.
+2. Identify required and optional parameters from the spec (step 3) or FAST PATH.
+3. Ask the user for any required path/query/body parameters that weren't provided.
+4. Build and execute a **direct curl command** (see How to execute requests above). Do NOT use `scripts/execute-request.sh`.
+5. Parse the JSON response and display it clearly. Extract and summarize key fields for the user.
+
+**Example — list users and parse response:**
+```bash
+RESPONSE=$(curl -s "https://api.clerk.com/v1/users?limit=10" \
+ -H "Authorization: Bearer $CLERK_SECRET_KEY")
+echo "$RESPONSE" | python3 -c "
+import sys, json
+data = json.load(sys.stdin)
+if isinstance(data, list):
+ print(f'Found {len(data)} users:')
+ for u in data:
+ print(f' {u[\"id\"]}: {u.get(\"email_addresses\", [{}])[0].get(\"email_address\", \"no email\")}')
+else:
+ print(json.dumps(data, indent=2))
+"
+```
+
+## See Also
+
+- `clerk-setup` - Initial Clerk install
+- `clerk-orgs` - Manage organizations via API
+- `clerk-webhooks` - Real-time event sync
diff --git a/.agents/skills/clerk-backend-api/evals/evals.json b/.agents/skills/clerk-backend-api/evals/evals.json
new file mode 100644
index 0000000..9013dd9
--- /dev/null
+++ b/.agents/skills/clerk-backend-api/evals/evals.json
@@ -0,0 +1,87 @@
+{
+ "skill_name": "clerk-backend-api",
+ "evals": [
+ {
+ "id": 1,
+ "prompt": "i need to get all users who signed up in the last 7 days from clerk's backend API. show me how",
+ "expected_output": "REST API call to GET /v1/users with date filter, Bearer token auth using CLERK_SECRET_KEY, response parsing and pagination handling",
+ "scaffold": "nextjs-basic-auth",
+ "files": [],
+ "expectations": [
+ "Uses GET /v1/users endpoint",
+ "Includes a created_at or date-based filter query parameter to narrow to last 7 days",
+ "Sets CLERK_SECRET_KEY as Bearer token in the Authorization header",
+ "Parses the JSON response array of user objects",
+ "Handles or mentions pagination via limit and offset parameters"
+ ]
+ },
+ {
+ "id": 2,
+ "prompt": "use the clerk backend api to create a new organization called 'Acme Corp' and invite user@example.com as an admin",
+ "expected_output": "Two API calls: POST /v1/organizations to create org, then POST /v1/organizations/{id}/invitations to invite with admin role",
+ "scaffold": "nextjs-basic-auth",
+ "files": [],
+ "expectations": [
+ "Uses POST /v1/organizations to create the organization with name 'Acme Corp'",
+ "Uses POST /v1/organizations/{id}/invitations to send the invitation",
+ "Sets the role to admin (or org:admin) in the invitation payload",
+ "Authenticates both API calls using CLERK_SECRET_KEY in the Authorization header",
+ "Extracts the organization ID from the first response and uses it in the invitation request"
+ ]
+ },
+ {
+ "id": 3,
+ "prompt": "i need to set custom metadata on a user via clerk's backend api. set their plan to 'pro' and onboarded to true",
+ "expected_output": "PATCH /v1/users/{user_id} with public_metadata or private_metadata body, explanation of metadata types and when to use each",
+ "scaffold": "nextjs-basic-auth",
+ "files": [],
+ "expectations": [
+ "Uses PATCH /v1/users/{user_id} endpoint",
+ "Sets the metadata in the correct field: public_metadata, private_metadata, or unsafe_metadata",
+ "Explains the difference between metadata types (client-readable vs server-only vs client-writable)",
+ "Includes a properly formed JSON body with the plan and onboarded fields",
+ "Mentions checking write permissions before executing the update"
+ ]
+ },
+ {
+ "id": 4,
+ "prompt": "remove a user with id user_abc123 from our clerk instance using the backend api",
+ "expected_output": "DELETE /v1/users/{user_id} call with warning about irreversibility, CLERK_BAPI_SCOPES check, and CLERK_SECRET_KEY auth",
+ "scaffold": "nextjs-basic-auth",
+ "files": [],
+ "expectations": [
+ "Uses DELETE /v1/users/{user_id} endpoint with the correct user ID",
+ "Warns that the action is destructive and irreversible",
+ "Requires or recommends explicit confirmation before executing the delete",
+ "Includes CLERK_SECRET_KEY as Bearer token in the Authorization header",
+ "Mentions implications such as loss of user data, sessions, and associated records"
+ ]
+ },
+ {
+ "id": 5,
+ "prompt": "i'm updating user metadata to add a 'plan' field but it keeps deleting the existing 'role' field. what am i doing wrong?",
+ "expected_output": "Metadata updates overwrite not merge. Read existing metadata first, spread it, then write back.",
+ "scaffold": "nextjs-basic-auth",
+ "expectations": [
+ "Explains that updateUser publicMetadata replaces all existing metadata, not merges",
+ "Shows reading the existing user first with getUser(userId)",
+ "Spreads existing metadata before adding new fields ({ ...user.publicMetadata, plan: 'pro' })",
+ "Calls updateUser with the merged metadata object",
+ "Warns that this applies to publicMetadata, privateMetadata, and unsafeMetadata equally"
+ ]
+ },
+ {
+ "id": 6,
+ "prompt": "my clerk backend api calls are failing with 429 errors in development. what are the rate limits?",
+ "expected_output": "Development has 100 req/10s limit (vs 1000/10s in production). Batch operations or reduce call frequency.",
+ "scaffold": "nextjs-basic-auth",
+ "expectations": [
+ "States the development rate limit (100 requests per 10 seconds)",
+ "States the production rate limit (1000 requests per 10 seconds)",
+ "Suggests batching operations or reducing call frequency",
+ "Mentions that currentUser() counts as an API call against the limit",
+ "Recommends using auth() instead of currentUser() when only session claims are needed"
+ ]
+ }
+ ]
+}
diff --git a/.agents/skills/clerk-backend-api/scripts/api-specs-context.sh b/.agents/skills/clerk-backend-api/scripts/api-specs-context.sh
new file mode 100644
index 0000000..7015d1b
--- /dev/null
+++ b/.agents/skills/clerk-backend-api/scripts/api-specs-context.sh
@@ -0,0 +1,30 @@
+#!/usr/bin/env bash
+
+# Fetches all available BAPI spec versions, determines the latest,
+# and extracts tags from it. Output is used as skill context.
+
+set -euo pipefail
+
+API_URL="https://api.github.com/repos/clerk/openapi-specs/contents/bapi"
+RAW_BASE="https://raw.githubusercontent.com/clerk/openapi-specs/main/bapi"
+
+# Fetch version list, parse dates, sort, pick latest
+versions=$(curl -s "$API_URL" | node -e "
+ let d='';
+ process.stdin.on('data',c=>d+=c);
+ process.stdin.on('end',()=>{
+ const items = JSON.parse(d)
+ .map(i=>i.name)
+ .filter(n=>/^\d{4}-\d{2}-\d{2}\.yml$/.test(n))
+ .sort();
+ items.forEach(n=>console.log(n));
+ });
+")
+
+latest=$(echo "$versions" | tail -1)
+
+echo "AVAILABLE VERSIONS: $(echo "$versions" | tr '\n' ' ')"
+echo "LATEST VERSION: $latest"
+echo ""
+echo "TAGS:"
+curl -s "${RAW_BASE}/${latest}" | node "$(dirname "$0")/extract-tags.js"
diff --git a/.agents/skills/clerk-backend-api/scripts/execute-request.sh b/.agents/skills/clerk-backend-api/scripts/execute-request.sh
new file mode 100644
index 0000000..26dcb43
--- /dev/null
+++ b/.agents/skills/clerk-backend-api/scripts/execute-request.sh
@@ -0,0 +1,88 @@
+#!/usr/bin/env bash
+
+# Execute a Clerk Backend API request with scope enforcement.
+#
+# Usage: bash execute-request.sh [--admin] [BODY]
+#
+# Scope enforcement:
+# GET — always allowed
+# POST, PUT, PATCH — requires CLERK_BAPI_SCOPES="write" or --admin flag
+# DELETE — requires CLERK_BAPI_SCOPES="write,delete" or --admin flag
+
+set -euo pipefail
+
+# Walk up from $PWD to find .env/.env.local (mirrors Clerk CLI behavior).
+# Stops at the first directory that provides CLERK_SECRET_KEY.
+_dir="$PWD"
+while true; do
+ for _envfile in "$_dir/.env" "$_dir/.env.local"; do
+ if [[ -f "$_envfile" ]]; then
+ set -a
+ source "$_envfile"
+ set +a
+ fi
+ done
+ [[ -n "${CLERK_SECRET_KEY:-}" ]] && break
+ _parent="$(dirname "$_dir")"
+ [[ "$_parent" == "$_dir" ]] && break
+ _dir="$_parent"
+done
+unset _dir _parent _envfile
+
+# Parse --admin flag
+ADMIN=false
+if [[ "${1:-}" == "--admin" ]]; then
+ ADMIN=true
+ shift
+fi
+
+METHOD="${1:?Usage: execute-request.sh [--admin] [BODY]}"
+PATH_ARG="${2:?Usage: execute-request.sh [--admin] [BODY]}"
+BODY="${3:-}"
+
+METHOD_UPPER=$(echo "$METHOD" | tr '[:lower:]' '[:upper:]')
+SCOPES="${CLERK_BAPI_SCOPES:-}"
+
+# Scope check
+if [[ "$ADMIN" == false ]]; then
+ case "$METHOD_UPPER" in
+ GET)
+ ;; # always allowed
+ POST|PUT|PATCH)
+ if [[ "$SCOPES" != *"write"* ]]; then
+ echo "ERROR: $METHOD_UPPER requests require CLERK_BAPI_SCOPES=\"write\" or --admin flag." >&2
+ echo "Current CLERK_BAPI_SCOPES: \"$SCOPES\"" >&2
+ exit 1
+ fi
+ ;;
+ DELETE)
+ if [[ "$SCOPES" != *"write"* ]] || [[ "$SCOPES" != *"delete"* ]]; then
+ echo "ERROR: DELETE requests require CLERK_BAPI_SCOPES=\"write,delete\" or --admin flag." >&2
+ echo "Current CLERK_BAPI_SCOPES: \"$SCOPES\"" >&2
+ exit 1
+ fi
+ ;;
+ *)
+ echo "ERROR: Unknown HTTP method: $METHOD_UPPER" >&2
+ exit 1
+ ;;
+ esac
+fi
+
+# Base URL: use CLERK_REST_API_URL if set, otherwise default to production
+BASE_URL="${CLERK_REST_API_URL:-https://api.clerk.com}"
+
+# Build curl command
+CURL_ARGS=(
+ -s
+ -X "$METHOD_UPPER"
+ "${BASE_URL}/v1${PATH_ARG}"
+ -H "Authorization: Bearer ${CLERK_SECRET_KEY:?CLERK_SECRET_KEY is not set}"
+ -H "Content-Type: application/json"
+)
+
+if [[ -n "$BODY" ]]; then
+ CURL_ARGS+=(-d "$BODY")
+fi
+
+curl "${CURL_ARGS[@]}"
diff --git a/.agents/skills/clerk-backend-api/scripts/extract-endpoint-detail.sh b/.agents/skills/clerk-backend-api/scripts/extract-endpoint-detail.sh
new file mode 100644
index 0000000..19eb632
--- /dev/null
+++ b/.agents/skills/clerk-backend-api/scripts/extract-endpoint-detail.sh
@@ -0,0 +1,165 @@
+#!/usr/bin/env bash
+# extract-endpoint-detail.sh
+#
+# Extracts full details for a specific endpoint from an OpenAPI YAML spec (stdin),
+# including parameters, request body, responses, and all referenced component schemas.
+#
+# Usage:
+# curl -s | bash extract-endpoint-detail.sh "/users/{user_id}/billing/subscription" "get"
+
+set -euo pipefail
+
+ENDPOINT="${1:?Usage: extract-endpoint-detail.sh }"
+METHOD="${2:?Usage: extract-endpoint-detail.sh }"
+TMPDIR_WORK=$(mktemp -d)
+trap 'rm -rf "$TMPDIR_WORK"' EXIT
+
+SPEC="$TMPDIR_WORK/spec.yml"
+cat > "$SPEC"
+
+node - "$ENDPOINT" "$METHOD" "$SPEC" <<'SCRIPT'
+const fs = require("fs");
+const endpoint = process.argv[2];
+const method = process.argv[3].toLowerCase();
+const specFile = process.argv[4];
+const lines = fs.readFileSync(specFile, "utf8").split("\n");
+
+const httpMethods = ["get", "post", "put", "patch", "delete", "options", "head"];
+
+// Locate paths: and components: sections
+let pathsStart = -1, pathsEnd = -1, componentsStart = -1;
+for (let i = 0; i < lines.length; i++) {
+ if (/^paths:\s*$/.test(lines[i])) pathsStart = i;
+ else if (pathsStart >= 0 && pathsEnd < 0 && /^\S/.test(lines[i]) && i > pathsStart) pathsEnd = i;
+ if (/^components:\s*$/.test(lines[i])) componentsStart = i;
+}
+if (pathsEnd < 0) pathsEnd = lines.length;
+
+// Find the target path + method block
+let targetStart = -1, targetEnd = -1;
+let currentPath = null;
+
+for (let i = pathsStart + 1; i < pathsEnd; i++) {
+ const line = lines[i];
+
+ // Path line: exactly 2 spaces + /
+ if (/^ {2}\/\S/.test(line)) {
+ currentPath = line.trim().replace(/:$/, "");
+ continue;
+ }
+
+ // Method line: exactly 4 spaces + method name
+ const methodMatch = line.match(/^ {4}(\w+):\s*$/);
+ if (methodMatch && httpMethods.includes(methodMatch[1])) {
+ if (currentPath === endpoint && methodMatch[1] === method) {
+ targetStart = i;
+ // Find end of this method block
+ for (let j = i + 1; j < pathsEnd; j++) {
+ const nextLine = lines[j];
+ // New method or new path
+ if (/^ {2}\/\S/.test(nextLine) || (/^ {4}\w+:\s*$/.test(nextLine) && httpMethods.some(m => nextLine.trim().startsWith(m + ":")))) {
+ targetEnd = j;
+ break;
+ }
+ }
+ if (targetEnd < 0) targetEnd = pathsEnd;
+ break;
+ }
+ }
+}
+
+if (targetStart < 0) {
+ console.error(`Endpoint not found: ${method.toUpperCase()} ${endpoint}`);
+ process.exit(1);
+}
+
+const blockLines = lines.slice(targetStart, targetEnd);
+
+// Collect all $refs from the block
+const allRefs = new Set();
+for (const bl of blockLines) {
+ const refMatch = bl.match(/\$ref:\s*['"]?(#\/[^'"}\s]+)['"]?/);
+ if (refMatch) allRefs.add(refMatch[1]);
+}
+
+// Resolve a $ref path to the raw YAML lines for that component
+function resolveRef(ref) {
+ const parts = ref.replace("#/", "").split("/");
+ // Find the component in the file by walking indentation
+ let searchStart = 0;
+ for (let p = 0; p < parts.length; p++) {
+ const indent = p * 2;
+ const target = " ".repeat(indent) + parts[p] + ":";
+ let found = false;
+ for (let i = searchStart; i < lines.length; i++) {
+ if (lines[i].startsWith(target) && (lines[i] === target || lines[i][target.length] === " ")) {
+ searchStart = i + 1;
+ found = true;
+ break;
+ }
+ }
+ if (!found) return null;
+ }
+
+ // Collect lines for this component (until same or lower indent)
+ const componentStart = searchStart - 1;
+ const baseIndent = parts.length * 2;
+ const result = [];
+ for (let i = searchStart; i < lines.length; i++) {
+ const line = lines[i];
+ if (line.trim() === "") { result.push(line); continue; }
+ const lineIndent = line.length - line.trimStart().length;
+ if (lineIndent < baseIndent) break;
+ result.push(line);
+ }
+ return result;
+}
+
+// Recursively resolve refs from component bodies
+function collectDeepRefs(refSet, visited) {
+ const toProcess = [...refSet].filter(r => !visited.has(r));
+ for (const ref of toProcess) {
+ visited.add(ref);
+ const body = resolveRef(ref);
+ if (!body) continue;
+ for (const bl of body) {
+ const refMatch = bl.match(/\$ref:\s*['"]?(#\/[^'"}\s]+)['"]?/);
+ if (refMatch && !visited.has(refMatch[1])) {
+ refSet.add(refMatch[1]);
+ }
+ }
+ }
+ // Recurse if new refs were found
+ const newRefs = [...refSet].filter(r => !visited.has(r));
+ if (newRefs.length > 0) collectDeepRefs(refSet, visited);
+}
+
+collectDeepRefs(allRefs, new Set());
+
+// Output
+console.log(`## \`${method.toUpperCase()}\` \`${endpoint}\`\n`);
+console.log("### Endpoint Definition\n");
+console.log("```yaml");
+for (const bl of blockLines) {
+ console.log(bl);
+}
+console.log("```\n");
+
+if (allRefs.size > 0) {
+ console.log(`### Referenced Components (${allRefs.size})\n`);
+ const sorted = [...allRefs].sort();
+ for (const ref of sorted) {
+ const name = ref.split("/").pop();
+ const category = ref.replace("#/", "").split("/").slice(0, -1).join("/");
+ console.log(`#### \`${name}\` (${category})\n`);
+ const body = resolveRef(ref);
+ if (body) {
+ console.log("```yaml");
+ for (const bl of body) console.log(bl);
+ console.log("```\n");
+ } else {
+ console.log("_(could not resolve)_\n");
+ }
+ }
+}
+SCRIPT
diff --git a/.agents/skills/clerk-backend-api/scripts/extract-tag-endpoints.sh b/.agents/skills/clerk-backend-api/scripts/extract-tag-endpoints.sh
new file mode 100644
index 0000000..5076498
--- /dev/null
+++ b/.agents/skills/clerk-backend-api/scripts/extract-tag-endpoints.sh
@@ -0,0 +1,208 @@
+#!/usr/bin/env bash
+# extract-tag-endpoints.sh
+#
+# Extracts all endpoints for a given tag from an OpenAPI YAML spec (stdin),
+# along with any $ref'd schemas/components.
+#
+# Usage:
+# curl -s | bash extract-tag-endpoints.sh "Billing"
+
+set -euo pipefail
+
+TAG="${1:?Usage: extract-tag-endpoints.sh }"
+TMPDIR_WORK=$(mktemp -d)
+trap 'rm -rf "$TMPDIR_WORK"' EXIT
+
+SPEC="$TMPDIR_WORK/spec.yml"
+cat > "$SPEC"
+
+# 1. Find all path+method blocks that have a matching tag
+# Strategy: find line numbers of path entries (lines starting with " /"),
+# then for each method block under that path, check if it contains the tag.
+
+node - "$TAG" "$SPEC" <<'SCRIPT'
+const fs = require("fs");
+const tag = process.argv[2];
+const specFile = process.argv[3];
+const lines = fs.readFileSync(specFile, "utf8").split("\n");
+
+const tagLower = tag.toLowerCase();
+
+// Phase 1: Find all path definitions and their method blocks
+// Paths start at indent 2 with " /"
+// Methods start at indent 4 with " get:", " post:", etc.
+const methods = ["get", "post", "put", "patch", "delete", "options", "head"];
+const endpoints = [];
+const refs = new Set();
+
+let currentPath = null;
+let currentMethod = null;
+let blockStart = -1;
+let blockLines = [];
+let inPaths = false;
+let inComponents = false;
+
+// First pass: locate the "paths:" and "components:" top-level keys
+let pathsStart = -1;
+let pathsEnd = -1;
+let componentsStart = -1;
+
+for (let i = 0; i < lines.length; i++) {
+ const line = lines[i];
+ if (/^paths:\s*$/.test(line)) {
+ pathsStart = i;
+ } else if (pathsStart >= 0 && pathsEnd < 0 && /^\S/.test(line) && i > pathsStart) {
+ pathsEnd = i;
+ }
+ if (/^components:\s*$/.test(line)) {
+ componentsStart = i;
+ }
+}
+if (pathsEnd < 0) pathsEnd = lines.length;
+
+// Second pass: extract endpoints matching the tag
+function flushBlock() {
+ if (!currentPath || !currentMethod || blockLines.length === 0) return;
+
+ // Check if this block has the target tag
+ let inTags = false;
+ let hasTag = false;
+ const blockRefs = [];
+
+ for (const bl of blockLines) {
+ const trimmed = bl.trim();
+
+ // Detect tags section
+ if (/^tags:\s*$/.test(trimmed)) {
+ inTags = true;
+ continue;
+ }
+ if (inTags) {
+ if (/^- /.test(trimmed)) {
+ const tagVal = trimmed.replace(/^- /, "").trim().replace(/^['"]|['"]$/g, "");
+ if (tagVal.toLowerCase() === tagLower) hasTag = true;
+ } else {
+ inTags = false;
+ }
+ }
+
+ // Collect $ref values
+ const refMatch = bl.match(/\$ref:\s*['"]?(#\/[^'"}\s]+)['"]?/);
+ if (refMatch) blockRefs.push(refMatch[1]);
+ }
+
+ if (hasTag) {
+ // Extract summary, operationId, description
+ let summary = "";
+ let operationId = "";
+ let description = "";
+ let params = [];
+ let inDesc = false;
+ let inParams = false;
+
+ for (const bl of blockLines) {
+ const trimmed = bl.trim();
+ const indent = bl.length - bl.trimStart().length;
+
+ // Only capture operation-level keys (indent 6 = direct children of the method block)
+ if (indent === 6) {
+ const sumMatch = trimmed.match(/^summary:\s*(.+)/);
+ if (sumMatch) summary = sumMatch[1].replace(/^['"]|['"]$/g, "");
+
+ const opMatch = trimmed.match(/^operationId:\s*(.+)/);
+ if (opMatch) operationId = opMatch[1].replace(/^['"]|['"]$/g, "");
+
+ const descMatch = trimmed.match(/^description:\s*(.+)/);
+ if (descMatch && !inDesc) {
+ const val = descMatch[1].trim();
+ if (val === "|-" || val === "|" || val === ">-" || val === ">") {
+ inDesc = true;
+ } else {
+ description = val.replace(/^['"]|['"]$/g, "");
+ }
+ continue;
+ }
+ }
+
+ if (inDesc) {
+ // Continuation lines of description — grab first non-empty line
+ if (!description && trimmed.length > 0) {
+ description = trimmed;
+ }
+ // Stop when we hit the next operation-level key
+ if (indent === 6 && trimmed.length > 0 && !/^description:/.test(trimmed)) {
+ inDesc = false;
+ }
+ }
+ }
+
+ endpoints.push({
+ method: currentMethod.toUpperCase(),
+ path: currentPath,
+ operationId,
+ summary,
+ description,
+ refs: blockRefs,
+ });
+
+ for (const r of blockRefs) refs.add(r);
+ }
+}
+
+for (let i = pathsStart + 1; i < pathsEnd; i++) {
+ const line = lines[i];
+
+ // Path line: exactly 2 spaces + /
+ if (/^ {2}\/\S/.test(line)) {
+ flushBlock();
+ currentPath = line.trim().replace(/:$/, "");
+ currentMethod = null;
+ blockLines = [];
+ continue;
+ }
+
+ // Method line: exactly 4 spaces + method name
+ const methodMatch = line.match(/^ {4}(\w+):\s*$/);
+ if (methodMatch && methods.includes(methodMatch[1])) {
+ flushBlock();
+ currentMethod = methodMatch[1];
+ blockLines = [];
+ continue;
+ }
+
+ if (currentMethod) {
+ blockLines.push(line);
+ }
+}
+flushBlock();
+
+// Output endpoints
+if (endpoints.length === 0) {
+ console.error(`No endpoints found for tag: "${tag}"`);
+ process.exit(1);
+}
+
+console.log(`## Endpoints for "${tag}" (${endpoints.length} total)\n`);
+for (const ep of endpoints) {
+ console.log(`### \`${ep.method}\` \`${ep.path}\``);
+ if (ep.operationId) console.log(`- **operationId**: \`${ep.operationId}\``);
+ if (ep.summary) console.log(`- **summary**: ${ep.summary}`);
+ if (ep.description && ep.description !== ep.summary)
+ console.log(`- **description**: ${ep.description}`);
+ if (ep.refs.length > 0) {
+ console.log(`- **refs**: ${ep.refs.map(r => "\`" + r.split("/").pop() + "\`").join(", ")}`);
+ }
+ console.log();
+}
+
+// Output unique refs list
+if (refs.size > 0) {
+ console.log(`## Referenced Components (${refs.size} unique)\n`);
+ const sorted = [...refs].sort();
+ for (const r of sorted) {
+ const name = r.split("/").pop();
+ const category = r.split("/").slice(0, -1).join("/").replace("#/", "");
+ console.log(`- \`${name}\` (${category})`);
+ }
+}
+SCRIPT
diff --git a/.agents/skills/clerk-backend-api/scripts/extract-tags.js b/.agents/skills/clerk-backend-api/scripts/extract-tags.js
new file mode 100644
index 0000000..b1a4fb2
--- /dev/null
+++ b/.agents/skills/clerk-backend-api/scripts/extract-tags.js
@@ -0,0 +1,14 @@
+let input = "";
+process.stdin.on("data", d => input += d);
+process.stdin.on("end", () => {
+ const lines = input.replace(/\r/g, "").split("\n");
+ let inTags = false;
+ for (const line of lines) {
+ if (line === "tags:") { inTags = true; continue; }
+ if (inTags && line.length > 0 && line[0] !== " ") break;
+ if (inTags) {
+ const m = line.match(/^\s{2}- name:\s*(.+)/);
+ if (m) console.log(m[1]);
+ }
+ }
+});
diff --git a/.agents/skills/clerk-custom-ui/SKILL.md b/.agents/skills/clerk-custom-ui/SKILL.md
new file mode 100644
index 0000000..e6e05dc
--- /dev/null
+++ b/.agents/skills/clerk-custom-ui/SKILL.md
@@ -0,0 +1,175 @@
+---
+name: clerk-custom-ui
+description: Custom authentication flows and component appearance - hooks (useSignIn,
+ useSignUp), themes, colors, fonts, CSS. Use for custom sign-in/sign-up flows, appearance
+ styling, visual customization, branding.
+allowed-tools: WebFetch
+license: MIT
+metadata:
+ author: clerk
+ version: 2.3.0
+---
+
+# Custom UI
+
+> **Prerequisite**: Ensure `ClerkProvider` wraps your app. See `clerk-setup` skill.
+>
+> **Version**: Check `package.json` for the SDK version — see `clerk` skill for the version table. This determines which custom flow references to use below.
+
+This skill covers two areas:
+1. **Custom authentication flows** — build your own sign-in/sign-up UI with hooks
+2. **Appearance customization** — theme, style, and brand Clerk's pre-built components
+
+## What Do You Need?
+
+| Task | Reference |
+|------|-----------|
+| Custom sign-in (Core 2 / LTS) | core-2/custom-sign-in.md |
+| Custom sign-up (Core 2 / LTS) | core-2/custom-sign-up.md |
+| Custom sign-in (Current SDK v7+) | core-3/custom-sign-in.md |
+| Custom sign-up (Current SDK v7+) | core-3/custom-sign-up.md |
+| Show component pattern (Current SDK) | core-3/show-component.md |
+
+## Custom Flow References
+
+| Task | Core 2 | Current |
+|------|--------|---------|
+| Custom sign-in (useSignIn) | `core-2/custom-sign-in.md` | `core-3/custom-sign-in.md` |
+| Custom sign-up (useSignUp) | `core-2/custom-sign-up.md` | `core-3/custom-sign-up.md` |
+| `` component | *(use ``, ``, ``)* | `core-3/show-component.md` |
+
+---
+
+## Appearance Customization
+
+Appearance customization applies to both Core 2 and the current SDK.
+
+### Component Customization Options
+
+| Task | Documentation |
+|------|---------------|
+| Appearance prop overview | https://clerk.com/docs/nextjs/guides/customizing-clerk/appearance-prop/overview |
+| Options (structure, logo, buttons) | https://clerk.com/docs/nextjs/guides/customizing-clerk/appearance-prop/layout |
+| Themes (pre-built dark/light) | https://clerk.com/docs/nextjs/guides/customizing-clerk/appearance-prop/themes |
+| Variables (colors, fonts, spacing) | https://clerk.com/docs/nextjs/guides/customizing-clerk/appearance-prop/variables |
+| CAPTCHA configuration | https://clerk.com/docs/nextjs/guides/customizing-clerk/appearance-prop/captcha |
+| Bring your own CSS | https://clerk.com/docs/nextjs/guides/customizing-clerk/appearance-prop/bring-your-own-css |
+
+### Appearance Pattern
+
+```typescript
+
+```
+
+> **Core 2 ONLY (skip if current SDK):** The `options` property was named `layout`. Use `layout: { logoImageUrl: '...', socialButtonsVariant: '...' }` instead of `options`.
+
+### variables (colors, typography, borders)
+
+| Property | Description |
+|----------|-------------|
+| `colorPrimary` | Primary color throughout |
+| `colorBackground` | Background color |
+| `borderRadius` | Border radius (default: `0.375rem`) |
+
+**Opacity change:** `colorRing` and `colorModalBackdrop` now render at full opacity. Use explicit `rgba()` values if you need transparency.
+
+> **Core 2 ONLY (skip if current SDK):** `colorRing` and `colorModalBackdrop` rendered at 15% opacity by default.
+
+### options (structure, logo, social buttons)
+
+| Property | Description |
+|----------|-------------|
+| `logoImageUrl` | URL to custom logo |
+| `socialButtonsVariant` | `'blockButton'` \| `'iconButton'` \| `'auto'` |
+| `socialButtonsPlacement` | `'top'` \| `'bottom'` |
+| `showOptionalFields` | Show optional fields (default: `false`) |
+
+> **Core 2 ONLY (skip if current SDK):** This property is called `layout`, not `options`. Also, `showOptionalFields` defaulted to `true`.
+
+### Themes
+
+Install themes from `@clerk/ui`:
+
+```bash
+npm install @clerk/ui
+```
+
+```typescript
+import { dark } from '@clerk/ui/themes'
+
+
+```
+
+> **Core 2 ONLY (skip if current SDK):** Themes are imported from `@clerk/themes` (install `@clerk/themes` instead of `@clerk/ui`). Example: `import { dark } from '@clerk/themes'`.
+
+**Theme stacking** — pass an array where the last theme takes precedence:
+
+```typescript
+import { dark, neobrutalism } from '@clerk/ui/themes'
+
+
+```
+
+**CSS `color-scheme` support** — the default theme respects the CSS `color-scheme` property for automatic light/dark mode toggling.
+
+**Available themes:** `dark`, `neobrutalism`, `shadcn`, `simple`
+
+#### shadcn Theme
+
+> **IMPORTANT:** If the project has `components.json` (shadcn/ui installed), ALWAYS apply the shadcn theme as the FIRST customization step. This ensures Clerk components visually match the existing shadcn design system. Skip this only if the user explicitly requests a different theme.
+
+**If the project uses shadcn/ui** (check for `components.json` in the project root), **always use the shadcn theme**:
+
+```typescript
+import { shadcn } from '@clerk/ui/themes'
+
+
+```
+
+Also import shadcn CSS in your global styles:
+```css
+@import 'tailwindcss';
+@import '@clerk/ui/themes/shadcn.css';
+```
+
+> **Core 2 ONLY (skip if current SDK):** Import from `@clerk/themes` and `@clerk/themes/shadcn.css`:
+> ```typescript
+> import { shadcn } from '@clerk/themes'
+> ```
+> ```css
+> @import '@clerk/themes/shadcn.css';
+> ```
+
+## Workflow
+
+1. Identify customization needs (custom flow or appearance)
+2. For custom flows: check SDK version → read appropriate `core-2/` or `core-3/` reference
+3. For appearance: WebFetch the appropriate documentation from table above
+4. Apply appearance prop to your Clerk components or build custom flow with hooks
+
+## Common Pitfalls
+
+| Issue | Solution |
+|-------|----------|
+| Colors not applying | Use `colorPrimary` not `primaryColor` |
+| Logo not showing | Put `logoImageUrl` inside `options: {}` (or `layout: {}` in Core 2) |
+| Social buttons wrong | Add `socialButtonsVariant: 'iconButton'` in `options` (or `layout` in Core 2) |
+| Styling not working | Use appearance prop, not direct CSS (unless with bring-your-own-css) |
+| Hook returns different shape | Check SDK version — Core 2 and current have completely different `useSignIn`/`useSignUp` APIs |
+
+## See Also
+
+- `clerk-setup` - Initial Clerk install
+- `clerk-nextjs-patterns` - Next.js patterns
+- `clerk-orgs` - B2B organizations
diff --git a/.agents/skills/clerk-custom-ui/core-2/custom-sign-in.md b/.agents/skills/clerk-custom-ui/core-2/custom-sign-in.md
new file mode 100644
index 0000000..28759de
--- /dev/null
+++ b/.agents/skills/clerk-custom-ui/core-2/custom-sign-in.md
@@ -0,0 +1,224 @@
+# Custom Sign-In Flow (Core 2)
+
+> This document covers the **older SDK** (`@clerk/nextjs` v5–v6, `@clerk/clerk-react` v5–v6, `@clerk/clerk-expo` v1–v2). For the current SDK, see `core-3/custom-sign-in.md`.
+
+Build a custom sign-in experience using the `useSignIn()` hook.
+
+## Hook API
+
+```typescript
+import { useSignIn } from '@clerk/nextjs' // or @clerk/clerk-react, @clerk/clerk-expo
+
+const { signIn, isLoaded, setActive } = useSignIn()
+```
+
+| Property | Type | Description |
+|----------|------|-------------|
+| `signIn` | `SignIn` | Sign-in object with methods |
+| `isLoaded` | `boolean` | Whether the hook has loaded |
+| `setActive` | `(params) => Promise` | Sets the active session |
+
+## Sign-In Flow
+
+### 1. Create Sign-In
+
+```typescript
+const result = await signIn.create({
+ identifier: 'user@example.com',
+ password: 'securePassword123',
+})
+```
+
+### 2. First Factor Verification
+
+If additional verification is needed (email code, phone code):
+
+```typescript
+// Prepare first factor
+await signIn.prepareFirstFactor({
+ strategy: 'email_code', // or 'phone_code'
+})
+
+// Attempt first factor
+const result = await signIn.attemptFirstFactor({
+ strategy: 'email_code',
+ code: '123456',
+})
+```
+
+### 3. Second Factor (MFA)
+
+If the sign-in requires MFA:
+
+```typescript
+// Prepare second factor
+await signIn.prepareSecondFactor({
+ strategy: 'email_code', // or 'phone_code'
+})
+
+// Attempt second factor
+const result = await signIn.attemptSecondFactor({
+ strategy: 'totp', // or 'email_code', 'phone_code', 'backup_code'
+ code: '123456',
+})
+```
+
+### 4. Finalize
+
+Set the active session after successful authentication:
+
+```typescript
+await setActive({ session: signIn.createdSessionId })
+```
+
+### Password Reset
+
+```typescript
+// 1. Start reset flow
+await signIn.create({ strategy: 'reset_password_email_code', identifier: 'user@example.com' })
+
+// or prepare after initial create:
+await signIn.prepareFirstFactor({ strategy: 'reset_password_email_code' })
+
+// 2. Verify reset code
+await signIn.attemptFirstFactor({ strategy: 'reset_password_email_code', code: '123456' })
+
+// 3. Set new password
+await signIn.resetPassword({ password: 'newSecurePassword123' })
+```
+
+### SSO (OAuth)
+
+```typescript
+await signIn.authenticateWithRedirect({
+ strategy: 'oauth_google', // or 'oauth_github', etc.
+ redirectUrl: '/sso-callback',
+ redirectUrlComplete: '/',
+})
+```
+
+## Error Handling
+
+Use try/catch with `isClerkAPIResponseError()`:
+
+```typescript
+import { isClerkAPIResponseError } from '@clerk/nextjs/errors'
+
+try {
+ await signIn.create({ identifier, password })
+} catch (err) {
+ if (isClerkAPIResponseError(err)) {
+ err.errors.forEach((e) => {
+ console.log(e.code) // e.g. 'form_identifier_not_found'
+ console.log(e.message) // Human-readable message
+ console.log(e.longMessage) // Detailed message
+ })
+ }
+}
+```
+
+## Complete Example: Email/Password with MFA
+
+```tsx
+'use client'
+import { useState } from 'react'
+import { useSignIn } from '@clerk/nextjs'
+import { isClerkAPIResponseError } from '@clerk/nextjs/errors'
+import { useRouter } from 'next/navigation'
+
+export default function SignInPage() {
+ const { signIn, isLoaded, setActive } = useSignIn()
+ const router = useRouter()
+
+ const [identifier, setIdentifier] = useState('')
+ const [password, setPassword] = useState('')
+ const [mfaCode, setMfaCode] = useState('')
+ const [step, setStep] = useState<'credentials' | 'mfa'>('credentials')
+ const [error, setError] = useState('')
+
+ if (!isLoaded) return Loading...
+
+ async function handleSignIn(e: React.FormEvent) {
+ e.preventDefault()
+ setError('')
+
+ try {
+ const result = await signIn.create({ identifier, password })
+
+ if (result.status === 'needs_second_factor') {
+ setStep('mfa')
+ return
+ }
+
+ if (result.status === 'complete') {
+ await setActive({ session: result.createdSessionId })
+ router.push('/')
+ }
+ } catch (err) {
+ if (isClerkAPIResponseError(err)) {
+ setError(err.errors[0]?.message || 'Sign in failed')
+ }
+ }
+ }
+
+ async function handleMFA(e: React.FormEvent) {
+ e.preventDefault()
+ setError('')
+
+ try {
+ const result = await signIn.attemptSecondFactor({
+ strategy: 'totp',
+ code: mfaCode,
+ })
+
+ if (result.status === 'complete') {
+ await setActive({ session: result.createdSessionId })
+ router.push('/')
+ }
+ } catch (err) {
+ if (isClerkAPIResponseError(err)) {
+ setError(err.errors[0]?.message || 'Verification failed')
+ }
+ }
+ }
+
+ if (step === 'mfa') {
+ return (
+
+ )
+ }
+
+ return (
+
+ )
+}
+```
+
+## Docs
+
+- [Custom sign-in flow](https://clerk.com/docs/custom-flows/overview)
+- [useSignIn() reference](https://clerk.com/docs/references/react/use-sign-in)
diff --git a/.agents/skills/clerk-custom-ui/core-2/custom-sign-up.md b/.agents/skills/clerk-custom-ui/core-2/custom-sign-up.md
new file mode 100644
index 0000000..574dbe7
--- /dev/null
+++ b/.agents/skills/clerk-custom-ui/core-2/custom-sign-up.md
@@ -0,0 +1,190 @@
+# Custom Sign-Up Flow (Core 2)
+
+> This document covers the **older SDK** (`@clerk/nextjs` v5–v6, `@clerk/clerk-react` v5–v6, `@clerk/clerk-expo` v1–v2). For the current SDK, see `core-3/custom-sign-up.md`.
+
+Build a custom sign-up experience using the `useSignUp()` hook.
+
+## Hook API
+
+```typescript
+import { useSignUp } from '@clerk/nextjs' // or @clerk/clerk-react, @clerk/clerk-expo
+
+const { signUp, isLoaded, setActive } = useSignUp()
+```
+
+| Property | Type | Description |
+|----------|------|-------------|
+| `signUp` | `SignUp` | Sign-up object with methods |
+| `isLoaded` | `boolean` | Whether the hook has loaded |
+| `setActive` | `(params) => Promise` | Sets the active session |
+
+## Sign-Up Flow
+
+### 1. Create Sign-Up
+
+```typescript
+const result = await signUp.create({
+ emailAddress: 'user@example.com',
+ password: 'securePassword123',
+ firstName: 'Jane', // optional
+ lastName: 'Doe', // optional
+})
+```
+
+### 2. Prepare Verification
+
+Send a verification code to the user's email or phone:
+
+```typescript
+await signUp.prepareVerification({
+ strategy: 'email_code', // or 'phone_code', 'email_link'
+})
+```
+
+### 3. Attempt Verification
+
+Verify the code the user received:
+
+```typescript
+const result = await signUp.attemptVerification({
+ strategy: 'email_code',
+ code: '123456',
+})
+```
+
+### 4. Finalize
+
+Set the active session after successful sign-up:
+
+```typescript
+await setActive({ session: signUp.createdSessionId })
+```
+
+### SSO (OAuth)
+
+```typescript
+await signUp.authenticateWithRedirect({
+ strategy: 'oauth_google',
+ redirectUrl: '/sso-callback',
+ redirectUrlComplete: '/',
+})
+```
+
+## Error Handling
+
+Use try/catch with `isClerkAPIResponseError()`:
+
+```typescript
+import { isClerkAPIResponseError } from '@clerk/nextjs/errors'
+
+try {
+ await signUp.create({ emailAddress, password })
+} catch (err) {
+ if (isClerkAPIResponseError(err)) {
+ err.errors.forEach((e) => {
+ console.log(e.code) // e.g. 'form_password_pwned'
+ console.log(e.message) // Human-readable message
+ console.log(e.longMessage) // Detailed message
+ })
+ }
+}
+```
+
+## Complete Example: Email/Password with Email Verification
+
+```tsx
+'use client'
+import { useState } from 'react'
+import { useSignUp } from '@clerk/nextjs'
+import { isClerkAPIResponseError } from '@clerk/nextjs/errors'
+import { useRouter } from 'next/navigation'
+
+export default function SignUpPage() {
+ const { signUp, isLoaded, setActive } = useSignUp()
+ const router = useRouter()
+
+ const [email, setEmail] = useState('')
+ const [password, setPassword] = useState('')
+ const [code, setCode] = useState('')
+ const [step, setStep] = useState<'register' | 'verify'>('register')
+ const [error, setError] = useState('')
+
+ if (!isLoaded) return Loading...
+
+ async function handleRegister(e: React.FormEvent) {
+ e.preventDefault()
+ setError('')
+
+ try {
+ await signUp.create({ emailAddress: email, password })
+ await signUp.prepareVerification({ strategy: 'email_code' })
+ setStep('verify')
+ } catch (err) {
+ if (isClerkAPIResponseError(err)) {
+ setError(err.errors[0]?.message || 'Sign up failed')
+ }
+ }
+ }
+
+ async function handleVerify(e: React.FormEvent) {
+ e.preventDefault()
+ setError('')
+
+ try {
+ const result = await signUp.attemptVerification({
+ strategy: 'email_code',
+ code,
+ })
+
+ if (result.status === 'complete') {
+ await setActive({ session: result.createdSessionId })
+ router.push('/')
+ }
+ } catch (err) {
+ if (isClerkAPIResponseError(err)) {
+ setError(err.errors[0]?.message || 'Verification failed')
+ }
+ }
+ }
+
+ if (step === 'verify') {
+ return (
+
+ )
+ }
+
+ return (
+
+ )
+}
+```
+
+## Docs
+
+- [Custom sign-up flow](https://clerk.com/docs/custom-flows/overview)
+- [useSignUp() reference](https://clerk.com/docs/references/react/use-sign-up)
diff --git a/.agents/skills/clerk-custom-ui/core-3/custom-sign-in.md b/.agents/skills/clerk-custom-ui/core-3/custom-sign-in.md
new file mode 100644
index 0000000..50f13c2
--- /dev/null
+++ b/.agents/skills/clerk-custom-ui/core-3/custom-sign-in.md
@@ -0,0 +1,314 @@
+# Custom Sign-In Flow
+
+Build a custom sign-in experience using the `useSignIn()` hook.
+
+## Hook API
+
+```typescript
+import { useSignIn } from '@clerk/nextjs' // or @clerk/react, @clerk/expo
+
+const { signIn, errors, fetchStatus } = useSignIn()
+```
+
+| Property | Type | Description |
+|----------|------|-------------|
+| `signIn` | `SignInFuture` | Sign-in object with namespaced methods |
+| `errors` | `Errors` | Structured error object |
+| `fetchStatus` | `'idle' \| 'fetching'` | Network request status |
+
+## Sign-In Methods
+
+### Password
+
+```typescript
+const { error } = await signIn.password({
+ identifier: 'user@example.com',
+ password: 'securePassword123',
+})
+```
+
+### SSO (OAuth / Enterprise)
+
+```typescript
+const { error } = await signIn.sso({
+ strategy: 'oauth_google', // or 'oauth_github', 'enterprise_sso', etc.
+ redirectUrl: '/dashboard', // where to go after SSO completes
+ redirectCallbackUrl: '/sso-callback', // intermediate callback route
+})
+```
+
+### Passkey
+
+```typescript
+const { error } = await signIn.passkey({ flow: 'discoverable' })
+```
+
+### Web3
+
+```typescript
+const { error } = await signIn.web3({ strategy: 'web3_solana_signature' })
+// or
+const { error } = await signIn.web3({ strategy: 'web3_base_signature' })
+```
+
+### Ticket (Invitation link)
+
+```typescript
+const { error } = await signIn.ticket({ ticket: 'ticket_abc123' })
+```
+
+### Email Code
+
+```typescript
+// Send code (emailAddress is optional if a signIn already exists from a prior method call)
+const { error } = await signIn.emailCode.sendCode({ emailAddress: 'user@example.com' })
+
+// Verify code
+const { error } = await signIn.emailCode.verifyCode({ code: '123456' })
+```
+
+### Phone Code
+
+```typescript
+// Send code (phoneNumber is optional if a signIn already exists from a prior method call)
+const { error } = await signIn.phoneCode.sendCode({ phoneNumber: '+12015551234' })
+
+// Verify code
+const { error } = await signIn.phoneCode.verifyCode({ code: '123456' })
+```
+
+## MFA (Second Factor)
+
+A second factor is required when `signIn.status` is one of:
+- `'needs_second_factor'` — user has MFA enabled (TOTP, backup codes, etc.)
+- `'needs_client_trust'` — new device sign-in without MFA; requires email or phone code verification
+
+```typescript
+// TOTP (Authenticator app)
+const { error } = await signIn.mfa.verifyTOTP({ code: '123456' })
+
+// Backup code
+const { error } = await signIn.mfa.verifyBackupCode({ code: 'backup-code-here' })
+
+// Email code
+const { error: sendErr } = await signIn.mfa.sendEmailCode()
+const { error: verifyErr } = await signIn.mfa.verifyEmailCode({ code: '123456' })
+
+// Phone code
+const { error: sendErr } = await signIn.mfa.sendPhoneCode()
+const { error: verifyErr } = await signIn.mfa.verifyPhoneCode({ code: '123456' })
+```
+
+## Password Reset
+
+```typescript
+// 1. Send reset code
+const { error } = await signIn.resetPasswordEmailCode.sendCode()
+
+// 2. Verify the code
+const { error } = await signIn.resetPasswordEmailCode.verifyCode({ code: '123456' })
+
+// 3. Submit new password
+const { error } = await signIn.resetPasswordEmailCode.submitPassword({
+ password: 'newSecurePassword123',
+})
+```
+
+## Client Trust
+
+When a user signs in with a valid password from a new device without MFA enabled, the sign-in status becomes `needs_client_trust`. This requires an additional verification step:
+
+```typescript
+if (signIn.status === 'needs_client_trust') {
+ // Check supportedSecondFactors for available methods (email_code or phone_code)
+ const factors = signIn.supportedSecondFactors
+ // Use the appropriate mfa method to verify
+}
+```
+
+## Finalizing Sign-In
+
+After successful authentication, call `finalize()` to activate the session:
+
+```typescript
+await signIn.finalize({
+ navigate: async ({ session, decorateUrl }) => {
+ const destination = session.currentTask
+ ? `/sign-in/tasks/${session.currentTask.key}`
+ : '/'
+ const url = decorateUrl(destination)
+ // decorateUrl may return an absolute URL for Safari ITP
+ if (url.startsWith('http')) {
+ window.location.href = url
+ } else {
+ router.push(url)
+ }
+ },
+})
+```
+
+- `decorateUrl(path)` — decorates the URL with session info (required to support Safari's Intelligent Tracking Prevention). May return an absolute URL.
+- `session.currentTask` — check for pending session tasks before redirecting
+
+### Reset State
+
+Clear local sign-in state and start over:
+
+```typescript
+signIn.reset()
+```
+
+## Error Handling
+
+All methods return `Promise<{ error: ClerkError | null }>`. Errors are also available reactively on the hook:
+
+```typescript
+const { signIn, errors } = useSignIn()
+
+// Field-level errors
+errors?.fields?.identifier // { code, message, longMessage? }
+errors?.fields?.password // { code, message, longMessage? }
+errors?.fields?.code // { code, message, longMessage? }
+
+// Global errors (not tied to a field)
+errors?.global // ClerkGlobalHookError[] | null
+
+// Raw error array
+errors?.raw // ClerkError[] | null
+```
+
+## Complete Example: Email/Password with MFA
+
+From [the docs](https://clerk.com/docs/guides/development/custom-flows/authentication/multi-factor-authentication). Supports SMS verification codes, authenticator app (TOTP), and backup codes.
+
+```tsx
+'use client'
+
+import { useSignIn } from '@clerk/nextjs'
+import { useRouter } from 'next/navigation'
+
+export default function Page() {
+ const { signIn, errors, fetchStatus } = useSignIn()
+ const router = useRouter()
+
+ const handleSubmit = async (formData: FormData) => {
+ const emailAddress = formData.get('email') as string
+ const password = formData.get('password') as string
+
+ await signIn.password({
+ emailAddress,
+ password,
+ })
+
+ // If you're using the authenticator app strategy, remove this check.
+ if (signIn.status === 'needs_second_factor') {
+ await signIn.mfa.sendPhoneCode()
+ }
+
+ if (signIn.status === 'complete') {
+ await signIn.finalize({
+ navigate: ({ session, decorateUrl }) => {
+ if (session?.currentTask) {
+ // Handle pending session tasks
+ // See https://clerk.com/docs/guides/development/custom-flows/authentication/session-tasks
+ console.log(session?.currentTask)
+ return
+ }
+
+ const url = decorateUrl('/')
+ if (url.startsWith('http')) {
+ window.location.href = url
+ } else {
+ router.push(url)
+ }
+ },
+ })
+ }
+ }
+
+ const handleMFAVerification = async (formData: FormData) => {
+ const code = formData.get('code') as string
+ const useBackupCode = formData.get('useBackupCode') === 'on'
+
+ if (useBackupCode) {
+ await signIn.mfa.verifyBackupCode({ code })
+ } else {
+ await signIn.mfa.verifyPhoneCode({ code })
+ // If you're using the authenticator app strategy, use the following method instead:
+ // await signIn.mfa.verifyTOTP({ code })
+ }
+
+ if (signIn.status === 'complete') {
+ await signIn.finalize({
+ navigate: ({ session, decorateUrl }) => {
+ if (session?.currentTask) {
+ // Handle pending session tasks
+ // See https://clerk.com/docs/guides/development/custom-flows/authentication/session-tasks
+ console.log(session?.currentTask)
+ return
+ }
+
+ const url = decorateUrl('/')
+ if (url.startsWith('http')) {
+ window.location.href = url
+ } else {
+ router.push(url)
+ }
+ },
+ })
+ }
+ }
+
+ if (signIn.status === 'needs_second_factor') {
+ return (
+
+
Verify your account
+
+
+ )
+ }
+
+ return (
+ <>
+ Sign in
+
+ {errors && {JSON.stringify(errors, null, 2)}
}
+ >
+ )
+}
+```
+
+## Docs
+
+- [Custom sign-in flow](https://clerk.com/docs/custom-flows/overview)
+- [MFA custom flow](https://clerk.com/docs/guides/development/custom-flows/authentication/multi-factor-authentication)
+- [useSignIn() reference](https://clerk.com/docs/references/react/use-sign-in)
diff --git a/.agents/skills/clerk-custom-ui/core-3/custom-sign-up.md b/.agents/skills/clerk-custom-ui/core-3/custom-sign-up.md
new file mode 100644
index 0000000..ac243ba
--- /dev/null
+++ b/.agents/skills/clerk-custom-ui/core-3/custom-sign-up.md
@@ -0,0 +1,259 @@
+# Custom Sign-Up Flow
+
+Build a custom sign-up experience using the `useSignUp()` hook.
+
+## Hook API
+
+```typescript
+import { useSignUp } from '@clerk/nextjs' // or @clerk/react, @clerk/expo
+
+const { signUp, errors, fetchStatus } = useSignUp()
+```
+
+| Property | Type | Description |
+|----------|------|-------------|
+| `signUp` | `SignUpFuture` | Sign-up object with namespaced methods |
+| `errors` | `Errors` | Structured error object |
+| `fetchStatus` | `'idle' \| 'fetching'` | Network request status |
+
+## Sign-Up Methods
+
+### Password (Email/Password)
+
+```typescript
+const { error } = await signUp.password({
+ emailAddress: 'user@example.com',
+ password: 'securePassword123',
+ firstName: 'Jane', // optional
+ lastName: 'Doe', // optional
+})
+```
+
+### SSO (OAuth)
+
+```typescript
+const { error } = await signUp.sso({
+ strategy: 'oauth_google', // or 'oauth_github', etc.
+ redirectUrl: '/dashboard', // where to go after SSO completes
+ redirectCallbackUrl: '/sso-callback', // intermediate callback route
+})
+```
+
+### Web3
+
+```typescript
+const { error } = await signUp.web3({ strategy: 'web3_solana_signature' })
+```
+
+### Update (add fields to existing sign-up)
+
+Use `update()` to add optional fields (name, metadata, legal acceptance, locale) to an existing sign-up before finalization.
+
+```typescript
+const { error } = await signUp.update({
+ firstName: 'Jane',
+ lastName: 'Doe',
+ unsafeMetadata: { referralSource: 'twitter' },
+ legalAccepted: true,
+})
+```
+
+## Email / Phone Verification
+
+After creating a sign-up, verify the user's email or phone:
+
+### Email Code
+
+```typescript
+// Send verification code
+const { error } = await signUp.verifications.sendEmailCode()
+
+// Verify the code
+const { error } = await signUp.verifications.verifyEmailCode({ code: '123456' })
+```
+
+### Phone Code
+
+```typescript
+// Send verification code
+const { error } = await signUp.verifications.sendPhoneCode()
+
+// Verify the code
+const { error } = await signUp.verifications.verifyPhoneCode({ code: '123456' })
+```
+
+### Email Link
+
+```typescript
+// verificationUrl: where the user lands after clicking the email link (relative or absolute)
+const { error } = await signUp.verifications.sendEmailLink({ verificationUrl: '/verify' })
+// User clicks the link in their email to verify
+```
+
+## Finalizing Sign-Up
+
+After successful sign-up and verification, call `finalize()` to activate the session:
+
+```typescript
+await signUp.finalize({
+ navigate: async ({ session, decorateUrl }) => {
+ const destination = session.currentTask
+ ? `/sign-up/tasks/${session.currentTask.key}`
+ : '/'
+ const url = decorateUrl(destination)
+ // decorateUrl may return an absolute URL for Safari ITP
+ if (url.startsWith('http')) {
+ window.location.href = url
+ } else {
+ router.push(url)
+ }
+ },
+})
+```
+
+### Transferable Sign-Ups
+
+If `signUp.isTransferable` is `true`, the identifier matches an existing user and the sign-up should be transferred to a sign-in flow. This involves coordinating between sign-up and sign-in resources. See the [transferable sign-up docs](https://clerk.com/docs/custom-flows/overview) for the full implementation.
+
+### Reset State
+
+Clear local sign-up state and start over:
+
+```typescript
+signUp.reset()
+```
+
+## Error Handling
+
+All methods return `Promise<{ error: ClerkError | null }>`. Errors are also available reactively on the hook:
+
+```typescript
+const { signUp, errors } = useSignUp()
+
+// Field-level errors
+errors?.fields?.emailAddress // { code, message, longMessage? }
+errors?.fields?.password // { code, message, longMessage? }
+errors?.fields?.firstName // { code, message, longMessage? }
+errors?.fields?.lastName // { code, message, longMessage? }
+errors?.fields?.phoneNumber // { code, message, longMessage? }
+errors?.fields?.username // { code, message, longMessage? }
+errors?.fields?.code // { code, message, longMessage? }
+
+// Global errors
+errors?.global // ClerkGlobalHookError[] | null
+
+// Raw error array
+errors?.raw // ClerkError[] | null
+```
+
+## Complete Example: Phone OTP Sign-Up
+
+From [the docs](https://clerk.com/docs/guides/development/custom-flows/authentication/email-sms-otp). Uses phone OTP with inline comments for adapting to email OTP.
+
+```tsx
+'use client'
+
+import * as React from 'react'
+import { useAuth, useSignUp } from '@clerk/nextjs'
+import { useRouter } from 'next/navigation'
+
+export default function SignUpPage() {
+ const { signUp, errors, fetchStatus } = useSignUp()
+ const { isSignedIn } = useAuth()
+ const router = useRouter()
+
+ const handleSubmit = async (formData: FormData) => {
+ // For email OTP: collect the email address instead of the phone number
+ const phoneNumber = formData.get('phoneNumber') as string
+
+ // For email OTP: change create({ phoneNumber }) to create({ emailAddress })
+ const error = await signUp.create({ phoneNumber })
+
+ // For email OTP: change sendPhoneCode() to sendEmailCode()
+ if (!error) await signUp.verifications.sendPhoneCode()
+ }
+
+ const handleVerify = async (formData: FormData) => {
+ const code = formData.get('code') as string
+
+ // For email OTP: change verifyPhoneCode() to verifyEmailCode()
+ await signUp.verifications.verifyPhoneCode({ code })
+
+ if (signUp.status === 'complete') {
+ await signUp.finalize({
+ navigate: ({ session, decorateUrl }) => {
+ if (session?.currentTask) {
+ // Handle pending session tasks
+ // See https://clerk.com/docs/guides/development/custom-flows/authentication/session-tasks
+ console.log(session?.currentTask)
+ return
+ }
+
+ const url = decorateUrl('/')
+ if (url.startsWith('http')) {
+ window.location.href = url
+ } else {
+ router.push(url)
+ }
+ },
+ })
+ }
+ }
+
+ if (signUp.status === 'complete' || isSignedIn) {
+ return null
+ }
+
+ if (
+ signUp.status === 'missing_requirements' &&
+ // For email OTP: check for phone_number instead of email_address
+ signUp.unverifiedFields.includes('phone_number') &&
+ signUp.missingFields.length === 0
+ ) {
+ return (
+ <>
+ Verify your account
+
+ {/* For email OTP: change sendPhoneCode() to sendEmailCode() */}
+ signUp.verifications.sendPhoneCode()}>I need a new code
+ >
+ )
+ }
+
+ return (
+ <>
+ Sign up
+
+ {errors && {JSON.stringify(errors, null, 2)}
}
+
+ {/* Required for sign-up flows. Clerk's bot sign-up protection is enabled by default */}
+
+ >
+ )
+}
+```
+
+## Docs
+
+- [Custom sign-up flow](https://clerk.com/docs/custom-flows/overview)
+- [Email/phone OTP custom flow](https://clerk.com/docs/guides/development/custom-flows/authentication/email-sms-otp)
+- [useSignUp() reference](https://clerk.com/docs/references/react/use-sign-up)
diff --git a/.agents/skills/clerk-custom-ui/core-3/show-component.md b/.agents/skills/clerk-custom-ui/core-3/show-component.md
new file mode 100644
index 0000000..f01a8b4
--- /dev/null
+++ b/.agents/skills/clerk-custom-ui/core-3/show-component.md
@@ -0,0 +1,125 @@
+# `` Component
+
+The `` component conditionally renders content based on authentication state, roles, permissions, billing plans, and features.
+
+> **Core 2 ONLY (skip if current SDK):** The `` component does not exist in Core 2. Use ``, ``, and `` instead. See migration table below.
+
+## Import
+
+```typescript
+import { Show } from '@clerk/nextjs' // Next.js
+import { Show } from '@clerk/react' // React
+import { Show } from '@clerk/react-router' // React Router
+import { Show } from '@clerk/expo' // Expo
+```
+
+## Props
+
+| Prop | Type | Description |
+|------|------|-------------|
+| `when` | `string \| object \| function` | Condition for rendering children |
+| `fallback?` | `ReactNode` | Content shown when condition fails |
+| `treatPendingAsSignedOut?` | `boolean` | Treat pending sessions as signed-out (default: `true`) |
+
+## `when` Prop Variants
+
+### Authentication State
+
+```tsx
+// Show content only when signed in
+
+ Welcome back!
+
+
+// Show content only when signed out
+
+ Please sign in.
+
+```
+
+### Role Check
+
+```tsx
+
+
+
+```
+
+### Permission Check
+
+```tsx
+
+
+
+```
+
+### Billing Feature Check
+
+```tsx
+
+
+
+```
+
+### Billing Plan Check
+
+```tsx
+
+
+
+```
+
+### Custom Condition (Function)
+
+```tsx
+ has({ role: 'org:admin' }) || has({ permission: 'org:billing:manage' })}>
+
+
+```
+
+## Fallback Content
+
+Show alternative content when the condition fails:
+
+```tsx
+Please sign in to continue.
}>
+
+
+```
+
+## Session Tasks and Pending State
+
+The `treatPendingAsSignedOut` prop controls how pending sessions (sessions with incomplete tasks) are handled:
+
+```tsx
+// Default: pending sessions are treated as signed-out
+
+
+
+
+// Treat pending sessions as signed-in (e.g., to show task completion UI)
+
+
+
+```
+
+## Security Caveat
+
+**`` only visually hides content** — it remains in browser source. It is not a security boundary. For protecting sensitive data, always verify authentication server-side with `auth()` or use `auth.protect()` in middleware.
+
+## Migration from Core 2
+
+| Core 2 | Current |
+|--------|---------|
+| `` | `` |
+| `` | `` |
+| `` | `` |
+| `` | `` |
+| ` expr}>` | ` expr}>` |
+| `` | `` |
+| *(no equivalent)* | `` |
+| *(no equivalent)* | `` |
+
+## Docs
+
+- [Show component reference](https://clerk.com/docs/components/control/show)
diff --git a/.agents/skills/clerk-nextjs-patterns/SKILL.md b/.agents/skills/clerk-nextjs-patterns/SKILL.md
new file mode 100644
index 0000000..cd9f161
--- /dev/null
+++ b/.agents/skills/clerk-nextjs-patterns/SKILL.md
@@ -0,0 +1,214 @@
+---
+name: clerk-nextjs-patterns
+description: Advanced Next.js patterns - middleware, Server Actions, caching with
+ Clerk.
+license: MIT
+allowed-tools: WebFetch
+metadata:
+ author: clerk
+ version: 2.2.0
+---
+
+# Next.js Patterns
+
+> **Version**: Check `package.json` for the SDK version — see `clerk` skill for the version table. Core 2 differences are noted inline with `> **Core 2 ONLY (skip if current SDK):**` callouts.
+
+For basic setup, see `clerk-setup` skill.
+
+## What Do You Need?
+
+| Task | Reference |
+|------|-----------|
+| Server vs client auth (`auth()` vs hooks) | references/server-vs-client.md |
+| Configure middleware (public-first vs protected-first) | references/middleware-strategies.md |
+| Protect Server Actions | references/server-actions.md |
+| API route auth (401 vs 403) | references/api-routes.md |
+| Cache auth data (user-scoped caching) | references/caching-auth.md |
+
+## References
+
+| Reference | Description |
+|-----------|-------------|
+| `references/server-vs-client.md` | `await auth()` vs hooks |
+| `references/middleware-strategies.md` | Public-first vs protected-first, `proxy.ts` (Next.js <=15: `middleware.ts`) |
+| `references/server-actions.md` | Protect mutations |
+| `references/api-routes.md` | 401 vs 403 |
+| `references/caching-auth.md` | User-scoped caching |
+
+## Mental Model
+
+Server vs Client = different auth APIs:
+- **Server**: `await auth()` from `@clerk/nextjs/server` (async!)
+- **Client**: `useAuth()` hook from `@clerk/nextjs` (sync)
+
+Never mix them. Server Components use server imports, Client Components use hooks.
+
+Key properties from `auth()`:
+- `isAuthenticated` — boolean, replaces the `!!userId` pattern
+- `sessionStatus` — `'active'` | `'pending'`, for detecting incomplete session tasks
+- `userId`, `orgId`, `orgSlug`, `has()`, `protect()` — unchanged
+
+> **Core 2 ONLY (skip if current SDK):** `isAuthenticated` and `sessionStatus` are not available. Check `!!userId` instead.
+
+## Minimal Pattern
+
+```typescript
+// Server Component
+import { auth } from '@clerk/nextjs/server'
+
+export default async function Page() {
+ const { isAuthenticated, userId } = await auth() // MUST await!
+ if (!isAuthenticated) return Not signed in
+ return Hello {userId}
+}
+```
+
+> **Core 2 ONLY (skip if current SDK):** `isAuthenticated` is not available. Use `if (!userId)` instead.
+
+### Conditional Rendering with ``
+
+For client-side conditional rendering based on auth state:
+
+```tsx
+import { Show } from '@clerk/nextjs'
+
+Please sign in}>
+
+
+```
+
+> **Core 2 ONLY (skip if current SDK):** Use `` and `` components instead of ``. See `clerk-custom-ui` skill, `core-3/show-component.md` for the full migration table.
+
+## Common Pitfalls
+
+| Symptom | Cause | Fix |
+|---------|-------|-----|
+| `undefined` userId in Server Component | Missing `await` | `await auth()` not `auth()` |
+| Auth not working on API routes | Missing matcher | Add `'/(api|trpc)(.*)'` to `proxy.ts` (Next.js <=15: `middleware.ts`) |
+| Cache returns wrong user's data | Missing userId in key | Include `userId` in `unstable_cache` key |
+| Mutations bypass auth | Unprotected Server Action | Check `auth()` at start of action |
+| Wrong HTTP error code | Confused 401/403 | 401 = not signed in, 403 = no permission |
+
+## Session Tokens & Custom JWTs
+
+### getToken() for external APIs
+
+Pass a custom JWT to third-party services (Hasura, Supabase, etc.) using JWT templates defined in the Clerk dashboard.
+
+**Server-side (Server Component or Route Handler)**:
+
+```typescript
+import { auth } from '@clerk/nextjs/server'
+
+export default async function Page() {
+ const { getToken } = await auth()
+ const token = await getToken({ template: 'hasura' })
+ if (!token) return Not authenticated
+
+ const res = await fetch('https://api.example.com/graphql', {
+ headers: { Authorization: `Bearer ${token}` },
+ })
+ const data = await res.json()
+ return {JSON.stringify(data)}
+}
+```
+
+**Client-side (Client Component)**:
+
+```typescript
+'use client'
+import { useAuth } from '@clerk/nextjs'
+
+export function DataFetcher() {
+ const { getToken } = useAuth()
+
+ async function fetchData() {
+ const token = await getToken({ template: 'supabase' })
+ if (!token) return
+
+ const res = await fetch('https://api.example.com/data', {
+ headers: { Authorization: `Bearer ${token}` },
+ })
+ return res.json()
+ }
+
+ return Fetch
+}
+```
+
+`getToken()` returns `null` when the user is not authenticated — always null-check before use.
+
+### useSession() for session data
+
+Access session metadata in client components:
+
+```typescript
+'use client'
+import { useSession } from '@clerk/nextjs'
+
+export function SessionInfo() {
+ const { session } = useSession()
+ if (!session) return null
+
+ return (
+
+ Session {session.id} — last active: {session.lastActiveAt.toISOString()}
+
+ )
+}
+```
+
+### Manual JWT verification (no Clerk middleware)
+
+For standalone API servers that receive Clerk session tokens from the `Authorization` header or the `__session` cookie (same-origin).
+
+**Using `@clerk/backend` `verifyToken`** (recommended):
+
+```typescript
+import { verifyToken } from '@clerk/backend'
+
+const token = req.headers.authorization?.replace('Bearer ', '')
+if (!token) return res.status(401).json({ error: 'No token' })
+
+try {
+ const claims = await verifyToken(token, {
+ jwtKey: process.env.CLERK_JWT_KEY,
+ })
+ // claims.sub = userId
+} catch {
+ return res.status(401).json({ error: 'Invalid token' })
+}
+```
+
+**Using `jsonwebtoken`** (when you can't use `@clerk/backend`):
+
+```typescript
+import jwt from 'jsonwebtoken'
+
+const publicKey = process.env.CLERK_PEM_PUBLIC_KEY!.replace(/\\n/g, '\n')
+const token = req.headers.authorization?.replace('Bearer ', '')
+if (!token) return res.status(401).json({ error: 'No token' })
+
+try {
+ const claims = jwt.verify(token, publicKey, { algorithms: ['RS256'] }) as jwt.JwtPayload
+ // Manually check exp and nbf (jsonwebtoken does this automatically, but verify azp if needed)
+ // claims.sub = userId
+} catch {
+ return res.status(401).json({ error: 'Invalid or expired token' })
+}
+```
+
+Token sources:
+- **Same-origin requests**: `__session` cookie (Clerk sets this automatically)
+- **Cross-origin / mobile / API-to-API**: `Authorization: Bearer ` header
+
+> **CRITICAL**: Always check `exp` and `nbf` claims. `verifyToken` from `@clerk/backend` handles this automatically; with raw `jsonwebtoken`, set `ignoreExpiration: false` (default) and ensure `clockTolerance` is minimal.
+
+## See Also
+
+- `clerk-setup`
+- `clerk-orgs`
+
+## Docs
+
+[Next.js SDK](https://clerk.com/docs/reference/nextjs/overview)
diff --git a/.agents/skills/clerk-nextjs-patterns/evals/evals.json b/.agents/skills/clerk-nextjs-patterns/evals/evals.json
new file mode 100644
index 0000000..f2f0cb9
--- /dev/null
+++ b/.agents/skills/clerk-nextjs-patterns/evals/evals.json
@@ -0,0 +1,82 @@
+{
+ "skill_name": "clerk-nextjs-patterns",
+ "evals": [
+ {
+ "id": 1,
+ "prompt": "my dashboard page uses useAuth and useUser hooks with useEffect for redirect. this causes a flash of unauthenticated content. convert it to a server component using auth() from @clerk/nextjs/server instead.",
+ "expected_output": "Converts dashboard from client component with hooks to server component with auth(), removes useEffect redirect pattern",
+ "scaffold": "nextjs-basic-auth",
+ "expectations": [
+ "Removes 'use client' directive from dashboard page",
+ "Replaces useAuth/useUser hooks with auth() from @clerk/nextjs/server",
+ "Uses server-side redirect() from next/navigation instead of useEffect + router.push",
+ "Removes useEffect, useRouter, isLoaded checks",
+ "Page still displays user data (userId from auth or currentUser)"
+ ]
+ },
+ {
+ "id": 2,
+ "prompt": "my api route at app/api/data/route.ts has no auth protection. anyone can access the data. add clerk auth to this api route so only authenticated users can get the data, and return 401 for unauthenticated requests.",
+ "expected_output": "Adds auth() check to API route, returns 401 for unauthenticated requests",
+ "scaffold": "nextjs-basic-auth",
+ "expectations": [
+ "Imports auth from @clerk/nextjs/server",
+ "Calls auth() at the top of the GET handler",
+ "Returns 401 status when userId is null",
+ "Only returns data when user is authenticated",
+ "Does NOT use client-side hooks in the API route"
+ ]
+ },
+ {
+ "id": 3,
+ "prompt": "my homepage is a client component that uses useUser to check if the user is signed in. convert it to use clerk's Show component pattern instead so it can be a server component with conditional rendering.",
+ "expected_output": "Converts home page to use SignedIn/SignedOut or Show components instead of useUser hook",
+ "scaffold": "nextjs-basic-auth",
+ "expectations": [
+ "Removes 'use client' directive from home page",
+ "Removes useUser hook import and usage",
+ "Uses SignedIn/SignedOut components from @clerk/nextjs for conditional rendering",
+ "Preserves the same visual output (welcome message when signed in, sign-in prompt when not)",
+ "Page works as a server component"
+ ]
+ },
+ {
+ "id": 4,
+ "prompt": "i need to protect all routes under /dashboard with clerk middleware instead of checking auth in each page component. update the middleware to use createRouteMatcher so only / and /sign-in are public.",
+ "expected_output": "Updates middleware.ts to use createRouteMatcher with public routes, protecting /dashboard and all sub-routes",
+ "scaffold": "nextjs-basic-auth",
+ "expectations": [
+ "Imports createRouteMatcher from @clerk/nextjs/server",
+ "Defines public routes array including / and /sign-in",
+ "Uses auth.protect() for non-public routes inside clerkMiddleware callback",
+ "Middleware protects /dashboard, /profile, and /api routes",
+ "Does NOT remove the clerkMiddleware wrapper"
+ ]
+ },
+ {
+ "id": 5,
+ "prompt": "i need to call an external API (Hasura GraphQL) from my Next.js server component. get a custom JWT using a template called 'hasura' and pass it in the Authorization header.",
+ "expected_output": "Uses getToken with template parameter from auth() server-side, passes as Bearer token to external API",
+ "scaffold": "nextjs-basic-auth",
+ "expectations": [
+ "Uses getToken with a template parameter (e.g. 'hasura') to get a custom JWT",
+ "Uses either auth() server-side or useAuth() client-side to access getToken",
+ "Passes the token as Authorization Bearer header to the external API call",
+ "Handles the case where getToken returns null (user not authenticated)"
+ ]
+ },
+ {
+ "id": 6,
+ "prompt": "i have a standalone Node.js API server that receives requests with a Clerk session token in the Authorization header. i need to verify the JWT signature and check if the user is authenticated. i don't want to use Clerk middleware, just manual verification.",
+ "expected_output": "Manually verifies Clerk JWT using jsonwebtoken or @clerk/backend verifyToken, checks claims",
+ "scaffold": "nextjs-basic-auth",
+ "expectations": [
+ "Extracts the token from the Authorization Bearer header",
+ "Verifies the token using either jsonwebtoken with CLERK_PEM_PUBLIC_KEY or @clerk/backend verifyToken",
+ "Checks token expiration (exp claim) and not-before (nbf claim)",
+ "Returns 401 for invalid or expired tokens",
+ "Returns the decoded claims or user data on successful verification"
+ ]
+ }
+ ]
+}
diff --git a/.agents/skills/clerk-nextjs-patterns/references/api-routes.md b/.agents/skills/clerk-nextjs-patterns/references/api-routes.md
new file mode 100644
index 0000000..e45bfa2
--- /dev/null
+++ b/.agents/skills/clerk-nextjs-patterns/references/api-routes.md
@@ -0,0 +1,50 @@
+# API Routes (HIGH)
+
+## Auth Check Pattern
+
+```typescript
+import { auth } from '@clerk/nextjs/server';
+
+export async function GET() {
+ const { isAuthenticated, userId } = await auth();
+ if (!isAuthenticated) {
+ return Response.json({ error: 'Unauthorized' }, { status: 401 });
+ }
+ const data = await db.data.findMany({ where: { userId } });
+ return Response.json(data);
+}
+```
+
+> **Core 2 ONLY (skip if current SDK):** `isAuthenticated` is not available. Use `if (!userId)` instead.
+
+## 401 vs 403
+
+- **401** - Not authenticated
+- **403** - Authenticated but lacks permission
+
+```typescript
+export async function DELETE(req: Request) {
+ const { isAuthenticated, has } = await auth();
+ if (!isAuthenticated) return Response.json({ error: 'Unauthorized' }, { status: 401 });
+
+ const isAdmin = await has({ role: 'org:admin' });
+ if (!isAdmin) return Response.json({ error: 'Forbidden' }, { status: 403 });
+
+ return Response.json({ success: true });
+}
+```
+
+## Org Route Protection
+
+```typescript
+export async function GET(req: Request, { params }: { params: { orgId: string } }) {
+ const { userId, orgId } = await auth();
+ if (!userId) return Response.json({ error: 'Unauthorized' }, { status: 401 });
+ if (orgId !== params.orgId) return Response.json({ error: 'Forbidden' }, { status: 403 });
+
+ const orgData = await db.orgs.findUnique({ where: { id: orgId } });
+ return Response.json(orgData);
+}
+```
+
+[Docs](https://clerk.com/docs/reference/nextjs/auth)
diff --git a/.agents/skills/clerk-nextjs-patterns/references/caching-auth.md b/.agents/skills/clerk-nextjs-patterns/references/caching-auth.md
new file mode 100644
index 0000000..d67ea44
--- /dev/null
+++ b/.agents/skills/clerk-nextjs-patterns/references/caching-auth.md
@@ -0,0 +1,56 @@
+# Caching with Auth (CRITICAL)
+
+**CRITICAL**: Cache keys MUST include userId/orgId to prevent data leaking between users.
+
+## User-Scoped Cache
+
+```typescript
+import { auth } from '@clerk/nextjs/server';
+import { unstable_cache } from 'next/cache';
+
+export default async function ProfilePage() {
+ const { userId } = await auth();
+ if (!userId) return Not signed in
;
+
+ const cachedGetUserData = unstable_cache(
+ () => getUserData(userId),
+ [`user-${userId}`],
+ { revalidate: 60, tags: [`user-${userId}`] }
+ );
+
+ const userData = await cachedGetUserData();
+ return {userData.name}
;
+}
+```
+
+## Revalidate After Updates
+
+```typescript
+'use server';
+import { revalidateTag } from 'next/cache';
+import { auth } from '@clerk/nextjs/server';
+
+export async function updateProfile(formData: FormData) {
+ const { userId } = await auth();
+ if (!userId) throw new Error('Unauthorized');
+
+ await db.users.update({
+ where: { id: userId },
+ data: { name: formData.get('name') as string },
+ });
+ revalidateTag(`user-${userId}`);
+}
+```
+
+## Org-Scoped Cache
+
+```typescript
+const { orgId } = await auth();
+const getOrgData = unstable_cache(
+ () => db.orgData.findMany({ where: { organizationId: orgId } }),
+ [`org-${orgId}-data`],
+ { revalidate: 300, tags: [`org-${orgId}`] }
+);
+```
+
+[Docs](https://nextjs.org/docs/app/building-your-application/caching)
diff --git a/.agents/skills/clerk-nextjs-patterns/references/middleware-strategies.md b/.agents/skills/clerk-nextjs-patterns/references/middleware-strategies.md
new file mode 100644
index 0000000..9ca7e91
--- /dev/null
+++ b/.agents/skills/clerk-nextjs-patterns/references/middleware-strategies.md
@@ -0,0 +1,68 @@
+# Middleware Strategies (HIGH)
+
+> **Filename:** `proxy.ts` (Next.js <=15: `middleware.ts`). The code is identical; only the filename changes.
+
+## Public-First (marketing sites, blogs)
+
+Protect specific routes, allow everything else:
+
+```typescript
+import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server';
+
+const isProtectedRoute = createRouteMatcher([
+ '/dashboard(.*)',
+ '/settings(.*)',
+ '/api/private(.*)',
+]);
+
+export default clerkMiddleware(async (auth, req) => {
+ if (isProtectedRoute(req)) await auth.protect();
+});
+
+export const config = {
+ matcher: [
+ '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)',
+ '/(api|trpc)(.*)',
+ ],
+};
+```
+
+## Protected-First (internal tools, dashboards)
+
+Block everything, allow specific public routes:
+
+```typescript
+import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server';
+
+const isPublicRoute = createRouteMatcher([
+ '/',
+ '/sign-in(.*)',
+ '/sign-up(.*)',
+ '/api/public(.*)',
+]);
+
+export default clerkMiddleware(async (auth, req) => {
+ if (!isPublicRoute(req)) await auth.protect();
+});
+```
+
+## Session Tasks
+
+When session tasks are enabled (e.g., forced password reset, MFA setup), users may have a `pending` session status. You can handle this in middleware:
+
+```typescript
+export default clerkMiddleware(async (auth, req) => {
+ const { sessionStatus } = await auth();
+
+ // Redirect pending sessions to task completion page
+ if (sessionStatus === 'pending') {
+ return NextResponse.redirect(new URL('/sign-in/tasks', req.url));
+ }
+
+ if (isProtectedRoute(req)) await auth.protect();
+});
+```
+
+> **Core 2 ONLY (skip if current SDK):** `sessionStatus` is not available. Session tasks do not exist in Core 2.
+
+[Docs](https://clerk.com/docs/reference/nextjs/clerk-middleware)
diff --git a/.agents/skills/clerk-nextjs-patterns/references/server-actions.md b/.agents/skills/clerk-nextjs-patterns/references/server-actions.md
new file mode 100644
index 0000000..3c286f7
--- /dev/null
+++ b/.agents/skills/clerk-nextjs-patterns/references/server-actions.md
@@ -0,0 +1,56 @@
+# Server Actions (HIGH)
+
+Server Actions are public endpoints. Always verify auth.
+
+## Basic Protection
+
+```typescript
+'use server';
+import { auth } from '@clerk/nextjs/server';
+
+export async function createPost(formData: FormData) {
+ const { isAuthenticated, userId } = await auth();
+ if (!isAuthenticated) throw new Error('Unauthorized');
+
+ const title = formData.get('title') as string;
+ await db.posts.create({ data: { title, authorId: userId } });
+ revalidatePath('/posts');
+}
+```
+
+## Org + Role Check (B2B)
+
+```typescript
+'use server';
+import { auth } from '@clerk/nextjs/server';
+
+export async function createTeamProject(formData: FormData) {
+ const { userId, orgId, orgRole } = await auth();
+ if (!userId || !orgId) throw new Error('Must be in an organization');
+ if (orgRole !== 'org:admin') throw new Error('Only admins can create projects');
+
+ const name = formData.get('name') as string;
+ await db.projects.create({ data: { name, organizationId: orgId } });
+}
+```
+
+## Permission Check (RBAC)
+
+```typescript
+'use server';
+import { auth } from '@clerk/nextjs/server';
+
+export async function deleteProject(projectId: string) {
+ const { userId, has } = await auth();
+ if (!userId) throw new Error('Unauthorized');
+
+ const canDelete = await has({ permission: 'org:project:delete' });
+ if (!canDelete) throw new Error('Missing permission');
+
+ await db.projects.delete({ where: { id: projectId } });
+}
+```
+
+> **Core 2 ONLY (skip if current SDK):** `isAuthenticated` is not available. Use `if (!userId)` instead.
+
+[Docs](https://clerk.com/docs/reference/nextjs/server-actions)
diff --git a/.agents/skills/clerk-nextjs-patterns/references/server-vs-client.md b/.agents/skills/clerk-nextjs-patterns/references/server-vs-client.md
new file mode 100644
index 0000000..bf0e659
--- /dev/null
+++ b/.agents/skills/clerk-nextjs-patterns/references/server-vs-client.md
@@ -0,0 +1,104 @@
+# Server vs Client (CRITICAL)
+
+## CRITICAL: Always `await auth()`
+
+```tsx
+// WRONG
+const { userId } = auth(); // undefined!
+
+// CORRECT
+const { userId } = await auth();
+```
+
+## When to Use
+
+- **Server Components** - Initial load, SEO, DB queries
+- **Client Components** - Interactive UI, sign out, token fetching
+
+## Import Rules
+
+```tsx
+// Server Components
+import { auth, currentUser } from '@clerk/nextjs/server';
+
+// Client Components
+'use client';
+import { useAuth, useUser } from '@clerk/nextjs';
+```
+
+## Server Component
+
+```tsx
+import { auth, currentUser } from '@clerk/nextjs/server';
+
+export default async function DashboardPage() {
+ const { isAuthenticated } = await auth();
+ if (!isAuthenticated) return Please sign in
;
+
+ const user = await currentUser();
+ return Welcome, {user?.firstName}! ;
+}
+```
+
+> **Core 2 ONLY (skip if current SDK):** `isAuthenticated` is not available. Use `const { userId } = await auth()` and check `if (!userId)` instead.
+
+## Client Component
+
+```tsx
+'use client';
+import { useUser, useAuth } from '@clerk/nextjs';
+
+export function UserDashboard() {
+ const { isLoaded, isSignedIn, user } = useUser();
+ const { signOut } = useAuth();
+
+ if (!isLoaded) return Loading...
;
+ if (!isSignedIn) return Not signed in
;
+
+ return (
+
+
Hello, {user.firstName}!
+
signOut()}>Sign out
+
+ );
+}
+```
+
+## Hybrid Pattern
+
+```tsx
+// Server: fetch initial data
+import { currentUser } from '@clerk/nextjs/server';
+import { ProfileForm } from './ProfileForm';
+
+export default async function ProfilePage() {
+ const user = await currentUser();
+ if (!user) return Please sign in
;
+ return ;
+}
+
+// Client: handle interactions
+'use client';
+import { useUser } from '@clerk/nextjs';
+
+export function ProfileForm({ initialData }) {
+ const { user } = useUser();
+ return ;
+}
+```
+
+## Conditional Rendering
+
+Use `` for client-side conditional rendering based on auth state:
+
+```tsx
+import { Show } from '@clerk/nextjs';
+
+Please sign in}>
+
+
+```
+
+> **Core 2 ONLY (skip if current SDK):** Use `` and `` components instead of ``.
+
+[Docs](https://clerk.com/docs/reference/nextjs/auth)
diff --git a/.agents/skills/clerk-nextjs-patterns/templates/nextjs-basic-auth/app/layout.tsx b/.agents/skills/clerk-nextjs-patterns/templates/nextjs-basic-auth/app/layout.tsx
new file mode 100644
index 0000000..aec51d9
--- /dev/null
+++ b/.agents/skills/clerk-nextjs-patterns/templates/nextjs-basic-auth/app/layout.tsx
@@ -0,0 +1,22 @@
+import { ClerkProvider, Show, SignInButton, SignUpButton, UserButton } from '@clerk/nextjs'
+
+export default function RootLayout({ children }: { children: React.ReactNode }) {
+ return (
+
+
+
+
+ {children}
+
+
+
+ )
+}
diff --git a/.agents/skills/clerk-nextjs-patterns/templates/nextjs-basic-auth/app/page.tsx b/.agents/skills/clerk-nextjs-patterns/templates/nextjs-basic-auth/app/page.tsx
new file mode 100644
index 0000000..3e62e69
--- /dev/null
+++ b/.agents/skills/clerk-nextjs-patterns/templates/nextjs-basic-auth/app/page.tsx
@@ -0,0 +1,3 @@
+export default function Home() {
+ return Home
+}
diff --git a/.agents/skills/clerk-nextjs-patterns/templates/nextjs-basic-auth/package.json b/.agents/skills/clerk-nextjs-patterns/templates/nextjs-basic-auth/package.json
new file mode 100644
index 0000000..f8c6bf6
--- /dev/null
+++ b/.agents/skills/clerk-nextjs-patterns/templates/nextjs-basic-auth/package.json
@@ -0,0 +1,16 @@
+{
+ "name": "clerk-nextjs",
+ "private": true,
+ "scripts": { "dev": "next dev", "build": "next build" },
+ "dependencies": {
+ "next": "latest",
+ "react": "latest",
+ "react-dom": "latest",
+ "@clerk/nextjs": "latest"
+ },
+ "devDependencies": {
+ "typescript": "latest",
+ "@types/react": "latest",
+ "@types/react-dom": "latest"
+ }
+}
diff --git a/.agents/skills/clerk-nextjs-patterns/templates/nextjs-basic-auth/proxy.ts b/.agents/skills/clerk-nextjs-patterns/templates/nextjs-basic-auth/proxy.ts
new file mode 100644
index 0000000..cca0334
--- /dev/null
+++ b/.agents/skills/clerk-nextjs-patterns/templates/nextjs-basic-auth/proxy.ts
@@ -0,0 +1,10 @@
+import { clerkMiddleware } from '@clerk/nextjs/server'
+
+export default clerkMiddleware()
+
+export const config = {
+ matcher: [
+ '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)',
+ '/(api|trpc)(.*)',
+ ],
+}
diff --git a/.agents/skills/clerk-nextjs-patterns/templates/nextjs-basic-auth/tsconfig.json b/.agents/skills/clerk-nextjs-patterns/templates/nextjs-basic-auth/tsconfig.json
new file mode 100644
index 0000000..b8cdcc7
--- /dev/null
+++ b/.agents/skills/clerk-nextjs-patterns/templates/nextjs-basic-auth/tsconfig.json
@@ -0,0 +1,23 @@
+{
+ "compilerOptions": {
+ "target": "ES2017",
+ "lib": ["dom", "dom.iterable", "esnext"],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": true,
+ "noEmit": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "bundler",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "preserve",
+ "incremental": true,
+ "plugins": [{ "name": "next" }],
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ },
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
+ "exclude": ["node_modules"]
+}
diff --git a/.agents/skills/clerk-setup/SKILL.md b/.agents/skills/clerk-setup/SKILL.md
new file mode 100644
index 0000000..1ad9d01
--- /dev/null
+++ b/.agents/skills/clerk-setup/SKILL.md
@@ -0,0 +1,266 @@
+---
+name: clerk-setup
+description: Add Clerk authentication to any project by following the official quickstart
+ guides.
+license: MIT
+allowed-tools: WebFetch
+metadata:
+ author: clerk
+ version: 2.3.0
+---
+
+# Adding Clerk
+
+> **Version**: Check `package.json` for the SDK version — see `clerk` skill for the version table. Core 2 differences are noted inline with `> **Core 2 ONLY (skip if current SDK):**` callouts.
+
+This skill sets up Clerk for authentication by following the official quickstart documentation.
+
+## Quick Reference
+
+| Step | Action |
+|------|--------|
+| 1. Detect framework | Check `package.json` dependencies |
+| 2. Fetch quickstart | Use WebFetch on the appropriate docs URL |
+| 3. Follow instructions | Execute steps; create `proxy.ts` (Next.js <=15: `middleware.ts`) |
+| 4. Get API keys | From [dashboard.clerk.com](https://dashboard.clerk.com/last-active?path=api-keys) |
+
+> If the project has `components.json` (shadcn/ui), apply the shadcn theme after setup. See `clerk-custom-ui` skill → shadcn Theme.
+
+## Framework Detection
+
+Check `package.json` to identify the framework:
+
+| Dependency | Framework | Quickstart URL |
+|------------|-----------|----------------|
+| `next` | Next.js | `https://clerk.com/docs/nextjs/getting-started/quickstart` |
+| `@remix-run/react` | Remix | `https://clerk.com/docs/remix/getting-started/quickstart` |
+| `astro` | Astro | `https://clerk.com/docs/astro/getting-started/quickstart` |
+| `nuxt` | Nuxt | `https://clerk.com/docs/nuxt/getting-started/quickstart` |
+| `react-router` | React Router | `https://clerk.com/docs/react-router/getting-started/quickstart` |
+| `@tanstack/react-start` | TanStack Start | `https://clerk.com/docs/tanstack-react-start/getting-started/quickstart` |
+| `react` (no framework) | React SPA | `https://clerk.com/docs/react/getting-started/quickstart` |
+| `vue` | Vue | `https://clerk.com/docs/vue/getting-started/quickstart` |
+| `express` | Express | `https://clerk.com/docs/expressjs/getting-started/quickstart` |
+| `fastify` | Fastify | `https://clerk.com/docs/fastify/getting-started/quickstart` |
+| `expo` | Expo | `https://clerk.com/docs/expo/getting-started/quickstart` |
+
+For other platforms:
+- **Chrome Extension**: `https://clerk.com/docs/chrome-extension/getting-started/quickstart`
+- **Android**: `https://clerk.com/docs/android/getting-started/quickstart`
+- **iOS**: `https://clerk.com/docs/ios/getting-started/quickstart`
+- **Vanilla JavaScript**: `https://clerk.com/docs/js-frontend/getting-started/quickstart`
+
+## Decision Tree
+
+```
+User Request: "Add Clerk" / "Add authentication"
+ │
+ ├─ Read package.json
+ │
+ ├─ Existing auth detected?
+ │ ├─ YES → Audit → Migration plan
+ │ └─ NO → Fresh install
+ │
+ ├─ Identify framework → WebFetch quickstart → Follow instructions
+ │ └─ Next.js? → Create proxy.ts (Next.js <=15: middleware.ts)
+ │
+ └─ components.json exists? → YES → Apply shadcn theme (see clerk-custom-ui)
+```
+
+## Setup Process
+
+### 1. Detect the Framework
+
+Read the project's `package.json` and match dependencies to the table above.
+
+### 2. Fetch the Quickstart Guide
+
+Use WebFetch to retrieve the official quickstart for the detected framework:
+
+```
+WebFetch: https://clerk.com/docs/{framework}/getting-started/quickstart
+Prompt: "Extract the complete setup instructions including all code snippets, file paths, and configuration steps."
+```
+
+### 3. Follow the Instructions
+
+Execute each step from the quickstart guide:
+- Install the required packages
+- Set up environment variables
+- Add the provider and proxy/middleware
+- Create sign-in/sign-up routes if needed
+- Test the integration
+
+> **Next.js:** Create `proxy.ts` (Next.js <=15: `middleware.ts`). See the `clerk-nextjs-patterns` skill for middleware strategies.
+
+> **shadcn/ui detected** (`components.json` exists): ALWAYS apply the shadcn theme. See `clerk-custom-ui` skill → shadcn Theme section.
+
+### 4. Get API Keys
+
+Two paths for development API keys:
+
+**Keyless (Automatic)**
+- On first SDK initialization, Clerk auto-generates dev keys and shows "Claim your application" popover
+- No manual key setup required—keys are created and injected automatically
+- Simplest path for new projects
+
+**Manual (Dashboard)**
+- Get keys from [dashboard.clerk.com](https://dashboard.clerk.com/last-active?path=api-keys) if Keyless doesn't trigger
+- **Publishable Key**: Starts with `pk_test_` or `pk_live_`
+- **Secret Key**: Starts with `sk_test_` or `sk_live_`
+- Set as environment variables: `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY` and `CLERK_SECRET_KEY`
+
+## Migrating from Another Auth Provider
+
+If the project already has authentication, create a migration plan before replacing it.
+
+### Detect Existing Auth
+
+Check `package.json` for existing auth libraries:
+- `next-auth` / `@auth/core` → NextAuth/Auth.js
+- `@supabase/supabase-js` → Supabase Auth
+- `firebase` / `firebase-admin` → Firebase Auth
+- `@aws-amplify/auth` → AWS Cognito
+- `auth0` / `@auth0/nextjs-auth0` → Auth0
+- `passport` → Passport.js
+- Custom JWT/session implementation
+
+### Migration Process
+
+1. **Audit current auth** - Identify all auth touchpoints:
+ - Sign-in/sign-up pages
+ - Session/token handling
+ - Protected routes and middleware
+ - User data storage (database tables, external IDs)
+ - OAuth providers configured
+
+2. **Create migration plan** - Consider:
+ - **User data export** - Export users and import via Clerk's Backend API
+ - **Password hashes** - Clerk can upgrade hashes to Bcrypt transparently
+ - **External IDs** - Store legacy user IDs as `external_id` in Clerk
+ - **Session handling** - Existing sessions will terminate on switch
+
+3. **Choose migration strategy**:
+ - **Big bang** - Switch all users at once (simpler, requires maintenance window)
+ - **Trickle migration** - Run both systems temporarily (lower risk, higher complexity)
+
+### Migration Reference
+
+- **Migration Overview**: https://clerk.com/docs/guides/development/migrating/overview
+
+## SDK Notes
+
+### Package Names
+
+| Package | Install |
+|---------|---------|
+| Next.js | `@clerk/nextjs` |
+| React | `@clerk/react` |
+| Expo | `@clerk/expo` |
+| React Router | `@clerk/react-router` |
+| TanStack Start | `@clerk/tanstack-react-start` |
+
+> **Core 2 ONLY (skip if current SDK):** React and Expo packages have different names: `@clerk/clerk-react` and `@clerk/clerk-expo` (with `clerk-` prefix).
+
+### ClerkProvider Placement (Next.js)
+
+`ClerkProvider` must be placed **inside ``**, not wrapping ``:
+
+```tsx
+// root layout.tsx
+export default function RootLayout({ children }) {
+ return (
+
+
+ {children}
+
+
+ )
+}
+```
+
+> **Core 2 ONLY (skip if current SDK):** `ClerkProvider` can wrap `` directly.
+
+### Dynamic Rendering (Next.js)
+
+For dynamic rendering with auth data, use the `dynamic` prop:
+
+```tsx
+{children}
+```
+
+### Node.js Requirement
+
+Requires **Node.js 20.9.0** or higher.
+
+> **Core 2 ONLY (skip if current SDK):** Minimum Node.js 18.17.0.
+
+### Themes Package
+
+Themes are installed from `@clerk/ui`:
+
+```bash
+npm install @clerk/ui
+```
+
+> **Core 2 ONLY (skip if current SDK):** Themes are from `@clerk/themes` instead of `@clerk/ui`.
+
+### shadcn Theme
+
+If the project uses shadcn/ui (check for `components.json` in the project root), apply the shadcn theme so Clerk components match the app's design system:
+
+```bash
+npm install @clerk/ui
+```
+
+```tsx
+import { shadcn } from '@clerk/ui/themes'
+
+{children}
+```
+
+Also import the shadcn CSS in your global styles:
+```css
+@import 'tailwindcss';
+@import '@clerk/ui/themes/shadcn.css';
+```
+
+> **Core 2 ONLY (skip if current SDK):** Import from `@clerk/themes` and `@clerk/themes/shadcn.css` instead.
+
+## Common Pitfalls
+
+| Level | Issue | Solution |
+|-------|-------|----------|
+| CRITICAL | Missing `await` on `auth()` | In Next.js 15+, `auth()` is async: `const { userId } = await auth()` |
+| CRITICAL | Exposing `CLERK_SECRET_KEY` | Never use secret key in client code; only `NEXT_PUBLIC_*` keys are safe |
+| HIGH | Missing middleware matcher | Include API routes: `matcher: ['/((?!.*\\..*|_next).*)', '/']` |
+| HIGH | ClerkProvider placement | Must be inside `` in root layout (Core 2: could wrap ``) |
+| HIGH | Auth routes not public | Allow `/sign-in`, `/sign-up` in middleware config |
+| HIGH | Landing page requires auth | To keep "/" public, exclude it: `matcher: ['/((?!.*\\..*|_next|^/$).*)', '/api/(.*)']` |
+| MEDIUM | Wrong import path | Server code uses `@clerk/nextjs/server`, client uses `@clerk/nextjs` |
+| MEDIUM | Wrong package name | Use `@clerk/react` not `@clerk/clerk-react` (Core 2 naming) |
+
+## See Also
+
+- `clerk-custom-ui` - Custom sign-in/up components
+- `clerk-nextjs-patterns` - Advanced Next.js patterns
+- `clerk-react-patterns` - React SPA patterns
+- `clerk-react-router-patterns` - React Router patterns
+- `clerk-vue-patterns` - Vue patterns
+- `clerk-nuxt-patterns` - Nuxt patterns
+- `clerk-astro-patterns` - Astro patterns
+- `clerk-tanstack-patterns` - TanStack Start patterns
+- `clerk-expo-patterns` - Expo patterns
+- `clerk-chrome-extension-patterns` - Chrome Extension patterns
+- `clerk-orgs` - B2B multi-tenant organizations
+- `clerk-webhooks` - Webhook → database sync
+- `clerk-testing` - E2E testing setup
+- `clerk-swift` - Native iOS auth
+- `clerk-android` - Native Android auth
+- `clerk-backend-api` - Backend REST API explorer
+
+## Documentation
+
+- **Quickstart Overview**: https://clerk.com/docs/getting-started/quickstart/overview
+- **Migration Guide**: https://clerk.com/docs/guides/development/migrating/overview
+- **Full Documentation**: https://clerk.com/docs
diff --git a/.agents/skills/clerk-setup/evals/evals.json b/.agents/skills/clerk-setup/evals/evals.json
new file mode 100644
index 0000000..c9bd338
--- /dev/null
+++ b/.agents/skills/clerk-setup/evals/evals.json
@@ -0,0 +1,74 @@
+{
+ "skill_name": "clerk-setup",
+ "evals": [
+ {
+ "id": 1,
+ "prompt": "hey i just created a new next.js app with create-next-app and i want to add auth. i heard clerk is good, can you set it up? im using the app router btw and tailwind. project is at ./my-saas-app",
+ "expected_output": "Installs @clerk/nextjs, wraps layout with ClerkProvider inside , creates middleware.ts with clerkMiddleware, sets up .env.local with publishable and secret keys, detects shadcn if present",
+ "files": [],
+ "expectations": [
+ "Installs @clerk/nextjs via npm/pnpm/bun",
+ "Adds ClerkProvider to root layout.tsx inside tag, not wrapping ",
+ "Creates middleware.ts (or proxy.ts for Next.js 16+) with clerkMiddleware export",
+ "Creates or updates .env.local with NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY and CLERK_SECRET_KEY",
+ "Does NOT install @clerk/clerk-react or any non-Next.js Clerk package",
+ "Mentions getting API keys from dashboard.clerk.com or keyless dev mode"
+ ]
+ },
+ {
+ "id": 2,
+ "prompt": "im building a rest api with express and typescript, no frontend. i need to protect some routes with authentication. can you add clerk? i want /api/public to be open and everything under /api/private/* to require auth",
+ "expected_output": "Installs @clerk/express, adds clerkMiddleware globally, uses requireAuth for protected routes, keeps public routes open",
+ "files": [],
+ "expectations": [
+ "Installs @clerk/express (not @clerk/nextjs)",
+ "Adds clerkMiddleware() to the Express app",
+ "Shows how to protect /api/private/* routes with requireAuth or getAuth check",
+ "Leaves /api/public accessible without auth",
+ "Does NOT create React components, ClerkProvider, or any frontend code",
+ "Sets up CLERK_SECRET_KEY (and optionally CLERK_PUBLISHABLE_KEY) env vars"
+ ]
+ },
+ {
+ "id": 3,
+ "prompt": "we have a next.js app thats been using next-auth with google and github oauth for about a year. we want to switch to clerk because next-auth sessions keep expiring randomly. theres about 2000 users in our postgres db. how do we migrate without losing everyone?",
+ "expected_output": "Migration plan: audit current NextAuth setup, export users via Clerk Backend API, handle OAuth provider mapping, plan session transition",
+ "files": [],
+ "expectations": [
+ "Detects or acknowledges existing NextAuth/next-auth setup",
+ "Addresses user data migration (2000 users) - mentions Clerk Backend API import or trickle migration",
+ "Addresses OAuth provider continuity (Google and GitHub)",
+ "Mentions that existing sessions will terminate during switch",
+ "Suggests either big-bang or gradual migration strategy",
+ "Does NOT just install Clerk and ignore the existing auth system"
+ ]
+ },
+ {
+ "id": 4,
+ "prompt": "setting up a react spa with vite for an internal tool at work. no ssr, no next.js. just plain react 19 + react-router. need login/logout. whats the quickest way to get clerk working?",
+ "expected_output": "Installs @clerk/react, wraps app with ClerkProvider, no middleware needed for SPA",
+ "files": [],
+ "expectations": [
+ "Installs @clerk/react (not @clerk/nextjs or @clerk/clerk-react)",
+ "Wraps app root with ClerkProvider and passes publishableKey",
+ "Does NOT create middleware.ts or proxy.ts (not applicable to SPAs)",
+ "Does NOT reference Next.js-specific patterns like server components or auth()",
+ "Shows SignIn/SignUp components or redirect-based auth flow",
+ "Sets up NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY or VITE_CLERK_PUBLISHABLE_KEY env var"
+ ]
+ },
+ {
+ "id": 5,
+ "prompt": "i have an astro site with some react islands, its mostly static but i want to add a members-only section. never used clerk before. using bun as my package manager",
+ "expected_output": "Installs @clerk/astro via bun, configures Astro integration, sets up protected routes for members-only section",
+ "files": [],
+ "expectations": [
+ "Installs @clerk/astro using bun (not npm or pnpm)",
+ "Configures Clerk as an Astro integration in astro.config",
+ "Shows how to protect specific routes for the members-only section",
+ "Sets up environment variables for Clerk keys",
+ "Does NOT install @clerk/nextjs or create Next.js-specific files"
+ ]
+ }
+ ]
+}
diff --git a/.agents/skills/clerk/SKILL.md b/.agents/skills/clerk/SKILL.md
new file mode 100644
index 0000000..568b521
--- /dev/null
+++ b/.agents/skills/clerk/SKILL.md
@@ -0,0 +1,154 @@
+---
+name: clerk
+description: Clerk authentication router. Use when user asks about adding authentication,
+ setting up Clerk, custom sign-in flows, Swift or native iOS auth, native Android
+ auth, Next.js patterns, React patterns, Vue patterns, Nuxt patterns, Astro patterns,
+ TanStack Start patterns, Expo patterns, React Router patterns, Chrome Extension patterns,
+ organizations, billing, subscriptions, payments, pricing, plans, seat-based pricing,
+ feature entitlements, syncing users, or testing. Automatically routes to the specific
+ skill based on their task.
+license: MIT
+metadata:
+ version: 2.0.0
+---
+
+# Clerk Skills Router
+
+## Version Detection
+
+Check `package.json` to determine the Clerk SDK version. This determines which patterns to use:
+
+| Package | Core 2 (LTS until Jan 2027) | Current |
+|---------|----------------------------|---------|
+| `@clerk/nextjs` | v5–v6 | v7+ |
+| `@clerk/react` or `@clerk/clerk-react` | v5–v6 | v7+ |
+| `@clerk/expo` or `@clerk/clerk-expo` | v1–v2 | v3+ |
+| `@clerk/react-router` | v1–v2 | v3+ |
+| `@clerk/tanstack-react-start` | < v0.26.0 | v0.26.0+ |
+
+**Default to current** if the version is unclear or the project is new. Core 2 packages use `@clerk/clerk-react` and `@clerk/clerk-expo` (with `clerk-` prefix); current packages use `@clerk/react` and `@clerk/expo`.
+
+All skills are written for the current SDK. When something differs in Core 2, it's noted inline with `> **Core 2 ONLY (skip if current SDK):**` callouts. The exception is `clerk-custom-ui`, which has separate `core-2/` and `core-3/` directories for custom flow hooks since those APIs are entirely different between versions.
+
+---
+
+## By Task
+
+**Adding Clerk to your project** → Use `clerk-setup`
+- Framework detection and quickstart
+- Environment setup, API keys, Keyless flow
+- Migration from other auth providers
+
+**Custom sign-in/sign-up UI** → Use `clerk-custom-ui`
+- Custom authentication flows with `useSignIn` / `useSignUp` hooks
+- Appearance and styling (themes, colors, layout)
+- `` component for conditional rendering
+
+**Advanced Next.js patterns** → Use `clerk-nextjs-patterns`
+- Server vs Client auth APIs
+- Middleware strategies
+- Server Actions, caching
+- API route protection
+
+**React patterns** → Use `clerk-react-patterns`
+- Hooks (`useAuth`, `useUser`, `useClerk`)
+- Protected routes, auth guards
+- Router integration
+
+**React Router patterns** → Use `clerk-react-router-patterns`
+- Loaders & actions with auth
+- Route protection
+- SSR auth
+
+**Vue patterns** → Use `clerk-vue-patterns`
+- Composables (`useAuth`, `useUser`, `useClerk`)
+- Vue Router guards
+- Pinia auth store integration
+
+**Nuxt patterns** → Use `clerk-nuxt-patterns`
+- Server middleware auth
+- SSR auth with composables
+- Server API routes
+
+**Astro patterns** → Use `clerk-astro-patterns`
+- SSR auth pages
+- Island components with React
+- Middleware & API routes
+
+**TanStack Start patterns** → Use `clerk-tanstack-patterns`
+- Server functions with auth
+- Route protection via loaders
+- Vinxi server integration
+
+**Expo patterns** → Use `clerk-expo-patterns`
+- Secure token storage
+- OAuth deep linking
+- Push notifications with auth
+
+**Chrome Extension patterns** → Use `clerk-chrome-extension-patterns`
+- Background scripts auth
+- Popup auth flows
+- Content scripts with sync host
+
+**B2B / Organizations** → Use `clerk-orgs`
+- Multi-tenant apps
+- Organization slugs in URLs
+- Roles, permissions, RBAC
+- Member management
+
+**Billing & Subscriptions** → Use `clerk-billing`
+- ` ` component
+- Plan and feature gating with `has()`
+- Seat-based B2B billing with organizations
+- Subscription lifecycle webhooks
+- Free trials, invoicing
+
+**Webhooks** → Use `clerk-webhooks`
+- Real-time events
+- Data syncing
+- Notifications & integrations
+
+**E2E Testing** → Use `clerk-testing`
+- Playwright/Cypress setup
+- Auth flow testing
+- Test utilities
+
+**Swift / native iOS auth** → Use `clerk-swift`
+- Native iOS Swift and SwiftUI projects
+- ClerkKit and ClerkKitUI implementation guidance
+- Source-driven patterns from `clerk-ios`
+
+**Android / native mobile auth** → Use `clerk-android`
+- Native Android Kotlin and Jetpack Compose projects
+- `clerk-android-api` and `clerk-android-ui` implementation guidance
+- Source-driven patterns from `clerk-android`
+- Do not use for Expo or React Native projects
+
+**Backend REST API** → Use `clerk-backend-api`
+- Browse API tags and endpoints
+- Inspect endpoint schemas
+- Execute API requests with scope enforcement
+
+## Quick Navigation
+
+If you know your task, you can directly access:
+- `/clerk-setup` - Framework setup
+- `/clerk-custom-ui` - Custom flows & appearance
+- `/clerk-nextjs-patterns` - Next.js patterns
+- `/clerk-react-patterns` - React patterns
+- `/clerk-react-router-patterns` - React Router patterns
+- `/clerk-vue-patterns` - Vue patterns
+- `/clerk-nuxt-patterns` - Nuxt patterns
+- `/clerk-astro-patterns` - Astro patterns
+- `/clerk-tanstack-patterns` - TanStack Start patterns
+- `/clerk-expo-patterns` - Expo patterns
+- `/clerk-chrome-extension-patterns` - Chrome Extension patterns
+- `/clerk-orgs` - Organizations
+- `/clerk-billing` - Billing & subscriptions
+- `/clerk-webhooks` - Webhooks
+- `/clerk-testing` - Testing
+- `/clerk-swift` - Swift/native iOS
+- `/clerk-android` - Native Android
+- `/clerk-backend-api` - Backend REST API
+
+Or describe what you need and I'll recommend the right one.
diff --git a/.gitignore b/.gitignore
index 5ef6a52..20ac9d9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,6 +9,7 @@
!.yarn/plugins
!.yarn/releases
!.yarn/versions
+/context/current-issues.md
# testing
/coverage
diff --git a/app/editor/layout.tsx b/app/editor/layout.tsx
new file mode 100644
index 0000000..57821e6
--- /dev/null
+++ b/app/editor/layout.tsx
@@ -0,0 +1,9 @@
+import { EditorLayout } from "@/components/editor/editor-layout"
+
+export default function ProtectedEditorLayout({
+ children,
+}: Readonly<{
+ children: React.ReactNode
+}>) {
+ return {children}
+}
diff --git a/app/editor/page.tsx b/app/editor/page.tsx
new file mode 100644
index 0000000..3465017
--- /dev/null
+++ b/app/editor/page.tsx
@@ -0,0 +1,7 @@
+export default function EditorPage() {
+ return (
+
+
Ghost AI
+
+ )
+}
diff --git a/app/layout.tsx b/app/layout.tsx
index 1bef101..15a4af1 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -1,6 +1,7 @@
+import { ClerkProvider } from "@clerk/nextjs";
+import { dark } from "@clerk/ui/themes";
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
-import { EditorLayout } from "@/components/editor/editor-layout";
import "./globals.css";
const geistSans = Geist({
@@ -14,8 +15,29 @@ const geistMono = Geist_Mono({
});
export const metadata: Metadata = {
- title: "Create Next App",
- description: "Generated by create next app",
+ title: "Ghost AI",
+ description: "AI workflow editor",
+};
+
+const clerkAppearance = {
+ theme: dark,
+ variables: {
+ colorPrimary: "var(--primary)",
+ colorPrimaryForeground: "var(--primary-foreground)",
+ colorBackground: "var(--popover)",
+ colorForeground: "var(--popover-foreground)",
+ colorMuted: "var(--muted)",
+ colorMutedForeground: "var(--muted-foreground)",
+ colorInput: "var(--input)",
+ colorInputForeground: "var(--foreground)",
+ colorBorder: "var(--border)",
+ colorModalBackdrop: "transparent",
+ colorRing: "var(--ring)",
+ colorDanger: "var(--destructive)",
+ fontFamily: "var(--font-geist-sans)",
+ fontFamilyButtons: "var(--font-geist-sans)",
+ borderRadius: "var(--radius)",
+ },
};
export default function RootLayout({
@@ -29,7 +51,19 @@ export default function RootLayout({
className={`${geistSans.variable} ${geistMono.variable} dark h-full antialiased`}
>
- {children}
+
+ {children}
+
);
diff --git a/app/page.tsx b/app/page.tsx
index c112497..c91c86b 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -1,7 +1,9 @@
-export default function Home() {
- return (
-
-
Ghost AI
-
- );
+import { auth } from "@clerk/nextjs/server";
+import { redirect } from "next/navigation";
+
+export default async function Home() {
+ const { userId } = await auth();
+ const signInUrl = process.env.NEXT_PUBLIC_CLERK_SIGN_IN_URL ?? "/sign-in";
+
+ redirect(userId ? "/editor" : signInUrl);
}
diff --git a/app/sign-in/[[...sign-in]]/page.tsx b/app/sign-in/[[...sign-in]]/page.tsx
new file mode 100644
index 0000000..a2fddb8
--- /dev/null
+++ b/app/sign-in/[[...sign-in]]/page.tsx
@@ -0,0 +1,19 @@
+import { SignIn } from "@clerk/nextjs"
+
+import { AuthPageShell } from "@/components/auth/auth-page-shell"
+
+export default function SignInPage() {
+ return (
+
+
+
+ )
+}
diff --git a/app/sign-up/[[...sign-up]]/page.tsx b/app/sign-up/[[...sign-up]]/page.tsx
new file mode 100644
index 0000000..6946258
--- /dev/null
+++ b/app/sign-up/[[...sign-up]]/page.tsx
@@ -0,0 +1,19 @@
+import { SignUp } from "@clerk/nextjs"
+
+import { AuthPageShell } from "@/components/auth/auth-page-shell"
+
+export default function SignUpPage() {
+ return (
+
+
+
+ )
+}
diff --git a/components/auth/auth-page-shell.tsx b/components/auth/auth-page-shell.tsx
new file mode 100644
index 0000000..55b886c
--- /dev/null
+++ b/components/auth/auth-page-shell.tsx
@@ -0,0 +1,43 @@
+type AuthPageShellProps = {
+ title: string
+ tagline: string
+ children: React.ReactNode
+}
+
+const authFeatures = [
+ "Protected workflow editing",
+ "Project access tied to your account",
+ "Profile and logout handled securely",
+]
+
+function AuthPageShell({ title, tagline, children }: AuthPageShellProps) {
+ return (
+
+
+
+
+
Ghost AI
+
+ {tagline}
+
+
+
+
+
{title}
+
+ {authFeatures.map((feature) => (
+ {feature}
+ ))}
+
+
+
+
+
+
+
+ )
+}
+
+export { AuthPageShell }
diff --git a/components/editor/editor-navbar.tsx b/components/editor/editor-navbar.tsx
index 14ffeaf..bca4572 100644
--- a/components/editor/editor-navbar.tsx
+++ b/components/editor/editor-navbar.tsx
@@ -1,5 +1,6 @@
"use client"
+import { UserButton } from "@clerk/nextjs"
import { PanelLeftClose, PanelLeftOpen } from "lucide-react"
import { Button } from "@/components/ui/button"
@@ -40,7 +41,9 @@ function EditorNavbar({
-
+
+
+
)
}
diff --git a/context/architecture.md b/context/architecture.md
index 02d6772..5bd2cab 100644
--- a/context/architecture.md
+++ b/context/architecture.md
@@ -2,20 +2,21 @@
## Stack
-| Layer | Technology | Role |
-| --------- | --------------------------- | ------ |
-| Framework | [e.g. Next.js + TypeScript] | [Role] |
-| UI | [e.g. Tailwind + shadcn/ui] | [Role] |
-| Auth | [e.g. Clerk] | [Role] |
-| Database | [e.g. Prisma + PostgreSQL] | [Role] |
-| [Layer] | [Technology] | [Role] |
+| Layer | Technology | Role |
+| --------- | -------------------------- | ------------------------------------ |
+| Framework | Next.js 16 + TypeScript | App Router, layouts, pages, proxy |
+| UI | Tailwind CSS + shadcn/ui | Dark themed application components |
+| Auth | Clerk + `@clerk/ui` themes | Authentication, route protection, UI |
## System Boundaries
-- `[folder]` — [What this folder owns and is responsible for]
-- `[folder]` — [What this folder owns and is responsible for]
-- `[folder]` — [What this folder owns and is responsible for]
-- `[folder]` — [What this folder owns and is responsible for]
+- `app/` — Next.js routes and route-specific layouts.
+- `app/sign-in/` and `app/sign-up/` — public Clerk auth pages.
+- `app/editor/` — protected editor route tree wrapped by the editor chrome.
+- `components/editor/` — reusable editor navbar, sidebar, and editor layout shell.
+- `components/auth/` — reusable auth page presentation shell.
+- `components/ui/` — generated shadcn/ui primitives.
+- `proxy.ts` — root-level Clerk route protection for all matched requests.
## Storage Model
@@ -26,17 +27,15 @@
## Auth and Access Model
-- [How authentication works — e.g. Every user signs in
- via Clerk]
-- [How ownership works — e.g. Every project has a single
- owner]
-- [How access control works — e.g. Only the owner or a
- collaborator can mutate project resources]
+- Clerk provides authentication through `ClerkProvider` in the root layout.
+- `/sign-in`, `/sign-up`, and `/` are public entry routes; `/` only redirects users based on auth state.
+- All other matched routes are protected by Clerk in `proxy.ts` by default.
+- Authenticated users are redirected from `/` to `/editor`; unauthenticated users are redirected to `/sign-in`.
+- The editor chrome exposes Clerk's default `UserButton` for profile settings and logout.
## Invariants
-1. [Rule the codebase must never violate — e.g. Request
- handlers do not run long-lived background work]
-2. [Invariant two]
-3. [Invariant three]
-4. [Invariant four]
+1. Use `proxy.ts` for request protection; do not add `middleware.ts`.
+2. Keep Clerk auth UI on Clerk components and avoid rebuilding Clerk internals.
+3. Keep the editor shell under protected editor routes, not around public auth pages.
+4. Use existing Clerk environment variable names for auth URLs and keys.
diff --git a/context/current-issues.md b/context/current-issues.md
new file mode 100644
index 0000000..e69de29
diff --git a/context/feature-spec/03-auth.md b/context/feature-spec/03-auth.md
new file mode 100644
index 0000000..a94fb7a
--- /dev/null
+++ b/context/feature-spec/03-auth.md
@@ -0,0 +1,53 @@
+Clerk is already installed and connected. Wire it into the Next.js app: provider, auth pages, redirects, route protection, and user menu.
+
+## Design
+
+Use Clerk's `dark` theme from `@clerk/ui/themes` as the base.
+
+Override Clerk appearance variables using the app's existing CSS variables. Don't hardcode colors.
+
+### Sign-in and sign-up pages:
+
+- Large screens: Simple "two" "panel" layout
+- left: compact logo, tagline, short text-only feature list
+- right: centered Clerk form
+- small screens: form only
+- no gradients
+- no oversized hero sections
+- no feature cards
+- no scroll-heavy layouts
+
+Keep the layout minimal and professional.
+
+## Implementation
+
+wrap the root layout with `ClerkProvider` using Clerk's `dark` theme.
+
+Create sign-in and sign-up pages using Clerk components.
+
+Use `proxy.ts` at the project root, not `middleware.ts`.
+
+Define public routes using the existing sign-in and sign-up env vars. Protect everything else by default.
+
+Update `/`:
+
+- authenticated users redirect to `/editor`
+- unauthenticated users redirect to `/sign-in`
+
+Add Clerk's built-in `UserButton` to the editor navbar right section for profile settings and logout.
+
+Keep Clerk's default user menu and profile flows intact. Don't rebuild or heavily customize Clerk internals.
+
+Use existing Clerk env vars. Don't rename or invent new ones.
+
+## Dependencies
+
+install: @clerk/ui.
+
+## Check When Done
+
+- `proxy.ts` exists at the root
+- all routes are protected except public auth paths
+- auth pages use CSS variables with no hardcoded colors
+- `ClerkProvider` wraps the root layout
+- `npm run build` passes
\ No newline at end of file
diff --git a/context/progress-tracker.md b/context/progress-tracker.md
index 9c13a8b..2b4cbec 100644
--- a/context/progress-tracker.md
+++ b/context/progress-tracker.md
@@ -9,7 +9,7 @@ change.
## Current Goal
-- Editor shell foundation from `context/feature-spec/02-editor.md`
+- Clerk authentication from `context/feature-spec/03-auth.md`
## Completed
@@ -28,6 +28,20 @@ change.
- Wrapped application content with `EditorLayout` in `app/layout.tsx`.
- Adjusted `app/page.tsx` to fill the editor canvas area beneath the navbar.
- Verified `npm run lint` and `npm run build` pass after layout integration.
+- Marked auth feature as in progress.
+- Installed `@clerk/ui` for Clerk's dark theme support.
+- Wrapped the root layout in `ClerkProvider` using Clerk's `dark` theme and app CSS variable appearance overrides.
+- Moved editor chrome into `app/editor/layout.tsx` so public auth pages stay minimal.
+- Added `/sign-in` and `/sign-up` Clerk pages with responsive two-panel desktop layouts and form-only small screens.
+- Added root `proxy.ts` with Clerk route protection for all matched routes except `/`, sign-in, and sign-up.
+- Updated `/` to redirect authenticated users to `/editor` and unauthenticated users to `/sign-in`.
+- Added protected `/editor` route content.
+- Added Clerk `UserButton` to the editor navbar right section.
+- Updated `context/architecture.md` with the Clerk auth boundary, route protection model, and invariants.
+- Verified `npm run lint` and `npm run build` pass after auth implementation.
+- Fixed Clerk account modal backdrop so the editor background remains visually unchanged when profile/account windows open.
+- Added explicit Clerk sign-out redirects to `/sign-in` to avoid protected editor-route rendering stalls after logout.
+- Verified `npm run lint` and `npm run build` pass after the current issue fixes.
## In Progress
@@ -57,3 +71,10 @@ change.
- The sidebar is fixed-position and inert while closed, so it floats over the future canvas, slides from the left, and does not push page content.
- The dialog pattern is ready through `components/ui/dialog.tsx`; no actual editor dialog was built for this feature.
- `EditorLayout` is the client boundary for editor shell state; `app/layout.tsx` remains a server component and continues exporting metadata.
+- Started auth implementation by reading `03-auth.md` and marking Clerk auth tasks in progress.
+- Installed `@clerk/ui` as required by the auth spec.
+- `ClerkProvider` uses `appearance={{ theme: dark, variables: ... }}` with existing CSS variables only.
+- The root route is intentionally public so it can perform the specified auth-state redirect; protected application content begins at `/editor`.
+- `proxy.ts` is used instead of `middleware.ts` to match Next.js 16 conventions and the auth spec.
+- Clerk's default modal backdrop was washing out the editor; setting `colorModalBackdrop` to transparent keeps Clerk internals intact while preserving the canvas color.
+- Clerk sign-out now has explicit `afterSignOutUrl` and `afterMultiSessionSingleSignOutUrl` values pointing at the public sign-in route.
diff --git a/package-lock.json b/package-lock.json
index db9de5d..0b0e55e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,6 +8,8 @@
"name": "ghost",
"version": "0.1.0",
"dependencies": {
+ "@clerk/nextjs": "^7.3.0",
+ "@clerk/ui": "^1.7.0",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"lucide-react": "^1.14.0",
@@ -403,6 +405,15 @@
"@babel/core": "^7.0.0-0"
}
},
+ "node_modules/@babel/runtime": {
+ "version": "7.29.2",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz",
+ "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
"node_modules/@babel/template": {
"version": "7.28.6",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz",
@@ -448,6 +459,145 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@clerk/backend": {
+ "version": "3.4.4",
+ "resolved": "https://registry.npmjs.org/@clerk/backend/-/backend-3.4.4.tgz",
+ "integrity": "sha512-EGdpxBG1joIYzRBtpzTq2FGyM2ErSSF2UB7FZXrHiSb6V/uRUcvVcX7IWvYeEyg1AG100gJWr0KpbutajVCLMA==",
+ "license": "MIT",
+ "dependencies": {
+ "@clerk/shared": "^4.9.0",
+ "standardwebhooks": "^1.0.0",
+ "tslib": "2.8.1"
+ },
+ "engines": {
+ "node": ">=20.9.0"
+ }
+ },
+ "node_modules/@clerk/localizations": {
+ "version": "4.5.8",
+ "resolved": "https://registry.npmjs.org/@clerk/localizations/-/localizations-4.5.8.tgz",
+ "integrity": "sha512-WP6tyNwjTPmpbJ4EmIxYRHptHVxgs3RoI6lsGY2LvydKpfyH4mk1GzKF0YKfTXbrYrL5bNeMePAErxmMX1P0og==",
+ "license": "MIT",
+ "dependencies": {
+ "@clerk/shared": "^4.9.0"
+ },
+ "engines": {
+ "node": ">=20.9.0"
+ }
+ },
+ "node_modules/@clerk/nextjs": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/@clerk/nextjs/-/nextjs-7.3.0.tgz",
+ "integrity": "sha512-Dip2oOVc720amG9bBZT1L9y7FoDJjRyz8MaGtbp2SUrtRuvaVq0WhHYzGTI1Nqy5tHMcnzEOSG7KsGf4FwIvzw==",
+ "license": "MIT",
+ "dependencies": {
+ "@clerk/backend": "^3.4.4",
+ "@clerk/react": "^6.5.0",
+ "@clerk/shared": "^4.9.0",
+ "server-only": "0.0.1",
+ "tslib": "2.8.1"
+ },
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "peerDependencies": {
+ "next": "^15.2.8 || ^15.3.8 || ^15.4.10 || ^15.5.9 || ^15.6.0-0 || ^16.0.10 || ^16.1.0-0",
+ "react": "^18.0.0 || ~19.0.3 || ~19.1.4 || ~19.2.3 || ~19.3.0-0",
+ "react-dom": "^18.0.0 || ~19.0.3 || ~19.1.4 || ~19.2.3 || ~19.3.0-0"
+ }
+ },
+ "node_modules/@clerk/react": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/@clerk/react/-/react-6.5.0.tgz",
+ "integrity": "sha512-TXYxlJ9EvPvJo6NKTy//RlqoZ4nhvmIjlU9cp9KG3buHD7UCby0It9dtaPHbAu5h4s426C7F6GID47LolaLEbg==",
+ "license": "MIT",
+ "dependencies": {
+ "@clerk/shared": "^4.9.0",
+ "tslib": "2.8.1"
+ },
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "peerDependencies": {
+ "react": "^18.0.0 || ~19.0.3 || ~19.1.4 || ~19.2.3 || ~19.3.0-0",
+ "react-dom": "^18.0.0 || ~19.0.3 || ~19.1.4 || ~19.2.3 || ~19.3.0-0"
+ }
+ },
+ "node_modules/@clerk/shared": {
+ "version": "4.9.0",
+ "resolved": "https://registry.npmjs.org/@clerk/shared/-/shared-4.9.0.tgz",
+ "integrity": "sha512-YU9Fv6FK1EwxM7uz1hGPrLpvcHRhHm8Quuh5RL343oXakE+/JHtYy4OhwVgqYVA+j63pw+7lpghL3CYQTgk0hA==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "@tanstack/query-core": "^5.100.6",
+ "dequal": "2.0.3",
+ "glob-to-regexp": "0.4.1",
+ "js-cookie": "3.0.5",
+ "std-env": "^3.9.0"
+ },
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "peerDependencies": {
+ "react": "^18.0.0 || ~19.0.3 || ~19.1.4 || ~19.2.3 || ~19.3.0-0",
+ "react-dom": "^18.0.0 || ~19.0.3 || ~19.1.4 || ~19.2.3 || ~19.3.0-0"
+ },
+ "peerDependenciesMeta": {
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@clerk/ui": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/@clerk/ui/-/ui-1.7.0.tgz",
+ "integrity": "sha512-NU6kU0ywB8N67XlyZQPhvF1W00FnsE2n/7qfLGcn/E3M7TkZ0KH5C2uNjq8lDt91ekW3NgiYCpQlyBHz2RP4Rg==",
+ "license": "MIT",
+ "dependencies": {
+ "@clerk/localizations": "^4.5.8",
+ "@clerk/shared": "^4.9.0",
+ "@emotion/cache": "11.11.0",
+ "@emotion/react": "11.11.1",
+ "@floating-ui/react": "0.27.12",
+ "@formkit/auto-animate": "^0.8.2",
+ "@solana/wallet-adapter-base": "0.9.27",
+ "@solana/wallet-adapter-react": "0.15.39",
+ "@solana/wallet-standard": "1.1.4",
+ "@swc/helpers": "0.5.21",
+ "copy-to-clipboard": "3.3.3",
+ "core-js": "3.47.0",
+ "csstype": "3.1.3",
+ "dequal": "2.0.3",
+ "input-otp": "1.4.2",
+ "qrcode.react": "4.2.0"
+ },
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "peerDependencies": {
+ "react": "^18.0.0 || ~19.0.3 || ~19.1.4 || ~19.2.3 || ~19.3.0-0",
+ "react-dom": "^18.0.0 || ~19.0.3 || ~19.1.4 || ~19.2.3 || ~19.3.0-0"
+ }
+ },
+ "node_modules/@clerk/ui/node_modules/@swc/helpers": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.21.tgz",
+ "integrity": "sha512-jI/VAmtdjB/RnI8GTnokyX7Ug8c+g+ffD6QRLa6XQewtnGyukKkKSk3wLTM3b5cjt1jNh9x0jfVlagdN2gDKQg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.8.0"
+ }
+ },
+ "node_modules/@clerk/ui/node_modules/csstype": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
+ "license": "MIT"
+ },
"node_modules/@dotenvx/dotenvx": {
"version": "1.64.0",
"resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-1.64.0.tgz",
@@ -679,6 +829,147 @@
"tslib": "^2.4.0"
}
},
+ "node_modules/@emotion/babel-plugin": {
+ "version": "11.13.5",
+ "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz",
+ "integrity": "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.16.7",
+ "@babel/runtime": "^7.18.3",
+ "@emotion/hash": "^0.9.2",
+ "@emotion/memoize": "^0.9.0",
+ "@emotion/serialize": "^1.3.3",
+ "babel-plugin-macros": "^3.1.0",
+ "convert-source-map": "^1.5.0",
+ "escape-string-regexp": "^4.0.0",
+ "find-root": "^1.1.0",
+ "source-map": "^0.5.7",
+ "stylis": "4.2.0"
+ }
+ },
+ "node_modules/@emotion/babel-plugin/node_modules/@emotion/memoize": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz",
+ "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==",
+ "license": "MIT"
+ },
+ "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
+ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
+ "license": "MIT"
+ },
+ "node_modules/@emotion/babel-plugin/node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@emotion/cache": {
+ "version": "11.11.0",
+ "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz",
+ "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@emotion/memoize": "^0.8.1",
+ "@emotion/sheet": "^1.2.2",
+ "@emotion/utils": "^1.2.1",
+ "@emotion/weak-memoize": "^0.3.1",
+ "stylis": "4.2.0"
+ }
+ },
+ "node_modules/@emotion/hash": {
+ "version": "0.9.2",
+ "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz",
+ "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==",
+ "license": "MIT"
+ },
+ "node_modules/@emotion/memoize": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz",
+ "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==",
+ "license": "MIT"
+ },
+ "node_modules/@emotion/react": {
+ "version": "11.11.1",
+ "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz",
+ "integrity": "sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.18.3",
+ "@emotion/babel-plugin": "^11.11.0",
+ "@emotion/cache": "^11.11.0",
+ "@emotion/serialize": "^1.1.2",
+ "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1",
+ "@emotion/utils": "^1.2.1",
+ "@emotion/weak-memoize": "^0.3.1",
+ "hoist-non-react-statics": "^3.3.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@emotion/serialize": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz",
+ "integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==",
+ "license": "MIT",
+ "dependencies": {
+ "@emotion/hash": "^0.9.2",
+ "@emotion/memoize": "^0.9.0",
+ "@emotion/unitless": "^0.10.0",
+ "@emotion/utils": "^1.4.2",
+ "csstype": "^3.0.2"
+ }
+ },
+ "node_modules/@emotion/serialize/node_modules/@emotion/memoize": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz",
+ "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==",
+ "license": "MIT"
+ },
+ "node_modules/@emotion/sheet": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz",
+ "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==",
+ "license": "MIT"
+ },
+ "node_modules/@emotion/unitless": {
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz",
+ "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==",
+ "license": "MIT"
+ },
+ "node_modules/@emotion/use-insertion-effect-with-fallbacks": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz",
+ "integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": ">=16.8.0"
+ }
+ },
+ "node_modules/@emotion/utils": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz",
+ "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==",
+ "license": "MIT"
+ },
+ "node_modules/@emotion/weak-memoize": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz",
+ "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==",
+ "license": "MIT"
+ },
"node_modules/@eslint-community/eslint-utils": {
"version": "4.9.1",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz",
@@ -842,6 +1133,21 @@
"@floating-ui/utils": "^0.2.11"
}
},
+ "node_modules/@floating-ui/react": {
+ "version": "0.27.12",
+ "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.27.12.tgz",
+ "integrity": "sha512-kKlWNrpIQxF1B/a2MZvE0/uyKby4960yjO91W7nVyNKmmfNi62xU9HCjL1M1eWzx/LFj/VPSwJVbwQk9Pq/68A==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/react-dom": "^2.1.3",
+ "@floating-ui/utils": "^0.2.9",
+ "tabbable": "^6.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=17.0.0",
+ "react-dom": ">=17.0.0"
+ }
+ },
"node_modules/@floating-ui/react-dom": {
"version": "2.1.8",
"resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.8.tgz",
@@ -861,6 +1167,12 @@
"integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==",
"license": "MIT"
},
+ "node_modules/@formkit/auto-animate": {
+ "version": "0.8.4",
+ "resolved": "https://registry.npmjs.org/@formkit/auto-animate/-/auto-animate-0.8.4.tgz",
+ "integrity": "sha512-DHHC01EJ1p70Q0z/ZFRBIY8NDnmfKccQoyoM84Tgb6omLMat6jivCdf272Y8k3nf4Lzdin/Y4R9q8uFtU0GbnA==",
+ "license": "MIT"
+ },
"node_modules/@hono/node-server": {
"version": "1.19.14",
"resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.14.tgz",
@@ -1535,6 +1847,47 @@
}
}
},
+ "node_modules/@isaacs/ttlcache": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/@isaacs/ttlcache/-/ttlcache-1.4.1.tgz",
+ "integrity": "sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==",
+ "license": "ISC",
+ "peer": true,
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@jest/schemas": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
+ "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@sinclair/typebox": "^0.27.8"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/types": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
+ "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@jest/schemas": "^29.6.3",
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^17.0.8",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.13",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
@@ -1564,6 +1917,17 @@
"node": ">=6.0.0"
}
},
+ "node_modules/@jridgewell/source-map": {
+ "version": "0.3.11",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz",
+ "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25"
+ }
+ },
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.5",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
@@ -3438,95 +3802,906 @@
"integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==",
"license": "MIT"
},
- "node_modules/@rtsao/scc": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
- "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@sec-ant/readable-stream": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz",
- "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==",
- "license": "MIT"
- },
- "node_modules/@sindresorhus/merge-streams": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz",
- "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==",
+ "node_modules/@react-native-async-storage/async-storage": {
+ "version": "1.24.0",
+ "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.24.0.tgz",
+ "integrity": "sha512-W4/vbwUOYOjco0x3toB8QCr7EjIP6nE9G7o8PMguvvjYT5Awg09lyV4enACRx4s++PPulBiBSjL0KTFx2u0Z/g==",
"license": "MIT",
- "engines": {
- "node": ">=18"
+ "optional": true,
+ "dependencies": {
+ "merge-options": "^3.0.4"
},
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "peerDependencies": {
+ "react-native": "^0.0.0-0 || >=0.60 <1.0"
}
},
- "node_modules/@swc/helpers": {
- "version": "0.5.15",
- "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz",
- "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==",
- "license": "Apache-2.0",
- "dependencies": {
- "tslib": "^2.8.0"
+ "node_modules/@react-native/assets-registry": {
+ "version": "0.85.2",
+ "resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.85.2.tgz",
+ "integrity": "sha512-kauC/oPaxklU4Y+u9gBfCBJm51qX6WBZq4xx0USCdimtp+G8+554kpygfSWIjoqCJa2o06bWxBEjesiuCv+LzA==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
}
},
- "node_modules/@tailwindcss/node": {
- "version": "4.2.4",
- "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.4.tgz",
- "integrity": "sha512-Ai7+yQPxz3ddrDQzFfBKdHEVBg0w3Zl83jnjuwxnZOsnH9pGn93QHQtpU0p/8rYWxvbFZHneni6p1BSLK4DkGA==",
- "dev": true,
+ "node_modules/@react-native/codegen": {
+ "version": "0.85.2",
+ "resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.85.2.tgz",
+ "integrity": "sha512-XCginmxh0//++EXVOEJHBVZxHla294FzLCFF6jXwAUjvXVhqyIKyxhABfz+r4OOmaiuWk4Rtd4arqdAzeHeprg==",
"license": "MIT",
+ "peer": true,
"dependencies": {
- "@jridgewell/remapping": "^2.3.5",
- "enhanced-resolve": "^5.19.0",
- "jiti": "^2.6.1",
- "lightningcss": "1.32.0",
- "magic-string": "^0.30.21",
- "source-map-js": "^1.2.1",
- "tailwindcss": "4.2.4"
+ "@babel/core": "^7.25.2",
+ "@babel/parser": "^7.29.0",
+ "hermes-parser": "0.33.3",
+ "invariant": "^2.2.4",
+ "nullthrows": "^1.1.1",
+ "tinyglobby": "^0.2.15",
+ "yargs": "^17.6.2"
+ },
+ "engines": {
+ "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "*"
}
},
- "node_modules/@tailwindcss/oxide": {
- "version": "4.2.4",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.4.tgz",
- "integrity": "sha512-9El/iI069DKDSXwTvB9J4BwdO5JhRrOweGaK25taBAvBXyXqJAX+Jqdvs8r8gKpsI/1m0LeJLyQYTf/WLrBT1Q==",
- "dev": true,
+ "node_modules/@react-native/codegen/node_modules/hermes-estree": {
+ "version": "0.33.3",
+ "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.33.3.tgz",
+ "integrity": "sha512-6kzYZHCk8Fy1Uc+t3HGYyJn3OL4aeqKLTyina4UFtWl8I0kSL7OmKThaiX+Uh2f8nGw3mo4Ifxg0M5Zk3/Oeqg==",
"license": "MIT",
- "engines": {
- "node": ">= 20"
- },
- "optionalDependencies": {
- "@tailwindcss/oxide-android-arm64": "4.2.4",
- "@tailwindcss/oxide-darwin-arm64": "4.2.4",
- "@tailwindcss/oxide-darwin-x64": "4.2.4",
- "@tailwindcss/oxide-freebsd-x64": "4.2.4",
- "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.4",
- "@tailwindcss/oxide-linux-arm64-gnu": "4.2.4",
- "@tailwindcss/oxide-linux-arm64-musl": "4.2.4",
- "@tailwindcss/oxide-linux-x64-gnu": "4.2.4",
- "@tailwindcss/oxide-linux-x64-musl": "4.2.4",
- "@tailwindcss/oxide-wasm32-wasi": "4.2.4",
- "@tailwindcss/oxide-win32-arm64-msvc": "4.2.4",
- "@tailwindcss/oxide-win32-x64-msvc": "4.2.4"
+ "peer": true
+ },
+ "node_modules/@react-native/codegen/node_modules/hermes-parser": {
+ "version": "0.33.3",
+ "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.33.3.tgz",
+ "integrity": "sha512-Yg3HgaG4CqgyowtYjX/FsnPAuZdHOqSMtnbpylbptsQ9nwwSKsy6uRWcGO5RK0EqiX12q8HvDWKgeAVajRO5DA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "hermes-estree": "0.33.3"
}
},
- "node_modules/@tailwindcss/oxide-android-arm64": {
- "version": "4.2.4",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.4.tgz",
- "integrity": "sha512-e7MOr1SAn9U8KlZzPi1ZXGZHeC5anY36qjNwmZv9pOJ8E4Q6jmD1vyEHkQFmNOIN7twGPEMXRHmitN4zCMN03g==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
+ "node_modules/@react-native/community-cli-plugin": {
+ "version": "0.85.2",
+ "resolved": "https://registry.npmjs.org/@react-native/community-cli-plugin/-/community-cli-plugin-0.85.2.tgz",
+ "integrity": "sha512-3KLgSg1kHvBpr93zMaQhvfYTgnCw7yZRED+3J4dMcYjfSjtD0Wf8SofU6uBmAw9JaVYvP43lpdwUpI4p0+ABsg==",
"license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
+ "peer": true,
+ "dependencies": {
+ "@react-native/dev-middleware": "0.85.2",
+ "debug": "^4.4.0",
+ "invariant": "^2.2.4",
+ "metro": "^0.84.0",
+ "metro-config": "^0.84.0",
+ "metro-core": "^0.84.0",
+ "semver": "^7.1.3"
+ },
"engines": {
- "node": ">= 20"
+ "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
+ },
+ "peerDependencies": {
+ "@react-native-community/cli": "*",
+ "@react-native/metro-config": "0.85.2"
+ },
+ "peerDependenciesMeta": {
+ "@react-native-community/cli": {
+ "optional": true
+ },
+ "@react-native/metro-config": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@react-native/community-cli-plugin/node_modules/semver": {
+ "version": "7.7.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
+ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
+ "license": "ISC",
+ "peer": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@react-native/debugger-frontend": {
+ "version": "0.85.2",
+ "resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.85.2.tgz",
+ "integrity": "sha512-j+0b9H5f5hGTLQxHIhJU/b/W6ijuxJF+ZTLHB0se2kzUBNxFKd7DkIc6753qk3CJdiv55vxG3XDgmlpbHxOpmA==",
+ "license": "BSD-3-Clause",
+ "peer": true,
+ "engines": {
+ "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
+ }
+ },
+ "node_modules/@react-native/debugger-shell": {
+ "version": "0.85.2",
+ "resolved": "https://registry.npmjs.org/@react-native/debugger-shell/-/debugger-shell-0.85.2.tgz",
+ "integrity": "sha512-r5BkhqPMfg3LmaZS5zadHmBNVH5h4bhSpv4BEPGfK4gat9HABAMzUzybi+2wpgU3SoHxnyKGdExEJvoqVcjeRg==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "cross-spawn": "^7.0.6",
+ "debug": "^4.4.0",
+ "fb-dotslash": "0.5.8"
+ },
+ "engines": {
+ "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
+ }
+ },
+ "node_modules/@react-native/dev-middleware": {
+ "version": "0.85.2",
+ "resolved": "https://registry.npmjs.org/@react-native/dev-middleware/-/dev-middleware-0.85.2.tgz",
+ "integrity": "sha512-3J+NaDUg+QEfDeLAUzgaWhpaxEg78g+KwbydlDCewh2G6WnHpsty8XooruxNHzyAsqVWywZMrzmbn78Ctc1O9Q==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@isaacs/ttlcache": "^1.4.1",
+ "@react-native/debugger-frontend": "0.85.2",
+ "@react-native/debugger-shell": "0.85.2",
+ "chrome-launcher": "^0.15.2",
+ "chromium-edge-launcher": "^0.3.0",
+ "connect": "^3.6.5",
+ "debug": "^4.4.0",
+ "invariant": "^2.2.4",
+ "nullthrows": "^1.1.1",
+ "open": "^7.0.3",
+ "serve-static": "^1.16.2",
+ "ws": "^7.5.10"
+ },
+ "engines": {
+ "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
+ }
+ },
+ "node_modules/@react-native/dev-middleware/node_modules/fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/@react-native/dev-middleware/node_modules/is-docker": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
+ "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
+ "license": "MIT",
+ "peer": true,
+ "bin": {
+ "is-docker": "cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@react-native/dev-middleware/node_modules/is-wsl": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
+ "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "is-docker": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@react-native/dev-middleware/node_modules/open": {
+ "version": "7.4.2",
+ "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz",
+ "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "is-docker": "^2.0.0",
+ "is-wsl": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@react-native/dev-middleware/node_modules/send": {
+ "version": "0.19.2",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz",
+ "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "~0.5.2",
+ "http-errors": "~2.0.1",
+ "mime": "1.6.0",
+ "ms": "2.1.3",
+ "on-finished": "~2.4.1",
+ "range-parser": "~1.2.1",
+ "statuses": "~2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/@react-native/dev-middleware/node_modules/send/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/@react-native/dev-middleware/node_modules/send/node_modules/debug/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@react-native/dev-middleware/node_modules/serve-static": {
+ "version": "1.16.3",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz",
+ "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "~0.19.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/@react-native/gradle-plugin": {
+ "version": "0.85.2",
+ "resolved": "https://registry.npmjs.org/@react-native/gradle-plugin/-/gradle-plugin-0.85.2.tgz",
+ "integrity": "sha512-YXBOLeAqFrv7XwUeBPTKZeOV1FIxn4AW7UAEitScf3ibC8bu8+6NpJu4HWgbNQHg7vDbbTZVbcOl8EwGxsSq2w==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
+ }
+ },
+ "node_modules/@react-native/js-polyfills": {
+ "version": "0.85.2",
+ "resolved": "https://registry.npmjs.org/@react-native/js-polyfills/-/js-polyfills-0.85.2.tgz",
+ "integrity": "sha512-esGEAmKVM40DV/yVmNljCKZTIeUo7qXqc+Hwffkv3TG+b3E24xyFovHrbP98gGxZr2ZsEyx+2sKLdXF5asY5nw==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
+ }
+ },
+ "node_modules/@react-native/normalize-colors": {
+ "version": "0.85.2",
+ "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.85.2.tgz",
+ "integrity": "sha512-svuOLtjbFGXDdHsriHXuND5FgHg7XlkOXCbH/8+X4t76YLH6qSTffSIQQrKLDL5mn4EFU+Oh/PNO0/FfpnTOTg==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@react-native/virtualized-lists": {
+ "version": "0.85.2",
+ "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.85.2.tgz",
+ "integrity": "sha512-wmVKpAlcr+UB0L5SpbrV865EdleUP7I5+X+48e1aRsQK8q+wsTRBXeUwWVip/1l+HZwlZFeO8iOILJ16VRu0Cw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "invariant": "^2.2.4",
+ "nullthrows": "^1.1.1"
+ },
+ "engines": {
+ "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
+ },
+ "peerDependencies": {
+ "@types/react": "^19.2.0",
+ "react": "*",
+ "react-native": "0.85.2"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rtsao/scc": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
+ "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@sec-ant/readable-stream": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz",
+ "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==",
+ "license": "MIT"
+ },
+ "node_modules/@sinclair/typebox": {
+ "version": "0.27.10",
+ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.10.tgz",
+ "integrity": "sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@sindresorhus/merge-streams": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz",
+ "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@solana-mobile/mobile-wallet-adapter-protocol": {
+ "version": "2.2.8",
+ "resolved": "https://registry.npmjs.org/@solana-mobile/mobile-wallet-adapter-protocol/-/mobile-wallet-adapter-protocol-2.2.8.tgz",
+ "integrity": "sha512-c3FQsrM7nV62DqVaHGKtr2osE2w5gS3/wjy8ILF0zczS/s1mERX+JTmf+UHd8xgESmEj/IM7q+U2Qhrmac1PdA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@solana/codecs-strings": "^6.0.0",
+ "@solana/wallet-standard-features": "^1.3.0",
+ "@solana/wallet-standard-util": "^1.1.2",
+ "@wallet-standard/core": "^1.1.1",
+ "js-base64": "^3.7.5"
+ },
+ "peerDependencies": {
+ "react-native": ">0.74"
+ }
+ },
+ "node_modules/@solana-mobile/mobile-wallet-adapter-protocol-web3js": {
+ "version": "2.2.8",
+ "resolved": "https://registry.npmjs.org/@solana-mobile/mobile-wallet-adapter-protocol-web3js/-/mobile-wallet-adapter-protocol-web3js-2.2.8.tgz",
+ "integrity": "sha512-W9DbsFvl5lSOe7KT3dJX4tjbxfYIoOtOTJpvLMgkojyRU0UKChQ4vHvbOZQ3GkUJ8wOIS4qdrM0Yytd1Vy+YQQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@solana-mobile/mobile-wallet-adapter-protocol": "^2.2.8",
+ "bs58": "^6.0.0",
+ "js-base64": "^3.7.5"
+ },
+ "peerDependencies": {
+ "@solana/web3.js": "^1.98.4"
+ }
+ },
+ "node_modules/@solana-mobile/wallet-adapter-mobile": {
+ "version": "2.2.8",
+ "resolved": "https://registry.npmjs.org/@solana-mobile/wallet-adapter-mobile/-/wallet-adapter-mobile-2.2.8.tgz",
+ "integrity": "sha512-ZbXY3/0+UnnyS0hvArpO1b1pYzaQAiVIp+HBUm11aLEkE5+ISvHTRPr/bCEUXZfPkez/1n9zH3H0leK25Lj6Nw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@solana-mobile/mobile-wallet-adapter-protocol": "^2.2.8",
+ "@solana-mobile/mobile-wallet-adapter-protocol-web3js": "^2.2.8",
+ "@solana-mobile/wallet-standard-mobile": "^0.5.2",
+ "@solana/wallet-adapter-base": "^0.9.27",
+ "@solana/wallet-standard-features": "^1.3.0",
+ "@wallet-standard/core": "^1.1.1",
+ "bs58": "^6.0.0",
+ "js-base64": "^3.7.5",
+ "tslib": "^2.8.1"
+ },
+ "optionalDependencies": {
+ "@react-native-async-storage/async-storage": "^1.17.7"
+ },
+ "peerDependencies": {
+ "@solana/web3.js": "^1.98.4",
+ "react-native": ">0.74"
+ }
+ },
+ "node_modules/@solana-mobile/wallet-standard-mobile": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/@solana-mobile/wallet-standard-mobile/-/wallet-standard-mobile-0.5.2.tgz",
+ "integrity": "sha512-orEGv4N/Ttd0umwfWUzGcEnVc9eJDTgRSEcDitvFWpIf2D968h6128L0rq9/y7sUw88Gvu/lU0euoC2ASEijqQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@solana-mobile/mobile-wallet-adapter-protocol": "^2.2.8",
+ "@solana/wallet-standard-chains": "^1.1.1",
+ "@solana/wallet-standard-features": "^1.3.0",
+ "@wallet-standard/base": "^1.0.1",
+ "@wallet-standard/features": "^1.0.3",
+ "@wallet-standard/wallet": "^1.1.0",
+ "bs58": "^6.0.0",
+ "js-base64": "^3.7.5",
+ "qrcode": "^1.5.4",
+ "tslib": "^2.8.1"
+ },
+ "optionalDependencies": {
+ "@react-native-async-storage/async-storage": "^1.17.7"
+ }
+ },
+ "node_modules/@solana/buffer-layout": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz",
+ "integrity": "sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "buffer": "~6.0.3"
+ },
+ "engines": {
+ "node": ">=5.10"
+ }
+ },
+ "node_modules/@solana/codecs-core": {
+ "version": "6.8.0",
+ "resolved": "https://registry.npmjs.org/@solana/codecs-core/-/codecs-core-6.8.0.tgz",
+ "integrity": "sha512-udFO8TrvzgROonwX3rY3E2SG675RehILNb4ZYcKlf1mL7vkDJ9bEJnBxi87AEwl8RWZFTl+MhT0MmrJnbpvdug==",
+ "license": "MIT",
+ "dependencies": {
+ "@solana/errors": "6.8.0"
+ },
+ "engines": {
+ "node": ">=20.18.0"
+ },
+ "peerDependencies": {
+ "typescript": ">=5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@solana/codecs-numbers": {
+ "version": "6.8.0",
+ "resolved": "https://registry.npmjs.org/@solana/codecs-numbers/-/codecs-numbers-6.8.0.tgz",
+ "integrity": "sha512-ebf4f1D19EAe0uhdUYOCEYnn5+EellsBxbJ42tM2yYEoIBVz5FoBBC0gSsq+UTNbQHFa7XagyBT3LewxXttiTQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@solana/codecs-core": "6.8.0",
+ "@solana/errors": "6.8.0"
+ },
+ "engines": {
+ "node": ">=20.18.0"
+ },
+ "peerDependencies": {
+ "typescript": ">=5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@solana/codecs-strings": {
+ "version": "6.8.0",
+ "resolved": "https://registry.npmjs.org/@solana/codecs-strings/-/codecs-strings-6.8.0.tgz",
+ "integrity": "sha512-Rpk5NVhbKYcPnE7wz3IpTp0GVNVs0IYKdmyzByiimgPTiII8eb8ay4wQiYHGHrpYh62hD14Qy3GiGDFgipRKqA==",
+ "license": "MIT",
+ "dependencies": {
+ "@solana/codecs-core": "6.8.0",
+ "@solana/codecs-numbers": "6.8.0",
+ "@solana/errors": "6.8.0"
+ },
+ "engines": {
+ "node": ">=20.18.0"
+ },
+ "peerDependencies": {
+ "fastestsmallesttextencoderdecoder": "^1.0.22",
+ "typescript": ">=5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "fastestsmallesttextencoderdecoder": {
+ "optional": true
+ },
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@solana/errors": {
+ "version": "6.8.0",
+ "resolved": "https://registry.npmjs.org/@solana/errors/-/errors-6.8.0.tgz",
+ "integrity": "sha512-HRTrLgTn0c99GKz4v4IKgz2+6soaRY1mh2tLW4sk1Fe4Zzv85Q6ZLK1mXrVGL73z1apyHDrr9/Sd/9ZhUsUvpA==",
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "5.6.2",
+ "commander": "14.0.3"
+ },
+ "bin": {
+ "errors": "bin/cli.mjs"
+ },
+ "engines": {
+ "node": ">=20.18.0"
+ },
+ "peerDependencies": {
+ "typescript": ">=5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@solana/errors/node_modules/chalk": {
+ "version": "5.6.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
+ "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
+ "license": "MIT",
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/@solana/wallet-adapter-base": {
+ "version": "0.9.27",
+ "resolved": "https://registry.npmjs.org/@solana/wallet-adapter-base/-/wallet-adapter-base-0.9.27.tgz",
+ "integrity": "sha512-kXjeNfNFVs/NE9GPmysBRKQ/nf+foSaq3kfVSeMcO/iVgigyRmB551OjU3WyAolLG/1jeEfKLqF9fKwMCRkUqg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@solana/wallet-standard-features": "^1.3.0",
+ "@wallet-standard/base": "^1.1.0",
+ "@wallet-standard/features": "^1.1.0",
+ "eventemitter3": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=20"
+ },
+ "peerDependencies": {
+ "@solana/web3.js": "^1.98.0"
+ }
+ },
+ "node_modules/@solana/wallet-adapter-react": {
+ "version": "0.15.39",
+ "resolved": "https://registry.npmjs.org/@solana/wallet-adapter-react/-/wallet-adapter-react-0.15.39.tgz",
+ "integrity": "sha512-WXtlo88ith5m22qB+qiGw301/Zb9r5pYr4QdXWmlXnRNqwST5MGmJWhG+/RVrzc+OG7kSb3z1gkVNv+2X/Y0Gg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@solana-mobile/wallet-adapter-mobile": "^2.2.0",
+ "@solana/wallet-adapter-base": "^0.9.27",
+ "@solana/wallet-standard-wallet-adapter-react": "^1.1.4"
+ },
+ "engines": {
+ "node": ">=20"
+ },
+ "peerDependencies": {
+ "@solana/web3.js": "^1.98.0",
+ "react": "*"
+ }
+ },
+ "node_modules/@solana/wallet-standard": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@solana/wallet-standard/-/wallet-standard-1.1.4.tgz",
+ "integrity": "sha512-NF+MI5tOxyvfTU4A+O5idh/gJFmjm52bMwsPpFGRSL79GECSN0XLmpVOO/jqTKJgac2uIeYDpQw/eMaQuWuUXw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@solana/wallet-standard-core": "^1.1.2",
+ "@solana/wallet-standard-wallet-adapter": "^1.1.4"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@solana/wallet-standard-chains": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@solana/wallet-standard-chains/-/wallet-standard-chains-1.1.1.tgz",
+ "integrity": "sha512-Us3TgL4eMVoVWhuC4UrePlYnpWN+lwteCBlhZDUhFZBJ5UMGh94mYPXno3Ho7+iHPYRtuCi/ePvPcYBqCGuBOw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@wallet-standard/base": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@solana/wallet-standard-core": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@solana/wallet-standard-core/-/wallet-standard-core-1.1.2.tgz",
+ "integrity": "sha512-FaSmnVsIHkHhYlH8XX0Y4TYS+ebM+scW7ZeDkdXo3GiKge61Z34MfBPinZSUMV08hCtzxxqH2ydeU9+q/KDrLA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@solana/wallet-standard-chains": "^1.1.1",
+ "@solana/wallet-standard-features": "^1.3.0",
+ "@solana/wallet-standard-util": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@solana/wallet-standard-features": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@solana/wallet-standard-features/-/wallet-standard-features-1.3.0.tgz",
+ "integrity": "sha512-ZhpZtD+4VArf6RPitsVExvgkF+nGghd1rzPjd97GmBximpnt1rsUxMOEyoIEuH3XBxPyNB6Us7ha7RHWQR+abg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@wallet-standard/base": "^1.1.0",
+ "@wallet-standard/features": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@solana/wallet-standard-util": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@solana/wallet-standard-util/-/wallet-standard-util-1.1.2.tgz",
+ "integrity": "sha512-rUXFNP4OY81Ddq7qOjQV4Kmkozx4wjYAxljvyrqPx8Ycz0FYChG/hQVWqvgpK3sPsEaO/7ABG1NOACsyAKWNOA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@noble/curves": "^1.8.0",
+ "@solana/wallet-standard-chains": "^1.1.1",
+ "@solana/wallet-standard-features": "^1.3.0"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@solana/wallet-standard-wallet-adapter": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@solana/wallet-standard-wallet-adapter/-/wallet-standard-wallet-adapter-1.1.4.tgz",
+ "integrity": "sha512-YSBrxwov4irg2hx9gcmM4VTew3ofNnkqsXQ42JwcS6ykF1P1ecVY8JCbrv75Nwe6UodnqeoZRbN7n/p3awtjNQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@solana/wallet-standard-wallet-adapter-base": "^1.1.4",
+ "@solana/wallet-standard-wallet-adapter-react": "^1.1.4"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@solana/wallet-standard-wallet-adapter-base": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@solana/wallet-standard-wallet-adapter-base/-/wallet-standard-wallet-adapter-base-1.1.4.tgz",
+ "integrity": "sha512-Q2Rie9YaidyFA4UxcUIxUsvynW+/gE2noj/Wmk+IOwDwlVrJUAXCvFaCNsPDSyKoiYEKxkSnlG13OA1v08G4iw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@solana/wallet-adapter-base": "^0.9.23",
+ "@solana/wallet-standard-chains": "^1.1.1",
+ "@solana/wallet-standard-features": "^1.3.0",
+ "@solana/wallet-standard-util": "^1.1.2",
+ "@wallet-standard/app": "^1.1.0",
+ "@wallet-standard/base": "^1.1.0",
+ "@wallet-standard/features": "^1.1.0",
+ "@wallet-standard/wallet": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "peerDependencies": {
+ "@solana/web3.js": "^1.98.0",
+ "bs58": "^6.0.0"
+ }
+ },
+ "node_modules/@solana/wallet-standard-wallet-adapter-react": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@solana/wallet-standard-wallet-adapter-react/-/wallet-standard-wallet-adapter-react-1.1.4.tgz",
+ "integrity": "sha512-xa4KVmPgB7bTiWo4U7lg0N6dVUtt2I2WhEnKlIv0jdihNvtyhOjCKMjucWet6KAVhir6I/mSWrJk1U9SvVvhCg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@solana/wallet-standard-wallet-adapter-base": "^1.1.4",
+ "@wallet-standard/app": "^1.1.0",
+ "@wallet-standard/base": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "peerDependencies": {
+ "@solana/wallet-adapter-base": "*",
+ "react": "*"
+ }
+ },
+ "node_modules/@solana/web3.js": {
+ "version": "1.98.4",
+ "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.98.4.tgz",
+ "integrity": "sha512-vv9lfnvjUsRiq//+j5pBdXig0IQdtzA0BRZ3bXEP4KaIyF1CcaydWqgyzQgfZMNIsWNWmG+AUHwPy4AHOD6gpw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.25.0",
+ "@noble/curves": "^1.4.2",
+ "@noble/hashes": "^1.4.0",
+ "@solana/buffer-layout": "^4.0.1",
+ "@solana/codecs-numbers": "^2.1.0",
+ "agentkeepalive": "^4.5.0",
+ "bn.js": "^5.2.1",
+ "borsh": "^0.7.0",
+ "bs58": "^4.0.1",
+ "buffer": "6.0.3",
+ "fast-stable-stringify": "^1.0.0",
+ "jayson": "^4.1.1",
+ "node-fetch": "^2.7.0",
+ "rpc-websockets": "^9.0.2",
+ "superstruct": "^2.0.2"
+ }
+ },
+ "node_modules/@solana/web3.js/node_modules/@solana/codecs-core": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@solana/codecs-core/-/codecs-core-2.3.0.tgz",
+ "integrity": "sha512-oG+VZzN6YhBHIoSKgS5ESM9VIGzhWjEHEGNPSibiDTxFhsFWxNaz8LbMDPjBUE69r9wmdGLkrQ+wVPbnJcZPvw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@solana/errors": "2.3.0"
+ },
+ "engines": {
+ "node": ">=20.18.0"
+ },
+ "peerDependencies": {
+ "typescript": ">=5.3.3"
+ }
+ },
+ "node_modules/@solana/web3.js/node_modules/@solana/codecs-numbers": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@solana/codecs-numbers/-/codecs-numbers-2.3.0.tgz",
+ "integrity": "sha512-jFvvwKJKffvG7Iz9dmN51OGB7JBcy2CJ6Xf3NqD/VP90xak66m/Lg48T01u5IQ/hc15mChVHiBm+HHuOFDUrQg==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@solana/codecs-core": "2.3.0",
+ "@solana/errors": "2.3.0"
+ },
+ "engines": {
+ "node": ">=20.18.0"
+ },
+ "peerDependencies": {
+ "typescript": ">=5.3.3"
+ }
+ },
+ "node_modules/@solana/web3.js/node_modules/@solana/errors": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@solana/errors/-/errors-2.3.0.tgz",
+ "integrity": "sha512-66RI9MAbwYV0UtP7kGcTBVLxJgUxoZGm8Fbc0ah+lGiAw17Gugco6+9GrJCV83VyF2mDWyYnYM9qdI3yjgpnaQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "chalk": "^5.4.1",
+ "commander": "^14.0.0"
+ },
+ "bin": {
+ "errors": "bin/cli.mjs"
+ },
+ "engines": {
+ "node": ">=20.18.0"
+ },
+ "peerDependencies": {
+ "typescript": ">=5.3.3"
+ }
+ },
+ "node_modules/@solana/web3.js/node_modules/base-x": {
+ "version": "3.0.11",
+ "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.11.tgz",
+ "integrity": "sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/@solana/web3.js/node_modules/bs58": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz",
+ "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "base-x": "^3.0.2"
+ }
+ },
+ "node_modules/@solana/web3.js/node_modules/chalk": {
+ "version": "5.6.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
+ "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/@solana/web3.js/node_modules/node-fetch": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@stablelib/base64": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@stablelib/base64/-/base64-1.0.1.tgz",
+ "integrity": "sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ==",
+ "license": "MIT"
+ },
+ "node_modules/@swc/helpers": {
+ "version": "0.5.15",
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz",
+ "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.8.0"
+ }
+ },
+ "node_modules/@tailwindcss/node": {
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.4.tgz",
+ "integrity": "sha512-Ai7+yQPxz3ddrDQzFfBKdHEVBg0w3Zl83jnjuwxnZOsnH9pGn93QHQtpU0p/8rYWxvbFZHneni6p1BSLK4DkGA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/remapping": "^2.3.5",
+ "enhanced-resolve": "^5.19.0",
+ "jiti": "^2.6.1",
+ "lightningcss": "1.32.0",
+ "magic-string": "^0.30.21",
+ "source-map-js": "^1.2.1",
+ "tailwindcss": "4.2.4"
+ }
+ },
+ "node_modules/@tailwindcss/oxide": {
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.4.tgz",
+ "integrity": "sha512-9El/iI069DKDSXwTvB9J4BwdO5JhRrOweGaK25taBAvBXyXqJAX+Jqdvs8r8gKpsI/1m0LeJLyQYTf/WLrBT1Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 20"
+ },
+ "optionalDependencies": {
+ "@tailwindcss/oxide-android-arm64": "4.2.4",
+ "@tailwindcss/oxide-darwin-arm64": "4.2.4",
+ "@tailwindcss/oxide-darwin-x64": "4.2.4",
+ "@tailwindcss/oxide-freebsd-x64": "4.2.4",
+ "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.4",
+ "@tailwindcss/oxide-linux-arm64-gnu": "4.2.4",
+ "@tailwindcss/oxide-linux-arm64-musl": "4.2.4",
+ "@tailwindcss/oxide-linux-x64-gnu": "4.2.4",
+ "@tailwindcss/oxide-linux-x64-musl": "4.2.4",
+ "@tailwindcss/oxide-wasm32-wasi": "4.2.4",
+ "@tailwindcss/oxide-win32-arm64-msvc": "4.2.4",
+ "@tailwindcss/oxide-win32-x64-msvc": "4.2.4"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-android-arm64": {
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.4.tgz",
+ "integrity": "sha512-e7MOr1SAn9U8KlZzPi1ZXGZHeC5anY36qjNwmZv9pOJ8E4Q6jmD1vyEHkQFmNOIN7twGPEMXRHmitN4zCMN03g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 20"
}
},
"node_modules/@tailwindcss/oxide-darwin-arm64": {
@@ -3755,6 +4930,16 @@
"tailwindcss": "4.2.4"
}
},
+ "node_modules/@tanstack/query-core": {
+ "version": "5.100.8",
+ "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.100.8.tgz",
+ "integrity": "sha512-ceYwSFOqjPwET5TA6IOYxzxlGc0ekyH/gfOtWkP0PX43rzX9bxW48Iuw8KAduKCToi4rJAQ6nRy2kAe8gszdmg==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ }
+ },
"node_modules/@ts-morph/common": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.27.0.tgz",
@@ -3841,6 +5026,16 @@
"tslib": "^2.4.0"
}
},
+ "node_modules/@types/connect": {
+ "version": "3.4.38",
+ "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
+ "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
"node_modules/@types/estree": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
@@ -3848,6 +5043,33 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@types/istanbul-lib-coverage": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
+ "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@types/istanbul-lib-report": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz",
+ "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "*"
+ }
+ },
+ "node_modules/@types/istanbul-reports": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
+ "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
"node_modules/@types/json-schema": {
"version": "7.0.15",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
@@ -3871,6 +5093,12 @@
"undici-types": "~6.21.0"
}
},
+ "node_modules/@types/parse-json": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz",
+ "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==",
+ "license": "MIT"
+ },
"node_modules/@types/react": {
"version": "19.2.14",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz",
@@ -3906,12 +5134,46 @@
"integrity": "sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==",
"license": "MIT"
},
+ "node_modules/@types/uuid": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz",
+ "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==",
+ "license": "MIT",
+ "peer": true
+ },
"node_modules/@types/validate-npm-package-name": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@types/validate-npm-package-name/-/validate-npm-package-name-4.0.2.tgz",
"integrity": "sha512-lrpDziQipxCEeK5kWxvljWYhUvOiB2A9izZd9B2AFarYAkqZshb4lPbRs7zKEic6eGtH8V/2qJW+dPp9OtF6bw==",
"license": "MIT"
},
+ "node_modules/@types/ws": {
+ "version": "7.4.7",
+ "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz",
+ "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/yargs": {
+ "version": "17.0.35",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz",
+ "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/@types/yargs-parser": {
+ "version": "21.0.3",
+ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz",
+ "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==",
+ "license": "MIT",
+ "peer": true
+ },
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.59.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.59.1.tgz",
@@ -4500,6 +5762,117 @@
"win32"
]
},
+ "node_modules/@wallet-standard/app": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@wallet-standard/app/-/app-1.1.0.tgz",
+ "integrity": "sha512-3CijvrO9utx598kjr45hTbbeeykQrQfKmSnxeWOgU25TOEpvcipD/bYDQWIqUv1Oc6KK4YStokSMu/FBNecGUQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@wallet-standard/base": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@wallet-standard/base": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@wallet-standard/base/-/base-1.1.0.tgz",
+ "integrity": "sha512-DJDQhjKmSNVLKWItoKThJS+CsJQjR9AOBOirBVT1F9YpRyC9oYHE+ZnSf8y8bxUphtKqdQMPVQ2mHohYdRvDVQ==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@wallet-standard/core": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@wallet-standard/core/-/core-1.1.1.tgz",
+ "integrity": "sha512-5Xmjc6+Oe0hcPfVc5n8F77NVLwx1JVAoCVgQpLyv/43/bhtIif+Gx3WUrDlaSDoM8i2kA2xd6YoFbHCxs+e0zA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@wallet-standard/app": "^1.1.0",
+ "@wallet-standard/base": "^1.1.0",
+ "@wallet-standard/errors": "^0.1.1",
+ "@wallet-standard/features": "^1.1.0",
+ "@wallet-standard/wallet": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@wallet-standard/errors": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@wallet-standard/errors/-/errors-0.1.1.tgz",
+ "integrity": "sha512-V8Ju1Wvol8i/VDyQOHhjhxmMVwmKiwyxUZBnHhtiPZJTWY0U/Shb2iEWyGngYEbAkp2sGTmEeNX1tVyGR7PqNw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "chalk": "^5.4.1",
+ "commander": "^13.1.0"
+ },
+ "bin": {
+ "errors": "bin/cli.mjs"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@wallet-standard/errors/node_modules/chalk": {
+ "version": "5.6.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
+ "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
+ "license": "MIT",
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/@wallet-standard/errors/node_modules/commander": {
+ "version": "13.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz",
+ "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@wallet-standard/features": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@wallet-standard/features/-/features-1.1.0.tgz",
+ "integrity": "sha512-hiEivWNztx73s+7iLxsuD1sOJ28xtRix58W7Xnz4XzzA/pF0+aicnWgjOdA10doVDEDZdUuZCIIqG96SFNlDUg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@wallet-standard/base": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@wallet-standard/wallet": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@wallet-standard/wallet/-/wallet-1.1.0.tgz",
+ "integrity": "sha512-Gt8TnSlDZpAl+RWOOAB/kuvC7RpcdWAlFbHNoi4gsXsfaWa1QCT6LBcfIYTPdOZC9OVZUDwqGuGAcqZejDmHjg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@wallet-standard/base": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/abort-controller": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
+ "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "event-target-shim": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=6.5"
+ }
+ },
"node_modules/accepts": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
@@ -4517,7 +5890,6 @@
"version": "8.16.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
"integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
- "dev": true,
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
@@ -4545,6 +5917,19 @@
"node": ">= 14"
}
},
+ "node_modules/agentkeepalive": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz",
+ "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "humanize-ms": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 8.0.0"
+ }
+ },
"node_modules/ajv": {
"version": "6.15.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz",
@@ -4601,6 +5986,13 @@
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"license": "MIT"
},
+ "node_modules/anser": {
+ "version": "1.4.10",
+ "resolved": "https://registry.npmjs.org/anser/-/anser-1.4.10.tgz",
+ "integrity": "sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww==",
+ "license": "MIT",
+ "peer": true
+ },
"node_modules/ansi-regex": {
"version": "6.2.2",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
@@ -4816,6 +6208,13 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/asap": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+ "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
+ "license": "MIT",
+ "peer": true
+ },
"node_modules/ast-types": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz",
@@ -4881,6 +6280,94 @@
"node": ">= 0.4"
}
},
+ "node_modules/babel-plugin-macros": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz",
+ "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.12.5",
+ "cosmiconfig": "^7.0.0",
+ "resolve": "^1.19.0"
+ },
+ "engines": {
+ "node": ">=10",
+ "npm": ">=6"
+ }
+ },
+ "node_modules/babel-plugin-macros/node_modules/cosmiconfig": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
+ "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/parse-json": "^4.0.0",
+ "import-fresh": "^3.2.1",
+ "parse-json": "^5.0.0",
+ "path-type": "^4.0.0",
+ "yaml": "^1.10.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/babel-plugin-macros/node_modules/resolve": {
+ "version": "1.22.12",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz",
+ "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "is-core-module": "^2.16.1",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/babel-plugin-macros/node_modules/yaml": {
+ "version": "1.10.3",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.3.tgz",
+ "integrity": "sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==",
+ "license": "ISC",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/babel-plugin-syntax-hermes-parser": {
+ "version": "0.33.3",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.33.3.tgz",
+ "integrity": "sha512-/Z9xYdaJ1lC0pT9do6TqCqhOSLfZ5Ot8D5za1p+feEfWYupCOfGbhhEXN9r2ZgJtDNUNRw/Z+T2CvAGKBqtqWA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "hermes-parser": "0.33.3"
+ }
+ },
+ "node_modules/babel-plugin-syntax-hermes-parser/node_modules/hermes-estree": {
+ "version": "0.33.3",
+ "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.33.3.tgz",
+ "integrity": "sha512-6kzYZHCk8Fy1Uc+t3HGYyJn3OL4aeqKLTyina4UFtWl8I0kSL7OmKThaiX+Uh2f8nGw3mo4Ifxg0M5Zk3/Oeqg==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/babel-plugin-syntax-hermes-parser/node_modules/hermes-parser": {
+ "version": "0.33.3",
+ "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.33.3.tgz",
+ "integrity": "sha512-Yg3HgaG4CqgyowtYjX/FsnPAuZdHOqSMtnbpylbptsQ9nwwSKsy6uRWcGO5RK0EqiX12q8HvDWKgeAVajRO5DA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "hermes-estree": "0.33.3"
+ }
+ },
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -4888,6 +6375,33 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/base-x": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/base-x/-/base-x-5.0.1.tgz",
+ "integrity": "sha512-M7uio8Zt++eg3jPj+rHMfCC+IuygQHHCOU+IYsVtik6FWjuYpVt/+MRKcgsAMHh8mMFAwnB+Bs+mTrFiXjMzKg==",
+ "license": "MIT"
+ },
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "peer": true
+ },
"node_modules/baseline-browser-mapping": {
"version": "2.10.25",
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.25.tgz",
@@ -4900,6 +6414,13 @@
"node": ">=6.0.0"
}
},
+ "node_modules/bn.js": {
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.3.tgz",
+ "integrity": "sha512-EAcmnPkxpntVL+DS7bO1zhcZNvCkxqtkd0ZY53h06GNQ3DEkkGZ/gKgmDv6DdZQGj9BgfSPKtJJ7Dp1GPP8f7w==",
+ "license": "MIT",
+ "peer": true
+ },
"node_modules/body-parser": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz",
@@ -4924,6 +6445,38 @@
"url": "https://opencollective.com/express"
}
},
+ "node_modules/borsh": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/borsh/-/borsh-0.7.0.tgz",
+ "integrity": "sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "bn.js": "^5.2.0",
+ "bs58": "^4.0.0",
+ "text-encoding-utf-8": "^1.0.2"
+ }
+ },
+ "node_modules/borsh/node_modules/base-x": {
+ "version": "3.0.11",
+ "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.11.tgz",
+ "integrity": "sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/borsh/node_modules/bs58": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz",
+ "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "base-x": "^3.0.2"
+ }
+ },
"node_modules/brace-expansion": {
"version": "1.1.14",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz",
@@ -4980,6 +6533,72 @@
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
}
},
+ "node_modules/bs58": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/bs58/-/bs58-6.0.0.tgz",
+ "integrity": "sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==",
+ "license": "MIT",
+ "dependencies": {
+ "base-x": "^5.0.0"
+ }
+ },
+ "node_modules/bser": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
+ "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "node-int64": "^0.4.0"
+ }
+ },
+ "node_modules/buffer": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
+ "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.2.1"
+ }
+ },
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/bufferutil": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.1.0.tgz",
+ "integrity": "sha512-ZMANVnAixE6AWWnPzlW2KpUrxhm9woycYvPOo67jWHyFowASTEd9s+QN1EIMsSDtwhIxN4sWE1jotpuDUIgyIw==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "node-gyp-build": "^4.3.0"
+ },
+ "engines": {
+ "node": ">=6.14.2"
+ }
+ },
"node_modules/bundle-name": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz",
@@ -5061,6 +6680,19 @@
"node": ">=6"
}
},
+ "node_modules/camelcase": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/caniuse-lite": {
"version": "1.0.30001791",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001791.tgz",
@@ -5085,7 +6717,6 @@
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.1.0",
@@ -5098,6 +6729,104 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
+ "node_modules/chrome-launcher": {
+ "version": "0.15.2",
+ "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.15.2.tgz",
+ "integrity": "sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@types/node": "*",
+ "escape-string-regexp": "^4.0.0",
+ "is-wsl": "^2.2.0",
+ "lighthouse-logger": "^1.0.0"
+ },
+ "bin": {
+ "print-chrome-path": "bin/print-chrome-path.js"
+ },
+ "engines": {
+ "node": ">=12.13.0"
+ }
+ },
+ "node_modules/chrome-launcher/node_modules/is-docker": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
+ "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
+ "license": "MIT",
+ "peer": true,
+ "bin": {
+ "is-docker": "cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/chrome-launcher/node_modules/is-wsl": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
+ "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "is-docker": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/chromium-edge-launcher": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/chromium-edge-launcher/-/chromium-edge-launcher-0.3.0.tgz",
+ "integrity": "sha512-p03azHlGjtyRvFEee3cyvtsRYdniSkwjkzmM/KmVnqT5d7QkkwpJBhis/zCLMYdQMVJ5tt140TBNqqrZPaWeFA==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@types/node": "*",
+ "escape-string-regexp": "^4.0.0",
+ "is-wsl": "^2.2.0",
+ "lighthouse-logger": "^1.0.0",
+ "mkdirp": "^1.0.4"
+ }
+ },
+ "node_modules/chromium-edge-launcher/node_modules/is-docker": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
+ "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
+ "license": "MIT",
+ "peer": true,
+ "bin": {
+ "is-docker": "cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/chromium-edge-launcher/node_modules/is-wsl": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
+ "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "is-docker": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ci-info": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
+ "license": "MIT",
+ "peer": true
+ },
"node_modules/class-variance-authority": {
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz",
@@ -5240,22 +6969,107 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"license": "MIT"
},
- "node_modules/commander": {
- "version": "14.0.3",
- "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz",
- "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==",
+ "node_modules/commander": {
+ "version": "14.0.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz",
+ "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/connect": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz",
+ "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "debug": "2.6.9",
+ "finalhandler": "1.1.2",
+ "parseurl": "~1.3.3",
+ "utils-merge": "1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.10.0"
+ }
+ },
+ "node_modules/connect/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/connect/node_modules/encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/connect/node_modules/finalhandler": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
+ "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "statuses": "~1.5.0",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/connect/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/connect/node_modules/on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/connect/node_modules/statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==",
"license": "MIT",
+ "peer": true,
"engines": {
- "node": ">=20"
+ "node": ">= 0.6"
}
},
- "node_modules/concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/content-disposition": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz",
@@ -5302,6 +7116,26 @@
"node": ">=6.6.0"
}
},
+ "node_modules/copy-to-clipboard": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz",
+ "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==",
+ "license": "MIT",
+ "dependencies": {
+ "toggle-selection": "^1.0.6"
+ }
+ },
+ "node_modules/core-js": {
+ "version": "3.47.0",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.47.0.tgz",
+ "integrity": "sha512-c3Q2VVkGAUyupsjRnaNX6u8Dq2vAdzm9iuPj5FW0fRxzlxgq9Q39MDq10IvmQSpLgHQNyQzQmOo6bgGHmH3NNg==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/core-js"
+ }
+ },
"node_modules/cors": {
"version": "2.8.6",
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz",
@@ -5375,7 +7209,6 @@
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
- "devOptional": true,
"license": "MIT"
},
"node_modules/damerau-levenshtein": {
@@ -5465,6 +7298,15 @@
}
}
},
+ "node_modules/decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/dedent": {
"version": "1.7.2",
"resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz",
@@ -5571,6 +7413,19 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/delay": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz",
+ "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/depd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@@ -5580,6 +7435,26 @@
"node": ">= 0.8"
}
},
+ "node_modules/dequal": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
+ "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/destroy": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
+ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
"node_modules/detect-libc": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
@@ -5605,6 +7480,12 @@
"node": ">=0.3.1"
}
},
+ "node_modules/dijkstrajs": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz",
+ "integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==",
+ "license": "MIT"
+ },
"node_modules/doctrine": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
@@ -5721,6 +7602,16 @@
"is-arrayish": "^0.2.1"
}
},
+ "node_modules/error-stack-parser": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz",
+ "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "stackframe": "^1.3.4"
+ }
+ },
"node_modules/es-abstract": {
"version": "1.24.2",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz",
@@ -5895,6 +7786,23 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/es6-promise": {
+ "version": "4.2.8",
+ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
+ "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/es6-promisify": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
+ "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "es6-promise": "^4.0.3"
+ }
+ },
"node_modules/escalade": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
@@ -5914,7 +7822,6 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
@@ -6351,6 +8258,22 @@
"node": ">= 0.6"
}
},
+ "node_modules/event-target-shim": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
+ "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/eventemitter3": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz",
+ "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==",
+ "license": "MIT"
+ },
"node_modules/eventsource": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz",
@@ -6398,6 +8321,13 @@
"url": "https://github.com/sindresorhus/execa?sponsor=1"
}
},
+ "node_modules/exponential-backoff": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz",
+ "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==",
+ "license": "Apache-2.0",
+ "peer": true
+ },
"node_modules/express": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz",
@@ -6459,6 +8389,15 @@
"express": ">= 4.11"
}
},
+ "node_modules/eyes": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz",
+ "integrity": "sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==",
+ "peer": true,
+ "engines": {
+ "node": "> 0.1.90"
+ }
+ },
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -6509,6 +8448,19 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/fast-sha256": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/fast-sha256/-/fast-sha256-1.3.0.tgz",
+ "integrity": "sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ==",
+ "license": "Unlicense"
+ },
+ "node_modules/fast-stable-stringify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz",
+ "integrity": "sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==",
+ "license": "MIT",
+ "peer": true
+ },
"node_modules/fast-string-truncated-width": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/fast-string-truncated-width/-/fast-string-truncated-width-3.0.3.tgz",
@@ -6558,6 +8510,29 @@
"reusify": "^1.0.4"
}
},
+ "node_modules/fb-dotslash": {
+ "version": "0.5.8",
+ "resolved": "https://registry.npmjs.org/fb-dotslash/-/fb-dotslash-0.5.8.tgz",
+ "integrity": "sha512-XHYLKk9J4BupDxi9bSEhkfss0m+Vr9ChTrjhf9l2iw3jB5C7BnY4GVPoMcqbrTutsKJso6yj2nAB6BI/F2oZaA==",
+ "license": "(MIT OR Apache-2.0)",
+ "peer": true,
+ "bin": {
+ "dotslash": "bin/dotslash"
+ },
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/fb-watchman": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz",
+ "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "bser": "2.1.1"
+ }
+ },
"node_modules/fetch-blob": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
@@ -6642,6 +8617,12 @@
"url": "https://opencollective.com/express"
}
},
+ "node_modules/find-root": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
+ "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==",
+ "license": "MIT"
+ },
"node_modules/find-up": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
@@ -6680,6 +8661,13 @@
"dev": true,
"license": "ISC"
},
+ "node_modules/flow-enums-runtime": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/flow-enums-runtime/-/flow-enums-runtime-0.0.6.tgz",
+ "integrity": "sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw==",
+ "license": "MIT",
+ "peer": true
+ },
"node_modules/for-each": {
"version": "0.3.5",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
@@ -6944,6 +8932,12 @@
"node": ">=10.13.0"
}
},
+ "node_modules/glob-to-regexp": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
+ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
+ "license": "BSD-2-Clause"
+ },
"node_modules/globals": {
"version": "14.0.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
@@ -7018,7 +9012,6 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -7103,6 +9096,13 @@
"set-cookie-parser": "^3.0.1"
}
},
+ "node_modules/hermes-compiler": {
+ "version": "250829098.0.10",
+ "resolved": "https://registry.npmjs.org/hermes-compiler/-/hermes-compiler-250829098.0.10.tgz",
+ "integrity": "sha512-TcRlZ0/TlyfJqquRFAWoyElVNnkdYRi/sEp4/Qy8/GYxjg8j2cS9D4MjuaQ+qimkmLN7AmO+44IznRf06mAr0w==",
+ "license": "MIT",
+ "peer": true
+ },
"node_modules/hermes-estree": {
"version": "0.25.1",
"resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz",
@@ -7120,6 +9120,15 @@
"hermes-estree": "0.25.1"
}
},
+ "node_modules/hoist-non-react-statics": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
+ "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "react-is": "^16.7.0"
+ }
+ },
"node_modules/hono": {
"version": "4.12.16",
"resolved": "https://registry.npmjs.org/hono/-/hono-4.12.16.tgz",
@@ -7171,6 +9180,16 @@
"node": ">=18.18.0"
}
},
+ "node_modules/humanize-ms": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
+ "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "ms": "^2.0.0"
+ }
+ },
"node_modules/iconv-lite": {
"version": "0.7.2",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz",
@@ -7187,6 +9206,27 @@
"url": "https://opencollective.com/express"
}
},
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
"node_modules/ignore": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
@@ -7196,6 +9236,22 @@
"node": ">= 4"
}
},
+ "node_modules/image-size": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.2.1.tgz",
+ "integrity": "sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "queue": "6.0.2"
+ },
+ "bin": {
+ "image-size": "bin/image-size.js"
+ },
+ "engines": {
+ "node": ">=16.x"
+ }
+ },
"node_modules/import-fresh": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
@@ -7228,6 +9284,16 @@
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"license": "ISC"
},
+ "node_modules/input-otp": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/input-otp/-/input-otp-1.4.2.tgz",
+ "integrity": "sha512-l3jWwYNvrEa6NTCt7BECfCm48GvwuZzkoeG3gBL2w4CHeOXW3eKFmf9UNYkNfYc3mxMrthMnxjIE07MT0zLBQA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc"
+ }
+ },
"node_modules/internal-slot": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
@@ -7243,6 +9309,16 @@
"node": ">= 0.4"
}
},
+ "node_modules/invariant": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
+ "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.0.0"
+ }
+ },
"node_modules/ip-address": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz",
@@ -7378,7 +9454,6 @@
"version": "2.16.1",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
"integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
- "dev": true,
"license": "MIT",
"dependencies": {
"hasown": "^2.0.2"
@@ -7794,73 +9869,218 @@
"call-bound": "^1.0.3"
},
"engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakset": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz",
+ "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-wsl": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz",
+ "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==",
+ "license": "MIT",
+ "dependencies": {
+ "is-inside-container": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "license": "ISC"
+ },
+ "node_modules/isomorphic-ws": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz",
+ "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==",
+ "license": "MIT",
+ "peer": true,
+ "peerDependencies": {
+ "ws": "*"
+ }
+ },
+ "node_modules/iterator.prototype": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz",
+ "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.6",
+ "get-proto": "^1.0.0",
+ "has-symbols": "^1.1.0",
+ "set-function-name": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/jayson": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/jayson/-/jayson-4.3.0.tgz",
+ "integrity": "sha512-AauzHcUcqs8OBnCHOkJY280VaTiCm57AbuO7lqzcw7JapGj50BisE3xhksye4zlTSR1+1tAz67wLTl8tEH1obQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/connect": "^3.4.33",
+ "@types/node": "^12.12.54",
+ "@types/ws": "^7.4.4",
+ "commander": "^2.20.3",
+ "delay": "^5.0.0",
+ "es6-promisify": "^5.0.0",
+ "eyes": "^0.1.8",
+ "isomorphic-ws": "^4.0.1",
+ "json-stringify-safe": "^5.0.1",
+ "stream-json": "^1.9.1",
+ "uuid": "^8.3.2",
+ "ws": "^7.5.10"
+ },
+ "bin": {
+ "jayson": "bin/jayson.js"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jayson/node_modules/@types/node": {
+ "version": "12.20.55",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz",
+ "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/jayson/node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/jest-get-type": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz",
+ "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-util": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz",
+ "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "ci-info": "^3.2.0",
+ "graceful-fs": "^4.2.9",
+ "picomatch": "^2.2.3"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-util/node_modules/ci-info": {
+ "version": "3.9.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
+ "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/sibiraj-s"
+ }
+ ],
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=8"
}
},
- "node_modules/is-weakset": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz",
- "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==",
- "dev": true,
+ "node_modules/jest-validate": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz",
+ "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==",
"license": "MIT",
+ "peer": true,
"dependencies": {
- "call-bound": "^1.0.3",
- "get-intrinsic": "^1.2.6"
+ "@jest/types": "^29.6.3",
+ "camelcase": "^6.2.0",
+ "chalk": "^4.0.0",
+ "jest-get-type": "^29.6.3",
+ "leven": "^3.1.0",
+ "pretty-format": "^29.7.0"
},
"engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
- "node_modules/is-wsl": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz",
- "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==",
+ "node_modules/jest-worker": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz",
+ "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==",
"license": "MIT",
+ "peer": true,
"dependencies": {
- "is-inside-container": "^1.0.0"
+ "@types/node": "*",
+ "jest-util": "^29.7.0",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^8.0.0"
},
"engines": {
- "node": ">=16"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
- "node_modules/isarray": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
- "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/isexe": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
- "license": "ISC"
- },
- "node_modules/iterator.prototype": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz",
- "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==",
- "dev": true,
+ "node_modules/jest-worker/node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
"license": "MIT",
+ "peer": true,
"dependencies": {
- "define-data-property": "^1.1.4",
- "es-object-atoms": "^1.0.0",
- "get-intrinsic": "^1.2.6",
- "get-proto": "^1.0.0",
- "has-symbols": "^1.1.0",
- "set-function-name": "^2.0.2"
+ "has-flag": "^4.0.0"
},
"engines": {
- "node": ">= 0.4"
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
"node_modules/jiti": {
@@ -7882,6 +10102,21 @@
"url": "https://github.com/sponsors/panva"
}
},
+ "node_modules/js-base64": {
+ "version": "3.7.8",
+ "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.8.tgz",
+ "integrity": "sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/js-cookie": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz",
+ "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ }
+ },
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -7900,6 +10135,13 @@
"js-yaml": "bin/js-yaml.js"
}
},
+ "node_modules/jsc-safe-url": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/jsc-safe-url/-/jsc-safe-url-0.2.4.tgz",
+ "integrity": "sha512-0wM3YBWtYePOjfyXQH5MWQ8H7sdk5EXSwZvmSLKk2RboVQ2Bu239jycHDz5J/8Blf3K0Qnoy2b6xD+z10MFB+Q==",
+ "license": "0BSD",
+ "peer": true
+ },
"node_modules/jsesc": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
@@ -7945,6 +10187,13 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
+ "license": "ISC",
+ "peer": true
+ },
"node_modules/json5": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
@@ -8024,6 +10273,16 @@
"node": ">=0.10"
}
},
+ "node_modules/leven": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
+ "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@@ -8038,6 +10297,34 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/lighthouse-logger": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.4.2.tgz",
+ "integrity": "sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "debug": "^2.6.9",
+ "marky": "^1.2.2"
+ }
+ },
+ "node_modules/lighthouse-logger/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/lighthouse-logger/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "license": "MIT",
+ "peer": true
+ },
"node_modules/lightningcss": {
"version": "1.32.0",
"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz",
@@ -8340,6 +10627,13 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/lodash.throttle": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
+ "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==",
+ "license": "MIT",
+ "peer": true
+ },
"node_modules/log-symbols": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz",
@@ -8384,7 +10678,6 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
- "dev": true,
"license": "MIT",
"dependencies": {
"js-tokens": "^3.0.0 || ^4.0.0"
@@ -8421,49 +10714,442 @@
"@jridgewell/sourcemap-codec": "^1.5.5"
}
},
- "node_modules/math-intrinsics": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
- "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
- "license": "MIT",
+ "node_modules/makeerror": {
+ "version": "1.0.12",
+ "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
+ "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==",
+ "license": "BSD-3-Clause",
+ "peer": true,
+ "dependencies": {
+ "tmpl": "1.0.5"
+ }
+ },
+ "node_modules/marky": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/marky/-/marky-1.3.0.tgz",
+ "integrity": "sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ==",
+ "license": "Apache-2.0",
+ "peer": true
+ },
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/media-typer": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
+ "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/memoize-one": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
+ "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/merge-descriptors": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
+ "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/merge-options": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-3.0.4.tgz",
+ "integrity": "sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "is-plain-obj": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/merge-options/node_modules/is-plain-obj": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
+ "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "license": "MIT"
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/metro": {
+ "version": "0.84.4",
+ "resolved": "https://registry.npmjs.org/metro/-/metro-0.84.4.tgz",
+ "integrity": "sha512-8ETTubqfD6ornDy2zYDvRcKnVDOXdFJsjetYDBsY4oAsb6NJkiwFR+FaMESyGppFmQUyBQA4H4sFGxzcQSGtFA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.29.0",
+ "@babel/core": "^7.25.2",
+ "@babel/generator": "^7.29.1",
+ "@babel/parser": "^7.29.0",
+ "@babel/template": "^7.28.6",
+ "@babel/traverse": "^7.29.0",
+ "@babel/types": "^7.29.0",
+ "accepts": "^2.0.0",
+ "ci-info": "^2.0.0",
+ "connect": "^3.6.5",
+ "debug": "^4.4.0",
+ "error-stack-parser": "^2.0.6",
+ "flow-enums-runtime": "^0.0.6",
+ "graceful-fs": "^4.2.4",
+ "hermes-parser": "0.35.0",
+ "image-size": "^1.0.2",
+ "invariant": "^2.2.4",
+ "jest-worker": "^29.7.0",
+ "jsc-safe-url": "^0.2.2",
+ "lodash.throttle": "^4.1.1",
+ "metro-babel-transformer": "0.84.4",
+ "metro-cache": "0.84.4",
+ "metro-cache-key": "0.84.4",
+ "metro-config": "0.84.4",
+ "metro-core": "0.84.4",
+ "metro-file-map": "0.84.4",
+ "metro-resolver": "0.84.4",
+ "metro-runtime": "0.84.4",
+ "metro-source-map": "0.84.4",
+ "metro-symbolicate": "0.84.4",
+ "metro-transform-plugins": "0.84.4",
+ "metro-transform-worker": "0.84.4",
+ "mime-types": "^3.0.1",
+ "nullthrows": "^1.1.1",
+ "serialize-error": "^2.1.0",
+ "source-map": "^0.5.6",
+ "throat": "^5.0.0",
+ "ws": "^7.5.10",
+ "yargs": "^17.6.2"
+ },
+ "bin": {
+ "metro": "src/cli.js"
+ },
+ "engines": {
+ "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
+ }
+ },
+ "node_modules/metro-babel-transformer": {
+ "version": "0.84.4",
+ "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.84.4.tgz",
+ "integrity": "sha512-rvCfz8snl9h20VcvpOHxZuHP1SlAkv4HXbzw7nyyVwu6Eqo5PRerbakQ9XmUCOsRy70spJ37O+G1TK8oMzo48g==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@babel/core": "^7.25.2",
+ "flow-enums-runtime": "^0.0.6",
+ "hermes-parser": "0.35.0",
+ "metro-cache-key": "0.84.4",
+ "nullthrows": "^1.1.1"
+ },
+ "engines": {
+ "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
+ }
+ },
+ "node_modules/metro-babel-transformer/node_modules/hermes-estree": {
+ "version": "0.35.0",
+ "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.35.0.tgz",
+ "integrity": "sha512-xVx5Opwy8Oo1I5yGpVRhCvWL/iV3M+ylksSKVNlxxD90cpDpR/AR1jLYqK8HWihm065a6UI3HeyAmYzwS8NOOg==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/metro-babel-transformer/node_modules/hermes-parser": {
+ "version": "0.35.0",
+ "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.35.0.tgz",
+ "integrity": "sha512-9JLjeHxBx8T4CAsydZR49PNZUaix+WpQJwu9p2010lu+7Kwl6D/7wYFFJxoz+aXkaaClp9Zfg6W6/zVlSJORaA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "hermes-estree": "0.35.0"
+ }
+ },
+ "node_modules/metro-cache": {
+ "version": "0.84.4",
+ "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.84.4.tgz",
+ "integrity": "sha512-gpcFQdSLUwUCk71saKoE64jLFbx2nwTfVCcPSULMNT8QYq0p1eZZE29Jvd0HtT/UlhC3ZOutLxJME5xqD2JUZg==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "exponential-backoff": "^3.1.1",
+ "flow-enums-runtime": "^0.0.6",
+ "https-proxy-agent": "^7.0.5",
+ "metro-core": "0.84.4"
+ },
+ "engines": {
+ "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
+ }
+ },
+ "node_modules/metro-cache-key": {
+ "version": "0.84.4",
+ "resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.84.4.tgz",
+ "integrity": "sha512-wVO79aGrkYImpnaVS4+d5RrRBRPX31QtvKB3wKGBuiNSznduZTQHzsrJZRroFJSwnygrzdsGUtDQPuqqFjFdvw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "flow-enums-runtime": "^0.0.6"
+ },
+ "engines": {
+ "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
+ }
+ },
+ "node_modules/metro-config": {
+ "version": "0.84.4",
+ "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.84.4.tgz",
+ "integrity": "sha512-PMotGDjXcXLWo2TMRH+VR99phFNgYTwqh4OoieIKK3yTJa1Jmkl+fZJxDO0jfBvNF+WESHciHvpNuBtXaF3B0Q==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "connect": "^3.6.5",
+ "flow-enums-runtime": "^0.0.6",
+ "jest-validate": "^29.7.0",
+ "metro": "0.84.4",
+ "metro-cache": "0.84.4",
+ "metro-core": "0.84.4",
+ "metro-runtime": "0.84.4",
+ "yaml": "^2.6.1"
+ },
+ "engines": {
+ "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
+ }
+ },
+ "node_modules/metro-core": {
+ "version": "0.84.4",
+ "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.84.4.tgz",
+ "integrity": "sha512-HONpWC5LGXZn3ffkd4Hu6AIrfE7j4Z0g0wMo/goV24WOB3lhuFZ40KgvaDiSw8iyQHloMYay5N/wPX+z8oN/PQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "flow-enums-runtime": "^0.0.6",
+ "lodash.throttle": "^4.1.1",
+ "metro-resolver": "0.84.4"
+ },
+ "engines": {
+ "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
+ }
+ },
+ "node_modules/metro-file-map": {
+ "version": "0.84.4",
+ "resolved": "https://registry.npmjs.org/metro-file-map/-/metro-file-map-0.84.4.tgz",
+ "integrity": "sha512-KSVDi/u60hKPx++NLu3MTIvyjzNoJnFAF8PQFxaj1jiSka/wjw+Ua6sNuJ0TDHQv+7AAoFQxeMgaRAe8Yic5wQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "debug": "^4.4.0",
+ "fb-watchman": "^2.0.0",
+ "flow-enums-runtime": "^0.0.6",
+ "graceful-fs": "^4.2.4",
+ "invariant": "^2.2.4",
+ "jest-worker": "^29.7.0",
+ "micromatch": "^4.0.4",
+ "nullthrows": "^1.1.1",
+ "walker": "^1.0.7"
+ },
+ "engines": {
+ "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
+ }
+ },
+ "node_modules/metro-minify-terser": {
+ "version": "0.84.4",
+ "resolved": "https://registry.npmjs.org/metro-minify-terser/-/metro-minify-terser-0.84.4.tgz",
+ "integrity": "sha512-5qpbaVOMC7CPitIpuewzVeGw7E+C3ykbv2mqTjQLl85Z3annSVGlSCTcsZjqXZzjupfK4Ztj3dDc4kc44NZwtQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "flow-enums-runtime": "^0.0.6",
+ "terser": "^5.15.0"
+ },
+ "engines": {
+ "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
+ }
+ },
+ "node_modules/metro-resolver": {
+ "version": "0.84.4",
+ "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.84.4.tgz",
+ "integrity": "sha512-1qLgbxQ5ZGhhutuPot1Yp348ofDsATL2WkrHF65TobqTT9K3P9qJXw38bomk7ncp5B7OYMfWwtyBZo1lCV792A==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "flow-enums-runtime": "^0.0.6"
+ },
+ "engines": {
+ "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
+ }
+ },
+ "node_modules/metro-runtime": {
+ "version": "0.84.4",
+ "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.84.4.tgz",
+ "integrity": "sha512-Jibypds4g7AhzdRKY+kDoj51s5EXMwgyp5ddtlreDAsWefMdOx+agWqgm0H2XSZ/ueanHHVM89fnf5OJnlxa8Q==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.25.0",
+ "flow-enums-runtime": "^0.0.6"
+ },
+ "engines": {
+ "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
+ }
+ },
+ "node_modules/metro-source-map": {
+ "version": "0.84.4",
+ "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.84.4.tgz",
+ "integrity": "sha512-jbWkPxIesVuo1IWkvezmMJld6iu8nD62GsrZiV6jP37AOdbo4OBq1FJ+qkOg8sV05wAHB//jAbziuW0SlJfW4g==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@babel/traverse": "^7.29.0",
+ "@babel/types": "^7.29.0",
+ "flow-enums-runtime": "^0.0.6",
+ "invariant": "^2.2.4",
+ "metro-symbolicate": "0.84.4",
+ "nullthrows": "^1.1.1",
+ "ob1": "0.84.4",
+ "source-map": "^0.5.6",
+ "vlq": "^1.0.0"
+ },
+ "engines": {
+ "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
+ }
+ },
+ "node_modules/metro-source-map/node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
+ "license": "BSD-3-Clause",
+ "peer": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/metro-symbolicate": {
+ "version": "0.84.4",
+ "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.84.4.tgz",
+ "integrity": "sha512-OnfpacxUqGPZQ27t8qK9mFa7uqHIlVWeqRqkCbvMvreEBiamEeOn8krKtcwgP5M4cYDPwuSmCTopHMVthqG4zA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "flow-enums-runtime": "^0.0.6",
+ "invariant": "^2.2.4",
+ "metro-source-map": "0.84.4",
+ "nullthrows": "^1.1.1",
+ "source-map": "^0.5.6",
+ "vlq": "^1.0.0"
+ },
+ "bin": {
+ "metro-symbolicate": "src/index.js"
+ },
+ "engines": {
+ "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
+ }
+ },
+ "node_modules/metro-symbolicate/node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
+ "license": "BSD-3-Clause",
+ "peer": true,
"engines": {
- "node": ">= 0.4"
+ "node": ">=0.10.0"
}
},
- "node_modules/media-typer": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
- "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
+ "node_modules/metro-transform-plugins": {
+ "version": "0.84.4",
+ "resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.84.4.tgz",
+ "integrity": "sha512-kehr6HbAecqD0/a3xLXobELdPaAmRAl8bel0qagPF4vhZtux93nS8S4eq2kgKt6J2GnQpVjSoW1PXdst04mwow==",
"license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@babel/core": "^7.25.2",
+ "@babel/generator": "^7.29.1",
+ "@babel/template": "^7.28.6",
+ "@babel/traverse": "^7.29.0",
+ "flow-enums-runtime": "^0.0.6",
+ "nullthrows": "^1.1.1"
+ },
"engines": {
- "node": ">= 0.8"
+ "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
}
},
- "node_modules/merge-descriptors": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
- "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
+ "node_modules/metro-transform-worker": {
+ "version": "0.84.4",
+ "resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.84.4.tgz",
+ "integrity": "sha512-W1IYMvvXTu4MxYr7d9h7CeG2vpIr3bmLLIavkPY4O1ilzDrvS8z/NEe6y+pC44Ff7raMXQgYSfdqDUwN/i39gg==",
"license": "MIT",
- "engines": {
- "node": ">=18"
+ "peer": true,
+ "dependencies": {
+ "@babel/core": "^7.25.2",
+ "@babel/generator": "^7.29.1",
+ "@babel/parser": "^7.29.0",
+ "@babel/types": "^7.29.0",
+ "flow-enums-runtime": "^0.0.6",
+ "metro": "0.84.4",
+ "metro-babel-transformer": "0.84.4",
+ "metro-cache": "0.84.4",
+ "metro-cache-key": "0.84.4",
+ "metro-minify-terser": "0.84.4",
+ "metro-source-map": "0.84.4",
+ "metro-transform-plugins": "0.84.4",
+ "nullthrows": "^1.1.1"
},
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "engines": {
+ "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
}
},
- "node_modules/merge-stream": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
- "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
- "license": "MIT"
+ "node_modules/metro/node_modules/hermes-estree": {
+ "version": "0.35.0",
+ "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.35.0.tgz",
+ "integrity": "sha512-xVx5Opwy8Oo1I5yGpVRhCvWL/iV3M+ylksSKVNlxxD90cpDpR/AR1jLYqK8HWihm065a6UI3HeyAmYzwS8NOOg==",
+ "license": "MIT",
+ "peer": true
},
- "node_modules/merge2": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
- "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "node_modules/metro/node_modules/hermes-parser": {
+ "version": "0.35.0",
+ "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.35.0.tgz",
+ "integrity": "sha512-9JLjeHxBx8T4CAsydZR49PNZUaix+WpQJwu9p2010lu+7Kwl6D/7wYFFJxoz+aXkaaClp9Zfg6W6/zVlSJORaA==",
"license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "hermes-estree": "0.35.0"
+ }
+ },
+ "node_modules/metro/node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
+ "license": "BSD-3-Clause",
+ "peer": true,
"engines": {
- "node": ">= 8"
+ "node": ">=0.10.0"
}
},
"node_modules/micromatch": {
@@ -8479,6 +11165,19 @@
"node": ">=8.6"
}
},
+ "node_modules/mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "license": "MIT",
+ "peer": true,
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/mime-db": {
"version": "1.54.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
@@ -8547,6 +11246,19 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "license": "MIT",
+ "peer": true,
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
@@ -8807,6 +11519,26 @@
"url": "https://opencollective.com/node-fetch"
}
},
+ "node_modules/node-gyp-build": {
+ "version": "4.8.4",
+ "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz",
+ "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "bin": {
+ "node-gyp-build": "bin.js",
+ "node-gyp-build-optional": "optional.js",
+ "node-gyp-build-test": "build-test.js"
+ }
+ },
+ "node_modules/node-int64": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
+ "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==",
+ "license": "MIT",
+ "peer": true
+ },
"node_modules/node-releases": {
"version": "2.0.38",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.38.tgz",
@@ -8841,6 +11573,26 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/nullthrows": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz",
+ "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/ob1": {
+ "version": "0.84.4",
+ "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.84.4.tgz",
+ "integrity": "sha512-eJXMpz4aQHXF/YBB9ddqZDIS+ooO91hObo9FoW/xBkr54/zCwYYCDqT/O54vNo8kOkWs5Ou/y28NgdrV0edQNA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "flow-enums-runtime": "^0.0.6"
+ },
+ "engines": {
+ "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
+ }
+ },
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -9136,6 +11888,15 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@@ -9197,7 +11958,6 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -9216,7 +11976,6 @@
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
- "dev": true,
"license": "MIT"
},
"node_modules/path-to-regexp": {
@@ -9225,6 +11984,15 @@
"integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==",
"license": "MIT"
},
+ "node_modules/path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
@@ -9252,6 +12020,15 @@
"node": ">=16.20.0"
}
},
+ "node_modules/pngjs": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz",
+ "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
"node_modules/possible-typed-array-names": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
@@ -9325,6 +12102,41 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/pretty-format": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
+ "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@jest/schemas": "^29.6.3",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/pretty-format/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/pretty-format/node_modules/react-is": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
+ "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
+ "license": "MIT",
+ "peer": true
+ },
"node_modules/pretty-ms": {
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.3.0.tgz",
@@ -9340,6 +12152,16 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/promise": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz",
+ "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "asap": "~2.0.6"
+ }
+ },
"node_modules/prompts": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
@@ -9397,6 +12219,200 @@
"node": ">=6"
}
},
+ "node_modules/qrcode": {
+ "version": "1.5.4",
+ "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.4.tgz",
+ "integrity": "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==",
+ "license": "MIT",
+ "dependencies": {
+ "dijkstrajs": "^1.0.1",
+ "pngjs": "^5.0.0",
+ "yargs": "^15.3.1"
+ },
+ "bin": {
+ "qrcode": "bin/qrcode"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/qrcode.react": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/qrcode.react/-/qrcode.react-4.2.0.tgz",
+ "integrity": "sha512-QpgqWi8rD9DsS9EP3z7BT+5lY5SFhsqGjpgW5DY/i3mK4M9DTBNz3ErMi8BWYEfI3L0d8GIbGmcdFAS1uIRGjA==",
+ "license": "ISC",
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
+ "node_modules/qrcode/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/qrcode/node_modules/camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/qrcode/node_modules/cliui": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
+ "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^6.2.0"
+ }
+ },
+ "node_modules/qrcode/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "license": "MIT"
+ },
+ "node_modules/qrcode/node_modules/find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/qrcode/node_modules/locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/qrcode/node_modules/p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "license": "MIT",
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/qrcode/node_modules/p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/qrcode/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/qrcode/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/qrcode/node_modules/wrap-ansi": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+ "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/qrcode/node_modules/y18n": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
+ "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
+ "license": "ISC"
+ },
+ "node_modules/qrcode/node_modules/yargs": {
+ "version": "15.4.1",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
+ "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
+ "license": "MIT",
+ "dependencies": {
+ "cliui": "^6.0.0",
+ "decamelize": "^1.2.0",
+ "find-up": "^4.1.0",
+ "get-caller-file": "^2.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^2.0.0",
+ "set-blocking": "^2.0.0",
+ "string-width": "^4.2.0",
+ "which-module": "^2.0.0",
+ "y18n": "^4.0.0",
+ "yargs-parser": "^18.1.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/qrcode/node_modules/yargs-parser": {
+ "version": "18.1.3",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
+ "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
+ "license": "ISC",
+ "dependencies": {
+ "camelcase": "^5.0.0",
+ "decamelize": "^1.2.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/qs": {
"version": "6.15.1",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.15.1.tgz",
@@ -9412,6 +12428,16 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/queue": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz",
+ "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "inherits": "~2.0.3"
+ }
+ },
"node_modules/queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -9542,6 +12568,17 @@
"node": ">=0.10.0"
}
},
+ "node_modules/react-devtools-core": {
+ "version": "6.1.5",
+ "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-6.1.5.tgz",
+ "integrity": "sha512-ePrwPfxAnB+7hgnEr8vpKxL9cmnp7F322t8oqcPshbIQQhDKgFDW4tjhF2wjVbdXF9O/nyuy3sQWd9JGpiLPvA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "shell-quote": "^1.6.1",
+ "ws": "^7"
+ }
+ },
"node_modules/react-dom": {
"version": "19.2.4",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz",
@@ -9558,9 +12595,111 @@
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
- "dev": true,
"license": "MIT"
},
+ "node_modules/react-native": {
+ "version": "0.85.2",
+ "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.85.2.tgz",
+ "integrity": "sha512-GFWEPwLYirfj5X8gMtXOWtqX0cqUEURRHETZfFk37VCa4++izrKvGvv24anvuyulXV87NAhVkfNw93rLg3HByw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@react-native/assets-registry": "0.85.2",
+ "@react-native/codegen": "0.85.2",
+ "@react-native/community-cli-plugin": "0.85.2",
+ "@react-native/gradle-plugin": "0.85.2",
+ "@react-native/js-polyfills": "0.85.2",
+ "@react-native/normalize-colors": "0.85.2",
+ "@react-native/virtualized-lists": "0.85.2",
+ "abort-controller": "^3.0.0",
+ "anser": "^1.4.9",
+ "ansi-regex": "^5.0.0",
+ "babel-plugin-syntax-hermes-parser": "0.33.3",
+ "base64-js": "^1.5.1",
+ "commander": "^12.0.0",
+ "flow-enums-runtime": "^0.0.6",
+ "hermes-compiler": "250829098.0.10",
+ "invariant": "^2.2.4",
+ "memoize-one": "^5.0.0",
+ "metro-runtime": "^0.84.0",
+ "metro-source-map": "^0.84.0",
+ "nullthrows": "^1.1.1",
+ "pretty-format": "^29.7.0",
+ "promise": "^8.3.0",
+ "react-devtools-core": "^6.1.5",
+ "react-refresh": "^0.14.0",
+ "regenerator-runtime": "^0.13.2",
+ "scheduler": "0.27.0",
+ "semver": "^7.1.3",
+ "stacktrace-parser": "^0.1.10",
+ "tinyglobby": "^0.2.15",
+ "whatwg-fetch": "^3.0.0",
+ "ws": "^7.5.10",
+ "yargs": "^17.6.2"
+ },
+ "bin": {
+ "react-native": "cli.js"
+ },
+ "engines": {
+ "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
+ },
+ "peerDependencies": {
+ "@react-native/jest-preset": "0.85.2",
+ "@types/react": "^19.1.1",
+ "react": "^19.2.3"
+ },
+ "peerDependenciesMeta": {
+ "@react-native/jest-preset": {
+ "optional": true
+ },
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-native/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/react-native/node_modules/commander": {
+ "version": "12.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz",
+ "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/react-native/node_modules/semver": {
+ "version": "7.7.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
+ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
+ "license": "ISC",
+ "peer": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/react-refresh": {
+ "version": "0.14.2",
+ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",
+ "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/react-remove-scroll": {
"version": "2.7.2",
"resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.2.tgz",
@@ -9669,6 +12808,13 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/regenerator-runtime": {
+ "version": "0.13.11",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
+ "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==",
+ "license": "MIT",
+ "peer": true
+ },
"node_modules/regexp.prototype.flags": {
"version": "1.5.4",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz",
@@ -9708,6 +12854,12 @@
"node": ">=0.10.0"
}
},
+ "node_modules/require-main-filename": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
+ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
+ "license": "ISC"
+ },
"node_modules/resolve": {
"version": "2.0.0-next.6",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.6.tgz",
@@ -9809,6 +12961,91 @@
"url": "https://opencollective.com/express"
}
},
+ "node_modules/rpc-websockets": {
+ "version": "9.3.8",
+ "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-9.3.8.tgz",
+ "integrity": "sha512-7r+fm4tSJmLf9GvZfL1DJ1SJwpagpp6AazqM0FUaeV7CA+7+NYINSk1syWa4tU/6OF2CyBicLtzENGmXRJH6wQ==",
+ "license": "LGPL-3.0-only",
+ "peer": true,
+ "dependencies": {
+ "@swc/helpers": "^0.5.11",
+ "@types/uuid": "^10.0.0",
+ "@types/ws": "^8.2.2",
+ "buffer": "^6.0.3",
+ "eventemitter3": "^5.0.1",
+ "uuid": "^11.0.0",
+ "ws": "^8.5.0"
+ },
+ "funding": {
+ "type": "paypal",
+ "url": "https://paypal.me/kozjak"
+ },
+ "optionalDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": "^6.0.0"
+ }
+ },
+ "node_modules/rpc-websockets/node_modules/@types/ws": {
+ "version": "8.18.1",
+ "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
+ "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/rpc-websockets/node_modules/utf-8-validate": {
+ "version": "6.0.6",
+ "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-6.0.6.tgz",
+ "integrity": "sha512-q3l3P9UtEEiAHcsgsqTgf9PPjctrDWoIXW3NpOHFdRDbLvu4DLIcxHangJ4RLrWkBcKjmcs/6NkerI8T/rE4LA==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "node-gyp-build": "^4.3.0"
+ },
+ "engines": {
+ "node": ">=6.14.2"
+ }
+ },
+ "node_modules/rpc-websockets/node_modules/uuid": {
+ "version": "11.1.1",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.1.tgz",
+ "integrity": "sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ==",
+ "funding": [
+ "https://github.com/sponsors/broofa",
+ "https://github.com/sponsors/ctavan"
+ ],
+ "license": "MIT",
+ "peer": true,
+ "bin": {
+ "uuid": "dist/esm/bin/uuid"
+ }
+ },
+ "node_modules/rpc-websockets/node_modules/ws": {
+ "version": "8.20.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz",
+ "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
"node_modules/run-applescript": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz",
@@ -9864,6 +13101,27 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "peer": true
+ },
"node_modules/safe-push-apply": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz",
@@ -9946,6 +13204,16 @@
"url": "https://opencollective.com/express"
}
},
+ "node_modules/serialize-error": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz",
+ "integrity": "sha512-ghgmKt5o4Tly5yEG/UJp8qTd0AN7Xalw4XBtDEKP655B699qMEtra1WlXeE6WIvdEG481JvRxULKsInq/iNysw==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/serve-static": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz",
@@ -9965,6 +13233,18 @@
"url": "https://opencollective.com/express"
}
},
+ "node_modules/server-only": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/server-only/-/server-only-0.0.1.tgz",
+ "integrity": "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==",
+ "license": "MIT"
+ },
+ "node_modules/set-blocking": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
+ "license": "ISC"
+ },
"node_modules/set-cookie-parser": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-3.1.0.tgz",
@@ -10201,6 +13481,19 @@
"node": ">=8"
}
},
+ "node_modules/shell-quote": {
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz",
+ "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/side-channel": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
@@ -10309,6 +13602,17 @@
"node": ">=0.10.0"
}
},
+ "node_modules/source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
"node_modules/stable-hash": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz",
@@ -10316,6 +13620,46 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/stackframe": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz",
+ "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/stacktrace-parser": {
+ "version": "0.1.11",
+ "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.11.tgz",
+ "integrity": "sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "type-fest": "^0.7.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/stacktrace-parser/node_modules/type-fest": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz",
+ "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==",
+ "license": "(MIT OR CC0-1.0)",
+ "peer": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/standardwebhooks": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/standardwebhooks/-/standardwebhooks-1.0.0.tgz",
+ "integrity": "sha512-BbHGOQK9olHPMvQNHWul6MYlrRTAOKn03rOe4A8O3CLWhNf4YHBqq2HJKKC+sfqpxiBY52pNeesD6jIiLDz8jg==",
+ "license": "MIT",
+ "dependencies": {
+ "@stablelib/base64": "^1.0.0",
+ "fast-sha256": "^1.3.0"
+ }
+ },
"node_modules/statuses": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
@@ -10325,6 +13669,12 @@
"node": ">= 0.8"
}
},
+ "node_modules/std-env": {
+ "version": "3.10.0",
+ "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz",
+ "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==",
+ "license": "MIT"
+ },
"node_modules/stdin-discarder": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz",
@@ -10351,6 +13701,23 @@
"node": ">= 0.4"
}
},
+ "node_modules/stream-chain": {
+ "version": "2.2.5",
+ "resolved": "https://registry.npmjs.org/stream-chain/-/stream-chain-2.2.5.tgz",
+ "integrity": "sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA==",
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
+ "node_modules/stream-json": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/stream-json/-/stream-json-1.9.1.tgz",
+ "integrity": "sha512-uWkjJ+2Nt/LO9Z/JyKZbMusL8Dkh97uUBTv3AJQ74y07lVahLY4eEFsPsE97pxYBwr8nnjMAIch5eqI0gPShyw==",
+ "license": "BSD-3-Clause",
+ "peer": true,
+ "dependencies": {
+ "stream-chain": "^2.2.5"
+ }
+ },
"node_modules/strict-event-emitter": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz",
@@ -10582,11 +13949,26 @@
}
}
},
+ "node_modules/stylis": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz",
+ "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==",
+ "license": "MIT"
+ },
+ "node_modules/superstruct": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-2.0.2.tgz",
+ "integrity": "sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
"license": "MIT",
"dependencies": {
"has-flag": "^4.0.0"
@@ -10599,7 +13981,6 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -10608,6 +13989,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/tabbable": {
+ "version": "6.4.0",
+ "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.4.0.tgz",
+ "integrity": "sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==",
+ "license": "MIT"
+ },
"node_modules/tagged-tag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz",
@@ -10651,6 +14038,45 @@
"url": "https://opencollective.com/webpack"
}
},
+ "node_modules/terser": {
+ "version": "5.46.2",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.2.tgz",
+ "integrity": "sha512-uxfo9fPcSgLDYob/w1FuL0c99MWiJDnv+5qXSQc5+Ki5NjVNsYi66INnMFBjf6uFz6OnX12piJQPF4IpjJTNTw==",
+ "license": "BSD-2-Clause",
+ "peer": true,
+ "dependencies": {
+ "@jridgewell/source-map": "^0.3.3",
+ "acorn": "^8.15.0",
+ "commander": "^2.20.0",
+ "source-map-support": "~0.5.20"
+ },
+ "bin": {
+ "terser": "bin/terser"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/terser/node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/text-encoding-utf-8": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz",
+ "integrity": "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==",
+ "peer": true
+ },
+ "node_modules/throat": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz",
+ "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==",
+ "license": "MIT",
+ "peer": true
+ },
"node_modules/tiny-invariant": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz",
@@ -10661,7 +14087,6 @@
"version": "0.2.16",
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz",
"integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==",
- "dev": true,
"license": "MIT",
"dependencies": {
"fdir": "^6.5.0",
@@ -10678,7 +14103,6 @@
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
"integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=12.0.0"
@@ -10696,7 +14120,6 @@
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
@@ -10723,6 +14146,13 @@
"integrity": "sha512-uiHN8PIB1VmWyS98eZYja4xzlYqeFZVjb4OuYlJQnZAuJhMw4PbKQOKgHKhBdJR3FE/t5mUQ1Kd80++B+qhD1Q==",
"license": "MIT"
},
+ "node_modules/tmpl": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
+ "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@@ -10735,6 +14165,12 @@
"node": ">=8.0"
}
},
+ "node_modules/toggle-selection": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz",
+ "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==",
+ "license": "MIT"
+ },
"node_modules/toidentifier": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
@@ -10756,6 +14192,13 @@
"node": ">=16"
}
},
+ "node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
+ "license": "MIT",
+ "peer": true
+ },
"node_modules/ts-api-utils": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz",
@@ -10944,7 +14387,6 @@
"version": "5.9.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
- "devOptional": true,
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
@@ -11175,6 +14617,27 @@
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"license": "MIT"
},
+ "node_modules/utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).",
+ "license": "MIT",
+ "peer": true,
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
"node_modules/validate-npm-package-name": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-7.0.2.tgz",
@@ -11193,6 +14656,23 @@
"node": ">= 0.8"
}
},
+ "node_modules/vlq": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/vlq/-/vlq-1.0.1.tgz",
+ "integrity": "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/walker": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
+ "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "makeerror": "1.0.12"
+ }
+ },
"node_modules/web-streams-polyfill": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
@@ -11202,6 +14682,31 @@
"node": ">= 8"
}
},
+ "node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
+ "license": "BSD-2-Clause",
+ "peer": true
+ },
+ "node_modules/whatwg-fetch": {
+ "version": "3.6.20",
+ "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz",
+ "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@@ -11284,6 +14789,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/which-module": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz",
+ "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==",
+ "license": "ISC"
+ },
"node_modules/which-typed-array": {
"version": "1.1.20",
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz",
@@ -11380,6 +14891,28 @@
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"license": "ISC"
},
+ "node_modules/ws": {
+ "version": "7.5.10",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
+ "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=8.3.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": "^5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
"node_modules/wsl-utils": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.3.1.tgz",
@@ -11411,6 +14944,22 @@
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
"license": "ISC"
},
+ "node_modules/yaml": {
+ "version": "2.8.4",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.4.tgz",
+ "integrity": "sha512-ml/JPOj9fOQK8RNnWojA67GbZ0ApXAUlN2UQclwv2eVgTgn7O9gg9o7paZWKMp4g0H3nTLtS9LVzhkpOFIKzog==",
+ "license": "ISC",
+ "peer": true,
+ "bin": {
+ "yaml": "bin.mjs"
+ },
+ "engines": {
+ "node": ">= 14.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/eemeli"
+ }
+ },
"node_modules/yargs": {
"version": "17.7.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
diff --git a/package.json b/package.json
index 14bd8f5..158ac96 100644
--- a/package.json
+++ b/package.json
@@ -9,6 +9,8 @@
"lint": "eslint"
},
"dependencies": {
+ "@clerk/nextjs": "^7.3.0",
+ "@clerk/ui": "^1.7.0",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"lucide-react": "^1.14.0",
diff --git a/proxy.ts b/proxy.ts
new file mode 100644
index 0000000..01c119c
--- /dev/null
+++ b/proxy.ts
@@ -0,0 +1,24 @@
+import { clerkMiddleware, createRouteMatcher } from "@clerk/nextjs/server"
+
+const signInRoute = process.env.NEXT_PUBLIC_CLERK_SIGN_IN_URL ?? "/sign-in"
+const signUpRoute = process.env.NEXT_PUBLIC_CLERK_SIGN_UP_URL ?? "/sign-up"
+
+const isPublicRoute = createRouteMatcher([
+ "/",
+ `${signInRoute}(.*)`,
+ `${signUpRoute}(.*)`,
+])
+
+export default clerkMiddleware(async (auth, request) => {
+ if (!isPublicRoute(request)) {
+ await auth.protect()
+ }
+})
+
+export const config = {
+ matcher: [
+ "/",
+ "/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)",
+ "/(api|trpc)(.*)",
+ ],
+}
diff --git a/skills-lock.json b/skills-lock.json
new file mode 100644
index 0000000..0c3fd76
--- /dev/null
+++ b/skills-lock.json
@@ -0,0 +1,35 @@
+{
+ "version": 1,
+ "skills": {
+ "clerk": {
+ "source": "clerk/skills",
+ "sourceType": "github",
+ "skillPath": "skills/core/clerk/SKILL.md",
+ "computedHash": "d1c09b948996e0ea71b2a27d5207fff43f7b5930fde39c42413a7867fddf06b5"
+ },
+ "clerk-backend-api": {
+ "source": "clerk/skills",
+ "sourceType": "github",
+ "skillPath": "skills/core/clerk-backend-api/SKILL.md",
+ "computedHash": "cbcad1341a7d32fed789abe864c829f27a2858dc8ba68b92254e9beb53467148"
+ },
+ "clerk-custom-ui": {
+ "source": "clerk/skills",
+ "sourceType": "github",
+ "skillPath": "skills/core/clerk-custom-ui/SKILL.md",
+ "computedHash": "b45ddd91c4924e8a74cb5272e769b06a5bbbde329983e7e565e6902b1cc80ded"
+ },
+ "clerk-nextjs-patterns": {
+ "source": "clerk/skills",
+ "sourceType": "github",
+ "skillPath": "skills/frameworks/clerk-nextjs-patterns/SKILL.md",
+ "computedHash": "f397ece3da422044705341ae85940fc3c36de8f5970e36146dda6ae6955974e2"
+ },
+ "clerk-setup": {
+ "source": "clerk/skills",
+ "sourceType": "github",
+ "skillPath": "skills/core/clerk-setup/SKILL.md",
+ "computedHash": "645b6330424cb2108562852a8d2818bed64484db74aa939476c2f57b63b1da10"
+ }
+ }
+}