@mcp-s/skills 1.0.5 → 1.3.1

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/package.json CHANGED
@@ -1,53 +1,111 @@
1
1
  {
2
2
  "name": "@mcp-s/skills",
3
- "version": "1.0.5",
4
- "description": "Install skills onto coding agents from MCP-S server",
3
+ "version": "1.3.1",
4
+ "description": "The open agent skills ecosystem",
5
5
  "type": "module",
6
- "files": [
7
- "dist"
8
- ],
9
- "main": "dist/index.js",
10
6
  "bin": {
11
- "skills": "dist/index.js"
7
+ "skills": "./bin/cli.mjs",
8
+ "add-skill": "./bin/cli.mjs"
12
9
  },
10
+ "files": [
11
+ "dist",
12
+ "bin",
13
+ "README.md",
14
+ "ThirdPartyNoticeText.txt"
15
+ ],
13
16
  "scripts": {
14
- "start": "node dist/index.js",
15
- "build": "tsc && shx chmod +x dist/*.js",
16
- "prepare": "npm run build",
17
- "prepublishOnly": "npm run build && npm version patch",
18
- "test": "echo \"Error: no test specified\" && exit 1"
17
+ "build": "node scripts/generate-licenses.ts && obuild",
18
+ "generate-licenses": "node scripts/generate-licenses.ts",
19
+ "dev": "node src/cli.ts",
20
+ "exec:test": "node scripts/execute-tests.ts",
21
+ "prepublishOnly": "npm run build",
22
+ "format": "prettier --write 'src/**/*.ts' 'scripts/**/*.ts'",
23
+ "format:check": "prettier --check 'src/**/*.ts' 'scripts/**/*.ts'",
24
+ "prepare": "husky",
25
+ "test": "vitest",
26
+ "type-check": "tsc --noEmit",
27
+ "publish:snapshot": "npm version prerelease --preid=snapshot --no-git-tag-version && npm publish --tag snapshot"
28
+ },
29
+ "lint-staged": {
30
+ "src/**/*.ts": "prettier --write",
31
+ "scripts/**/*.ts": "prettier --write",
32
+ "tests/**/*.ts": "prettier --write"
19
33
  },
20
- "author": "MCP-S",
21
- "license": "ISC",
22
34
  "keywords": [
23
35
  "cli",
24
36
  "agent-skills",
25
37
  "skills",
26
38
  "ai-agents",
27
- "mcp-s",
39
+ "amp",
40
+ "antigravity",
41
+ "augment",
28
42
  "claude-code",
43
+ "openclaw",
29
44
  "cline",
45
+ "codebuddy",
30
46
  "codex",
47
+ "command-code",
48
+ "continue",
49
+ "crush",
31
50
  "cursor",
51
+ "droid",
52
+ "gemini-cli",
53
+ "github-copilot",
54
+ "goose",
55
+ "junie",
56
+ "iflow-cli",
57
+ "kilo",
58
+ "kimi-cli",
59
+ "kiro-cli",
60
+ "kode",
61
+ "mcpjam",
62
+ "mistral-vibe",
63
+ "mux",
32
64
  "opencode",
65
+ "openclaude",
33
66
  "openhands",
34
- "windsurf"
67
+ "pi",
68
+ "qoder",
69
+ "qwen-code",
70
+ "replit",
71
+ "roo",
72
+ "trae",
73
+ "trae-cn",
74
+ "windsurf",
75
+ "zencoder",
76
+ "neovate",
77
+ "pochi",
78
+ "adal"
35
79
  ],
36
- "dependencies": {
37
- "@clack/prompts": "^0.9.1",
38
- "chalk": "^5.4.1",
39
- "commander": "^13.1.0",
40
- "open": "^10.1.1"
80
+ "repository": {
81
+ "type": "git",
82
+ "url": "git+https://github.com/vercel-labs/skills.git"
41
83
  },
42
- "publishConfig": {
43
- "access": "public"
84
+ "homepage": "https://github.com/vercel-labs/skills#readme",
85
+ "bugs": {
86
+ "url": "https://github.com/vercel-labs/skills/issues"
44
87
  },
88
+ "author": "",
89
+ "license": "MIT",
45
90
  "devDependencies": {
46
- "@types/node": "^22.14.0",
47
- "shx": "^0.4.0",
48
- "typescript": "^5.8.3"
91
+ "@clack/prompts": "^0.11.0",
92
+ "@types/bun": "latest",
93
+ "@types/node": "^22.10.0",
94
+ "@types/unzipper": "^0.10.11",
95
+ "gray-matter": "^4.0.3",
96
+ "husky": "^9.1.7",
97
+ "lint-staged": "^16.2.7",
98
+ "obuild": "^0.4.22",
99
+ "picocolors": "^1.1.1",
100
+ "prettier": "^3.8.1",
101
+ "simple-git": "^3.27.0",
102
+ "typescript": "^5.9.3",
103
+ "unzipper": "^0.12.3",
104
+ "vitest": "^4.0.17",
105
+ "xdg-basedir": "^5.1.0"
49
106
  },
50
107
  "engines": {
51
108
  "node": ">=18"
52
- }
109
+ },
110
+ "packageManager": "pnpm@10.17.1"
53
111
  }
package/dist/agents.js DELETED
@@ -1,246 +0,0 @@
1
- import { homedir } from "os";
2
- import { join } from "path";
3
- import { existsSync } from "fs";
4
- const home = homedir();
5
- export const agents = {
6
- amp: {
7
- name: "amp",
8
- displayName: "Amp",
9
- skillsDir: ".agents/skills",
10
- globalSkillsDir: join(home, ".config/agents/skills"),
11
- detectInstalled: async () => {
12
- return existsSync(join(home, ".config/amp"));
13
- },
14
- },
15
- antigravity: {
16
- name: "antigravity",
17
- displayName: "Antigravity",
18
- skillsDir: ".agent/skills",
19
- globalSkillsDir: join(home, ".gemini/antigravity/skills"),
20
- detectInstalled: async () => {
21
- return (existsSync(join(process.cwd(), ".agent")) ||
22
- existsSync(join(home, ".gemini/antigravity")));
23
- },
24
- },
25
- "claude-code": {
26
- name: "claude-code",
27
- displayName: "Claude Code",
28
- skillsDir: ".claude/skills",
29
- globalSkillsDir: join(home, ".claude/skills"),
30
- detectInstalled: async () => {
31
- return existsSync(join(home, ".claude"));
32
- },
33
- },
34
- clawdbot: {
35
- name: "clawdbot",
36
- displayName: "Clawdbot",
37
- skillsDir: "skills",
38
- globalSkillsDir: join(home, ".clawdbot/skills"),
39
- detectInstalled: async () => {
40
- return existsSync(join(home, ".clawdbot"));
41
- },
42
- },
43
- cline: {
44
- name: "cline",
45
- displayName: "Cline",
46
- skillsDir: ".cline/skills",
47
- globalSkillsDir: join(home, ".cline/skills"),
48
- detectInstalled: async () => {
49
- return existsSync(join(home, ".cline"));
50
- },
51
- },
52
- codex: {
53
- name: "codex",
54
- displayName: "Codex",
55
- skillsDir: ".codex/skills",
56
- globalSkillsDir: join(home, ".codex/skills"),
57
- detectInstalled: async () => {
58
- return existsSync(join(home, ".codex"));
59
- },
60
- },
61
- "command-code": {
62
- name: "command-code",
63
- displayName: "Command Code",
64
- skillsDir: ".commandcode/skills",
65
- globalSkillsDir: join(home, ".commandcode/skills"),
66
- detectInstalled: async () => {
67
- return existsSync(join(home, ".commandcode"));
68
- },
69
- },
70
- cursor: {
71
- name: "cursor",
72
- displayName: "Cursor",
73
- skillsDir: ".cursor/skills",
74
- globalSkillsDir: join(home, ".cursor/skills"),
75
- detectInstalled: async () => {
76
- return existsSync(join(home, ".cursor"));
77
- },
78
- },
79
- droid: {
80
- name: "droid",
81
- displayName: "Droid",
82
- skillsDir: ".factory/skills",
83
- globalSkillsDir: join(home, ".factory/skills"),
84
- detectInstalled: async () => {
85
- return existsSync(join(home, ".factory/skills"));
86
- },
87
- },
88
- "gemini-cli": {
89
- name: "gemini-cli",
90
- displayName: "Gemini CLI",
91
- skillsDir: ".gemini/skills",
92
- globalSkillsDir: join(home, ".gemini/skills"),
93
- detectInstalled: async () => {
94
- return existsSync(join(home, ".gemini"));
95
- },
96
- },
97
- "github-copilot": {
98
- name: "github-copilot",
99
- displayName: "GitHub Copilot",
100
- skillsDir: ".github/skills",
101
- globalSkillsDir: join(home, ".copilot/skills"),
102
- detectInstalled: async () => {
103
- return (existsSync(join(process.cwd(), ".github")) ||
104
- existsSync(join(home, ".copilot")));
105
- },
106
- },
107
- goose: {
108
- name: "goose",
109
- displayName: "Goose",
110
- skillsDir: ".goose/skills",
111
- globalSkillsDir: join(home, ".config/goose/skills"),
112
- detectInstalled: async () => {
113
- return existsSync(join(home, ".config/goose"));
114
- },
115
- },
116
- kilo: {
117
- name: "kilo",
118
- displayName: "Kilo Code",
119
- skillsDir: ".kilocode/skills",
120
- globalSkillsDir: join(home, ".kilocode/skills"),
121
- detectInstalled: async () => {
122
- return existsSync(join(home, ".kilocode"));
123
- },
124
- },
125
- "kiro-cli": {
126
- name: "kiro-cli",
127
- displayName: "Kiro CLI",
128
- skillsDir: ".kiro/skills",
129
- globalSkillsDir: join(home, ".kiro/skills"),
130
- detectInstalled: async () => {
131
- return existsSync(join(home, ".kiro"));
132
- },
133
- },
134
- mcpjam: {
135
- name: "mcpjam",
136
- displayName: "MCPJam",
137
- skillsDir: ".mcpjam/skills",
138
- globalSkillsDir: join(home, ".mcpjam/skills"),
139
- detectInstalled: async () => {
140
- return existsSync(join(home, ".mcpjam"));
141
- },
142
- },
143
- opencode: {
144
- name: "opencode",
145
- displayName: "OpenCode",
146
- skillsDir: ".opencode/skills",
147
- globalSkillsDir: join(home, ".config/opencode/skills"),
148
- detectInstalled: async () => {
149
- return (existsSync(join(home, ".config/opencode")) ||
150
- existsSync(join(home, ".claude/skills")));
151
- },
152
- },
153
- openhands: {
154
- name: "openhands",
155
- displayName: "OpenHands",
156
- skillsDir: ".openhands/skills",
157
- globalSkillsDir: join(home, ".openhands/skills"),
158
- detectInstalled: async () => {
159
- return existsSync(join(home, ".openhands"));
160
- },
161
- },
162
- pi: {
163
- name: "pi",
164
- displayName: "Pi",
165
- skillsDir: ".pi/skills",
166
- globalSkillsDir: join(home, ".pi/agent/skills"),
167
- detectInstalled: async () => {
168
- return existsSync(join(home, ".pi/agent"));
169
- },
170
- },
171
- qoder: {
172
- name: "qoder",
173
- displayName: "Qoder",
174
- skillsDir: ".qoder/skills",
175
- globalSkillsDir: join(home, ".qoder/skills"),
176
- detectInstalled: async () => {
177
- return existsSync(join(home, ".qoder"));
178
- },
179
- },
180
- "qwen-code": {
181
- name: "qwen-code",
182
- displayName: "Qwen Code",
183
- skillsDir: ".qwen/skills",
184
- globalSkillsDir: join(home, ".qwen/skills"),
185
- detectInstalled: async () => {
186
- return existsSync(join(home, ".qwen"));
187
- },
188
- },
189
- roo: {
190
- name: "roo",
191
- displayName: "Roo Code",
192
- skillsDir: ".roo/skills",
193
- globalSkillsDir: join(home, ".roo/skills"),
194
- detectInstalled: async () => {
195
- return existsSync(join(home, ".roo"));
196
- },
197
- },
198
- trae: {
199
- name: "trae",
200
- displayName: "Trae",
201
- skillsDir: ".trae/skills",
202
- globalSkillsDir: join(home, ".trae/skills"),
203
- detectInstalled: async () => {
204
- return existsSync(join(home, ".trae"));
205
- },
206
- },
207
- windsurf: {
208
- name: "windsurf",
209
- displayName: "Windsurf",
210
- skillsDir: ".windsurf/skills",
211
- globalSkillsDir: join(home, ".codeium/windsurf/skills"),
212
- detectInstalled: async () => {
213
- return existsSync(join(home, ".codeium/windsurf"));
214
- },
215
- },
216
- zencoder: {
217
- name: "zencoder",
218
- displayName: "Zencoder",
219
- skillsDir: ".zencoder/skills",
220
- globalSkillsDir: join(home, ".zencoder/skills"),
221
- detectInstalled: async () => {
222
- return existsSync(join(home, ".zencoder"));
223
- },
224
- },
225
- neovate: {
226
- name: "neovate",
227
- displayName: "Neovate",
228
- skillsDir: ".neovate/skills",
229
- globalSkillsDir: join(home, ".neovate/skills"),
230
- detectInstalled: async () => {
231
- return existsSync(join(home, ".neovate"));
232
- },
233
- },
234
- };
235
- export async function detectInstalledAgents() {
236
- const installed = [];
237
- for (const [type, config] of Object.entries(agents)) {
238
- if (await config.detectInstalled()) {
239
- installed.push(type);
240
- }
241
- }
242
- return installed;
243
- }
244
- export function getAgentConfig(type) {
245
- return agents[type];
246
- }
package/dist/api.js DELETED
@@ -1,98 +0,0 @@
1
- export async function fetchSkills(baseUrl, auth) {
2
- const headers = {
3
- "Content-Type": "application/json",
4
- };
5
- if (auth) {
6
- headers["Authorization"] = `${auth.userAccessKey}:${auth.userOTT}`;
7
- }
8
- const response = await fetch(`${baseUrl}/skills`, {
9
- headers,
10
- });
11
- if (!response.ok) {
12
- const errorText = await response.text();
13
- // Check for authentication error
14
- if (response.status === 401) {
15
- const error = new Error("Unauthorized");
16
- error.status = 401;
17
- throw error;
18
- }
19
- throw new Error(`Failed to fetch skills: ${response.status} ${response.statusText}\n${errorText}`);
20
- }
21
- const data = await response.json();
22
- return data.data;
23
- }
24
- export async function fetchSkillContent(baseUrl, skillSlug, auth) {
25
- const headers = {
26
- "Content-Type": "application/json",
27
- };
28
- if (auth) {
29
- headers["Authorization"] = `${auth.userAccessKey}:${auth.userOTT}`;
30
- }
31
- const response = await fetch(`${baseUrl}/skills/${skillSlug}/content`, {
32
- headers,
33
- });
34
- if (!response.ok) {
35
- const errorText = await response.text();
36
- if (response.status === 401) {
37
- const error = new Error("Unauthorized");
38
- error.status = 401;
39
- throw error;
40
- }
41
- throw new Error(`Failed to fetch skill content: ${response.status} ${response.statusText}\n${errorText}`);
42
- }
43
- const data = await response.json();
44
- return data.content;
45
- }
46
- export async function fetchSkillFiles(baseUrl, skillSlug, auth) {
47
- const headers = {
48
- "Content-Type": "application/json",
49
- };
50
- if (auth) {
51
- headers["Authorization"] = `${auth.userAccessKey}:${auth.userOTT}`;
52
- }
53
- const response = await fetch(`${baseUrl}/skills/${skillSlug}/files`, {
54
- headers,
55
- });
56
- if (!response.ok) {
57
- const errorText = await response.text();
58
- if (response.status === 401) {
59
- const error = new Error("Unauthorized");
60
- error.status = 401;
61
- throw error;
62
- }
63
- if (response.status === 404) {
64
- const error = new Error("Skill not found");
65
- error.status = 404;
66
- throw error;
67
- }
68
- throw new Error(`Failed to fetch skill files: ${response.status} ${response.statusText}\n${errorText}`);
69
- }
70
- const data = await response.json();
71
- return data.data;
72
- }
73
- export async function fetchSkillFile(baseUrl, skillSlug, filePath, auth) {
74
- const headers = {
75
- "Content-Type": "application/json",
76
- };
77
- if (auth) {
78
- headers["Authorization"] = `${auth.userAccessKey}:${auth.userOTT}`;
79
- }
80
- const response = await fetch(`${baseUrl}/skills/${skillSlug}/file/${filePath}`, {
81
- headers,
82
- });
83
- if (!response.ok) {
84
- const errorText = await response.text();
85
- if (response.status === 401) {
86
- const error = new Error("Unauthorized");
87
- error.status = 401;
88
- throw error;
89
- }
90
- if (response.status === 404) {
91
- const error = new Error("File not found");
92
- error.status = 404;
93
- throw error;
94
- }
95
- throw new Error(`Failed to fetch skill file: ${response.status} ${response.statusText}\n${errorText}`);
96
- }
97
- return response.json();
98
- }
package/dist/auth.js DELETED
@@ -1,117 +0,0 @@
1
- import { homedir } from "os";
2
- import { join } from "path";
3
- import { readFile, writeFile, mkdir } from "fs/promises";
4
- import { existsSync } from "fs";
5
- import crypto from "crypto";
6
- import open from "open";
7
- const CONFIG_DIR = join(homedir(), ".mcp-s");
8
- const CONFIG_FILE = join(CONFIG_DIR, "skills-config.json");
9
- export const generateToken = () => crypto.randomBytes(32).toString("hex");
10
- export async function loadAuthConfig() {
11
- try {
12
- if (!existsSync(CONFIG_FILE)) {
13
- return null;
14
- }
15
- const content = await readFile(CONFIG_FILE, "utf-8");
16
- return JSON.parse(content);
17
- }
18
- catch (_a) {
19
- return null;
20
- }
21
- }
22
- export async function saveAuthConfig(config) {
23
- if (!existsSync(CONFIG_DIR)) {
24
- await mkdir(CONFIG_DIR, { recursive: true });
25
- }
26
- await writeFile(CONFIG_FILE, JSON.stringify(config, null, 2), "utf-8");
27
- }
28
- export async function generateAuthUrl({ baseUrl, userAccessKey, userOTT, }) {
29
- const response = await fetch(`${baseUrl}/generate-auth-url`, {
30
- method: "POST",
31
- headers: {
32
- Authorization: `${userAccessKey}:${userOTT}`,
33
- },
34
- });
35
- if (!response.ok) {
36
- throw new Error(`Failed to generate auth URL: ${response.status}`);
37
- }
38
- const { data: { url }, } = await response.json();
39
- return url;
40
- }
41
- export async function authenticate({ baseUrl, userAccessKey, userOTT, openBrowser = true, }) {
42
- const url = await generateAuthUrl({ baseUrl, userAccessKey, userOTT });
43
- let opened = false;
44
- if (openBrowser) {
45
- try {
46
- await open(url);
47
- opened = true;
48
- }
49
- catch (_a) {
50
- // Browser opening failed, user will need to use the URL manually
51
- }
52
- }
53
- return { url, opened };
54
- }
55
- export async function getOrCreateAuth(org, providedUserAccessKey) {
56
- const existing = await loadAuthConfig();
57
- // If a userAccessKey is provided via CLI, use it
58
- if (providedUserAccessKey) {
59
- // Check if it matches existing config
60
- if (existing &&
61
- existing.userAccessKey === providedUserAccessKey &&
62
- existing.userOTT &&
63
- existing.org === org) {
64
- return {
65
- userAccessKey: existing.userAccessKey,
66
- userOTT: existing.userOTT,
67
- isNew: false,
68
- };
69
- }
70
- // New key provided or org changed, generate new OTT
71
- const userOTT = generateToken();
72
- await saveAuthConfig({
73
- userAccessKey: providedUserAccessKey,
74
- userOTT,
75
- org,
76
- });
77
- return {
78
- userAccessKey: providedUserAccessKey,
79
- userOTT,
80
- isNew: true,
81
- };
82
- }
83
- if (existing && existing.userAccessKey && existing.userOTT) {
84
- // If org changed, generate new OTT
85
- if (org && existing.org !== org) {
86
- const newOTT = generateToken();
87
- await saveAuthConfig(Object.assign(Object.assign({}, existing), { userOTT: newOTT, org }));
88
- return {
89
- userAccessKey: existing.userAccessKey,
90
- userOTT: newOTT,
91
- isNew: true,
92
- };
93
- }
94
- return {
95
- userAccessKey: existing.userAccessKey,
96
- userOTT: existing.userOTT,
97
- isNew: false,
98
- };
99
- }
100
- // No existing auth and no key provided - this is an error
101
- // The user must provide their userAccessKey
102
- throw new Error("No user access key found. Please provide your MCP-S user access key with --key <userAccessKey>");
103
- }
104
- export async function refreshToken(org, providedUserAccessKey) {
105
- const existing = await loadAuthConfig();
106
- const userAccessKey = providedUserAccessKey || (existing === null || existing === void 0 ? void 0 : existing.userAccessKey);
107
- if (!userAccessKey) {
108
- throw new Error("No user access key found. Please provide your MCP-S user access key with --key <userAccessKey>");
109
- }
110
- const userOTT = generateToken();
111
- await saveAuthConfig({
112
- userAccessKey,
113
- userOTT,
114
- org,
115
- });
116
- return { userAccessKey, userOTT };
117
- }