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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions plugins/emulate/.agents/skills/github/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,32 @@ const github = await createEmulator({ service: 'github', port: 4001 })
// github.url === 'http://localhost:4001'
```

For a programmatic GitHub App, omit `private_key` and read the generated RSA key from the instance:

```typescript
const github = await createEmulator({
service: 'github',
port: 4001,
seed: {
github: {
users: [{ login: 'octocat' }],
apps: [{
app_id: 12345,
slug: 'my-github-app',
name: 'My GitHub App',
installations: [{ installation_id: 100, account: 'octocat' }],
}],
},
},
})

const privateKey = github.generatedSecrets.find(
secret => secret.kind === 'github.app_private_key' && secret.id === '12345',
)?.value
```

The key remains stable across `github.reset()`. Explicit keys are not included in `generatedSecrets`. CLI seed files still require `private_key`.

## Auth

Pass tokens as `Authorization: Bearer <token>` or `Authorization: token <token>`.
Expand Down Expand Up @@ -210,6 +236,9 @@ curl http://localhost:4001/user/emails -H "Authorization: Bearer $TOKEN"
# Get repo
curl http://localhost:4001/repos/octocat/hello-world

# Get repo by numeric ID
curl http://localhost:4001/repositories/1

# Create user repo
curl -X POST http://localhost:4001/user/repos \
-H "Authorization: Bearer $TOKEN" \
Expand All @@ -235,6 +264,27 @@ curl -X DELETE http://localhost:4001/repos/octocat/hello-world \
# Topics, languages, contributors, forks, collaborators, tags, transfer
```

### Contents & Commit History

```bash
# Read a file or list a directory at a branch, tag, or commit
curl "http://localhost:4001/repos/octocat/hello-world/contents/README.md?ref=main"

# Download raw file content from the URL advertised by contents and commit responses
curl http://localhost:4001/octocat/hello-world/raw/main/README.md

# Create or update a file and commit the change
curl -X PUT http://localhost:4001/repos/octocat/hello-world/contents/notes.txt \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"message": "Update notes", "content": "aGVsbG8K"}'

# List commits, get a commit with file stats, or compare refs
curl http://localhost:4001/repos/octocat/hello-world/commits
curl http://localhost:4001/repos/octocat/hello-world/commits/main
curl http://localhost:4001/repos/octocat/hello-world/compare/v1.0.0...main
```

### Issues

```bash
Expand Down
1 change: 1 addition & 0 deletions plugins/emulate/.agents/skills/stripe/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ curl http://localhost:4000/v1/payment_methods
## Webhooks

The emulator dispatches webhook events when state changes. Register webhooks via seed config or programmatically.
Webhooks configured with a `secret` include `Stripe-Signature: t=<timestamp>,v1=<signature>`. The signature is an HMAC SHA-256 over `<timestamp>.<raw body>`.

### Events dispatched

Expand Down
50 changes: 50 additions & 0 deletions plugins/emulate/agent/skills/github/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,32 @@ const github = await createEmulator({ service: 'github', port: 4001 })
// github.url === 'http://localhost:4001'
```

For a programmatic GitHub App, omit `private_key` and read the generated RSA key from the instance:

```typescript
const github = await createEmulator({
service: 'github',
port: 4001,
seed: {
github: {
users: [{ login: 'octocat' }],
apps: [{
app_id: 12345,
slug: 'my-github-app',
name: 'My GitHub App',
installations: [{ installation_id: 100, account: 'octocat' }],
}],
},
},
})

const privateKey = github.generatedSecrets.find(
secret => secret.kind === 'github.app_private_key' && secret.id === '12345',
)?.value
```

The key remains stable across `github.reset()`. Explicit keys are not included in `generatedSecrets`. CLI seed files still require `private_key`.

## Auth

Pass tokens as `Authorization: Bearer <token>` or `Authorization: token <token>`.
Expand Down Expand Up @@ -207,6 +233,9 @@ curl http://localhost:4001/user/emails -H "Authorization: Bearer $TOKEN"
# Get repo
curl http://localhost:4001/repos/octocat/hello-world

# Get repo by numeric ID
curl http://localhost:4001/repositories/1

# Create user repo
curl -X POST http://localhost:4001/user/repos \
-H "Authorization: Bearer $TOKEN" \
Expand All @@ -232,6 +261,27 @@ curl -X DELETE http://localhost:4001/repos/octocat/hello-world \
# Topics, languages, contributors, forks, collaborators, tags, transfer
```

### Contents & Commit History

```bash
# Read a file or list a directory at a branch, tag, or commit
curl "http://localhost:4001/repos/octocat/hello-world/contents/README.md?ref=main"

# Download raw file content from the URL advertised by contents and commit responses
curl http://localhost:4001/octocat/hello-world/raw/main/README.md

# Create or update a file and commit the change
curl -X PUT http://localhost:4001/repos/octocat/hello-world/contents/notes.txt \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"message": "Update notes", "content": "aGVsbG8K"}'

# List commits, get a commit with file stats, or compare refs
curl http://localhost:4001/repos/octocat/hello-world/commits
curl http://localhost:4001/repos/octocat/hello-world/commits/main
curl http://localhost:4001/repos/octocat/hello-world/compare/v1.0.0...main
```

### Issues

```bash
Expand Down
1 change: 1 addition & 0 deletions plugins/emulate/agent/skills/stripe/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ curl http://localhost:4000/v1/payment_methods
## Webhooks

The emulator dispatches webhook events when state changes. Register webhooks via seed config or programmatically.
Webhooks configured with a `secret` include `Stripe-Signature: t=<timestamp>,v1=<signature>`. The signature is an HMAC SHA-256 over `<timestamp>.<raw body>`.

### Events dispatched

Expand Down
4 changes: 2 additions & 2 deletions plugins/emulate/skills-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"source": "vercel-labs/emulate",
"sourceType": "github",
"skillPath": "skills/github/SKILL.md",
"computedHash": "9f35addc8b40f7e75804f07ec140044ab32cf00f9b4ef536d2d9c2e1a5b24a3c"
"computedHash": "cde1f1eb6bc92ccf36b9c1fe18039b3cb8f1a5008f5b3bce95052c31bb574063"
},
"google": {
"source": "vercel-labs/emulate",
Expand Down Expand Up @@ -65,7 +65,7 @@
"source": "vercel-labs/emulate",
"sourceType": "github",
"skillPath": "skills/stripe/SKILL.md",
"computedHash": "406885aaa09f57d0a326d6af005e8cd432ea69d9fbbf07de5bda251cb92d8cd1"
"computedHash": "d2e822c16e3e7698b719e9dd06e21ed1019cc37a62e29c1b51718da838ee106d"
},
"vercel": {
"source": "vercel-labs/emulate",
Expand Down
14 changes: 7 additions & 7 deletions plugins/nuxt-ui/.agents/skills/nuxt-ui/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ claude mcp add --transport http nuxt-ui https://ui.nuxt.com/mcp
```

Key MCP tools:
- `search_components` — find components by name, description, or category (no params = list all)
- `search_composables` — find composables by name or description (no params = list all)
- `search_icons` — search Iconify icons (defaults to `lucide`), returns `i-{prefix}-{name}` names
- `get_component` — full component documentation with usage examples
- `get_component_metadata` — props, slots, events (lightweight, no docs content)
- `get_example` — real-world code examples
- `search-components` — find components by name, category, or intent (no params = list all)
- `search-composables` — find composables by name or description (no params = list all)
- `search-icons` — search Iconify icons (defaults to `lucide`), returns `i-{prefix}-{name}` names
- `get-component` — full component documentation with usage examples
- `get-component-metadata` — props, slots, events (lightweight, no docs content)
- `get-example` — real-world code examples

When you need to know **what a component accepts** or **how its API works**, use the MCP. This skill teaches you **when to use which component** and **how to build well**.

Expand All @@ -39,7 +39,7 @@ When you need to know **what a component accepts** or **how its API works**, use
2. **Always use semantic colors** — `text-default`, `bg-elevated`, `border-muted`, etc. Never use raw Tailwind palette colors like `text-gray-500`.
3. **Read generated theme files for slot names** — Nuxt: `.nuxt/ui/<component>.ts`, Vue: `node_modules/.nuxt-ui/ui/<component>.ts`. These show every slot, variant, and default class for any component.
4. **Override priority** (highest wins): `ui` prop / `class` prop → global config → theme defaults.
5. **Icons use `i-{collection}-{name}` format** — `lucide` is the default collection. Use the MCP `search_icons` tool to find icons, or browse at [icones.js.org](https://icones.js.org).
5. **Icons use `i-{collection}-{name}` format** — `lucide` is the default collection. Use the MCP `search-icons` tool to find icons, or browse at [icones.js.org](https://icones.js.org).

## How to use this skill

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Components

Quick-reference index of all 125+ components. For full API docs (props, slots, events, examples), use the MCP `get_component` or `get_component_metadata` tools.
Quick-reference index of all 125+ components. For full API docs (props, slots, events, examples), use the MCP `get-component` or `get-component-metadata` tools.

## Layout

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Component Selection

Decision matrices for choosing the right component. When in doubt, use the MCP `search_components` tool.
Decision matrices for choosing the right component. When in doubt, use the MCP `search-components` tool.

## Overlays

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ npx nuxi@latest init -t ui/chat # AI chat (Vercel AI SDK)
npx nuxi@latest init -t ui/editor # Rich text editor
npx nuxi@latest init -t ui/portfolio # Portfolio
npx nuxi@latest init -t ui/changelog # Changelog
npx nuxi@latest init -t ui/calendar # Calendar
```

## Responsive patterns
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,9 @@ Tailwind Variants uses `tailwind-merge` under the hood — conflicting classes a

### Replace instead of merge

Classes from the `ui` prop, the `class` prop, and global config are merged onto the component defaults. To replace a slot's defaults entirely instead, set it to a function in the `ui` prop or global config. It receives the resolved default classes as its argument, so you can reuse part of them.
Classes from the `ui` prop, the `class` prop, and global config are merged onto the component defaults. To replace them instead, set the slot to a function, which receives the default classes as its argument so you can reuse part of them.

In global config it replaces the slot's own classes, so `variants` and `compoundVariants` still apply on top. In the `ui` and `class` props it runs after the variants, so it replaces the resolved classes, variants included.

```vue
<UButton :ui="{ label: () => 'text-base font-bold' }" />
Expand Down
14 changes: 7 additions & 7 deletions plugins/nuxt-ui/agent/skills/nuxt-ui/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ claude mcp add --transport http nuxt-ui https://ui.nuxt.com/mcp
```

Key MCP tools:
- `search_components` — find components by name, description, or category (no params = list all)
- `search_composables` — find composables by name or description (no params = list all)
- `search_icons` — search Iconify icons (defaults to `lucide`), returns `i-{prefix}-{name}` names
- `get_component` — full component documentation with usage examples
- `get_component_metadata` — props, slots, events (lightweight, no docs content)
- `get_example` — real-world code examples
- `search-components` — find components by name, category, or intent (no params = list all)
- `search-composables` — find composables by name or description (no params = list all)
- `search-icons` — search Iconify icons (defaults to `lucide`), returns `i-{prefix}-{name}` names
- `get-component` — full component documentation with usage examples
- `get-component-metadata` — props, slots, events (lightweight, no docs content)
- `get-example` — real-world code examples

When you need to know **what a component accepts** or **how its API works**, use the MCP. This skill teaches you **when to use which component** and **how to build well**.

Expand All @@ -37,7 +37,7 @@ When you need to know **what a component accepts** or **how its API works**, use
2. **Always use semantic colors** — `text-default`, `bg-elevated`, `border-muted`, etc. Never use raw Tailwind palette colors like `text-gray-500`.
3. **Read generated theme files for slot names** — Nuxt: `.nuxt/ui/<component>.ts`, Vue: `node_modules/.nuxt-ui/ui/<component>.ts`. These show every slot, variant, and default class for any component.
4. **Override priority** (highest wins): `ui` prop / `class` prop → global config → theme defaults.
5. **Icons use `i-{collection}-{name}` format** — `lucide` is the default collection. Use the MCP `search_icons` tool to find icons, or browse at [icones.js.org](https://icones.js.org).
5. **Icons use `i-{collection}-{name}` format** — `lucide` is the default collection. Use the MCP `search-icons` tool to find icons, or browse at [icones.js.org](https://icones.js.org).

## How to use this skill

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Components

Quick-reference index of all 125+ components. For full API docs (props, slots, events, examples), use the MCP `get_component` or `get_component_metadata` tools.
Quick-reference index of all 125+ components. For full API docs (props, slots, events, examples), use the MCP `get-component` or `get-component-metadata` tools.

## Layout

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Component Selection

Decision matrices for choosing the right component. When in doubt, use the MCP `search_components` tool.
Decision matrices for choosing the right component. When in doubt, use the MCP `search-components` tool.

## Overlays

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ npx nuxi@latest init -t ui/chat # AI chat (Vercel AI SDK)
npx nuxi@latest init -t ui/editor # Rich text editor
npx nuxi@latest init -t ui/portfolio # Portfolio
npx nuxi@latest init -t ui/changelog # Changelog
npx nuxi@latest init -t ui/calendar # Calendar
```

## Responsive patterns
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,9 @@ Tailwind Variants uses `tailwind-merge` under the hood — conflicting classes a

### Replace instead of merge

Classes from the `ui` prop, the `class` prop, and global config are merged onto the component defaults. To replace a slot's defaults entirely instead, set it to a function in the `ui` prop or global config. It receives the resolved default classes as its argument, so you can reuse part of them.
Classes from the `ui` prop, the `class` prop, and global config are merged onto the component defaults. To replace them instead, set the slot to a function, which receives the default classes as its argument so you can reuse part of them.

In global config it replaces the slot's own classes, so `variants` and `compoundVariants` still apply on top. In the `ui` and `class` props it runs after the variants, so it replaces the resolved classes, variants included.

```vue
<UButton :ui="{ label: () => 'text-base font-bold' }" />
Expand Down
2 changes: 1 addition & 1 deletion plugins/nuxt-ui/skills-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"source": "nuxt/ui",
"sourceType": "github",
"skillPath": "skills/nuxt-ui/SKILL.md",
"computedHash": "ef3a731fdfa8439d3c7f0c6d497a67073216b8cb7d7fa6a3c605a6fda4ede19a"
"computedHash": "e4701edeb717288700e311e74511a96d4a8a7e1c74fa0c1624b01379d91459f3"
}
}
}
4 changes: 2 additions & 2 deletions plugins/portless/.agents/skills/portless/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ Use `portless proxy start --tld localhost --tld test` to serve the same app name

TLDs can be multi-segment DNS names such as `dev.example.com`, so local URLs can mirror production structure (`myapp.dev.example.com`). Each label follows DNS rules: lowercase letters, digits, interior hyphens, 63 characters per label, 253 total. Strict OAuth providers that reject `.localhost` redirect URIs accept a real domain like `https://myapp.dev.example.com/api/auth/callback/google`.

Most frameworks (Next.js, Express, Nuxt, etc.) respect the `PORT` env var automatically. For frameworks that ignore `PORT` (Vite, VitePlus, Astro, React Router, Angular, Expo, React Native), portless auto-injects the correct `--port` flag and, when needed, a matching `--host` CLI flag.
Most frameworks (Next.js, Express, Nuxt, etc.) respect the `PORT` env var automatically. For frameworks that ignore `PORT` (Vite, VitePlus, Astro, React Router, Angular, Expo, React Native), portless auto-injects the correct `--port` flag and, when needed, a matching `--host` CLI flag. Injection reaches through a package script whose command starts with the framework or a known runner (`"dev": "vite"`, `"dev": "bunx vite"`). Only the framework's server commands get the flags (`dev`, `serve`, `preview`, `start`, a bare `vite`, or `vite [root]`); a command that does not serve, such as `vite build`, `vite optimize`, `vp test` or `astro check`, rejects them and is left alone. Expo connection modes (`--localhost`, `--lan`, `--tunnel`) are preserved while the assigned port is still injected. A script portless cannot classify is left alone too: a flag before the subcommand on a CLI whose flag grammar it does not track (`vp --mode dev build`). Portless also leaves a script alone when appending flags to it would not work: a compound command (`&&`, `|`, `;`), a trailing `#` comment, its own `--` option terminator, an env prefix (`NODE_ENV=production vite`), delegation to another script (`"dev": "npm run dev:vite"`), or runner flags before the script name (`bun run --bun dev`). Those keep their own port, so set it in the script yourself.

### State directory

Expand Down Expand Up @@ -383,7 +383,7 @@ portless proxy start -p 8080

### Framework not respecting PORT

Portless auto-injects the right `--port` flag and, when needed, a matching `--host` flag for frameworks that ignore the `PORT` env var: **Vite**, **VitePlus** (`vp`), **Astro**, **React Router**, **Angular**, **Expo**, and **React Native**. SvelteKit uses Vite internally and is handled automatically.
Portless auto-injects the right `--port` flag and, when needed, a matching `--host` flag for frameworks that ignore the `PORT` env var: **Vite**, **VitePlus** (`vp`), **Astro**, **React Router**, **Angular**, **Expo**, and **React Native**. SvelteKit uses Vite internally and is handled automatically. Injection reaches through a package script whose command starts with the framework or a known runner, and only for the framework's server commands (`dev`, `serve`, `preview`, `start`, or a bare `vite`) — `vite build`, `vite optimize`, `vp test` and other non-serving commands reject the flags, so they are left untouched, as is any invocation portless cannot classify (`vp --mode dev build`). It is also skipped for a compound command (`&&`, `|`, `;`), a trailing `#` comment, its own `--` option terminator, an env prefix (`NODE_ENV=production vite`), delegation to another script, and runner flags before the script name (`bun run --bun dev`) — each of those keeps its own port and the app returns 502, so set the port in the script yourself.

For other frameworks that don't read `PORT`, pass the port manually:

Expand Down
Loading
Loading