add-skill 1.0.3 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -8
- package/package.json +3 -2
- package/.claude/skills/vercel-deploy/SKILL.md +0 -109
- package/.claude/skills/vercel-deploy/scripts/deploy.sh +0 -249
- package/.codex/skills/vercel-deploy/SKILL.md +0 -109
- package/.codex/skills/vercel-deploy/scripts/deploy.sh +0 -249
- package/.opencode/skill/vercel-deploy/SKILL.md +0 -109
- package/.opencode/skill/vercel-deploy/scripts/deploy.sh +0 -249
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Install agent skills onto your coding agents from any git repository.
|
|
4
4
|
|
|
5
|
-
Supports [OpenCode](https://opencode.ai), [Claude Code](https://claude.ai/code),
|
|
5
|
+
Supports [OpenCode](https://opencode.ai), [Claude Code](https://claude.ai/code), [Codex](https://developers.openai.com/codex), and [Cursor](https://cursor.com).
|
|
6
6
|
|
|
7
7
|
## Quick Start
|
|
8
8
|
|
|
@@ -47,7 +47,7 @@ npx add-skill git@github.com:vercel-labs/agent-skills.git
|
|
|
47
47
|
| Option | Description |
|
|
48
48
|
|--------|-------------|
|
|
49
49
|
| `-g, --global` | Install to user directory instead of project |
|
|
50
|
-
| `-a, --agent <agents...>` | Target specific agents: `opencode`, `claude-code`, `codex` |
|
|
50
|
+
| `-a, --agent <agents...>` | Target specific agents: `opencode`, `claude-code`, `codex`, `cursor` |
|
|
51
51
|
| `-s, --skill <skills...>` | Install specific skills by name |
|
|
52
52
|
| `-l, --list` | List available skills without installing |
|
|
53
53
|
| `-y, --yes` | Skip all confirmation prompts |
|
|
@@ -86,6 +86,7 @@ Installed in your current working directory. Commit these to share with your tea
|
|
|
86
86
|
| OpenCode | `.opencode/skill/<name>/` |
|
|
87
87
|
| Claude Code | `.claude/skills/<name>/` |
|
|
88
88
|
| Codex | `.codex/skills/<name>/` |
|
|
89
|
+
| Cursor | `.cursor/skills/<name>/` |
|
|
89
90
|
|
|
90
91
|
### Global (`--global`)
|
|
91
92
|
|
|
@@ -96,6 +97,7 @@ Installed in your home directory. Available across all projects.
|
|
|
96
97
|
| OpenCode | `~/.config/opencode/skill/<name>/` |
|
|
97
98
|
| Claude Code | `~/.claude/skills/<name>/` |
|
|
98
99
|
| Codex | `~/.codex/skills/<name>/` |
|
|
100
|
+
| Cursor | `~/.cursor/skills/<name>/` |
|
|
99
101
|
|
|
100
102
|
## Agent Detection
|
|
101
103
|
|
|
@@ -142,6 +144,7 @@ The CLI searches for skills in these locations within a repository:
|
|
|
142
144
|
- `.codex/skills/`
|
|
143
145
|
- `.claude/skills/`
|
|
144
146
|
- `.opencode/skill/`
|
|
147
|
+
- `.cursor/skills/`
|
|
145
148
|
|
|
146
149
|
If no skills are found in standard locations, a recursive search is performed.
|
|
147
150
|
|
|
@@ -149,12 +152,12 @@ If no skills are found in standard locations, a recursive search is performed.
|
|
|
149
152
|
|
|
150
153
|
Skills are generally compatible across agents since they follow a shared [Agent Skills specification](https://agentskills.io). However, some features may be agent-specific:
|
|
151
154
|
|
|
152
|
-
| Feature | OpenCode | Claude Code | Codex |
|
|
153
|
-
|
|
154
|
-
| Basic skills | Yes | Yes | Yes |
|
|
155
|
-
| `allowed-tools` | Yes | Yes | Yes |
|
|
156
|
-
| `context: fork` | No | Yes | No |
|
|
157
|
-
| Hooks | No | Yes | No |
|
|
155
|
+
| Feature | OpenCode | Claude Code | Codex | Cursor |
|
|
156
|
+
|---------|----------|-------------|-------|--------|
|
|
157
|
+
| Basic skills | Yes | Yes | Yes | Yes |
|
|
158
|
+
| `allowed-tools` | Yes | Yes | Yes | Yes |
|
|
159
|
+
| `context: fork` | No | Yes | No | No |
|
|
160
|
+
| Hooks | No | Yes | No | No |
|
|
158
161
|
|
|
159
162
|
## Troubleshooting
|
|
160
163
|
|
|
@@ -179,6 +182,7 @@ Ensure you have write access to the target directory.
|
|
|
179
182
|
- [OpenCode Skills Documentation](https://opencode.ai/docs/skills/)
|
|
180
183
|
- [Claude Code Skills Documentation](https://code.claude.com/docs/en/skills)
|
|
181
184
|
- [Codex Skills Documentation](https://developers.openai.com/codex/skills/)
|
|
185
|
+
- [Cursor Skills Documentation](https://cursor.com/docs/context/skills)
|
|
182
186
|
|
|
183
187
|
## License
|
|
184
188
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "add-skill",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Install agent skills onto coding agents (OpenCode, Claude Code, Codex)",
|
|
3
|
+
"version": "1.0.4",
|
|
4
|
+
"description": "Install agent skills onto coding agents (OpenCode, Claude Code, Codex, Cursor)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"add-skill": "./dist/index.js"
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
"opencode",
|
|
18
18
|
"claude-code",
|
|
19
19
|
"codex",
|
|
20
|
+
"cursor",
|
|
20
21
|
"ai-agents"
|
|
21
22
|
],
|
|
22
23
|
"author": "",
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: vercel-deploy
|
|
3
|
-
description: Deploy applications and websites to Vercel. Use this skill when the user requests deployment actions such as "Deploy my app", "Deploy this to production", "Create a preview deployment", "Deploy and give me the link", or "Push this live". No authentication required - returns preview URL and claimable deployment link.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Vercel Deploy
|
|
7
|
-
|
|
8
|
-
Deploy any project to Vercel instantly. No authentication required.
|
|
9
|
-
|
|
10
|
-
## How It Works
|
|
11
|
-
|
|
12
|
-
1. Packages your project into a tarball (excludes `node_modules` and `.git`)
|
|
13
|
-
2. Auto-detects framework from `package.json`
|
|
14
|
-
3. Uploads to deployment service
|
|
15
|
-
4. Returns **Preview URL** (live site) and **Claim URL** (transfer to your Vercel account)
|
|
16
|
-
|
|
17
|
-
## Usage
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
bash /mnt/skills/user/vercel-deploy/scripts/deploy.sh [path]
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
**Arguments:**
|
|
24
|
-
- `path` - Directory to deploy, or a `.tgz` file (defaults to current directory)
|
|
25
|
-
|
|
26
|
-
**Examples:**
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
# Deploy current directory
|
|
30
|
-
bash /mnt/skills/user/vercel-deploy/scripts/deploy.sh
|
|
31
|
-
|
|
32
|
-
# Deploy specific project
|
|
33
|
-
bash /mnt/skills/user/vercel-deploy/scripts/deploy.sh /path/to/project
|
|
34
|
-
|
|
35
|
-
# Deploy existing tarball
|
|
36
|
-
bash /mnt/skills/user/vercel-deploy/scripts/deploy.sh /path/to/project.tgz
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
## Output
|
|
40
|
-
|
|
41
|
-
```
|
|
42
|
-
Preparing deployment...
|
|
43
|
-
Detected framework: nextjs
|
|
44
|
-
Creating deployment package...
|
|
45
|
-
Deploying...
|
|
46
|
-
✓ Deployment successful!
|
|
47
|
-
|
|
48
|
-
Preview URL: https://skill-deploy-abc123.vercel.app
|
|
49
|
-
Claim URL: https://vercel.com/claim-deployment?code=...
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
The script also outputs JSON to stdout for programmatic use:
|
|
53
|
-
|
|
54
|
-
```json
|
|
55
|
-
{
|
|
56
|
-
"previewUrl": "https://skill-deploy-abc123.vercel.app",
|
|
57
|
-
"claimUrl": "https://vercel.com/claim-deployment?code=...",
|
|
58
|
-
"deploymentId": "dpl_...",
|
|
59
|
-
"projectId": "prj_..."
|
|
60
|
-
}
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
## Framework Detection
|
|
64
|
-
|
|
65
|
-
The script auto-detects frameworks from `package.json`. Supported frameworks include:
|
|
66
|
-
|
|
67
|
-
- **React**: Next.js, Gatsby, Create React App, Remix, React Router
|
|
68
|
-
- **Vue**: Nuxt, Vitepress, Vuepress, Gridsome
|
|
69
|
-
- **Svelte**: SvelteKit, Svelte, Sapper
|
|
70
|
-
- **Other Frontend**: Astro, Solid Start, Angular, Ember, Preact, Docusaurus
|
|
71
|
-
- **Backend**: Express, Hono, Fastify, NestJS, Elysia, h3, Nitro
|
|
72
|
-
- **Build Tools**: Vite, Parcel
|
|
73
|
-
- **And more**: Blitz, Hydrogen, RedwoodJS, Storybook, Sanity, etc.
|
|
74
|
-
|
|
75
|
-
For static HTML projects (no `package.json`), framework is set to `null`.
|
|
76
|
-
|
|
77
|
-
## Static HTML Projects
|
|
78
|
-
|
|
79
|
-
For projects without a `package.json`:
|
|
80
|
-
- If there's a single `.html` file not named `index.html`, it gets renamed automatically
|
|
81
|
-
- This ensures the page is served at the root URL (`/`)
|
|
82
|
-
|
|
83
|
-
## Present Results to User
|
|
84
|
-
|
|
85
|
-
Always show both URLs:
|
|
86
|
-
|
|
87
|
-
```
|
|
88
|
-
✓ Deployment successful!
|
|
89
|
-
|
|
90
|
-
Preview URL: https://skill-deploy-abc123.vercel.app
|
|
91
|
-
Claim URL: https://vercel.com/claim-deployment?code=...
|
|
92
|
-
|
|
93
|
-
View your site at the Preview URL.
|
|
94
|
-
To transfer this deployment to your Vercel account, visit the Claim URL.
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
## Troubleshooting
|
|
98
|
-
|
|
99
|
-
### Network Egress Error
|
|
100
|
-
|
|
101
|
-
If deployment fails due to network restrictions (common on claude.ai), tell the user:
|
|
102
|
-
|
|
103
|
-
```
|
|
104
|
-
Deployment failed due to network restrictions. To fix this:
|
|
105
|
-
|
|
106
|
-
1. Go to https://claude.ai/admin-settings/capabilities
|
|
107
|
-
2. Add *.vercel.com to the allowed domains
|
|
108
|
-
3. Try deploying again
|
|
109
|
-
```
|
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
# Vercel Deployment Script (via claimable deploy endpoint)
|
|
4
|
-
# Usage: ./deploy.sh [project-path]
|
|
5
|
-
# Returns: JSON with previewUrl, claimUrl, deploymentId, projectId
|
|
6
|
-
|
|
7
|
-
set -e
|
|
8
|
-
|
|
9
|
-
DEPLOY_ENDPOINT="https://claude-skills-deploy.vercel.com/api/deploy"
|
|
10
|
-
|
|
11
|
-
# Detect framework from package.json
|
|
12
|
-
detect_framework() {
|
|
13
|
-
local pkg_json="$1"
|
|
14
|
-
|
|
15
|
-
if [ ! -f "$pkg_json" ]; then
|
|
16
|
-
echo "null"
|
|
17
|
-
return
|
|
18
|
-
fi
|
|
19
|
-
|
|
20
|
-
local content=$(cat "$pkg_json")
|
|
21
|
-
|
|
22
|
-
# Helper to check if a package exists in dependencies or devDependencies
|
|
23
|
-
has_dep() {
|
|
24
|
-
echo "$content" | grep -q "\"$1\""
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
# Order matters - check more specific frameworks first
|
|
28
|
-
|
|
29
|
-
# Blitz
|
|
30
|
-
if has_dep "blitz"; then echo "blitzjs"; return; fi
|
|
31
|
-
|
|
32
|
-
# Next.js
|
|
33
|
-
if has_dep "next"; then echo "nextjs"; return; fi
|
|
34
|
-
|
|
35
|
-
# Gatsby
|
|
36
|
-
if has_dep "gatsby"; then echo "gatsby"; return; fi
|
|
37
|
-
|
|
38
|
-
# Remix
|
|
39
|
-
if has_dep "@remix-run/"; then echo "remix"; return; fi
|
|
40
|
-
|
|
41
|
-
# React Router (v7 framework mode)
|
|
42
|
-
if has_dep "@react-router/"; then echo "react-router"; return; fi
|
|
43
|
-
|
|
44
|
-
# TanStack Start
|
|
45
|
-
if has_dep "@tanstack/start"; then echo "tanstack-start"; return; fi
|
|
46
|
-
|
|
47
|
-
# Astro
|
|
48
|
-
if has_dep "astro"; then echo "astro"; return; fi
|
|
49
|
-
|
|
50
|
-
# Hydrogen (Shopify)
|
|
51
|
-
if has_dep "@shopify/hydrogen"; then echo "hydrogen"; return; fi
|
|
52
|
-
|
|
53
|
-
# SvelteKit
|
|
54
|
-
if has_dep "@sveltejs/kit"; then echo "sveltekit-1"; return; fi
|
|
55
|
-
|
|
56
|
-
# Svelte (standalone)
|
|
57
|
-
if has_dep "svelte"; then echo "svelte"; return; fi
|
|
58
|
-
|
|
59
|
-
# Nuxt
|
|
60
|
-
if has_dep "nuxt"; then echo "nuxtjs"; return; fi
|
|
61
|
-
|
|
62
|
-
# Vue with Vitepress
|
|
63
|
-
if has_dep "vitepress"; then echo "vitepress"; return; fi
|
|
64
|
-
|
|
65
|
-
# Vue with Vuepress
|
|
66
|
-
if has_dep "vuepress"; then echo "vuepress"; return; fi
|
|
67
|
-
|
|
68
|
-
# Gridsome
|
|
69
|
-
if has_dep "gridsome"; then echo "gridsome"; return; fi
|
|
70
|
-
|
|
71
|
-
# SolidStart
|
|
72
|
-
if has_dep "@solidjs/start"; then echo "solidstart-1"; return; fi
|
|
73
|
-
|
|
74
|
-
# Docusaurus
|
|
75
|
-
if has_dep "@docusaurus/core"; then echo "docusaurus-2"; return; fi
|
|
76
|
-
|
|
77
|
-
# RedwoodJS
|
|
78
|
-
if has_dep "@redwoodjs/"; then echo "redwoodjs"; return; fi
|
|
79
|
-
|
|
80
|
-
# Hexo
|
|
81
|
-
if has_dep "hexo"; then echo "hexo"; return; fi
|
|
82
|
-
|
|
83
|
-
# Eleventy
|
|
84
|
-
if has_dep "@11ty/eleventy"; then echo "eleventy"; return; fi
|
|
85
|
-
|
|
86
|
-
# Angular / Ionic Angular
|
|
87
|
-
if has_dep "@ionic/angular"; then echo "ionic-angular"; return; fi
|
|
88
|
-
if has_dep "@angular/core"; then echo "angular"; return; fi
|
|
89
|
-
|
|
90
|
-
# Ionic React
|
|
91
|
-
if has_dep "@ionic/react"; then echo "ionic-react"; return; fi
|
|
92
|
-
|
|
93
|
-
# Create React App
|
|
94
|
-
if has_dep "react-scripts"; then echo "create-react-app"; return; fi
|
|
95
|
-
|
|
96
|
-
# Ember
|
|
97
|
-
if has_dep "ember-cli" || has_dep "ember-source"; then echo "ember"; return; fi
|
|
98
|
-
|
|
99
|
-
# Dojo
|
|
100
|
-
if has_dep "@dojo/framework"; then echo "dojo"; return; fi
|
|
101
|
-
|
|
102
|
-
# Polymer
|
|
103
|
-
if has_dep "@polymer/"; then echo "polymer"; return; fi
|
|
104
|
-
|
|
105
|
-
# Preact
|
|
106
|
-
if has_dep "preact"; then echo "preact"; return; fi
|
|
107
|
-
|
|
108
|
-
# Stencil
|
|
109
|
-
if has_dep "@stencil/core"; then echo "stencil"; return; fi
|
|
110
|
-
|
|
111
|
-
# UmiJS
|
|
112
|
-
if has_dep "umi"; then echo "umijs"; return; fi
|
|
113
|
-
|
|
114
|
-
# Sapper (legacy Svelte)
|
|
115
|
-
if has_dep "sapper"; then echo "sapper"; return; fi
|
|
116
|
-
|
|
117
|
-
# Saber
|
|
118
|
-
if has_dep "saber"; then echo "saber"; return; fi
|
|
119
|
-
|
|
120
|
-
# Sanity
|
|
121
|
-
if has_dep "sanity"; then echo "sanity-v3"; return; fi
|
|
122
|
-
if has_dep "@sanity/"; then echo "sanity"; return; fi
|
|
123
|
-
|
|
124
|
-
# Storybook
|
|
125
|
-
if has_dep "@storybook/"; then echo "storybook"; return; fi
|
|
126
|
-
|
|
127
|
-
# NestJS
|
|
128
|
-
if has_dep "@nestjs/core"; then echo "nestjs"; return; fi
|
|
129
|
-
|
|
130
|
-
# Elysia
|
|
131
|
-
if has_dep "elysia"; then echo "elysia"; return; fi
|
|
132
|
-
|
|
133
|
-
# Hono
|
|
134
|
-
if has_dep "hono"; then echo "hono"; return; fi
|
|
135
|
-
|
|
136
|
-
# Fastify
|
|
137
|
-
if has_dep "fastify"; then echo "fastify"; return; fi
|
|
138
|
-
|
|
139
|
-
# h3
|
|
140
|
-
if has_dep "h3"; then echo "h3"; return; fi
|
|
141
|
-
|
|
142
|
-
# Nitro
|
|
143
|
-
if has_dep "nitropack"; then echo "nitro"; return; fi
|
|
144
|
-
|
|
145
|
-
# Express
|
|
146
|
-
if has_dep "express"; then echo "express"; return; fi
|
|
147
|
-
|
|
148
|
-
# Vite (generic - check last among JS frameworks)
|
|
149
|
-
if has_dep "vite"; then echo "vite"; return; fi
|
|
150
|
-
|
|
151
|
-
# Parcel
|
|
152
|
-
if has_dep "parcel"; then echo "parcel"; return; fi
|
|
153
|
-
|
|
154
|
-
# No framework detected
|
|
155
|
-
echo "null"
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
# Parse arguments
|
|
159
|
-
INPUT_PATH="${1:-.}"
|
|
160
|
-
|
|
161
|
-
# Create temp directory for packaging
|
|
162
|
-
TEMP_DIR=$(mktemp -d)
|
|
163
|
-
TARBALL="$TEMP_DIR/project.tgz"
|
|
164
|
-
CLEANUP_TEMP=true
|
|
165
|
-
|
|
166
|
-
cleanup() {
|
|
167
|
-
if [ "$CLEANUP_TEMP" = true ]; then
|
|
168
|
-
rm -rf "$TEMP_DIR"
|
|
169
|
-
fi
|
|
170
|
-
}
|
|
171
|
-
trap cleanup EXIT
|
|
172
|
-
|
|
173
|
-
echo "Preparing deployment..." >&2
|
|
174
|
-
|
|
175
|
-
# Check if input is a .tgz file or a directory
|
|
176
|
-
FRAMEWORK="null"
|
|
177
|
-
|
|
178
|
-
if [ -f "$INPUT_PATH" ] && [[ "$INPUT_PATH" == *.tgz ]]; then
|
|
179
|
-
# Input is already a tarball, use it directly
|
|
180
|
-
echo "Using provided tarball..." >&2
|
|
181
|
-
TARBALL="$INPUT_PATH"
|
|
182
|
-
CLEANUP_TEMP=false
|
|
183
|
-
# Can't detect framework from tarball, leave as null
|
|
184
|
-
elif [ -d "$INPUT_PATH" ]; then
|
|
185
|
-
# Input is a directory, need to tar it
|
|
186
|
-
PROJECT_PATH=$(cd "$INPUT_PATH" && pwd)
|
|
187
|
-
|
|
188
|
-
# Detect framework from package.json
|
|
189
|
-
FRAMEWORK=$(detect_framework "$PROJECT_PATH/package.json")
|
|
190
|
-
|
|
191
|
-
# Check if this is a static HTML project (no package.json)
|
|
192
|
-
if [ ! -f "$PROJECT_PATH/package.json" ]; then
|
|
193
|
-
# Find HTML files in root
|
|
194
|
-
HTML_FILES=$(find "$PROJECT_PATH" -maxdepth 1 -name "*.html" -type f)
|
|
195
|
-
HTML_COUNT=$(echo "$HTML_FILES" | grep -c . || echo 0)
|
|
196
|
-
|
|
197
|
-
# If there's exactly one HTML file and it's not index.html, rename it
|
|
198
|
-
if [ "$HTML_COUNT" -eq 1 ]; then
|
|
199
|
-
HTML_FILE=$(echo "$HTML_FILES" | head -1)
|
|
200
|
-
BASENAME=$(basename "$HTML_FILE")
|
|
201
|
-
if [ "$BASENAME" != "index.html" ]; then
|
|
202
|
-
echo "Renaming $BASENAME to index.html..." >&2
|
|
203
|
-
mv "$HTML_FILE" "$PROJECT_PATH/index.html"
|
|
204
|
-
fi
|
|
205
|
-
fi
|
|
206
|
-
fi
|
|
207
|
-
|
|
208
|
-
# Create tarball of the project (excluding node_modules and .git)
|
|
209
|
-
echo "Creating deployment package..." >&2
|
|
210
|
-
tar -czf "$TARBALL" -C "$PROJECT_PATH" --exclude='node_modules' --exclude='.git' .
|
|
211
|
-
else
|
|
212
|
-
echo "Error: Input must be a directory or a .tgz file" >&2
|
|
213
|
-
exit 1
|
|
214
|
-
fi
|
|
215
|
-
|
|
216
|
-
if [ "$FRAMEWORK" != "null" ]; then
|
|
217
|
-
echo "Detected framework: $FRAMEWORK" >&2
|
|
218
|
-
fi
|
|
219
|
-
|
|
220
|
-
# Deploy
|
|
221
|
-
echo "Deploying..." >&2
|
|
222
|
-
RESPONSE=$(curl -s -X POST "$DEPLOY_ENDPOINT" -F "file=@$TARBALL" -F "framework=$FRAMEWORK")
|
|
223
|
-
|
|
224
|
-
# Check for error in response
|
|
225
|
-
if echo "$RESPONSE" | grep -q '"error"'; then
|
|
226
|
-
ERROR_MSG=$(echo "$RESPONSE" | grep -o '"error":"[^"]*"' | cut -d'"' -f4)
|
|
227
|
-
echo "Error: $ERROR_MSG" >&2
|
|
228
|
-
exit 1
|
|
229
|
-
fi
|
|
230
|
-
|
|
231
|
-
# Extract URLs from response
|
|
232
|
-
PREVIEW_URL=$(echo "$RESPONSE" | grep -o '"previewUrl":"[^"]*"' | cut -d'"' -f4)
|
|
233
|
-
CLAIM_URL=$(echo "$RESPONSE" | grep -o '"claimUrl":"[^"]*"' | cut -d'"' -f4)
|
|
234
|
-
|
|
235
|
-
if [ -z "$PREVIEW_URL" ]; then
|
|
236
|
-
echo "Error: Could not extract preview URL from response" >&2
|
|
237
|
-
echo "$RESPONSE" >&2
|
|
238
|
-
exit 1
|
|
239
|
-
fi
|
|
240
|
-
|
|
241
|
-
echo "" >&2
|
|
242
|
-
echo "Deployment successful!" >&2
|
|
243
|
-
echo "" >&2
|
|
244
|
-
echo "Preview URL: $PREVIEW_URL" >&2
|
|
245
|
-
echo "Claim URL: $CLAIM_URL" >&2
|
|
246
|
-
echo "" >&2
|
|
247
|
-
|
|
248
|
-
# Output JSON for programmatic use
|
|
249
|
-
echo "$RESPONSE"
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: vercel-deploy
|
|
3
|
-
description: Deploy applications and websites to Vercel. Use this skill when the user requests deployment actions such as "Deploy my app", "Deploy this to production", "Create a preview deployment", "Deploy and give me the link", or "Push this live". No authentication required - returns preview URL and claimable deployment link.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Vercel Deploy
|
|
7
|
-
|
|
8
|
-
Deploy any project to Vercel instantly. No authentication required.
|
|
9
|
-
|
|
10
|
-
## How It Works
|
|
11
|
-
|
|
12
|
-
1. Packages your project into a tarball (excludes `node_modules` and `.git`)
|
|
13
|
-
2. Auto-detects framework from `package.json`
|
|
14
|
-
3. Uploads to deployment service
|
|
15
|
-
4. Returns **Preview URL** (live site) and **Claim URL** (transfer to your Vercel account)
|
|
16
|
-
|
|
17
|
-
## Usage
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
bash /mnt/skills/user/vercel-deploy/scripts/deploy.sh [path]
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
**Arguments:**
|
|
24
|
-
- `path` - Directory to deploy, or a `.tgz` file (defaults to current directory)
|
|
25
|
-
|
|
26
|
-
**Examples:**
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
# Deploy current directory
|
|
30
|
-
bash /mnt/skills/user/vercel-deploy/scripts/deploy.sh
|
|
31
|
-
|
|
32
|
-
# Deploy specific project
|
|
33
|
-
bash /mnt/skills/user/vercel-deploy/scripts/deploy.sh /path/to/project
|
|
34
|
-
|
|
35
|
-
# Deploy existing tarball
|
|
36
|
-
bash /mnt/skills/user/vercel-deploy/scripts/deploy.sh /path/to/project.tgz
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
## Output
|
|
40
|
-
|
|
41
|
-
```
|
|
42
|
-
Preparing deployment...
|
|
43
|
-
Detected framework: nextjs
|
|
44
|
-
Creating deployment package...
|
|
45
|
-
Deploying...
|
|
46
|
-
✓ Deployment successful!
|
|
47
|
-
|
|
48
|
-
Preview URL: https://skill-deploy-abc123.vercel.app
|
|
49
|
-
Claim URL: https://vercel.com/claim-deployment?code=...
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
The script also outputs JSON to stdout for programmatic use:
|
|
53
|
-
|
|
54
|
-
```json
|
|
55
|
-
{
|
|
56
|
-
"previewUrl": "https://skill-deploy-abc123.vercel.app",
|
|
57
|
-
"claimUrl": "https://vercel.com/claim-deployment?code=...",
|
|
58
|
-
"deploymentId": "dpl_...",
|
|
59
|
-
"projectId": "prj_..."
|
|
60
|
-
}
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
## Framework Detection
|
|
64
|
-
|
|
65
|
-
The script auto-detects frameworks from `package.json`. Supported frameworks include:
|
|
66
|
-
|
|
67
|
-
- **React**: Next.js, Gatsby, Create React App, Remix, React Router
|
|
68
|
-
- **Vue**: Nuxt, Vitepress, Vuepress, Gridsome
|
|
69
|
-
- **Svelte**: SvelteKit, Svelte, Sapper
|
|
70
|
-
- **Other Frontend**: Astro, Solid Start, Angular, Ember, Preact, Docusaurus
|
|
71
|
-
- **Backend**: Express, Hono, Fastify, NestJS, Elysia, h3, Nitro
|
|
72
|
-
- **Build Tools**: Vite, Parcel
|
|
73
|
-
- **And more**: Blitz, Hydrogen, RedwoodJS, Storybook, Sanity, etc.
|
|
74
|
-
|
|
75
|
-
For static HTML projects (no `package.json`), framework is set to `null`.
|
|
76
|
-
|
|
77
|
-
## Static HTML Projects
|
|
78
|
-
|
|
79
|
-
For projects without a `package.json`:
|
|
80
|
-
- If there's a single `.html` file not named `index.html`, it gets renamed automatically
|
|
81
|
-
- This ensures the page is served at the root URL (`/`)
|
|
82
|
-
|
|
83
|
-
## Present Results to User
|
|
84
|
-
|
|
85
|
-
Always show both URLs:
|
|
86
|
-
|
|
87
|
-
```
|
|
88
|
-
✓ Deployment successful!
|
|
89
|
-
|
|
90
|
-
Preview URL: https://skill-deploy-abc123.vercel.app
|
|
91
|
-
Claim URL: https://vercel.com/claim-deployment?code=...
|
|
92
|
-
|
|
93
|
-
View your site at the Preview URL.
|
|
94
|
-
To transfer this deployment to your Vercel account, visit the Claim URL.
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
## Troubleshooting
|
|
98
|
-
|
|
99
|
-
### Network Egress Error
|
|
100
|
-
|
|
101
|
-
If deployment fails due to network restrictions (common on claude.ai), tell the user:
|
|
102
|
-
|
|
103
|
-
```
|
|
104
|
-
Deployment failed due to network restrictions. To fix this:
|
|
105
|
-
|
|
106
|
-
1. Go to https://claude.ai/admin-settings/capabilities
|
|
107
|
-
2. Add *.vercel.com to the allowed domains
|
|
108
|
-
3. Try deploying again
|
|
109
|
-
```
|
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
# Vercel Deployment Script (via claimable deploy endpoint)
|
|
4
|
-
# Usage: ./deploy.sh [project-path]
|
|
5
|
-
# Returns: JSON with previewUrl, claimUrl, deploymentId, projectId
|
|
6
|
-
|
|
7
|
-
set -e
|
|
8
|
-
|
|
9
|
-
DEPLOY_ENDPOINT="https://claude-skills-deploy.vercel.com/api/deploy"
|
|
10
|
-
|
|
11
|
-
# Detect framework from package.json
|
|
12
|
-
detect_framework() {
|
|
13
|
-
local pkg_json="$1"
|
|
14
|
-
|
|
15
|
-
if [ ! -f "$pkg_json" ]; then
|
|
16
|
-
echo "null"
|
|
17
|
-
return
|
|
18
|
-
fi
|
|
19
|
-
|
|
20
|
-
local content=$(cat "$pkg_json")
|
|
21
|
-
|
|
22
|
-
# Helper to check if a package exists in dependencies or devDependencies
|
|
23
|
-
has_dep() {
|
|
24
|
-
echo "$content" | grep -q "\"$1\""
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
# Order matters - check more specific frameworks first
|
|
28
|
-
|
|
29
|
-
# Blitz
|
|
30
|
-
if has_dep "blitz"; then echo "blitzjs"; return; fi
|
|
31
|
-
|
|
32
|
-
# Next.js
|
|
33
|
-
if has_dep "next"; then echo "nextjs"; return; fi
|
|
34
|
-
|
|
35
|
-
# Gatsby
|
|
36
|
-
if has_dep "gatsby"; then echo "gatsby"; return; fi
|
|
37
|
-
|
|
38
|
-
# Remix
|
|
39
|
-
if has_dep "@remix-run/"; then echo "remix"; return; fi
|
|
40
|
-
|
|
41
|
-
# React Router (v7 framework mode)
|
|
42
|
-
if has_dep "@react-router/"; then echo "react-router"; return; fi
|
|
43
|
-
|
|
44
|
-
# TanStack Start
|
|
45
|
-
if has_dep "@tanstack/start"; then echo "tanstack-start"; return; fi
|
|
46
|
-
|
|
47
|
-
# Astro
|
|
48
|
-
if has_dep "astro"; then echo "astro"; return; fi
|
|
49
|
-
|
|
50
|
-
# Hydrogen (Shopify)
|
|
51
|
-
if has_dep "@shopify/hydrogen"; then echo "hydrogen"; return; fi
|
|
52
|
-
|
|
53
|
-
# SvelteKit
|
|
54
|
-
if has_dep "@sveltejs/kit"; then echo "sveltekit-1"; return; fi
|
|
55
|
-
|
|
56
|
-
# Svelte (standalone)
|
|
57
|
-
if has_dep "svelte"; then echo "svelte"; return; fi
|
|
58
|
-
|
|
59
|
-
# Nuxt
|
|
60
|
-
if has_dep "nuxt"; then echo "nuxtjs"; return; fi
|
|
61
|
-
|
|
62
|
-
# Vue with Vitepress
|
|
63
|
-
if has_dep "vitepress"; then echo "vitepress"; return; fi
|
|
64
|
-
|
|
65
|
-
# Vue with Vuepress
|
|
66
|
-
if has_dep "vuepress"; then echo "vuepress"; return; fi
|
|
67
|
-
|
|
68
|
-
# Gridsome
|
|
69
|
-
if has_dep "gridsome"; then echo "gridsome"; return; fi
|
|
70
|
-
|
|
71
|
-
# SolidStart
|
|
72
|
-
if has_dep "@solidjs/start"; then echo "solidstart-1"; return; fi
|
|
73
|
-
|
|
74
|
-
# Docusaurus
|
|
75
|
-
if has_dep "@docusaurus/core"; then echo "docusaurus-2"; return; fi
|
|
76
|
-
|
|
77
|
-
# RedwoodJS
|
|
78
|
-
if has_dep "@redwoodjs/"; then echo "redwoodjs"; return; fi
|
|
79
|
-
|
|
80
|
-
# Hexo
|
|
81
|
-
if has_dep "hexo"; then echo "hexo"; return; fi
|
|
82
|
-
|
|
83
|
-
# Eleventy
|
|
84
|
-
if has_dep "@11ty/eleventy"; then echo "eleventy"; return; fi
|
|
85
|
-
|
|
86
|
-
# Angular / Ionic Angular
|
|
87
|
-
if has_dep "@ionic/angular"; then echo "ionic-angular"; return; fi
|
|
88
|
-
if has_dep "@angular/core"; then echo "angular"; return; fi
|
|
89
|
-
|
|
90
|
-
# Ionic React
|
|
91
|
-
if has_dep "@ionic/react"; then echo "ionic-react"; return; fi
|
|
92
|
-
|
|
93
|
-
# Create React App
|
|
94
|
-
if has_dep "react-scripts"; then echo "create-react-app"; return; fi
|
|
95
|
-
|
|
96
|
-
# Ember
|
|
97
|
-
if has_dep "ember-cli" || has_dep "ember-source"; then echo "ember"; return; fi
|
|
98
|
-
|
|
99
|
-
# Dojo
|
|
100
|
-
if has_dep "@dojo/framework"; then echo "dojo"; return; fi
|
|
101
|
-
|
|
102
|
-
# Polymer
|
|
103
|
-
if has_dep "@polymer/"; then echo "polymer"; return; fi
|
|
104
|
-
|
|
105
|
-
# Preact
|
|
106
|
-
if has_dep "preact"; then echo "preact"; return; fi
|
|
107
|
-
|
|
108
|
-
# Stencil
|
|
109
|
-
if has_dep "@stencil/core"; then echo "stencil"; return; fi
|
|
110
|
-
|
|
111
|
-
# UmiJS
|
|
112
|
-
if has_dep "umi"; then echo "umijs"; return; fi
|
|
113
|
-
|
|
114
|
-
# Sapper (legacy Svelte)
|
|
115
|
-
if has_dep "sapper"; then echo "sapper"; return; fi
|
|
116
|
-
|
|
117
|
-
# Saber
|
|
118
|
-
if has_dep "saber"; then echo "saber"; return; fi
|
|
119
|
-
|
|
120
|
-
# Sanity
|
|
121
|
-
if has_dep "sanity"; then echo "sanity-v3"; return; fi
|
|
122
|
-
if has_dep "@sanity/"; then echo "sanity"; return; fi
|
|
123
|
-
|
|
124
|
-
# Storybook
|
|
125
|
-
if has_dep "@storybook/"; then echo "storybook"; return; fi
|
|
126
|
-
|
|
127
|
-
# NestJS
|
|
128
|
-
if has_dep "@nestjs/core"; then echo "nestjs"; return; fi
|
|
129
|
-
|
|
130
|
-
# Elysia
|
|
131
|
-
if has_dep "elysia"; then echo "elysia"; return; fi
|
|
132
|
-
|
|
133
|
-
# Hono
|
|
134
|
-
if has_dep "hono"; then echo "hono"; return; fi
|
|
135
|
-
|
|
136
|
-
# Fastify
|
|
137
|
-
if has_dep "fastify"; then echo "fastify"; return; fi
|
|
138
|
-
|
|
139
|
-
# h3
|
|
140
|
-
if has_dep "h3"; then echo "h3"; return; fi
|
|
141
|
-
|
|
142
|
-
# Nitro
|
|
143
|
-
if has_dep "nitropack"; then echo "nitro"; return; fi
|
|
144
|
-
|
|
145
|
-
# Express
|
|
146
|
-
if has_dep "express"; then echo "express"; return; fi
|
|
147
|
-
|
|
148
|
-
# Vite (generic - check last among JS frameworks)
|
|
149
|
-
if has_dep "vite"; then echo "vite"; return; fi
|
|
150
|
-
|
|
151
|
-
# Parcel
|
|
152
|
-
if has_dep "parcel"; then echo "parcel"; return; fi
|
|
153
|
-
|
|
154
|
-
# No framework detected
|
|
155
|
-
echo "null"
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
# Parse arguments
|
|
159
|
-
INPUT_PATH="${1:-.}"
|
|
160
|
-
|
|
161
|
-
# Create temp directory for packaging
|
|
162
|
-
TEMP_DIR=$(mktemp -d)
|
|
163
|
-
TARBALL="$TEMP_DIR/project.tgz"
|
|
164
|
-
CLEANUP_TEMP=true
|
|
165
|
-
|
|
166
|
-
cleanup() {
|
|
167
|
-
if [ "$CLEANUP_TEMP" = true ]; then
|
|
168
|
-
rm -rf "$TEMP_DIR"
|
|
169
|
-
fi
|
|
170
|
-
}
|
|
171
|
-
trap cleanup EXIT
|
|
172
|
-
|
|
173
|
-
echo "Preparing deployment..." >&2
|
|
174
|
-
|
|
175
|
-
# Check if input is a .tgz file or a directory
|
|
176
|
-
FRAMEWORK="null"
|
|
177
|
-
|
|
178
|
-
if [ -f "$INPUT_PATH" ] && [[ "$INPUT_PATH" == *.tgz ]]; then
|
|
179
|
-
# Input is already a tarball, use it directly
|
|
180
|
-
echo "Using provided tarball..." >&2
|
|
181
|
-
TARBALL="$INPUT_PATH"
|
|
182
|
-
CLEANUP_TEMP=false
|
|
183
|
-
# Can't detect framework from tarball, leave as null
|
|
184
|
-
elif [ -d "$INPUT_PATH" ]; then
|
|
185
|
-
# Input is a directory, need to tar it
|
|
186
|
-
PROJECT_PATH=$(cd "$INPUT_PATH" && pwd)
|
|
187
|
-
|
|
188
|
-
# Detect framework from package.json
|
|
189
|
-
FRAMEWORK=$(detect_framework "$PROJECT_PATH/package.json")
|
|
190
|
-
|
|
191
|
-
# Check if this is a static HTML project (no package.json)
|
|
192
|
-
if [ ! -f "$PROJECT_PATH/package.json" ]; then
|
|
193
|
-
# Find HTML files in root
|
|
194
|
-
HTML_FILES=$(find "$PROJECT_PATH" -maxdepth 1 -name "*.html" -type f)
|
|
195
|
-
HTML_COUNT=$(echo "$HTML_FILES" | grep -c . || echo 0)
|
|
196
|
-
|
|
197
|
-
# If there's exactly one HTML file and it's not index.html, rename it
|
|
198
|
-
if [ "$HTML_COUNT" -eq 1 ]; then
|
|
199
|
-
HTML_FILE=$(echo "$HTML_FILES" | head -1)
|
|
200
|
-
BASENAME=$(basename "$HTML_FILE")
|
|
201
|
-
if [ "$BASENAME" != "index.html" ]; then
|
|
202
|
-
echo "Renaming $BASENAME to index.html..." >&2
|
|
203
|
-
mv "$HTML_FILE" "$PROJECT_PATH/index.html"
|
|
204
|
-
fi
|
|
205
|
-
fi
|
|
206
|
-
fi
|
|
207
|
-
|
|
208
|
-
# Create tarball of the project (excluding node_modules and .git)
|
|
209
|
-
echo "Creating deployment package..." >&2
|
|
210
|
-
tar -czf "$TARBALL" -C "$PROJECT_PATH" --exclude='node_modules' --exclude='.git' .
|
|
211
|
-
else
|
|
212
|
-
echo "Error: Input must be a directory or a .tgz file" >&2
|
|
213
|
-
exit 1
|
|
214
|
-
fi
|
|
215
|
-
|
|
216
|
-
if [ "$FRAMEWORK" != "null" ]; then
|
|
217
|
-
echo "Detected framework: $FRAMEWORK" >&2
|
|
218
|
-
fi
|
|
219
|
-
|
|
220
|
-
# Deploy
|
|
221
|
-
echo "Deploying..." >&2
|
|
222
|
-
RESPONSE=$(curl -s -X POST "$DEPLOY_ENDPOINT" -F "file=@$TARBALL" -F "framework=$FRAMEWORK")
|
|
223
|
-
|
|
224
|
-
# Check for error in response
|
|
225
|
-
if echo "$RESPONSE" | grep -q '"error"'; then
|
|
226
|
-
ERROR_MSG=$(echo "$RESPONSE" | grep -o '"error":"[^"]*"' | cut -d'"' -f4)
|
|
227
|
-
echo "Error: $ERROR_MSG" >&2
|
|
228
|
-
exit 1
|
|
229
|
-
fi
|
|
230
|
-
|
|
231
|
-
# Extract URLs from response
|
|
232
|
-
PREVIEW_URL=$(echo "$RESPONSE" | grep -o '"previewUrl":"[^"]*"' | cut -d'"' -f4)
|
|
233
|
-
CLAIM_URL=$(echo "$RESPONSE" | grep -o '"claimUrl":"[^"]*"' | cut -d'"' -f4)
|
|
234
|
-
|
|
235
|
-
if [ -z "$PREVIEW_URL" ]; then
|
|
236
|
-
echo "Error: Could not extract preview URL from response" >&2
|
|
237
|
-
echo "$RESPONSE" >&2
|
|
238
|
-
exit 1
|
|
239
|
-
fi
|
|
240
|
-
|
|
241
|
-
echo "" >&2
|
|
242
|
-
echo "Deployment successful!" >&2
|
|
243
|
-
echo "" >&2
|
|
244
|
-
echo "Preview URL: $PREVIEW_URL" >&2
|
|
245
|
-
echo "Claim URL: $CLAIM_URL" >&2
|
|
246
|
-
echo "" >&2
|
|
247
|
-
|
|
248
|
-
# Output JSON for programmatic use
|
|
249
|
-
echo "$RESPONSE"
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: vercel-deploy
|
|
3
|
-
description: Deploy applications and websites to Vercel. Use this skill when the user requests deployment actions such as "Deploy my app", "Deploy this to production", "Create a preview deployment", "Deploy and give me the link", or "Push this live". No authentication required - returns preview URL and claimable deployment link.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Vercel Deploy
|
|
7
|
-
|
|
8
|
-
Deploy any project to Vercel instantly. No authentication required.
|
|
9
|
-
|
|
10
|
-
## How It Works
|
|
11
|
-
|
|
12
|
-
1. Packages your project into a tarball (excludes `node_modules` and `.git`)
|
|
13
|
-
2. Auto-detects framework from `package.json`
|
|
14
|
-
3. Uploads to deployment service
|
|
15
|
-
4. Returns **Preview URL** (live site) and **Claim URL** (transfer to your Vercel account)
|
|
16
|
-
|
|
17
|
-
## Usage
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
bash /mnt/skills/user/vercel-deploy/scripts/deploy.sh [path]
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
**Arguments:**
|
|
24
|
-
- `path` - Directory to deploy, or a `.tgz` file (defaults to current directory)
|
|
25
|
-
|
|
26
|
-
**Examples:**
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
# Deploy current directory
|
|
30
|
-
bash /mnt/skills/user/vercel-deploy/scripts/deploy.sh
|
|
31
|
-
|
|
32
|
-
# Deploy specific project
|
|
33
|
-
bash /mnt/skills/user/vercel-deploy/scripts/deploy.sh /path/to/project
|
|
34
|
-
|
|
35
|
-
# Deploy existing tarball
|
|
36
|
-
bash /mnt/skills/user/vercel-deploy/scripts/deploy.sh /path/to/project.tgz
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
## Output
|
|
40
|
-
|
|
41
|
-
```
|
|
42
|
-
Preparing deployment...
|
|
43
|
-
Detected framework: nextjs
|
|
44
|
-
Creating deployment package...
|
|
45
|
-
Deploying...
|
|
46
|
-
✓ Deployment successful!
|
|
47
|
-
|
|
48
|
-
Preview URL: https://skill-deploy-abc123.vercel.app
|
|
49
|
-
Claim URL: https://vercel.com/claim-deployment?code=...
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
The script also outputs JSON to stdout for programmatic use:
|
|
53
|
-
|
|
54
|
-
```json
|
|
55
|
-
{
|
|
56
|
-
"previewUrl": "https://skill-deploy-abc123.vercel.app",
|
|
57
|
-
"claimUrl": "https://vercel.com/claim-deployment?code=...",
|
|
58
|
-
"deploymentId": "dpl_...",
|
|
59
|
-
"projectId": "prj_..."
|
|
60
|
-
}
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
## Framework Detection
|
|
64
|
-
|
|
65
|
-
The script auto-detects frameworks from `package.json`. Supported frameworks include:
|
|
66
|
-
|
|
67
|
-
- **React**: Next.js, Gatsby, Create React App, Remix, React Router
|
|
68
|
-
- **Vue**: Nuxt, Vitepress, Vuepress, Gridsome
|
|
69
|
-
- **Svelte**: SvelteKit, Svelte, Sapper
|
|
70
|
-
- **Other Frontend**: Astro, Solid Start, Angular, Ember, Preact, Docusaurus
|
|
71
|
-
- **Backend**: Express, Hono, Fastify, NestJS, Elysia, h3, Nitro
|
|
72
|
-
- **Build Tools**: Vite, Parcel
|
|
73
|
-
- **And more**: Blitz, Hydrogen, RedwoodJS, Storybook, Sanity, etc.
|
|
74
|
-
|
|
75
|
-
For static HTML projects (no `package.json`), framework is set to `null`.
|
|
76
|
-
|
|
77
|
-
## Static HTML Projects
|
|
78
|
-
|
|
79
|
-
For projects without a `package.json`:
|
|
80
|
-
- If there's a single `.html` file not named `index.html`, it gets renamed automatically
|
|
81
|
-
- This ensures the page is served at the root URL (`/`)
|
|
82
|
-
|
|
83
|
-
## Present Results to User
|
|
84
|
-
|
|
85
|
-
Always show both URLs:
|
|
86
|
-
|
|
87
|
-
```
|
|
88
|
-
✓ Deployment successful!
|
|
89
|
-
|
|
90
|
-
Preview URL: https://skill-deploy-abc123.vercel.app
|
|
91
|
-
Claim URL: https://vercel.com/claim-deployment?code=...
|
|
92
|
-
|
|
93
|
-
View your site at the Preview URL.
|
|
94
|
-
To transfer this deployment to your Vercel account, visit the Claim URL.
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
## Troubleshooting
|
|
98
|
-
|
|
99
|
-
### Network Egress Error
|
|
100
|
-
|
|
101
|
-
If deployment fails due to network restrictions (common on claude.ai), tell the user:
|
|
102
|
-
|
|
103
|
-
```
|
|
104
|
-
Deployment failed due to network restrictions. To fix this:
|
|
105
|
-
|
|
106
|
-
1. Go to https://claude.ai/admin-settings/capabilities
|
|
107
|
-
2. Add *.vercel.com to the allowed domains
|
|
108
|
-
3. Try deploying again
|
|
109
|
-
```
|
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
# Vercel Deployment Script (via claimable deploy endpoint)
|
|
4
|
-
# Usage: ./deploy.sh [project-path]
|
|
5
|
-
# Returns: JSON with previewUrl, claimUrl, deploymentId, projectId
|
|
6
|
-
|
|
7
|
-
set -e
|
|
8
|
-
|
|
9
|
-
DEPLOY_ENDPOINT="https://claude-skills-deploy.vercel.com/api/deploy"
|
|
10
|
-
|
|
11
|
-
# Detect framework from package.json
|
|
12
|
-
detect_framework() {
|
|
13
|
-
local pkg_json="$1"
|
|
14
|
-
|
|
15
|
-
if [ ! -f "$pkg_json" ]; then
|
|
16
|
-
echo "null"
|
|
17
|
-
return
|
|
18
|
-
fi
|
|
19
|
-
|
|
20
|
-
local content=$(cat "$pkg_json")
|
|
21
|
-
|
|
22
|
-
# Helper to check if a package exists in dependencies or devDependencies
|
|
23
|
-
has_dep() {
|
|
24
|
-
echo "$content" | grep -q "\"$1\""
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
# Order matters - check more specific frameworks first
|
|
28
|
-
|
|
29
|
-
# Blitz
|
|
30
|
-
if has_dep "blitz"; then echo "blitzjs"; return; fi
|
|
31
|
-
|
|
32
|
-
# Next.js
|
|
33
|
-
if has_dep "next"; then echo "nextjs"; return; fi
|
|
34
|
-
|
|
35
|
-
# Gatsby
|
|
36
|
-
if has_dep "gatsby"; then echo "gatsby"; return; fi
|
|
37
|
-
|
|
38
|
-
# Remix
|
|
39
|
-
if has_dep "@remix-run/"; then echo "remix"; return; fi
|
|
40
|
-
|
|
41
|
-
# React Router (v7 framework mode)
|
|
42
|
-
if has_dep "@react-router/"; then echo "react-router"; return; fi
|
|
43
|
-
|
|
44
|
-
# TanStack Start
|
|
45
|
-
if has_dep "@tanstack/start"; then echo "tanstack-start"; return; fi
|
|
46
|
-
|
|
47
|
-
# Astro
|
|
48
|
-
if has_dep "astro"; then echo "astro"; return; fi
|
|
49
|
-
|
|
50
|
-
# Hydrogen (Shopify)
|
|
51
|
-
if has_dep "@shopify/hydrogen"; then echo "hydrogen"; return; fi
|
|
52
|
-
|
|
53
|
-
# SvelteKit
|
|
54
|
-
if has_dep "@sveltejs/kit"; then echo "sveltekit-1"; return; fi
|
|
55
|
-
|
|
56
|
-
# Svelte (standalone)
|
|
57
|
-
if has_dep "svelte"; then echo "svelte"; return; fi
|
|
58
|
-
|
|
59
|
-
# Nuxt
|
|
60
|
-
if has_dep "nuxt"; then echo "nuxtjs"; return; fi
|
|
61
|
-
|
|
62
|
-
# Vue with Vitepress
|
|
63
|
-
if has_dep "vitepress"; then echo "vitepress"; return; fi
|
|
64
|
-
|
|
65
|
-
# Vue with Vuepress
|
|
66
|
-
if has_dep "vuepress"; then echo "vuepress"; return; fi
|
|
67
|
-
|
|
68
|
-
# Gridsome
|
|
69
|
-
if has_dep "gridsome"; then echo "gridsome"; return; fi
|
|
70
|
-
|
|
71
|
-
# SolidStart
|
|
72
|
-
if has_dep "@solidjs/start"; then echo "solidstart-1"; return; fi
|
|
73
|
-
|
|
74
|
-
# Docusaurus
|
|
75
|
-
if has_dep "@docusaurus/core"; then echo "docusaurus-2"; return; fi
|
|
76
|
-
|
|
77
|
-
# RedwoodJS
|
|
78
|
-
if has_dep "@redwoodjs/"; then echo "redwoodjs"; return; fi
|
|
79
|
-
|
|
80
|
-
# Hexo
|
|
81
|
-
if has_dep "hexo"; then echo "hexo"; return; fi
|
|
82
|
-
|
|
83
|
-
# Eleventy
|
|
84
|
-
if has_dep "@11ty/eleventy"; then echo "eleventy"; return; fi
|
|
85
|
-
|
|
86
|
-
# Angular / Ionic Angular
|
|
87
|
-
if has_dep "@ionic/angular"; then echo "ionic-angular"; return; fi
|
|
88
|
-
if has_dep "@angular/core"; then echo "angular"; return; fi
|
|
89
|
-
|
|
90
|
-
# Ionic React
|
|
91
|
-
if has_dep "@ionic/react"; then echo "ionic-react"; return; fi
|
|
92
|
-
|
|
93
|
-
# Create React App
|
|
94
|
-
if has_dep "react-scripts"; then echo "create-react-app"; return; fi
|
|
95
|
-
|
|
96
|
-
# Ember
|
|
97
|
-
if has_dep "ember-cli" || has_dep "ember-source"; then echo "ember"; return; fi
|
|
98
|
-
|
|
99
|
-
# Dojo
|
|
100
|
-
if has_dep "@dojo/framework"; then echo "dojo"; return; fi
|
|
101
|
-
|
|
102
|
-
# Polymer
|
|
103
|
-
if has_dep "@polymer/"; then echo "polymer"; return; fi
|
|
104
|
-
|
|
105
|
-
# Preact
|
|
106
|
-
if has_dep "preact"; then echo "preact"; return; fi
|
|
107
|
-
|
|
108
|
-
# Stencil
|
|
109
|
-
if has_dep "@stencil/core"; then echo "stencil"; return; fi
|
|
110
|
-
|
|
111
|
-
# UmiJS
|
|
112
|
-
if has_dep "umi"; then echo "umijs"; return; fi
|
|
113
|
-
|
|
114
|
-
# Sapper (legacy Svelte)
|
|
115
|
-
if has_dep "sapper"; then echo "sapper"; return; fi
|
|
116
|
-
|
|
117
|
-
# Saber
|
|
118
|
-
if has_dep "saber"; then echo "saber"; return; fi
|
|
119
|
-
|
|
120
|
-
# Sanity
|
|
121
|
-
if has_dep "sanity"; then echo "sanity-v3"; return; fi
|
|
122
|
-
if has_dep "@sanity/"; then echo "sanity"; return; fi
|
|
123
|
-
|
|
124
|
-
# Storybook
|
|
125
|
-
if has_dep "@storybook/"; then echo "storybook"; return; fi
|
|
126
|
-
|
|
127
|
-
# NestJS
|
|
128
|
-
if has_dep "@nestjs/core"; then echo "nestjs"; return; fi
|
|
129
|
-
|
|
130
|
-
# Elysia
|
|
131
|
-
if has_dep "elysia"; then echo "elysia"; return; fi
|
|
132
|
-
|
|
133
|
-
# Hono
|
|
134
|
-
if has_dep "hono"; then echo "hono"; return; fi
|
|
135
|
-
|
|
136
|
-
# Fastify
|
|
137
|
-
if has_dep "fastify"; then echo "fastify"; return; fi
|
|
138
|
-
|
|
139
|
-
# h3
|
|
140
|
-
if has_dep "h3"; then echo "h3"; return; fi
|
|
141
|
-
|
|
142
|
-
# Nitro
|
|
143
|
-
if has_dep "nitropack"; then echo "nitro"; return; fi
|
|
144
|
-
|
|
145
|
-
# Express
|
|
146
|
-
if has_dep "express"; then echo "express"; return; fi
|
|
147
|
-
|
|
148
|
-
# Vite (generic - check last among JS frameworks)
|
|
149
|
-
if has_dep "vite"; then echo "vite"; return; fi
|
|
150
|
-
|
|
151
|
-
# Parcel
|
|
152
|
-
if has_dep "parcel"; then echo "parcel"; return; fi
|
|
153
|
-
|
|
154
|
-
# No framework detected
|
|
155
|
-
echo "null"
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
# Parse arguments
|
|
159
|
-
INPUT_PATH="${1:-.}"
|
|
160
|
-
|
|
161
|
-
# Create temp directory for packaging
|
|
162
|
-
TEMP_DIR=$(mktemp -d)
|
|
163
|
-
TARBALL="$TEMP_DIR/project.tgz"
|
|
164
|
-
CLEANUP_TEMP=true
|
|
165
|
-
|
|
166
|
-
cleanup() {
|
|
167
|
-
if [ "$CLEANUP_TEMP" = true ]; then
|
|
168
|
-
rm -rf "$TEMP_DIR"
|
|
169
|
-
fi
|
|
170
|
-
}
|
|
171
|
-
trap cleanup EXIT
|
|
172
|
-
|
|
173
|
-
echo "Preparing deployment..." >&2
|
|
174
|
-
|
|
175
|
-
# Check if input is a .tgz file or a directory
|
|
176
|
-
FRAMEWORK="null"
|
|
177
|
-
|
|
178
|
-
if [ -f "$INPUT_PATH" ] && [[ "$INPUT_PATH" == *.tgz ]]; then
|
|
179
|
-
# Input is already a tarball, use it directly
|
|
180
|
-
echo "Using provided tarball..." >&2
|
|
181
|
-
TARBALL="$INPUT_PATH"
|
|
182
|
-
CLEANUP_TEMP=false
|
|
183
|
-
# Can't detect framework from tarball, leave as null
|
|
184
|
-
elif [ -d "$INPUT_PATH" ]; then
|
|
185
|
-
# Input is a directory, need to tar it
|
|
186
|
-
PROJECT_PATH=$(cd "$INPUT_PATH" && pwd)
|
|
187
|
-
|
|
188
|
-
# Detect framework from package.json
|
|
189
|
-
FRAMEWORK=$(detect_framework "$PROJECT_PATH/package.json")
|
|
190
|
-
|
|
191
|
-
# Check if this is a static HTML project (no package.json)
|
|
192
|
-
if [ ! -f "$PROJECT_PATH/package.json" ]; then
|
|
193
|
-
# Find HTML files in root
|
|
194
|
-
HTML_FILES=$(find "$PROJECT_PATH" -maxdepth 1 -name "*.html" -type f)
|
|
195
|
-
HTML_COUNT=$(echo "$HTML_FILES" | grep -c . || echo 0)
|
|
196
|
-
|
|
197
|
-
# If there's exactly one HTML file and it's not index.html, rename it
|
|
198
|
-
if [ "$HTML_COUNT" -eq 1 ]; then
|
|
199
|
-
HTML_FILE=$(echo "$HTML_FILES" | head -1)
|
|
200
|
-
BASENAME=$(basename "$HTML_FILE")
|
|
201
|
-
if [ "$BASENAME" != "index.html" ]; then
|
|
202
|
-
echo "Renaming $BASENAME to index.html..." >&2
|
|
203
|
-
mv "$HTML_FILE" "$PROJECT_PATH/index.html"
|
|
204
|
-
fi
|
|
205
|
-
fi
|
|
206
|
-
fi
|
|
207
|
-
|
|
208
|
-
# Create tarball of the project (excluding node_modules and .git)
|
|
209
|
-
echo "Creating deployment package..." >&2
|
|
210
|
-
tar -czf "$TARBALL" -C "$PROJECT_PATH" --exclude='node_modules' --exclude='.git' .
|
|
211
|
-
else
|
|
212
|
-
echo "Error: Input must be a directory or a .tgz file" >&2
|
|
213
|
-
exit 1
|
|
214
|
-
fi
|
|
215
|
-
|
|
216
|
-
if [ "$FRAMEWORK" != "null" ]; then
|
|
217
|
-
echo "Detected framework: $FRAMEWORK" >&2
|
|
218
|
-
fi
|
|
219
|
-
|
|
220
|
-
# Deploy
|
|
221
|
-
echo "Deploying..." >&2
|
|
222
|
-
RESPONSE=$(curl -s -X POST "$DEPLOY_ENDPOINT" -F "file=@$TARBALL" -F "framework=$FRAMEWORK")
|
|
223
|
-
|
|
224
|
-
# Check for error in response
|
|
225
|
-
if echo "$RESPONSE" | grep -q '"error"'; then
|
|
226
|
-
ERROR_MSG=$(echo "$RESPONSE" | grep -o '"error":"[^"]*"' | cut -d'"' -f4)
|
|
227
|
-
echo "Error: $ERROR_MSG" >&2
|
|
228
|
-
exit 1
|
|
229
|
-
fi
|
|
230
|
-
|
|
231
|
-
# Extract URLs from response
|
|
232
|
-
PREVIEW_URL=$(echo "$RESPONSE" | grep -o '"previewUrl":"[^"]*"' | cut -d'"' -f4)
|
|
233
|
-
CLAIM_URL=$(echo "$RESPONSE" | grep -o '"claimUrl":"[^"]*"' | cut -d'"' -f4)
|
|
234
|
-
|
|
235
|
-
if [ -z "$PREVIEW_URL" ]; then
|
|
236
|
-
echo "Error: Could not extract preview URL from response" >&2
|
|
237
|
-
echo "$RESPONSE" >&2
|
|
238
|
-
exit 1
|
|
239
|
-
fi
|
|
240
|
-
|
|
241
|
-
echo "" >&2
|
|
242
|
-
echo "Deployment successful!" >&2
|
|
243
|
-
echo "" >&2
|
|
244
|
-
echo "Preview URL: $PREVIEW_URL" >&2
|
|
245
|
-
echo "Claim URL: $CLAIM_URL" >&2
|
|
246
|
-
echo "" >&2
|
|
247
|
-
|
|
248
|
-
# Output JSON for programmatic use
|
|
249
|
-
echo "$RESPONSE"
|