From 7f8cb9f963e7af459a7fd36619820f689f274d80 Mon Sep 17 00:00:00 2001 From: amondnet <1964421+amondnet@users.noreply.github.com> Date: Mon, 24 Aug 2026 06:21:30 +0000 Subject: [PATCH] fix: update vendored skills to latest versions --- plugins/axi/.agents/skills/axi/SKILL.md | 2 +- plugins/axi/agent/skills/axi/SKILL.md | 2 +- plugins/axi/skills-lock.json | 2 +- .../emulate/.agents/skills/emulate/SKILL.md | 6 + .../emulate/.agents/skills/github/SKILL.md | 59 ++ .../emulate/.agents/skills/stripe/SKILL.md | 1 + plugins/emulate/agent/skills/emulate/SKILL.md | 6 + plugins/emulate/agent/skills/github/SKILL.md | 59 ++ plugins/emulate/agent/skills/stripe/SKILL.md | 1 + plugins/emulate/skills-lock.json | 6 +- plugins/lavish/.agents/skills/lavish/SKILL.md | 76 +-- plugins/lavish/agent/skills/lavish/SKILL.md | 76 +-- plugins/lavish/skills-lock.json | 2 +- plugins/nostics/skills-lock.json | 4 +- .../nuxt-ui/.agents/skills/nuxt-ui/SKILL.md | 14 +- .../skills/nuxt-ui/references/components.md | 4 +- .../guidelines/component-selection.md | 4 +- .../references/guidelines/conventions.md | 1 + .../references/guidelines/design-system.md | 4 +- .../nuxt-ui/references/recipes/data-tables.md | 2 +- plugins/nuxt-ui/agent/skills/nuxt-ui/SKILL.md | 14 +- .../skills/nuxt-ui/references/components.md | 4 +- .../guidelines/component-selection.md | 4 +- .../references/guidelines/conventions.md | 1 + .../references/guidelines/design-system.md | 4 +- .../nuxt-ui/references/recipes/data-tables.md | 2 +- plugins/nuxt-ui/skills-lock.json | 2 +- .../portless/.agents/skills/portless/SKILL.md | 4 +- .../portless/agent/skills/portless/SKILL.md | 4 +- plugins/portless/skills-lock.json | 2 +- .../vercel-react-view-transitions/README.md | 5 +- .../vercel-react-view-transitions/SKILL.md | 43 +- .../references/css-recipes.md | 66 +++ .../references/implementation.md | 18 +- .../references/nextjs.md | 106 +++- .../references/patterns.md | 92 ++- .../vercel-react-view-transitions/README.md | 5 +- .../vercel-react-view-transitions/SKILL.md | 43 +- .../references/css-recipes.md | 66 +++ .../references/implementation.md | 18 +- .../references/nextjs.md | 106 +++- .../references/patterns.md | 92 ++- plugins/react/skills-lock.json | 2 +- .../.agents/skills/slack-agent/.gitignore | 21 + .../.agents/skills/slack-agent/LICENSE | 201 +++++++ .../.agents/skills/slack-agent/README.md | 108 ++++ .../slack-agent/patterns/slack-patterns.md | 355 ++++++++++++ .../slack-agent/patterns/testing-patterns.md | 423 ++++++++++++++ .../slack-agent/reference/agent-archetypes.md | 546 ++++++++++++++++++ .../skills/slack-agent/reference/env-vars.md | 348 +++++++++++ .../slack-agent/reference/slack-setup.md | 213 +++++++ .../slack-agent/reference/vercel-setup.md | 207 +++++++ .../templates/eve/sample-tests/agent.test.ts | 115 ++++ .../templates/eve/sample-tests/tools.test.ts | 316 ++++++++++ .../slack-agent/templates/eve/test-setup.ts | 139 +++++ .../templates/eve/vitest.config.ts | 55 ++ .../slack-agent/wizard/1-project-setup.md | 225 ++++++++ .../slack-agent/wizard/1b-approve-plan.md | 148 +++++ .../slack-agent/wizard/2-create-slack-app.md | 90 +++ .../wizard/3-configure-environment.md | 66 +++ .../slack-agent/wizard/4-test-locally.md | 116 ++++ .../slack-agent/wizard/5-deploy-production.md | 144 +++++ .../slack-agent/wizard/6-setup-testing.md | 154 +++++ .../skills/slack-agent/wizard/README.md | 84 +++ .../agent/skills/slack-agent/.gitignore | 21 + .../agent/skills/slack-agent/LICENSE | 201 +++++++ .../agent/skills/slack-agent/README.md | 108 ++++ .../slack-agent/patterns/slack-patterns.md | 355 ++++++++++++ .../slack-agent/patterns/testing-patterns.md | 423 ++++++++++++++ .../slack-agent/reference/agent-archetypes.md | 546 ++++++++++++++++++ .../skills/slack-agent/reference/env-vars.md | 348 +++++++++++ .../slack-agent/reference/slack-setup.md | 213 +++++++ .../slack-agent/reference/vercel-setup.md | 207 +++++++ .../templates/eve/sample-tests/agent.test.ts | 115 ++++ .../templates/eve/sample-tests/tools.test.ts | 316 ++++++++++ .../slack-agent/templates/eve/test-setup.ts | 139 +++++ .../templates/eve/vitest.config.ts | 55 ++ .../slack-agent/wizard/1-project-setup.md | 225 ++++++++ .../slack-agent/wizard/1b-approve-plan.md | 148 +++++ .../slack-agent/wizard/2-create-slack-app.md | 90 +++ .../wizard/3-configure-environment.md | 66 +++ .../slack-agent/wizard/4-test-locally.md | 116 ++++ .../slack-agent/wizard/5-deploy-production.md | 144 +++++ .../slack-agent/wizard/6-setup-testing.md | 154 +++++ .../agent/skills/slack-agent/wizard/README.md | 84 +++ plugins/slack-agent/skills-lock.json | 2 +- .../slidev/references/core-components.md | 5 +- .../slidev/references/core-components.md | 5 +- plugins/slidev/skills-lock.json | 2 +- plugins/tiptap/.agents/skills/tiptap/SKILL.md | 42 +- plugins/tiptap/agent/skills/tiptap/SKILL.md | 42 +- plugins/tiptap/skills-lock.json | 2 +- .../references/guide-migrate-from-tsup.md | 13 + .../tsdown/references/option-dependencies.md | 2 +- .../references/guide-migrate-from-tsup.md | 13 + .../tsdown/references/option-dependencies.md | 2 +- plugins/tsdown/skills-lock.json | 2 +- .../.agents/skills/turborepo/SKILL.md | 4 +- .../references/best-practices/structure.md | 4 +- .../turborepo/references/ci/github-actions.md | 4 +- .../references/configuration/RULE.md | 4 +- .../turborepo/references/environment/RULE.md | 2 +- .../references/environment/gotchas.md | 4 +- .../turborepo/agent/skills/turborepo/SKILL.md | 4 +- .../references/best-practices/structure.md | 4 +- .../turborepo/references/ci/github-actions.md | 4 +- .../references/configuration/RULE.md | 4 +- .../turborepo/references/environment/RULE.md | 2 +- .../references/environment/gotchas.md | 4 +- plugins/turborepo/skills-lock.json | 2 +- .../.agents/skills/sandbox/SKILL.md | 22 +- .../agent/skills/sandbox/SKILL.md | 22 +- plugins/vercel-sandbox/skills-lock.json | 2 +- plugins/web-design/skills-lock.json | 2 +- .../wp-block-themes/references/theme-json.md | 4 +- .../wp-block-themes/references/theme-json.md | 4 +- plugins/wordpress/skills-lock.json | 2 +- .../skills/migrating-to-workflow-sdk/SKILL.md | 12 +- .../references/aws-step-functions.md | 2 +- .../references/inngest.md | 2 +- .../references/resume-routing.md | 2 + .../references/retries.md | 14 +- .../references/temporal.md | 4 +- .../references/trigger-dev.md | 4 +- .../.agents/skills/workflow-init/SKILL.md | 4 +- .../.agents/skills/workflow/SKILL.md | 116 ++-- .../skills/migrating-to-workflow-sdk/SKILL.md | 12 +- .../references/aws-step-functions.md | 2 +- .../references/inngest.md | 2 +- .../references/resume-routing.md | 2 + .../references/retries.md | 14 +- .../references/temporal.md | 4 +- .../references/trigger-dev.md | 4 +- .../agent/skills/workflow-init/SKILL.md | 4 +- .../agent/skills/workflow/SKILL.md | 116 ++-- plugins/workflow-sdk/skills-lock.json | 6 +- 136 files changed, 9215 insertions(+), 529 deletions(-) create mode 100644 plugins/slack-agent/.agents/skills/slack-agent/.gitignore create mode 100644 plugins/slack-agent/.agents/skills/slack-agent/LICENSE create mode 100644 plugins/slack-agent/.agents/skills/slack-agent/README.md create mode 100644 plugins/slack-agent/.agents/skills/slack-agent/patterns/slack-patterns.md create mode 100644 plugins/slack-agent/.agents/skills/slack-agent/patterns/testing-patterns.md create mode 100644 plugins/slack-agent/.agents/skills/slack-agent/reference/agent-archetypes.md create mode 100644 plugins/slack-agent/.agents/skills/slack-agent/reference/env-vars.md create mode 100644 plugins/slack-agent/.agents/skills/slack-agent/reference/slack-setup.md create mode 100644 plugins/slack-agent/.agents/skills/slack-agent/reference/vercel-setup.md create mode 100644 plugins/slack-agent/.agents/skills/slack-agent/templates/eve/sample-tests/agent.test.ts create mode 100644 plugins/slack-agent/.agents/skills/slack-agent/templates/eve/sample-tests/tools.test.ts create mode 100644 plugins/slack-agent/.agents/skills/slack-agent/templates/eve/test-setup.ts create mode 100644 plugins/slack-agent/.agents/skills/slack-agent/templates/eve/vitest.config.ts create mode 100644 plugins/slack-agent/.agents/skills/slack-agent/wizard/1-project-setup.md create mode 100644 plugins/slack-agent/.agents/skills/slack-agent/wizard/1b-approve-plan.md create mode 100644 plugins/slack-agent/.agents/skills/slack-agent/wizard/2-create-slack-app.md create mode 100644 plugins/slack-agent/.agents/skills/slack-agent/wizard/3-configure-environment.md create mode 100644 plugins/slack-agent/.agents/skills/slack-agent/wizard/4-test-locally.md create mode 100644 plugins/slack-agent/.agents/skills/slack-agent/wizard/5-deploy-production.md create mode 100644 plugins/slack-agent/.agents/skills/slack-agent/wizard/6-setup-testing.md create mode 100644 plugins/slack-agent/.agents/skills/slack-agent/wizard/README.md create mode 100644 plugins/slack-agent/agent/skills/slack-agent/.gitignore create mode 100644 plugins/slack-agent/agent/skills/slack-agent/LICENSE create mode 100644 plugins/slack-agent/agent/skills/slack-agent/README.md create mode 100644 plugins/slack-agent/agent/skills/slack-agent/patterns/slack-patterns.md create mode 100644 plugins/slack-agent/agent/skills/slack-agent/patterns/testing-patterns.md create mode 100644 plugins/slack-agent/agent/skills/slack-agent/reference/agent-archetypes.md create mode 100644 plugins/slack-agent/agent/skills/slack-agent/reference/env-vars.md create mode 100644 plugins/slack-agent/agent/skills/slack-agent/reference/slack-setup.md create mode 100644 plugins/slack-agent/agent/skills/slack-agent/reference/vercel-setup.md create mode 100644 plugins/slack-agent/agent/skills/slack-agent/templates/eve/sample-tests/agent.test.ts create mode 100644 plugins/slack-agent/agent/skills/slack-agent/templates/eve/sample-tests/tools.test.ts create mode 100644 plugins/slack-agent/agent/skills/slack-agent/templates/eve/test-setup.ts create mode 100644 plugins/slack-agent/agent/skills/slack-agent/templates/eve/vitest.config.ts create mode 100644 plugins/slack-agent/agent/skills/slack-agent/wizard/1-project-setup.md create mode 100644 plugins/slack-agent/agent/skills/slack-agent/wizard/1b-approve-plan.md create mode 100644 plugins/slack-agent/agent/skills/slack-agent/wizard/2-create-slack-app.md create mode 100644 plugins/slack-agent/agent/skills/slack-agent/wizard/3-configure-environment.md create mode 100644 plugins/slack-agent/agent/skills/slack-agent/wizard/4-test-locally.md create mode 100644 plugins/slack-agent/agent/skills/slack-agent/wizard/5-deploy-production.md create mode 100644 plugins/slack-agent/agent/skills/slack-agent/wizard/6-setup-testing.md create mode 100644 plugins/slack-agent/agent/skills/slack-agent/wizard/README.md diff --git a/plugins/axi/.agents/skills/axi/SKILL.md b/plugins/axi/.agents/skills/axi/SKILL.md index b6e0819a..eb149213 100644 --- a/plugins/axi/.agents/skills/axi/SKILL.md +++ b/plugins/axi/.agents/skills/axi/SKILL.md @@ -180,7 +180,7 @@ help[2]: - **Claude Code**: use native hooks in `~/.claude/settings.json` or project `.claude/settings.json`. Prefer `SessionStart` to inject compact context via stdout - **Codex**: use native hooks in `~/.codex/hooks.json` or `/.codex/hooks.json`, and ensure `[features].hooks = true` in `config.toml`. Prefer `SessionStart` for ambient context via stdout -- **OpenCode**: use a managed plugin in `~/.config/opencode/plugins/`. Prefer ambient system-context injection for the home view rather than adding a custom tool +- **OpenCode**: use a managed plugin in `~/.config/opencode/plugins/` or `/.opencode/plugins/`. Prefer ambient system-context injection for the home view rather than adding a custom tool **Also ship an installable skill (secondary recommendation):** diff --git a/plugins/axi/agent/skills/axi/SKILL.md b/plugins/axi/agent/skills/axi/SKILL.md index adbb4949..79818524 100644 --- a/plugins/axi/agent/skills/axi/SKILL.md +++ b/plugins/axi/agent/skills/axi/SKILL.md @@ -176,7 +176,7 @@ help[2]: - **Claude Code**: use native hooks in `~/.claude/settings.json` or project `.claude/settings.json`. Prefer `SessionStart` to inject compact context via stdout - **Codex**: use native hooks in `~/.codex/hooks.json` or `/.codex/hooks.json`, and ensure `[features].hooks = true` in `config.toml`. Prefer `SessionStart` for ambient context via stdout -- **OpenCode**: use a managed plugin in `~/.config/opencode/plugins/`. Prefer ambient system-context injection for the home view rather than adding a custom tool +- **OpenCode**: use a managed plugin in `~/.config/opencode/plugins/` or `/.opencode/plugins/`. Prefer ambient system-context injection for the home view rather than adding a custom tool **Also ship an installable skill (secondary recommendation):** diff --git a/plugins/axi/skills-lock.json b/plugins/axi/skills-lock.json index 2f235a5d..74e374c5 100644 --- a/plugins/axi/skills-lock.json +++ b/plugins/axi/skills-lock.json @@ -5,7 +5,7 @@ "source": "kunchenguid/axi", "sourceType": "github", "skillPath": ".agents/skills/axi/SKILL.md", - "computedHash": "7de23a6b8171a06b7885712f3dd971e64d9301543d1b8c46f21660494303df95" + "computedHash": "b4294fa06402d65a8fce0528bd4bca9286d19fbcd9882717d0ebe8821c24a563" } } } diff --git a/plugins/emulate/.agents/skills/emulate/SKILL.md b/plugins/emulate/.agents/skills/emulate/SKILL.md index 1a7223a7..81a5e999 100644 --- a/plugins/emulate/.agents/skills/emulate/SKILL.md +++ b/plugins/emulate/.agents/skills/emulate/SKILL.md @@ -48,6 +48,9 @@ npx emulate --port 3000 # Use a seed config file npx emulate --seed config.yaml +# Generate omitted service secrets into a private file +npx emulate start --seed config.yaml --generated-secrets-file .emulate-secrets.json + # Generate a starter config npx emulate init @@ -67,9 +70,12 @@ npx emulate list | `--seed` | auto-detect | Path to seed config (YAML or JSON) | | `--base-url` | none | Override advertised base URL (supports `{service}` template) | | `--portless` | off | Serve over HTTPS via portless (auto-registers aliases) | +| `--generated-secrets-file` | none | Generate omitted service secrets and write them to a new owner-only JSON file | The port can also be set via `EMULATE_PORT` or `PORT` environment variables. +The generated-secrets destination must not exist. emulate removes inherited ACLs, verifies effective owner-only access, and publishes complete JSON before opening listeners or configuring portless. Handled startup failures remove the invocation-owned artifact. A hard termination can leave a complete artifact that must be removed manually after confirming no invocation is using it. Only service-generated values appear in the artifact. Linux requires `setfacl` and `getfacl` from the `acl` package. The flag fails closed when access controls cannot be verified and is not supported on Windows. + The advertised base URL (used in OAuth redirects, webhook URLs, etc.) can be overridden via `--base-url`, the `EMULATE_BASE_URL` env var (supports `{service}` template), or per-service `baseUrl` in the seed config. When running under portless, the `PORTLESS_URL` env var is also detected automatically. ## Programmatic API diff --git a/plugins/emulate/.agents/skills/github/SKILL.md b/plugins/emulate/.agents/skills/github/SKILL.md index da6f707e..6a9322a6 100644 --- a/plugins/emulate/.agents/skills/github/SKILL.md +++ b/plugins/emulate/.agents/skills/github/SKILL.md @@ -27,6 +27,41 @@ 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`. + +For the CLI, omit `private_key` only when requesting a private delivery file: + +```bash +npx emulate start --service github --seed emulate.config.yaml \ + --generated-secrets-file .emulate-secrets.json +``` + +The destination must not exist. emulate removes inherited ACLs, verifies effective owner-only access, and publishes complete JSON before any listener or portless alias starts. Handled startup failures remove the invocation-owned artifact. A hard termination can leave a complete artifact that must be removed manually after confirming no invocation is using it. Read `generatedSecrets` from the artifact, then keep the file out of source control. Linux requires `setfacl` and `getfacl` from the `acl` package. The flag fails closed when access controls cannot be verified and is not supported on Windows. Without `--generated-secrets-file`, CLI seed files still require `private_key`. + ## Auth Pass tokens as `Authorization: Bearer ` or `Authorization: token `. @@ -210,6 +245,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" \ @@ -235,6 +273,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 diff --git a/plugins/emulate/.agents/skills/stripe/SKILL.md b/plugins/emulate/.agents/skills/stripe/SKILL.md index 671fe535..932341fa 100644 --- a/plugins/emulate/.agents/skills/stripe/SKILL.md +++ b/plugins/emulate/.agents/skills/stripe/SKILL.md @@ -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=,v1=`. The signature is an HMAC SHA-256 over `.`. ### Events dispatched diff --git a/plugins/emulate/agent/skills/emulate/SKILL.md b/plugins/emulate/agent/skills/emulate/SKILL.md index 060f9874..fb5b8ab5 100644 --- a/plugins/emulate/agent/skills/emulate/SKILL.md +++ b/plugins/emulate/agent/skills/emulate/SKILL.md @@ -45,6 +45,9 @@ npx emulate --port 3000 # Use a seed config file npx emulate --seed config.yaml +# Generate omitted service secrets into a private file +npx emulate start --seed config.yaml --generated-secrets-file .emulate-secrets.json + # Generate a starter config npx emulate init @@ -64,9 +67,12 @@ npx emulate list | `--seed` | auto-detect | Path to seed config (YAML or JSON) | | `--base-url` | none | Override advertised base URL (supports `{service}` template) | | `--portless` | off | Serve over HTTPS via portless (auto-registers aliases) | +| `--generated-secrets-file` | none | Generate omitted service secrets and write them to a new owner-only JSON file | The port can also be set via `EMULATE_PORT` or `PORT` environment variables. +The generated-secrets destination must not exist. emulate removes inherited ACLs, verifies effective owner-only access, and publishes complete JSON before opening listeners or configuring portless. Handled startup failures remove the invocation-owned artifact. A hard termination can leave a complete artifact that must be removed manually after confirming no invocation is using it. Only service-generated values appear in the artifact. Linux requires `setfacl` and `getfacl` from the `acl` package. The flag fails closed when access controls cannot be verified and is not supported on Windows. + The advertised base URL (used in OAuth redirects, webhook URLs, etc.) can be overridden via `--base-url`, the `EMULATE_BASE_URL` env var (supports `{service}` template), or per-service `baseUrl` in the seed config. When running under portless, the `PORTLESS_URL` env var is also detected automatically. ## Programmatic API diff --git a/plugins/emulate/agent/skills/github/SKILL.md b/plugins/emulate/agent/skills/github/SKILL.md index 6b37f58b..2f789777 100644 --- a/plugins/emulate/agent/skills/github/SKILL.md +++ b/plugins/emulate/agent/skills/github/SKILL.md @@ -24,6 +24,41 @@ 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`. + +For the CLI, omit `private_key` only when requesting a private delivery file: + +```bash +npx emulate start --service github --seed emulate.config.yaml \ + --generated-secrets-file .emulate-secrets.json +``` + +The destination must not exist. emulate removes inherited ACLs, verifies effective owner-only access, and publishes complete JSON before any listener or portless alias starts. Handled startup failures remove the invocation-owned artifact. A hard termination can leave a complete artifact that must be removed manually after confirming no invocation is using it. Read `generatedSecrets` from the artifact, then keep the file out of source control. Linux requires `setfacl` and `getfacl` from the `acl` package. The flag fails closed when access controls cannot be verified and is not supported on Windows. Without `--generated-secrets-file`, CLI seed files still require `private_key`. + ## Auth Pass tokens as `Authorization: Bearer ` or `Authorization: token `. @@ -207,6 +242,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" \ @@ -232,6 +270,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 diff --git a/plugins/emulate/agent/skills/stripe/SKILL.md b/plugins/emulate/agent/skills/stripe/SKILL.md index 6f3f3e25..6fbcd3db 100644 --- a/plugins/emulate/agent/skills/stripe/SKILL.md +++ b/plugins/emulate/agent/skills/stripe/SKILL.md @@ -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=,v1=`. The signature is an HMAC SHA-256 over `.`. ### Events dispatched diff --git a/plugins/emulate/skills-lock.json b/plugins/emulate/skills-lock.json index 8f11ecad..3fedfa86 100644 --- a/plugins/emulate/skills-lock.json +++ b/plugins/emulate/skills-lock.json @@ -17,13 +17,13 @@ "source": "vercel-labs/emulate", "sourceType": "github", "skillPath": "skills/emulate/SKILL.md", - "computedHash": "a37ed153c79c6fe337535a1055d08644070186160c5f14c4ad990c1a16537512" + "computedHash": "9f490bb96968516335972dc0df78fcd7b75025aab169a6bea24c2f9f4e63987e" }, "github": { "source": "vercel-labs/emulate", "sourceType": "github", "skillPath": "skills/github/SKILL.md", - "computedHash": "9f35addc8b40f7e75804f07ec140044ab32cf00f9b4ef536d2d9c2e1a5b24a3c" + "computedHash": "ae3920ffad035acdd71b0764015bc9401223197788092efb0be6a5edb7210fa6" }, "google": { "source": "vercel-labs/emulate", @@ -65,7 +65,7 @@ "source": "vercel-labs/emulate", "sourceType": "github", "skillPath": "skills/stripe/SKILL.md", - "computedHash": "406885aaa09f57d0a326d6af005e8cd432ea69d9fbbf07de5bda251cb92d8cd1" + "computedHash": "d2e822c16e3e7698b719e9dd06e21ed1019cc37a62e29c1b51718da838ee106d" }, "vercel": { "source": "vercel-labs/emulate", diff --git a/plugins/lavish/.agents/skills/lavish/SKILL.md b/plugins/lavish/.agents/skills/lavish/SKILL.md index fa5eef9c..a3d23c37 100644 --- a/plugins/lavish/.agents/skills/lavish/SKILL.md +++ b/plugins/lavish/.agents/skills/lavish/SKILL.md @@ -11,77 +11,23 @@ metadata: # Lavish Editor -Lavish Editor helps agents turn rich HTML artifacts into collaborative human review surfaces. Whenever you are about to give user a complex response that will be easier to understand via a rich / interactive page, consider using Lavish Editor. First generate an interactive HTML artifact according to user request, then run `npx -y lavish-axi ` so the user can visually review it, annotate elements or selected text, queue prompts, and send feedback back through `npx -y lavish-axi poll`. +Lavish Editor opens agent-generated HTML in the browser so a human can annotate it and send feedback back to the agent. +Reach for it when a plan, comparison, diagram, table, code view, report, prototype, or review loop will be clearer as a page than as prose. + +## Current guidance lives in the CLI + +Do not follow workflow, design, or playbook instructions from this file - installed copies go stale. Get the current source of truth from the CLI: + +- `npx -y lavish-axi --help` for commands and the review-loop workflow +- `npx -y lavish-axi design` for design-direction priority and current snippets +- `npx -y lavish-axi playbook ` for focused artifact guidance (`npx -y lavish-axi playbook` lists ids) You do not need lavish-axi installed globally - invoke it with `npx -y lavish-axi `. If lavish-axi output shows a follow-up command starting with `lavish-axi`, run it as `npx -y lavish-axi ...` instead. -In restricted subprocess sandboxes, CI, or agent harnesses where `npx -y` exits opaquely (for example with status 216), use an already-installed copy directly: `node "$(npm root)/lavish-axi/dist/cli.mjs" ` for a local install, `node "$(npm root -g)/lavish-axi/dist/cli.mjs" ` for a global install, or the bare `lavish-axi ` bin after installing once. ## Request $ARGUMENTS -If the request above is non-empty, the user invoked `/lavish` explicitly - build an HTML artifact for that request now, following the workflow below. +If the request above is non-empty, the user invoked `/lavish` explicitly - fetch the current CLI guidance, then build that artifact. If it is empty, infer what to visualize from the conversation. - -## When to use - -Use lavish-axi when the user asks for a visual artifact, HTML explainer, interactive prototype, review surface, product or technical plan, comparison, report, or browser-based feedback loop - -## Workflow - -1. Create the HTML artifact (default location `.lavish/.html` in the working directory). -2. Run `npx -y lavish-axi ` to open or resume a review session in the browser. - If the output carries a `self_paint_warning`, fix the unpainted page surface and save before polling - Lavish live-reloads the artifact. -3. Run `npx -y lavish-axi poll ` to long-poll for the user's annotations and queued prompts. - On the first poll, prefer `--agent-reply ""` so the conversation panel opens with context. - Browser-detected layout issues are filed passively in the user's Layout issues inbox and arrive as an ordinary `layout-warnings` prompt only when the user selects and queues them. Never edit an issue the user has not queued. The only response that arrives without user action is `artifact_failures`, when the review surface itself is unusable. - The poll stays silent until the user acts or a fatal artifact failure makes the review surface unusable - leave it running, never kill it. - Cosmetic, intentional, transient, tiny, and uncertain observations remain silent. - Keep the poll in the foreground by default and let it return the feedback directly to the agent. - A background poll is allowed only through a harness-native tracked background-job facility whose completion result is guaranteed to resume or notify the same agent. - Never use `nohup`, shell `&`, `disown`, redirected fire-and-forget processes, or a detached terminal without an explicit verified callback merely to keep polling alive. - If the harness has no completion-aware background facility, use the foreground poll or first wire a verified wake callback into the surrounding supervisor. - Do not tell the user the artifact is being monitored until that wake path is live. - If the poll gets killed or times out anyway, just re-run it - queued feedback is never lost. -4. If poll returns feedback, apply the user's prompts. A `layout-warnings` prompt is an explicit repair request; apply every listed fix in one pass before saving, and let Lavish re-check it after a newer artifact load. -5. Apply human feedback, then poll again with `--agent-reply ""` to reply in the browser and keep the loop going under the same foreground-or-verified-wake-path rule. -6. Run `npx -y lavish-axi end ` when the review is finished. -7. `Send & End` ends the session. Its final feedback is still delivered once. After that response, polling stops, and the agent must not reopen the session uninvited. Deliver any remaining updates directly in this conversation. - -## Visual guidance - -- Use visual hierarchy to make the most important decisions, risks, tradeoffs, and next actions obvious at a glance -- Use visual structure such as sections, cards, tables, diagrams, annotated snippets, and side-by-side comparisons instead of long prose -- Choose typography, spacing, color, and layout deliberately so the artifact has a clear point of view -- Prevent horizontal overflow at every nesting level: nested grid/flex children also need minmax(0, 1fr) tracks and min-width: 0, especially when badges, labels, or status text use wide pixel or monospace fonts; wrap, truncate, or contain long unbreakable text deliberately -- When the artifact would describe existing or current UI or state, show it instead: capture screenshots of the real pages (run the app read-only if needed) and embed them, rather than explaining the current look in prose; reserve prose for what cannot be shown such as rationale, trade-offs, and open questions - -## Playbooks - -Run `npx -y lavish-axi playbook ` for focused, detailed guidance on any of these. -One artifact often combines several playbooks (for example a plan that includes a comparison and a diagram), so MUST open each matching playbook before writing HTML. -For flows, architecture, state, or sequence diagrams, do not hand-build boxes-and-arrows from div/flexbox; open the diagram playbook and use the theme-aware Mermaid snippet from `npx -y lavish-axi design` unless SVG is needed for richly annotated nodes. - -- `diagram` - Map relationships, flows, state, and architecture -- `table` - Turn dense records into scan-friendly review surfaces -- `comparison` - Show options, tradeoffs, and current vs target behavior -- `plan` - Explain a product or technical plan before implementation -- `code` - Render source code, code files, patches, PR diffs, and before/after code inside Lavish artifacts -- `input` - Must be used when the agent needs to collect user input on decisions, choices, preferences, triage, scope, or other structured feedback from within the artifact -- `slides` - Create a deliberate presentation when slides are requested - -## Commands & rules - -- Run `npx -y lavish-axi ` to open or resume a Lavish Editor session. If the user explicitly ended the session from the browser, this refuses to reopen it and explains why instead of reopening uninvited - pass `--reopen` only when the user asks for further review or something important needs their visual attention -- Unless the user specifies another location, create HTML artifacts in the current working directory under `.lavish/` -- Lavish serves the html file through a local express.js server. If your html needs to reference other filesystem assets such as images, CSS, fonts, and local scripts, copy them into the same directory as the HTML file, then reference them with relative paths from that directory. Never prepend `/` to those asset paths - root paths won't work -- Run `npx -y lavish-axi poll ` to wait for user feedback. It long-polls and stays silent until the user sends feedback or ends the session, so leave it running - never kill it. Detected layout issues never return this poll: the browser files them in the user's Layout issues inbox in the Lavish top bar, and they arrive as an ordinary tag "layout-warnings" prompt only when the user selects them and queues the fixes. Never edit the artifact to chase a layout issue the user has not queued. The only exception is a fatal artifact_failures response, which means the review surface itself could not be used. Keep the poll in the foreground by default and let it return the feedback directly to the agent. A background poll is allowed only through a harness-native tracked background-job facility whose completion result is guaranteed to resume or notify the same agent. Never use `nohup`, shell `&`, `disown`, redirected fire-and-forget processes, or a detached terminal without an explicit verified callback merely to keep polling alive. If the harness has no completion-aware background facility, use the foreground poll or first wire a verified wake callback into the surrounding supervisor. Do not tell the user the artifact is being monitored until that wake path is live. If the poll gets killed or times out anyway, just re-run it - queued feedback is never lost. `Send & End` ends the session. Its final feedback is still delivered once. After that response, polling stops, and the agent must not reopen the session uninvited. -- Rendered Mermaid diagrams in `.mermaid` containers become embedded, editable Excalidraw whiteboards in the browser (click a diagram to unlock editing; a Fullscreen action opens it over the whole viewport) - flowchart, sequence, class, ER, and state diagrams convert to editable shapes; other types embed as an image to draw on. Scenes autosave locally; when a reload detects a changed Mermaid source, the reviewer explicitly chooses to re-convert and discard saved edits or keep editing the saved scene. Standalone and exported copies still render plain Mermaid. Queue feedback adds a prompt to the Conversation panel; when the user sends it, poll returns a tag "whiteboard" prompt carrying a bounded edit summary plus local scenePath (.excalidraw JSON) and previewPath (PNG) files - read the summary first, open the files only when needed, then apply the edits by updating the Mermaid source in the artifact (never try to write the scene back) -- Run `npx -y lavish-axi end ` to end a session as the agent - ending it this way still allows a plain reopen later. When the user ends it from the browser instead, a later `npx -y lavish-axi ` refuses to reopen it without `--reopen` -- Run `npx -y lavish-axi export [--out ]` to write a portable copy of the artifact - one HTML file with its LOCAL assets inlined - so it opens with no Lavish server and no sibling files. Remote CDN/font references are left as links, so it needs network to render those. Users can also export from the browser chrome's overflow menu -- Run `npx -y lavish-axi share [--password ] [--token ]` to publish the artifact on ht-ml.app (https://ht-ml.app), a third-party hosting service not part of Lavish, and get back a visitable URL. Shares are PUBLIC by default, so anyone with the link can open them. Pass --password to publish a PRIVATE password-protected page; viewers must supply the password to view. Local assets are inlined; remote refs load over the network. It returns the url plus a secret update_key for managing the page later. Use --token or LAVISH_AXI_HTML_APP_TOKEN only when you have an optional bearer token; it is never required. Users can also publish from the browser chrome's overflow menu -- Run `npx -y lavish-axi stop` to shut down the background server (it also self-stops when idle or after the last session ends with nothing connected) -- Run `npx -y lavish-axi playbook ` for focused artifact guidance. One artifact often combines several playbooks (for example a plan that includes a comparison and a diagram), so MUST open each matching playbook before writing HTML. -- Lavish does not auto-inject any design system - artifacts stay portable so they render identically when opened directly without lavish-axi running. Before writing any HTML: Decide the design direction in this strict priority order, and only move to the next step when the current one truly yields nothing: (1) if the user asked for a specific look or named design system, use that; (2) otherwise you must first inspect the project the artifact is about - the subject or product whose content or UI it represents, which may differ from your current working directory - and match that project's design system: Tailwind or theme config, shared CSS variables or design tokens, component library, brand assets, or existing styled pages. If the artifact previews, proposes, or mocks a specific app's UI, render it in that app's own design system so it faithfully shows the product, even when you are running in a different repo; (3) only when both steps come up empty, use the Lavish-recommended Tailwind CSS browser runtime v4 + DaisyUI v5, available via CDN, and prefer that CDN snippet over hand-writing styles unless explicitly instructed otherwise by the user. Run `npx -y lavish-axi design` for a content-to-playbook router, a copy-pasteable CDN snippet, a Mermaid CDN snippet/init for diagrams, and the DaisyUI component reference. When you deliver the artifact, state which of the three design sources you used and why. -- Use lavish-axi when the user asks for a visual artifact, HTML explainer, interactive prototype, review surface, product or technical plan, comparison, report, or browser-based feedback loop diff --git a/plugins/lavish/agent/skills/lavish/SKILL.md b/plugins/lavish/agent/skills/lavish/SKILL.md index 06a399ce..c9e0d7d9 100644 --- a/plugins/lavish/agent/skills/lavish/SKILL.md +++ b/plugins/lavish/agent/skills/lavish/SKILL.md @@ -5,77 +5,23 @@ metadata: {"author":"Kun Chen (kunchenguid)","argument-hint":"` so the user can visually review it, annotate elements or selected text, queue prompts, and send feedback back through `npx -y lavish-axi poll`. +Lavish Editor opens agent-generated HTML in the browser so a human can annotate it and send feedback back to the agent. +Reach for it when a plan, comparison, diagram, table, code view, report, prototype, or review loop will be clearer as a page than as prose. + +## Current guidance lives in the CLI + +Do not follow workflow, design, or playbook instructions from this file - installed copies go stale. Get the current source of truth from the CLI: + +- `npx -y lavish-axi --help` for commands and the review-loop workflow +- `npx -y lavish-axi design` for design-direction priority and current snippets +- `npx -y lavish-axi playbook ` for focused artifact guidance (`npx -y lavish-axi playbook` lists ids) You do not need lavish-axi installed globally - invoke it with `npx -y lavish-axi `. If lavish-axi output shows a follow-up command starting with `lavish-axi`, run it as `npx -y lavish-axi ...` instead. -In restricted subprocess sandboxes, CI, or agent harnesses where `npx -y` exits opaquely (for example with status 216), use an already-installed copy directly: `node "$(npm root)/lavish-axi/dist/cli.mjs" ` for a local install, `node "$(npm root -g)/lavish-axi/dist/cli.mjs" ` for a global install, or the bare `lavish-axi ` bin after installing once. ## Request $ARGUMENTS -If the request above is non-empty, the user invoked `/lavish` explicitly - build an HTML artifact for that request now, following the workflow below. +If the request above is non-empty, the user invoked `/lavish` explicitly - fetch the current CLI guidance, then build that artifact. If it is empty, infer what to visualize from the conversation. - -## When to use - -Use lavish-axi when the user asks for a visual artifact, HTML explainer, interactive prototype, review surface, product or technical plan, comparison, report, or browser-based feedback loop - -## Workflow - -1. Create the HTML artifact (default location `.lavish/.html` in the working directory). -2. Run `npx -y lavish-axi ` to open or resume a review session in the browser. - If the output carries a `self_paint_warning`, fix the unpainted page surface and save before polling - Lavish live-reloads the artifact. -3. Run `npx -y lavish-axi poll ` to long-poll for the user's annotations and queued prompts. - On the first poll, prefer `--agent-reply ""` so the conversation panel opens with context. - Browser-detected layout issues are filed passively in the user's Layout issues inbox and arrive as an ordinary `layout-warnings` prompt only when the user selects and queues them. Never edit an issue the user has not queued. The only response that arrives without user action is `artifact_failures`, when the review surface itself is unusable. - The poll stays silent until the user acts or a fatal artifact failure makes the review surface unusable - leave it running, never kill it. - Cosmetic, intentional, transient, tiny, and uncertain observations remain silent. - Keep the poll in the foreground by default and let it return the feedback directly to the agent. - A background poll is allowed only through a harness-native tracked background-job facility whose completion result is guaranteed to resume or notify the same agent. - Never use `nohup`, shell `&`, `disown`, redirected fire-and-forget processes, or a detached terminal without an explicit verified callback merely to keep polling alive. - If the harness has no completion-aware background facility, use the foreground poll or first wire a verified wake callback into the surrounding supervisor. - Do not tell the user the artifact is being monitored until that wake path is live. - If the poll gets killed or times out anyway, just re-run it - queued feedback is never lost. -4. If poll returns feedback, apply the user's prompts. A `layout-warnings` prompt is an explicit repair request; apply every listed fix in one pass before saving, and let Lavish re-check it after a newer artifact load. -5. Apply human feedback, then poll again with `--agent-reply ""` to reply in the browser and keep the loop going under the same foreground-or-verified-wake-path rule. -6. Run `npx -y lavish-axi end ` when the review is finished. -7. `Send & End` ends the session. Its final feedback is still delivered once. After that response, polling stops, and the agent must not reopen the session uninvited. Deliver any remaining updates directly in this conversation. - -## Visual guidance - -- Use visual hierarchy to make the most important decisions, risks, tradeoffs, and next actions obvious at a glance -- Use visual structure such as sections, cards, tables, diagrams, annotated snippets, and side-by-side comparisons instead of long prose -- Choose typography, spacing, color, and layout deliberately so the artifact has a clear point of view -- Prevent horizontal overflow at every nesting level: nested grid/flex children also need minmax(0, 1fr) tracks and min-width: 0, especially when badges, labels, or status text use wide pixel or monospace fonts; wrap, truncate, or contain long unbreakable text deliberately -- When the artifact would describe existing or current UI or state, show it instead: capture screenshots of the real pages (run the app read-only if needed) and embed them, rather than explaining the current look in prose; reserve prose for what cannot be shown such as rationale, trade-offs, and open questions - -## Playbooks - -Run `npx -y lavish-axi playbook ` for focused, detailed guidance on any of these. -One artifact often combines several playbooks (for example a plan that includes a comparison and a diagram), so MUST open each matching playbook before writing HTML. -For flows, architecture, state, or sequence diagrams, do not hand-build boxes-and-arrows from div/flexbox; open the diagram playbook and use the theme-aware Mermaid snippet from `npx -y lavish-axi design` unless SVG is needed for richly annotated nodes. - -- `diagram` - Map relationships, flows, state, and architecture -- `table` - Turn dense records into scan-friendly review surfaces -- `comparison` - Show options, tradeoffs, and current vs target behavior -- `plan` - Explain a product or technical plan before implementation -- `code` - Render source code, code files, patches, PR diffs, and before/after code inside Lavish artifacts -- `input` - Must be used when the agent needs to collect user input on decisions, choices, preferences, triage, scope, or other structured feedback from within the artifact -- `slides` - Create a deliberate presentation when slides are requested - -## Commands & rules - -- Run `npx -y lavish-axi ` to open or resume a Lavish Editor session. If the user explicitly ended the session from the browser, this refuses to reopen it and explains why instead of reopening uninvited - pass `--reopen` only when the user asks for further review or something important needs their visual attention -- Unless the user specifies another location, create HTML artifacts in the current working directory under `.lavish/` -- Lavish serves the html file through a local express.js server. If your html needs to reference other filesystem assets such as images, CSS, fonts, and local scripts, copy them into the same directory as the HTML file, then reference them with relative paths from that directory. Never prepend `/` to those asset paths - root paths won't work -- Run `npx -y lavish-axi poll ` to wait for user feedback. It long-polls and stays silent until the user sends feedback or ends the session, so leave it running - never kill it. Detected layout issues never return this poll: the browser files them in the user's Layout issues inbox in the Lavish top bar, and they arrive as an ordinary tag "layout-warnings" prompt only when the user selects them and queues the fixes. Never edit the artifact to chase a layout issue the user has not queued. The only exception is a fatal artifact_failures response, which means the review surface itself could not be used. Keep the poll in the foreground by default and let it return the feedback directly to the agent. A background poll is allowed only through a harness-native tracked background-job facility whose completion result is guaranteed to resume or notify the same agent. Never use `nohup`, shell `&`, `disown`, redirected fire-and-forget processes, or a detached terminal without an explicit verified callback merely to keep polling alive. If the harness has no completion-aware background facility, use the foreground poll or first wire a verified wake callback into the surrounding supervisor. Do not tell the user the artifact is being monitored until that wake path is live. If the poll gets killed or times out anyway, just re-run it - queued feedback is never lost. `Send & End` ends the session. Its final feedback is still delivered once. After that response, polling stops, and the agent must not reopen the session uninvited. -- Rendered Mermaid diagrams in `.mermaid` containers become embedded, editable Excalidraw whiteboards in the browser (click a diagram to unlock editing; a Fullscreen action opens it over the whole viewport) - flowchart, sequence, class, ER, and state diagrams convert to editable shapes; other types embed as an image to draw on. Scenes autosave locally; when a reload detects a changed Mermaid source, the reviewer explicitly chooses to re-convert and discard saved edits or keep editing the saved scene. Standalone and exported copies still render plain Mermaid. Queue feedback adds a prompt to the Conversation panel; when the user sends it, poll returns a tag "whiteboard" prompt carrying a bounded edit summary plus local scenePath (.excalidraw JSON) and previewPath (PNG) files - read the summary first, open the files only when needed, then apply the edits by updating the Mermaid source in the artifact (never try to write the scene back) -- Run `npx -y lavish-axi end ` to end a session as the agent - ending it this way still allows a plain reopen later. When the user ends it from the browser instead, a later `npx -y lavish-axi ` refuses to reopen it without `--reopen` -- Run `npx -y lavish-axi export [--out ]` to write a portable copy of the artifact - one HTML file with its LOCAL assets inlined - so it opens with no Lavish server and no sibling files. Remote CDN/font references are left as links, so it needs network to render those. Users can also export from the browser chrome's overflow menu -- Run `npx -y lavish-axi share [--password ] [--token ]` to publish the artifact on ht-ml.app (https://ht-ml.app), a third-party hosting service not part of Lavish, and get back a visitable URL. Shares are PUBLIC by default, so anyone with the link can open them. Pass --password to publish a PRIVATE password-protected page; viewers must supply the password to view. Local assets are inlined; remote refs load over the network. It returns the url plus a secret update_key for managing the page later. Use --token or LAVISH_AXI_HTML_APP_TOKEN only when you have an optional bearer token; it is never required. Users can also publish from the browser chrome's overflow menu -- Run `npx -y lavish-axi stop` to shut down the background server (it also self-stops when idle or after the last session ends with nothing connected) -- Run `npx -y lavish-axi playbook ` for focused artifact guidance. One artifact often combines several playbooks (for example a plan that includes a comparison and a diagram), so MUST open each matching playbook before writing HTML. -- Lavish does not auto-inject any design system - artifacts stay portable so they render identically when opened directly without lavish-axi running. Before writing any HTML: Decide the design direction in this strict priority order, and only move to the next step when the current one truly yields nothing: (1) if the user asked for a specific look or named design system, use that; (2) otherwise you must first inspect the project the artifact is about - the subject or product whose content or UI it represents, which may differ from your current working directory - and match that project's design system: Tailwind or theme config, shared CSS variables or design tokens, component library, brand assets, or existing styled pages. If the artifact previews, proposes, or mocks a specific app's UI, render it in that app's own design system so it faithfully shows the product, even when you are running in a different repo; (3) only when both steps come up empty, use the Lavish-recommended Tailwind CSS browser runtime v4 + DaisyUI v5, available via CDN, and prefer that CDN snippet over hand-writing styles unless explicitly instructed otherwise by the user. Run `npx -y lavish-axi design` for a content-to-playbook router, a copy-pasteable CDN snippet, a Mermaid CDN snippet/init for diagrams, and the DaisyUI component reference. When you deliver the artifact, state which of the three design sources you used and why. -- Use lavish-axi when the user asks for a visual artifact, HTML explainer, interactive prototype, review surface, product or technical plan, comparison, report, or browser-based feedback loop diff --git a/plugins/lavish/skills-lock.json b/plugins/lavish/skills-lock.json index c259f312..87452bd3 100644 --- a/plugins/lavish/skills-lock.json +++ b/plugins/lavish/skills-lock.json @@ -5,7 +5,7 @@ "source": "kunchenguid/lavish-axi", "sourceType": "github", "skillPath": "skills/lavish/SKILL.md", - "computedHash": "1516c3ea2b973555b7cc052118102996266366ee27020ce9ec40d93bab6f7ab8" + "computedHash": "5ff18ff1fb92bda3049037e08d1f7db31f7667bc90635677c37dcf620fd0c1a4" } } } diff --git a/plugins/nostics/skills-lock.json b/plugins/nostics/skills-lock.json index 797422a3..72ff0b84 100644 --- a/plugins/nostics/skills-lock.json +++ b/plugins/nostics/skills-lock.json @@ -5,13 +5,13 @@ "source": "vercel-labs/nostics", "sourceType": "github", "skillPath": "skills/add-diagnostic/SKILL.md", - "computedHash": "c7b8e4657722027d0ec9099406e05941d33103cc76b4915859e3cd60f94617a0" + "computedHash": "bffe858a73515c6dcd391644a6c5ac494f0ef56454fa713156f093f7241544f6" }, "nostics": { "source": "vercel-labs/nostics", "sourceType": "github", "skillPath": "skills/nostics/SKILL.md", - "computedHash": "7a39ad8833dd28e1209b7c269564b6a864a859cf86fb3b64a87790bf3b47c5cc" + "computedHash": "07db3216d541cb51221ad4ad2af8e0581a73abe14ea0c0c685f5c3d4a586d3ad" } } } diff --git a/plugins/nuxt-ui/.agents/skills/nuxt-ui/SKILL.md b/plugins/nuxt-ui/.agents/skills/nuxt-ui/SKILL.md index 037e4946..2ce6e71f 100644 --- a/plugins/nuxt-ui/.agents/skills/nuxt-ui/SKILL.md +++ b/plugins/nuxt-ui/.agents/skills/nuxt-ui/SKILL.md @@ -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**. @@ -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/.ts`, Vue: `node_modules/.nuxt-ui/ui/.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 diff --git a/plugins/nuxt-ui/.agents/skills/nuxt-ui/references/components.md b/plugins/nuxt-ui/.agents/skills/nuxt-ui/references/components.md index 4d34ef4a..6f108bda 100644 --- a/plugins/nuxt-ui/.agents/skills/nuxt-ui/references/components.md +++ b/plugins/nuxt-ui/.agents/skills/nuxt-ui/references/components.md @@ -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 @@ -12,6 +12,7 @@ Quick-reference index of all 125+ components. For full API docs (props, slots, e | `UFooterColumns` | Multi-column footer with link groups | | `UMain` | Main content area | | `UContainer` | Centered max-width container | +| `USplitter` | Resizable panels separated by draggable handles | | `ULink` | Enhanced link — NuxtLink/RouterLink with active states | ## Element @@ -31,6 +32,7 @@ Quick-reference index of all 125+ components. For full API docs (props, slots, e | `USeparator` | Divider line with optional label | | `USkeleton` | Loading placeholder | | `UProgress` | Progress bar | +| `UProgressGroup` | Segmented progress bar with a list of items | | `UToast` | Toast notification (shown via `useToast`) | | `UCalendar` | Date calendar (single, range, multiple) | | `UCollapsible` | Animated expand/collapse | diff --git a/plugins/nuxt-ui/.agents/skills/nuxt-ui/references/guidelines/component-selection.md b/plugins/nuxt-ui/.agents/skills/nuxt-ui/references/guidelines/component-selection.md index 142a7a75..c2d1ce14 100644 --- a/plugins/nuxt-ui/.agents/skills/nuxt-ui/references/guidelines/component-selection.md +++ b/plugins/nuxt-ui/.agents/skills/nuxt-ui/references/guidelines/component-selection.md @@ -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 @@ -76,6 +76,7 @@ Decision matrices for choosing the right component. When in doubt, use the MCP ` | App-wide announcement | `UBanner` | Sticky top bar, dismissible | | Loading state | `USkeleton` | Placeholder shimmer while loading | | Progress indicator | `UProgress` | Determinate or indeterminate progress | +| Breakdown of a total | `UProgressGroup` | One bar split into colored segments that add up to `max` | ### Rules - Use `useToast()` for action feedback: "Item saved", "Email sent", "Error occurred" @@ -114,6 +115,7 @@ When rendering Markdown (for instance with Comark), **prefer Prose components** | Centered content wrapper | `UContainer` | Max-width container | | Collapsible section | `UCollapsible` | Animated expand/collapse | | Accordion (multiple collapsibles) | `UAccordion` | FAQ, grouped collapsible content | +| Resizable side-by-side panes | `USplitter` | IDE-style layouts, resizable sidebars | ### Rules - Don't overuse `UCard` — plain content with spacing is often better than wrapping everything in cards diff --git a/plugins/nuxt-ui/.agents/skills/nuxt-ui/references/guidelines/conventions.md b/plugins/nuxt-ui/.agents/skills/nuxt-ui/references/guidelines/conventions.md index e63c5d28..c1aa29eb 100644 --- a/plugins/nuxt-ui/.agents/skills/nuxt-ui/references/guidelines/conventions.md +++ b/plugins/nuxt-ui/.agents/skills/nuxt-ui/references/guidelines/conventions.md @@ -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 diff --git a/plugins/nuxt-ui/.agents/skills/nuxt-ui/references/guidelines/design-system.md b/plugins/nuxt-ui/.agents/skills/nuxt-ui/references/guidelines/design-system.md index 9392dd12..561dc411 100644 --- a/plugins/nuxt-ui/.agents/skills/nuxt-ui/references/guidelines/design-system.md +++ b/plugins/nuxt-ui/.agents/skills/nuxt-ui/references/guidelines/design-system.md @@ -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 diff --git a/plugins/nuxt-ui/.agents/skills/nuxt-ui/references/recipes/data-tables.md b/plugins/nuxt-ui/.agents/skills/nuxt-ui/references/recipes/data-tables.md index eef074e5..f5c81f86 100644 --- a/plugins/nuxt-ui/.agents/skills/nuxt-ui/references/recipes/data-tables.md +++ b/plugins/nuxt-ui/.agents/skills/nuxt-ui/references/recipes/data-tables.md @@ -216,7 +216,7 @@ const { data, status } = await useAsyncData( ## Tips -- Table is built on [TanStack Table](https://tanstack.com/table/latest) — columns use `ColumnDef` format with `accessorKey`, `header`, `cell` +- Table is built on [TanStack Table v8](https://tanstack.com/table/v8) — columns use `ColumnDef` format with `accessorKey`, `header`, `cell` - Use `#-cell` and `#-header` template slots to customize rendering with Vue templates - Alternatively, use the `h` function inside `header` and `cell` column properties for inline rendering - Row data in slots is accessed via `row.original` (not `row` directly) diff --git a/plugins/nuxt-ui/agent/skills/nuxt-ui/SKILL.md b/plugins/nuxt-ui/agent/skills/nuxt-ui/SKILL.md index e496c28a..735522de 100644 --- a/plugins/nuxt-ui/agent/skills/nuxt-ui/SKILL.md +++ b/plugins/nuxt-ui/agent/skills/nuxt-ui/SKILL.md @@ -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**. @@ -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/.ts`, Vue: `node_modules/.nuxt-ui/ui/.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 diff --git a/plugins/nuxt-ui/agent/skills/nuxt-ui/references/components.md b/plugins/nuxt-ui/agent/skills/nuxt-ui/references/components.md index 4d34ef4a..6f108bda 100644 --- a/plugins/nuxt-ui/agent/skills/nuxt-ui/references/components.md +++ b/plugins/nuxt-ui/agent/skills/nuxt-ui/references/components.md @@ -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 @@ -12,6 +12,7 @@ Quick-reference index of all 125+ components. For full API docs (props, slots, e | `UFooterColumns` | Multi-column footer with link groups | | `UMain` | Main content area | | `UContainer` | Centered max-width container | +| `USplitter` | Resizable panels separated by draggable handles | | `ULink` | Enhanced link — NuxtLink/RouterLink with active states | ## Element @@ -31,6 +32,7 @@ Quick-reference index of all 125+ components. For full API docs (props, slots, e | `USeparator` | Divider line with optional label | | `USkeleton` | Loading placeholder | | `UProgress` | Progress bar | +| `UProgressGroup` | Segmented progress bar with a list of items | | `UToast` | Toast notification (shown via `useToast`) | | `UCalendar` | Date calendar (single, range, multiple) | | `UCollapsible` | Animated expand/collapse | diff --git a/plugins/nuxt-ui/agent/skills/nuxt-ui/references/guidelines/component-selection.md b/plugins/nuxt-ui/agent/skills/nuxt-ui/references/guidelines/component-selection.md index 142a7a75..c2d1ce14 100644 --- a/plugins/nuxt-ui/agent/skills/nuxt-ui/references/guidelines/component-selection.md +++ b/plugins/nuxt-ui/agent/skills/nuxt-ui/references/guidelines/component-selection.md @@ -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 @@ -76,6 +76,7 @@ Decision matrices for choosing the right component. When in doubt, use the MCP ` | App-wide announcement | `UBanner` | Sticky top bar, dismissible | | Loading state | `USkeleton` | Placeholder shimmer while loading | | Progress indicator | `UProgress` | Determinate or indeterminate progress | +| Breakdown of a total | `UProgressGroup` | One bar split into colored segments that add up to `max` | ### Rules - Use `useToast()` for action feedback: "Item saved", "Email sent", "Error occurred" @@ -114,6 +115,7 @@ When rendering Markdown (for instance with Comark), **prefer Prose components** | Centered content wrapper | `UContainer` | Max-width container | | Collapsible section | `UCollapsible` | Animated expand/collapse | | Accordion (multiple collapsibles) | `UAccordion` | FAQ, grouped collapsible content | +| Resizable side-by-side panes | `USplitter` | IDE-style layouts, resizable sidebars | ### Rules - Don't overuse `UCard` — plain content with spacing is often better than wrapping everything in cards diff --git a/plugins/nuxt-ui/agent/skills/nuxt-ui/references/guidelines/conventions.md b/plugins/nuxt-ui/agent/skills/nuxt-ui/references/guidelines/conventions.md index e63c5d28..c1aa29eb 100644 --- a/plugins/nuxt-ui/agent/skills/nuxt-ui/references/guidelines/conventions.md +++ b/plugins/nuxt-ui/agent/skills/nuxt-ui/references/guidelines/conventions.md @@ -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 diff --git a/plugins/nuxt-ui/agent/skills/nuxt-ui/references/guidelines/design-system.md b/plugins/nuxt-ui/agent/skills/nuxt-ui/references/guidelines/design-system.md index 9392dd12..561dc411 100644 --- a/plugins/nuxt-ui/agent/skills/nuxt-ui/references/guidelines/design-system.md +++ b/plugins/nuxt-ui/agent/skills/nuxt-ui/references/guidelines/design-system.md @@ -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 diff --git a/plugins/nuxt-ui/agent/skills/nuxt-ui/references/recipes/data-tables.md b/plugins/nuxt-ui/agent/skills/nuxt-ui/references/recipes/data-tables.md index eef074e5..f5c81f86 100644 --- a/plugins/nuxt-ui/agent/skills/nuxt-ui/references/recipes/data-tables.md +++ b/plugins/nuxt-ui/agent/skills/nuxt-ui/references/recipes/data-tables.md @@ -216,7 +216,7 @@ const { data, status } = await useAsyncData( ## Tips -- Table is built on [TanStack Table](https://tanstack.com/table/latest) — columns use `ColumnDef` format with `accessorKey`, `header`, `cell` +- Table is built on [TanStack Table v8](https://tanstack.com/table/v8) — columns use `ColumnDef` format with `accessorKey`, `header`, `cell` - Use `#-cell` and `#-header` template slots to customize rendering with Vue templates - Alternatively, use the `h` function inside `header` and `cell` column properties for inline rendering - Row data in slots is accessed via `row.original` (not `row` directly) diff --git a/plugins/nuxt-ui/skills-lock.json b/plugins/nuxt-ui/skills-lock.json index dedff862..b49bde38 100644 --- a/plugins/nuxt-ui/skills-lock.json +++ b/plugins/nuxt-ui/skills-lock.json @@ -5,7 +5,7 @@ "source": "nuxt/ui", "sourceType": "github", "skillPath": "skills/nuxt-ui/SKILL.md", - "computedHash": "ef3a731fdfa8439d3c7f0c6d497a67073216b8cb7d7fa6a3c605a6fda4ede19a" + "computedHash": "f6235ff66b930f4fe3809a55167096c9626ebb806f767fe363f19384e0d84c87" } } } diff --git a/plugins/portless/.agents/skills/portless/SKILL.md b/plugins/portless/.agents/skills/portless/SKILL.md index d386f2ff..1e528ee0 100644 --- a/plugins/portless/.agents/skills/portless/SKILL.md +++ b/plugins/portless/.agents/skills/portless/SKILL.md @@ -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 @@ -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: diff --git a/plugins/portless/agent/skills/portless/SKILL.md b/plugins/portless/agent/skills/portless/SKILL.md index 3b9f2302..dda0dda7 100644 --- a/plugins/portless/agent/skills/portless/SKILL.md +++ b/plugins/portless/agent/skills/portless/SKILL.md @@ -167,7 +167,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 @@ -381,7 +381,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: diff --git a/plugins/portless/skills-lock.json b/plugins/portless/skills-lock.json index 583f677b..2f82146a 100644 --- a/plugins/portless/skills-lock.json +++ b/plugins/portless/skills-lock.json @@ -5,7 +5,7 @@ "source": "vercel-labs/portless", "sourceType": "github", "skillPath": "skills/portless/SKILL.md", - "computedHash": "5b758ea66233a1ebd494554904db55d902f5ea8832c353188d771f5c6fed9d2b" + "computedHash": "4dd2cfba1475a35878d3936d4ce80047b800f7d7f65c9c6ddccb4638651d66a5" } } } diff --git a/plugins/react/.agents/skills/vercel-react-view-transitions/README.md b/plugins/react/.agents/skills/vercel-react-view-transitions/README.md index 9f29bed9..061e32ae 100644 --- a/plugins/react/.agents/skills/vercel-react-view-transitions/README.md +++ b/plugins/react/.agents/skills/vercel-react-view-transitions/README.md @@ -9,7 +9,7 @@ An agent skill for implementing smooth, native-feeling animations using React's - **Shared element transitions** — morphing elements across different views - **View Transition Events** — imperative JavaScript animations via the Web Animations API - **CSS pseudo-elements** — `::view-transition-old`, `::view-transition-new`, `::view-transition-group` -- **Next.js integration** — `experimental.viewTransition`, the `transitionTypes` prop on `next/link`, App Router patterns +- **Next.js integration** — `experimental.viewTransition`, `transitionTypes` on `next/link` and `useRouter`, App Router patterns - **Accessibility** — `prefers-reduced-motion` handling - **Ready-to-use CSS recipes** — fade, slide, scale, directional navigation @@ -31,12 +31,13 @@ react-view-transitions/ Install via [skills.sh](https://skills.sh): ```bash -npx skills install https://github.com/vercel-labs/react-view-transitions-skill +npx skills add https://github.com/vercel-labs/agent-skills --skill vercel-react-view-transitions ``` ## Resources - [React `` docs](https://react.dev/reference/react/ViewTransition) - [React `addTransitionType` docs](https://react.dev/reference/react/addTransitionType) +- [Next.js View Transitions guide](https://nextjs.org/docs/app/guides/view-transitions) - [Next.js `viewTransition` config](https://nextjs.org/docs/app/api-reference/config/next-config-js/viewTransition) - [Next.js App Router Playground (view transitions)](https://github.com/vercel/next-app-router-playground/tree/main/app/view-transitions) — Vercel's reference implementation diff --git a/plugins/react/.agents/skills/vercel-react-view-transitions/SKILL.md b/plugins/react/.agents/skills/vercel-react-view-transitions/SKILL.md index dcecd8e3..1259682e 100644 --- a/plugins/react/.agents/skills/vercel-react-view-transitions/SKILL.md +++ b/plugins/react/.agents/skills/vercel-react-view-transitions/SKILL.md @@ -23,7 +23,7 @@ Implement **all** applicable patterns from this list, in this order: | 2 | **Suspense reveal** | "Data loaded" | | 3 | **List identity** (per-item `key`) | "Same items, new arrangement" | | 4 | **State change** (`enter`/`exit`) | "Something appeared/disappeared" | -| 5 | **Route change** (layout-level) | "Going to a new place" | +| 5 | **Route change** (page-level) | "Going to a new place" | This is an implementation order, not a "pick one" list. Implement every pattern that fits the app. Only skip a pattern if the app has no use case for it. @@ -44,13 +44,13 @@ Reserve directional slides for hierarchical navigation (list → detail) and ord - **Next.js:** Do **not** install `react@canary` — the App Router already bundles React canary internally. `ViewTransition` works out of the box. `npm ls react` may show a stable-looking version; this is expected. - **Without Next.js:** Install `react@canary react-dom@canary` (`ViewTransition` is not in stable React). -- Browser support: Chromium 111+, Firefox 144+, Safari 18.2+. Graceful degradation on unsupported browsers. +- Browser support: Chromium 125+ (React needs the v2 object form of `startViewTransition`), Firefox 144+, Safari 18.2+. Graceful degradation on unsupported browsers. --- ## Implementation Workflow -When adding view transitions to an existing app, **follow `references/implementation.md` step by step.** Start with the audit — do not skip it. Copy the CSS recipes from `references/css-recipes.md` into the global stylesheet — do not write your own animation CSS. +When adding view transitions to an existing app, **follow [references/implementation.md](references/implementation.md) step by step.** Start with the audit — do not skip it. Copy the CSS recipes from [references/css-recipes.md](references/css-recipes.md) into the global stylesheet — do not write your own animation CSS. --- @@ -74,7 +74,7 @@ React auto-assigns a unique `view-transition-name` and calls `document.startView |---------|--------------| | **enter** | `` first inserted during a Transition | | **exit** | `` first removed during a Transition | -| **update** | DOM mutations inside a ``. With nested VTs, mutation applies to the innermost one | +| **update** | DOM mutations inside a ``, or the boundary itself changing size/position due to an immediate sibling. With nested VTs, mutation applies to the innermost one | | **share** | Named VT unmounts and another with same `name` mounts in the same Transition | Only `startTransition`, `useDeferredValue`, or `Suspense` activate VTs. Regular `setState` does not animate. @@ -118,7 +118,7 @@ If `default` is `"none"`, all triggers are off unless explicitly listed. - `::view-transition-group(.class)` — container - `::view-transition-image-pair(.class)` — old + new pair -See `references/css-recipes.md` for ready-to-use animation recipes. +See [references/css-recipes.md](references/css-recipes.md) for ready-to-use animation recipes. --- @@ -177,12 +177,16 @@ export function DirectionalTransition({ children }: { children: React.ReactNode ### `router.back()` and Browser Back Button -`router.back()` and the browser's back/forward buttons do **not** trigger view transitions (`popstate` is synchronous, incompatible with `startViewTransition`). Use `router.push()` with an explicit URL instead. +`router.back()` and the browser's back/forward buttons carry **no transition types**, so type-keyed animations (directional slides) resolve to their `default` and don't play — untyped shared-element morphs still apply. For typed animations, use `router.push()` with an explicit URL. ### Types and Suspense Types are available during navigation but **not** during subsequent Suspense reveals (separate transitions, no type). Use type maps for page-level enter/exit; use simple string props for Suspense reveals. +### Shared Element Readiness + +A shared element transition can pair elements only when both the old and new views are rendered in the same Transition. If incoming content suspends, only its fallback exists for that update; the resolved content appears in a later Suspense transition and can be animated separately. + --- ## Shared Element Transitions @@ -202,6 +206,7 @@ Same `name` on two VTs — one unmounting, one mounting — creates a shared ele - Only one VT with a given `name` can be mounted at a time — use unique names (`photo-${id}`). Watch for reusable components: if a component with a named VT is rendered in both a modal/popover *and* a page, both mount simultaneously and break the morph. Either make the name conditional (via a prop) or move the named VT out of the shared component into the specific consumer. - `share` takes precedence over `enter`/`exit`. Think through each navigation path: when no matching pair forms (e.g., the target page doesn't have the same name), `enter`/`exit` fires instead. Consider whether the element needs a fallback animation for those paths. +- Two ways a wired-up morph silently never fires: (1) `default="none"` with no explicit `share` prop — share resolves to none; (2) type-keyed `share` where the navigation never adds the type — a plain link click resolves the map's `default`. Every link that should morph must add the type (`transitionTypes` on `next/link`, or `addTransitionType`). - Never use a fade-out exit on pages with shared morphs — use a directional slide instead. --- @@ -226,6 +231,10 @@ Same `name` on two VTs — one unmounting, one mounting — creates a shared ele Trigger inside `startTransition`. Avoid wrapper `
`s between list and VT. +### Layout Displacement Morph + +Only content inside an activated boundary animates position — everything else teleports to its new layout spot. Wrap the sibling content below a growing/shrinking list in a bare `` so it glides instead of jumping. See [Layout Displacement Morph](references/patterns.md#layout-displacement-morph). + ### Composing Shared Elements with List Identity Shared elements and list identity are independent concerns — don't confuse one for the other. When a list item contains a shared element (e.g., an image that morphs into a detail view), use two nested `` boundaries: @@ -271,7 +280,7 @@ Directional reveal: ``` -For more patterns, see `references/patterns.md`. +For more patterns, see [references/patterns.md](references/patterns.md). --- @@ -279,9 +288,11 @@ For more patterns, see `references/patterns.md`. Every VT matching the trigger fires simultaneously in a single `document.startViewTransition`. VTs in **different** transitions (navigation vs later Suspense resolve) don't compete. -### Use `default="none"` Liberally +### Use `default="none"` Deliberately + +Without it, every VT fires the browser cross-fade on **every** transition — Suspense resolves, `useDeferredValue` updates, background revalidations. Use `default="none"` on named/shared elements and type-keyed page VTs. -Without it, every VT fires the browser cross-fade on **every** transition — Suspense resolves, `useDeferredValue` updates, background revalidations. Always use `default="none"` and explicitly enable only desired triggers. +But it also turns off `update` (layout/reflow morphs) and `share` (a named pair with no explicit `share` prop never morphs). Keyed list items and displaced siblings *want* update — leave them bare or set `update="auto"`. ### Two Patterns Coexist @@ -292,28 +303,28 @@ They coexist because they fire at different moments. `default="none"` on both pr ### Nested VT Limitation -When a parent VT exits, nested VTs inside it do **not** fire their own enter/exit — only the outermost VT animates. Per-item staggered animations during page navigation are not possible today. See [react#36135](https://github.com/facebook/react/pull/36135) for an experimental opt-in fix. +When a parent VT mounts/unmounts **as one unit** with nested VTs inside it, the nested ones do not fire their own enter/exit — only the outermost VT animates. (A child VT mounted inside a *persistent* parent VT fires enter/exit normally.) Per-item staggered animations during page navigation are not possible today; the experimental opt-in is the `parentEnter`/`parentExit` props ([react#36690](https://github.com/facebook/react/pull/36690), experimental channel only). --- ## Next.js Integration -For Next.js setup (`experimental.viewTransition` flag, `transitionTypes` prop on `next/link`, App Router patterns, Server Components), see `references/nextjs.md`. +For Next.js setup (`experimental.viewTransition` flag, `transitionTypes` on `next/link` and `useRouter`, App Router patterns, Server Components), see [references/nextjs.md](references/nextjs.md). --- ## Accessibility -Always add the reduced motion CSS from `references/css-recipes.md` to your global stylesheet. +Always add the reduced motion CSS from [references/css-recipes.md](references/css-recipes.md#reduced-motion) to your global stylesheet. --- ## Reference Files -- **`references/implementation.md`** — Step-by-step implementation workflow. -- **`references/patterns.md`** — Patterns, animation timing, events API, troubleshooting. -- **`references/css-recipes.md`** — Ready-to-use CSS animation recipes. -- **`references/nextjs.md`** — Next.js App Router patterns and Server Component details. +- **[references/implementation.md](references/implementation.md)** — Step-by-step implementation workflow. +- **[references/patterns.md](references/patterns.md)** — Patterns, animation timing, events API, troubleshooting. +- **[references/css-recipes.md](references/css-recipes.md)** — Ready-to-use CSS animation recipes. +- **[references/nextjs.md](references/nextjs.md)** — Next.js App Router patterns and Server Component details. ## Full Compiled Document diff --git a/plugins/react/.agents/skills/vercel-react-view-transitions/references/css-recipes.md b/plugins/react/.agents/skills/vercel-react-view-transitions/references/css-recipes.md index f9c1fca5..8cd15783 100644 --- a/plugins/react/.agents/skills/vercel-react-view-transitions/references/css-recipes.md +++ b/plugins/react/.agents/skills/vercel-react-view-transitions/references/css-recipes.md @@ -204,6 +204,39 @@ Usage: `` --- +## Interactivity During Transitions + +The `::view-transition` overlay captures all pointer events. React shrinks it to zero when the root group doesn't animate, but in-flight animations still block clicks. To pass clicks/hover through even while animating: + +```css +::view-transition { + pointer-events: none; +} +``` + +Trade-offs: clicks can hit live elements under still-moving snapshots, and it only helps **unnamed** content — named participants are skipped by hit-testing for the transition's duration, no CSS override ([csswg#10930](https://github.com/w3c/csswg-drafts/issues/10930)). Weigh that before naming interactive elements; portal named popovers (see [Isolate Elements from Parent Animations](patterns.md#isolate-elements-from-parent-animations)). + +--- + +## No Root Cross-Fade (Live Root) + +The root cross-fades on every transition, freezing unnamed content behind a stale snapshot — hover and active styles stop rendering until it settles. `::view-transition-new(root)` is a **live** capture, so disabling the root animation keeps unnamed regions rendering (and, with the `pointer-events` recipe above, interactive): + +```css +::view-transition-old(root) { + display: none; +} +::view-transition-new(root) { + animation: none; +} +``` + +Named and classed groups still animate — they stack above root. Trade-off: unnamed content swaps instantly, so regions that should fade need their own VT. This also removes the main reason to hand-name static chrome; keep names only for elements that must stack above animating groups. + +Pairs well with enter-only reveals: skip the fallback-exit VT entirely (`` around the content, nothing on the skeleton) — the skeleton snaps out live while the content fades in. + +--- + ## Persistent Element Isolation ```css @@ -213,6 +246,8 @@ Usage: `` } ``` +Layer multiple pinned groups with z-index tiers — chrome at `100`, toasts/overlays that must beat everything at `200`. + ### Backdrop-Blur Workaround For elements with `backdrop-filter`, hide the old snapshot to avoid flash: @@ -226,6 +261,37 @@ For elements with `backdrop-filter`, hide the old snapshot to avoid flash: } ``` +### Floating Element Isolation (popovers, menus, tooltips, control clusters) + +Same freeze as persistent chrome. A floating/interactive element left rendered while a background transition runs is otherwise captured in the `root` snapshot and flickers as it settles. Give it a real, unique `view-transition-name` (never `none` — that's the CSS default = no isolation) and: + +```css +::view-transition-group(popover) { + animation: none; + z-index: 100; +} +::view-transition-old(popover), +::view-transition-new(popover) { + animation: none; +} +``` + +### Sliding Indicator (tab underline / segmented pill) + +One shared-name indicator morphs between positions. Slide the group; disable old/new so the solid bar slides instead of cross-fading: + +```css +::view-transition-group(.tab-underline) { + animation-duration: 220ms; + animation-timing-function: cubic-bezier(0.5, 0, 0.2, 1); +} +::view-transition-old(.tab-underline), +::view-transition-new(.tab-underline) { + animation: none; + height: 100%; +} +``` + --- ## Reduced Motion diff --git a/plugins/react/.agents/skills/vercel-react-view-transitions/references/implementation.md b/plugins/react/.agents/skills/vercel-react-view-transitions/references/implementation.md index e4207c9b..4d93bfcb 100644 --- a/plugins/react/.agents/skills/vercel-react-view-transitions/references/implementation.md +++ b/plugins/react/.agents/skills/vercel-react-view-transitions/references/implementation.md @@ -29,7 +29,7 @@ For each shared element (`name` prop), note every navigation where a pair forms ## Step 2: Add CSS Recipes -Copy the **complete** CSS recipe set from `css-recipes.md` into your global stylesheet. This includes timing variables, shared keyframes, fade, slide (vertical), directional navigation (forward/back), shared element morph, persistent element isolation, and reduced motion. +Copy the **complete** CSS recipe set from [css-recipes.md](css-recipes.md) into your global stylesheet. This includes timing variables, shared keyframes, fade, slide (vertical), directional navigation (forward/back), shared element morph, persistent element isolation, and reduced motion. Do not write your own animation CSS — the recipes handle staggered timing, motion blur on morphs, and reduced motion that are easy to get wrong. You can customize timing variables (`--duration-exit`, `--duration-enter`, `--duration-move`) after the initial setup. @@ -41,7 +41,7 @@ For every persistent element identified in Step 1, add a `viewTransitionName` st
...
``` -Then add the persistent element isolation CSS from `css-recipes.md` (prevents the element from animating during page transitions). If the element uses `backdrop-blur` or `backdrop-filter`, use the backdrop-blur workaround from `css-recipes.md` instead. +Then add the [Persistent Element Isolation](css-recipes.md#persistent-element-isolation) CSS (prevents the element from animating during page transitions). If the element uses `backdrop-blur` or `backdrop-filter`, use the [Backdrop-Blur Workaround](css-recipes.md#backdrop-blur-workaround) instead. If a Suspense fallback mirrors a persistent control (e.g., a skeleton search input), give both the real control and the skeleton the same `viewTransitionName` so they morph in place. @@ -76,7 +76,7 @@ Then wrap each **page component** (not layout) in a type-keyed ` ``` -The `nav-forward` and `nav-back` CSS classes from `css-recipes.md` produce horizontal slides. For simpler apps where directional motion isn't needed, a bare `` wrapper with `enter="fade-in"` / `exit="fade-out"` works too. +The `nav-forward` and `nav-back` CSS classes from [Directional Navigation](css-recipes.md#directional-navigation) produce horizontal slides. For simpler apps where directional motion isn't needed, a bare `` wrapper with `enter="fade-in"` / `exit="fade-out"` works too. Extract this into a reusable component so every page doesn't repeat the verbose type map: @@ -125,6 +125,7 @@ This example uses `slide-down` / `slide-up` for directional vertical motion. For **Rules:** - Always use `default="none"` on the content `` to prevent re-animation on revalidation or unrelated transitions. - Use simple string props (not type maps) on Suspense ``s — Suspense resolves fire as separate transitions with no type, so type-keyed props won't match. +- If the same element appears in **both** the fallback and the content (a title, a heading), it flickers on reveal — an opacity dip. Render it **outside** the `` boundary (or pin it), so it isn't in both. See [Suspense reveal flicker](patterns.md#suspense-reveal-flicker). ## Step 6: Add Shared Element Transitions @@ -142,13 +143,14 @@ For every shared visual element identified in Step 1, add matching named ` ``` -The `share="morph"` class uses the morph recipe from `css-recipes.md` (controlled duration + motion blur). For a simpler cross-fade, use `share="auto"` (browser default). +The `share="morph"` class uses the [Shared Element Morph](css-recipes.md#shared-element-morph) recipe (controlled duration + motion blur). For a simpler cross-fade, use `share="auto"` (browser default). -When list items contain shared elements, compose both patterns with two nested `` layers — see "Composing Shared Elements with List Identity" in `SKILL.md`. +When list items contain shared elements, compose both patterns with two nested `` layers — see [Composing Shared Elements with List Identity](../SKILL.md#composing-shared-elements-with-list-identity). **Rules:** - Names must be globally unique — use prefixes like `photo-${id}`. - Add `default="none"` on list-side shared elements to prevent per-item cross-fades on filter/search updates. +- The target must be **in the DOM at navigation time** for the pair to form. If it's behind a Suspense fallback (not rendered yet), no pair forms and it won't morph. It works when the target is present at the snapshot — render it above the data boundary, or have its data **cached/prefetched** so it resolves in time. ## Step 7: Verify Each Navigation Path @@ -169,14 +171,14 @@ If any path produces no animation or competing animations, revisit the relevant - **Bare `` without props** — without `default="none"`, it fires the browser's default cross-fade on every transition (every navigation, every Suspense resolve, every revalidation). Always set `default="none"` and explicitly enable only the triggers you want. - **Directional `` in a layout** — layouts persist across navigations and never unmount/remount. `enter`/`exit` props won't fire on route changes. Place the outer type-keyed `` in each page component. - **Fade-out exit with shared element morphs** — the page dissolving conflicts with the morph. Use a directional slide exit instead. -- **Writing custom animation CSS** — the recipes in `css-recipes.md` handle staggered timing, motion blur on morphs, and reduced motion. Copy them; don't reinvent them. +- **Writing custom animation CSS** — the recipes in [css-recipes.md](css-recipes.md) handle staggered timing, motion blur on morphs, and reduced motion. Copy them; don't reinvent them. - **Missing `default: "none"` in type-keyed objects** — TypeScript requires a `default` key, and without it the fallback is `"auto"` which fires on every transition. - **Type maps on Suspense reveals** — Suspense resolves fire as separate transitions with no type. Type-keyed props won't match — use simple string props instead. - **Raw `viewTransitionName` CSS to trigger animations** — React only calls `document.startViewTransition` when `` components are in the tree. A bare `viewTransitionName` style is for isolating elements from a parent's snapshot, not for triggering animations. - **`update` trigger for same-route navigations** — nested VTs inside the content steal the mutation from the parent, so `update` never fires on the outer VT. Use `key` + `name` + `share` instead. - **Named VT in a reusable component** — if a component with a named VT is rendered in both a modal/popover *and* a page, both mount simultaneously and break the morph. Make the name conditional or move it to the specific consumer. -- **`router.back()` for back navigation** — `router.back()` triggers synchronous `popstate`, incompatible with view transitions. Use `router.push()` with an explicit URL. +- **`router.back()` for back navigation** — traversals carry no transition types, so type-keyed animations don't play (untyped morphs still can). Use `router.push()` with an explicit URL for a fully animated back affordance. --- -For Next.js-specific implementation steps (config flag, `transitionTypes` on ``, same-route dynamic segments), see `nextjs.md`. +For Next.js-specific implementation steps (config flag, `transitionTypes` on ``, same-route dynamic segments), see [nextjs.md](nextjs.md). diff --git a/plugins/react/.agents/skills/vercel-react-view-transitions/references/nextjs.md b/plugins/react/.agents/skills/vercel-react-view-transitions/references/nextjs.md index 06a96c7e..dd42fd8d 100644 --- a/plugins/react/.agents/skills/vercel-react-view-transitions/references/nextjs.md +++ b/plugins/react/.agents/skills/vercel-react-view-transitions/references/nextjs.md @@ -2,7 +2,7 @@ ## Setup -`` works out of the box for `startTransition`/`Suspense` updates. To also animate `` navigations: +`` works out of the box — the bundled React canary ships it, and every `` navigation runs inside `React.startTransition`, so react-dom starts a view transition whenever affected `` components exist. Set the documented flag: ```js // next.config.js @@ -12,21 +12,23 @@ const nextConfig = { module.exports = nextConfig; ``` -This wraps every `` navigation in `document.startViewTransition`. Any VT with `default="auto"` fires on **every** link click — use `default="none"` to prevent competing animations. +(Historically the flag switched React to the experimental channel — required before `ViewTransition` reached canary. It no longer does; the experimental channel is only needed for `useSwipeTransition` gestures and `parentEnter`/`parentExit`, selected by other flags like `gestureTransition`.) -Do **not** install `react@canary` — see SKILL.md "Availability" for details. +Because every link click is a transition, any VT with `default="auto"` fires on **every** navigation — use `default="none"` to prevent competing animations. + +Do **not** install `react@canary` — see [Availability](../SKILL.md#availability) for details. --- ## Next.js Implementation Additions -When following `implementation.md`, apply these additions: +When following [implementation.md](implementation.md), apply these additions: **After Step 2:** Enable the experimental flag above. -**Step 4:** Use `transitionTypes` on `` — see "The `transitionTypes` Prop" section below for usage and availability. +**Step 4:** Use `transitionTypes` on `` — see [The `transitionTypes` Prop](#the-transitiontypes-prop-on-nextlink). If the animation depends on dynamic destination content, also see [When Content Must Be Ready](#when-content-must-be-ready). -**After Step 6:** For same-route dynamic segments (e.g., `/collection/[slug]`), use the `key` + `name` + `share` pattern — see Same-Route Dynamic Segment Transitions below. +**After Step 6:** For same-route dynamic segments (e.g., `/collection/[slug]`), use the `key` + `name` + `share` pattern — see [Same-Route Dynamic Segment Transitions](#same-route-dynamic-segment-transitions). --- @@ -36,7 +38,7 @@ When following `implementation.md`, apply these additions: A bare `` in layout works only if pages have **no** VTs of their own. -**Layouts persist across navigations** — `enter`/`exit` only fire on initial mount, not on route changes. Don't use type-keyed maps in layouts. +**Layouts persist across navigations** — `enter`/`exit` only fire on initial mount, not on route changes. Don't use type-keyed maps in layouts. Because layouts persist, chrome hosted in one (nav, sidebar, player) keeps its state across navigations for free — no `Activity` needed. Reserve `Activity` for in-page show/hide (see [Composing with Activity](patterns.md#composing-with-activity)). --- @@ -45,12 +47,34 @@ A bare `` in layout works only if pages have **no** VTs of their No wrapper component needed, works in Server Components: ```tsx -View Product + + View Product + ``` Replaces the manual pattern of `onNavigate` + `startTransition` + `addTransitionType` + `router.push()`. Reserve manual `startTransition` for non-link interactions (buttons, forms). -**Availability:** `transitionTypes` requires `experimental.viewTransition: true` and is available in Next.js 15+ canary builds and Next.js 16+. If unavailable, use `startTransition` + `addTransitionType` + `router.push()` (see Programmatic Navigation below). To check: `grep -r "transitionTypes" node_modules/next/dist/` — if no results, fall back to programmatic navigation. +**Availability:** `transitionTypes` shipped in **Next.js 16.2.0** (it is not gated on the `experimental.viewTransition` flag). If unavailable, use `startTransition` + `addTransitionType` + `router.push()` (see [Programmatic Navigation](#programmatic-navigation)). To check: `grep -r "transitionTypes" node_modules/next/dist/` — if no results, fall back to programmatic navigation. + +--- + +## When Content Must Be Ready + +A page transition can animate whatever Next.js renders during navigation, including a loading fallback. A shared content-to-content morph only works when the incoming content is ready as the navigation commits; content that has not rendered yet cannot form the incoming half of the pair. + +When an animation depends on dynamic destination content, use Next.js prefetching and caching to make that content available ahead of time. `` automatically prefetches in production, but the default behavior for dynamic routes may only prefetch a shell or loading boundary. Set `prefetch={true}` to prefetch the full route, and cache the data needed to render the shared content. + +```tsx + + Next + +``` + +With Cache Components, put reusable route data in a cached scope such as `use cache` so prefetching can include it. If the destination remains behind an unresolved Suspense boundary, the route transition animates the fallback instead. The content resolves in a separate Suspense transition without the original `nav-forward` or `nav-back` type, so give that content its own reveal animation when needed. + +Verify directional transitions in a production build with a cold client cache. Development mode does not run automatic `` prefetching. + +See the Next.js [View Transitions guide](https://nextjs.org/docs/app/guides/view-transitions) and [Prefetching guide](https://nextjs.org/docs/app/guides/prefetching). --- @@ -60,17 +84,20 @@ Replaces the manual pattern of `onNavigate` + `startTransition` + `addTransition 'use client'; import { useRouter } from 'next/navigation'; -import { startTransition, addTransitionType } from 'react'; -function handleNavigate(href: string) { +function DetailButton({ href }: { href: string }) { const router = useRouter(); - startTransition(() => { - addTransitionType('nav-forward'); - router.push(href); - }); + + return ( + + ); } ``` +The `transitionTypes` option adds the types inside the router's navigation Transition. Use `startTransition` + `addTransitionType` for non-navigation state updates, or as a fallback on Next.js versions without the router option. + --- ## Server-Side Filtering with `router.replace` @@ -91,7 +118,40 @@ function handleSort(sort: string) { } ``` -List items wrapped in `` will animate reorder. This is the server-component alternative to the client-side `useDeferredValue` pattern in `patterns.md`. +List items wrapped in `` will animate reorder. This is the server-component alternative to the client-side [Searchable Grid](patterns.md#searchable-grid-with-usedeferredvalue) pattern. + +--- + +## Routing-Driven Tabs + +The generalized sliding indicator ([Sliding Indicator](patterns.md#sliding-indicator-tabs)) driven by navigation instead of local state: tabs are ``s, `active` comes from the URL (a server prop), and `useOptimistic` slides the indicator instantly while the route commits. Key the mounted indicator to committed `active` so the bar lands where navigation actually settles. + +```tsx +'use client'; +import Link from 'next/link'; +import { useOptimistic, useTransition, ViewTransition } from 'react'; + +export function Tabs({ tabs, active, indicatorName = 'tab-indicator' }) { + const [optimisticActive, setOptimisticActive] = useOptimistic(active); + const [, startTransition] = useTransition(); + return ( + + ); +} +``` --- @@ -149,28 +209,34 @@ Same rules as explicit ``: use simple string props (not type maps) sin ``` +If the pair's `share` is type-keyed (or classed via CSS that expects a type), every `` between the two views must carry the type via `transitionTypes` — a plain link click resolves the share map's `default`, and if that's `none` the morph silently never fires. + --- ## Same-Route Dynamic Segment Transitions -When navigating between dynamic segments of the same route (e.g., `/collection/[slug]`), the page stays mounted — enter/exit never fire. Use `key` + `name` + `share`: +When navigating between dynamic segments of the same route (e.g., `/collection/[slug]`), the router swaps subtrees keyed by the segment value rather than doing a plain unmount/mount — enter/exit don't fire reliably. Use `key` + `name` + `share`: ```tsx }> - + ``` - `key={slug}` forces unmount/remount on change -- `name` + `share="auto"` creates a shared element crossfade +- The stable `name` pairs the outgoing and incoming containers; `share="auto"` creates the crossfade - VT inside `` (without keying Suspense) keeps old content visible during loading --- +## Nested enter/exit — `parentEnter` / `parentExit` (experimental) + +Lifts the "nested VTs don't fire enter/exit inside a parent" rule: a nested VT can animate when its **parent** enters/exits (`parentEnter`/`parentExit`, `onParentEnter`/`onParentExit`; `parentEnter="none"` stops propagation). Experimental-channel only today; SSR support landed in React PR #36917 ([commit](https://github.com/facebook/react/commit/83840902c890f0eb85decda239ef6b1b14945779)). Verify it's in the React your app runs: `grep -c "parentEnter" node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.production.js` — 0 means unavailable (Next uses the experimental channel only when `gestureTransition`/`blockingSSR`/`taint`/`transitionIndicator` is set). + ## Server Components - `` works in both Server and Client Components - `` works in Server Components — no `'use client'` needed -- `addTransitionType` and `startTransition` for programmatic nav require Client Components +- `router.push(..., { transitionTypes })`, `addTransitionType`, and `startTransition` require Client Components diff --git a/plugins/react/.agents/skills/vercel-react-view-transitions/references/patterns.md b/plugins/react/.agents/skills/vercel-react-view-transitions/references/patterns.md index 6919ea4a..23bc102a 100644 --- a/plugins/react/.agents/skills/vercel-react-view-transitions/references/patterns.md +++ b/plugins/react/.agents/skills/vercel-react-view-transitions/references/patterns.md @@ -114,38 +114,74 @@ Use `key` when content identity changes (state resets). Omit for cross-fades (ta ## Isolate Elements from Parent Animations -### Persistent Layout Elements +Pull an element out of the animated `root` snapshot by giving it its own `view-transition-name`. **`view-transition-name: none` is a no-op** — it's the CSS default, so the element stays in `root` (a common flicker bug). Use a real, unique name, then neutralize with `` (no CSS) or CSS (needed for `z-index`/`display` control — see [css-recipes.md](css-recipes.md#persistent-element-isolation)). -Persistent elements (headers, navbars, sidebars) get captured in the page's transition snapshot. Fix with `viewTransitionName`: +- **Persistent chrome** (nav, sidebar, player bar): `