From d919761023d4c084a558bd79fbb2205e79da9bcc Mon Sep 17 00:00:00 2001
From: daikictrl
Date: Sun, 3 May 2026 13:02:27 +0100
Subject: [PATCH 1/5] implement_auth
---
.agents/skills/clerk-backend-api/SKILL.md | 426 ++
.../skills/clerk-backend-api/evals/evals.json | 87 +
.../scripts/api-specs-context.sh | 30 +
.../scripts/execute-request.sh | 88 +
.../scripts/extract-endpoint-detail.sh | 165 +
.../scripts/extract-tag-endpoints.sh | 208 +
.../clerk-backend-api/scripts/extract-tags.js | 14 +
.agents/skills/clerk-custom-ui/SKILL.md | 175 +
.../clerk-custom-ui/core-2/custom-sign-in.md | 224 +
.../clerk-custom-ui/core-2/custom-sign-up.md | 190 +
.../clerk-custom-ui/core-3/custom-sign-in.md | 314 ++
.../clerk-custom-ui/core-3/custom-sign-up.md | 259 ++
.../clerk-custom-ui/core-3/show-component.md | 125 +
.agents/skills/clerk-nextjs-patterns/SKILL.md | 214 +
.../clerk-nextjs-patterns/evals/evals.json | 82 +
.../references/api-routes.md | 50 +
.../references/caching-auth.md | 56 +
.../references/middleware-strategies.md | 68 +
.../references/server-actions.md | 56 +
.../references/server-vs-client.md | 104 +
.../nextjs-basic-auth/app/layout.tsx | 22 +
.../templates/nextjs-basic-auth/app/page.tsx | 3 +
.../templates/nextjs-basic-auth/package.json | 16 +
.../templates/nextjs-basic-auth/proxy.ts | 10 +
.../templates/nextjs-basic-auth/tsconfig.json | 23 +
.agents/skills/clerk-setup/SKILL.md | 266 ++
.agents/skills/clerk-setup/evals/evals.json | 74 +
.agents/skills/clerk/SKILL.md | 154 +
app/editor/layout.tsx | 9 +
app/editor/page.tsx | 7 +
app/layout.tsx | 50 +-
app/page.tsx | 13 +-
app/sign-in/[[...sign-in]]/page.tsx | 19 +
app/sign-up/[[...sign-up]]/page.tsx | 19 +
components/auth/auth-page-shell.tsx | 43 +
components/editor/editor-navbar.tsx | 5 +-
context/architecture.md | 43 +-
context/current-issues.md | 3 +
context/feature-spec/03-auth.md | 53 +
context/progress-tracker.md | 23 +-
package-lock.json | 3909 ++++++++++++++++-
package.json | 2 +
proxy.ts | 24 +
skills-lock.json | 35 +
44 files changed, 7540 insertions(+), 220 deletions(-)
create mode 100644 .agents/skills/clerk-backend-api/SKILL.md
create mode 100644 .agents/skills/clerk-backend-api/evals/evals.json
create mode 100644 .agents/skills/clerk-backend-api/scripts/api-specs-context.sh
create mode 100644 .agents/skills/clerk-backend-api/scripts/execute-request.sh
create mode 100644 .agents/skills/clerk-backend-api/scripts/extract-endpoint-detail.sh
create mode 100644 .agents/skills/clerk-backend-api/scripts/extract-tag-endpoints.sh
create mode 100644 .agents/skills/clerk-backend-api/scripts/extract-tags.js
create mode 100644 .agents/skills/clerk-custom-ui/SKILL.md
create mode 100644 .agents/skills/clerk-custom-ui/core-2/custom-sign-in.md
create mode 100644 .agents/skills/clerk-custom-ui/core-2/custom-sign-up.md
create mode 100644 .agents/skills/clerk-custom-ui/core-3/custom-sign-in.md
create mode 100644 .agents/skills/clerk-custom-ui/core-3/custom-sign-up.md
create mode 100644 .agents/skills/clerk-custom-ui/core-3/show-component.md
create mode 100644 .agents/skills/clerk-nextjs-patterns/SKILL.md
create mode 100644 .agents/skills/clerk-nextjs-patterns/evals/evals.json
create mode 100644 .agents/skills/clerk-nextjs-patterns/references/api-routes.md
create mode 100644 .agents/skills/clerk-nextjs-patterns/references/caching-auth.md
create mode 100644 .agents/skills/clerk-nextjs-patterns/references/middleware-strategies.md
create mode 100644 .agents/skills/clerk-nextjs-patterns/references/server-actions.md
create mode 100644 .agents/skills/clerk-nextjs-patterns/references/server-vs-client.md
create mode 100644 .agents/skills/clerk-nextjs-patterns/templates/nextjs-basic-auth/app/layout.tsx
create mode 100644 .agents/skills/clerk-nextjs-patterns/templates/nextjs-basic-auth/app/page.tsx
create mode 100644 .agents/skills/clerk-nextjs-patterns/templates/nextjs-basic-auth/package.json
create mode 100644 .agents/skills/clerk-nextjs-patterns/templates/nextjs-basic-auth/proxy.ts
create mode 100644 .agents/skills/clerk-nextjs-patterns/templates/nextjs-basic-auth/tsconfig.json
create mode 100644 .agents/skills/clerk-setup/SKILL.md
create mode 100644 .agents/skills/clerk-setup/evals/evals.json
create mode 100644 .agents/skills/clerk/SKILL.md
create mode 100644 app/editor/layout.tsx
create mode 100644 app/editor/page.tsx
create mode 100644 app/sign-in/[[...sign-in]]/page.tsx
create mode 100644 app/sign-up/[[...sign-up]]/page.tsx
create mode 100644 components/auth/auth-page-shell.tsx
create mode 100644 context/current-issues.md
create mode 100644 context/feature-spec/03-auth.md
create mode 100644 proxy.ts
create mode 100644 skills-lock.json
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/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..f29c0e5 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({
@@ -24,13 +46,21 @@ export default function RootLayout({
children: React.ReactNode;
}>) {
return (
-
-
- {children}
-
-
+
+ {children}
+
+
);
}
diff --git a/app/page.tsx b/app/page.tsx
index c112497..6ead600 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -1,7 +1,8 @@
-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();
+
+ redirect(userId ? "/editor" : "/sign-in");
}
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..f6ee687
--- /dev/null
+++ b/context/current-issues.md
@@ -0,0 +1,3 @@
+After I sign-in to the app, when I click the Manage account button, a whitish/blurish foreground color appears on the editor behing the Manage account window. I've uploaded the picture in the chat so that you can see even clearly what I'm talking about. Fix that. I want the editors background color to be maintained no matter the feature or window I open.
+
+When I try signing-out, the Nextjs compiler at the buttom left corner of the page gets stuck on saying Redering..., until I manually refresh it the page myself before it completely gets me signed out. Fix that too
\ No newline at end of file
diff --git a/context/feature-spec/03-auth.md b/context/feature-spec/03-auth.md
new file mode 100644
index 0000000..0ad74d1
--- /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"
+ }
+ }
+}
From 497a066c0feb65a64f0f43ef6ced78e0e3feeed5 Mon Sep 17 00:00:00 2001
From: daikictrl
Date: Sun, 3 May 2026 16:04:15 +0100
Subject: [PATCH 2/5] upated_.git ignore
---
.gitignore | 1 +
1 file changed, 1 insertion(+)
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
From ae983dcf9754a718af332c0e5e704384ba3ba4e4 Mon Sep 17 00:00:00 2001
From: daikictrl
Date: Sun, 3 May 2026 16:12:31 +0100
Subject: [PATCH 3/5] Fix Clerk layout and sign-in redirect
---
app/layout.tsx | 34 +++++++++++++++++++---------------
app/page.tsx | 3 ++-
2 files changed, 21 insertions(+), 16 deletions(-)
diff --git a/app/layout.tsx b/app/layout.tsx
index f29c0e5..15a4af1 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -46,21 +46,25 @@ export default function RootLayout({
children: React.ReactNode;
}>) {
return (
-
-
- {children}
-
-
+
+
+ {children}
+
+
+
);
}
diff --git a/app/page.tsx b/app/page.tsx
index 6ead600..c91c86b 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -3,6 +3,7 @@ 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" : "/sign-in");
+ redirect(userId ? "/editor" : signInUrl);
}
From 77228f37ec8fbc62a7e0f37f043854a59bbff849 Mon Sep 17 00:00:00 2001
From: daikictrl
Date: Sun, 3 May 2026 16:15:19 +0100
Subject: [PATCH 4/5] upated_current-issue.md
---
context/current-issues.md | 3 ---
1 file changed, 3 deletions(-)
diff --git a/context/current-issues.md b/context/current-issues.md
index f6ee687..e69de29 100644
--- a/context/current-issues.md
+++ b/context/current-issues.md
@@ -1,3 +0,0 @@
-After I sign-in to the app, when I click the Manage account button, a whitish/blurish foreground color appears on the editor behing the Manage account window. I've uploaded the picture in the chat so that you can see even clearly what I'm talking about. Fix that. I want the editors background color to be maintained no matter the feature or window I open.
-
-When I try signing-out, the Nextjs compiler at the buttom left corner of the page gets stuck on saying Redering..., until I manually refresh it the page myself before it completely gets me signed out. Fix that too
\ No newline at end of file
From 8d5c9013900fb71bc9a6182bd71cd388f468e064 Mon Sep 17 00:00:00 2001
From: daikictrl
Date: Sun, 3 May 2026 16:21:12 +0100
Subject: [PATCH 5/5] upated_03-auth.md
---
context/feature-spec/03-auth.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/context/feature-spec/03-auth.md b/context/feature-spec/03-auth.md
index 0ad74d1..a94fb7a 100644
--- a/context/feature-spec/03-auth.md
+++ b/context/feature-spec/03-auth.md
@@ -8,7 +8,7 @@ Override Clerk appearance variables using the app's existing CSS variables. Don'
### Sign-in and sign-up pages:
-- Large screens: Simple two panel layout
+- Large screens: Simple "two" "panel" layout
- left: compact logo, tagline, short text-only feature list
- right: centered Clerk form
- small screens: form only