@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/README.md +399 -96
- package/ThirdPartyNoticeText.txt +171 -0
- package/bin/cli.mjs +14 -0
- package/dist/_chunks/libs/@clack/core.mjs +767 -0
- package/dist/_chunks/libs/@clack/prompts.mjs +275 -0
- package/dist/_chunks/libs/@kwsites/file-exists.mjs +562 -0
- package/dist/_chunks/libs/@kwsites/promise-deferred.mjs +37 -0
- package/dist/_chunks/libs/bluebird.mjs +4141 -0
- package/dist/_chunks/libs/core-util-is.mjs +65 -0
- package/dist/_chunks/libs/duplexer2.mjs +1726 -0
- package/dist/_chunks/libs/esprima.mjs +5338 -0
- package/dist/_chunks/libs/extend-shallow.mjs +31 -0
- package/dist/_chunks/libs/fs-extra.mjs +1801 -0
- package/dist/_chunks/libs/gray-matter.mjs +2596 -0
- package/dist/_chunks/libs/node-int64.mjs +103 -0
- package/dist/_chunks/libs/simple-git.mjs +3584 -0
- package/dist/_chunks/libs/unzipper.mjs +945 -0
- package/dist/_chunks/libs/xdg-basedir.mjs +14 -0
- package/dist/_chunks/rolldown-runtime.mjs +24 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +4258 -0
- package/package.json +85 -27
- package/dist/agents.js +0 -246
- package/dist/api.js +0 -98
- package/dist/auth.js +0 -117
- package/dist/index.js +0 -495
- package/dist/installer.js +0 -231
- package/dist/types.js +0 -1
package/dist/installer.js
DELETED
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
import { mkdir, access, symlink, lstat, rm, readlink, writeFile, } from "fs/promises";
|
|
2
|
-
import { join, normalize, resolve, sep, relative, dirname } from "path";
|
|
3
|
-
import { homedir, platform } from "os";
|
|
4
|
-
import { agents } from "./agents.js";
|
|
5
|
-
const AGENTS_DIR = ".agents";
|
|
6
|
-
const SKILLS_SUBDIR = "skills";
|
|
7
|
-
function sanitizeName(name) {
|
|
8
|
-
let sanitized = name.replace(/[\/\\:\0]/g, "");
|
|
9
|
-
sanitized = sanitized.replace(/^[.\s]+|[.\s]+$/g, "");
|
|
10
|
-
sanitized = sanitized.replace(/^\.+/, "");
|
|
11
|
-
if (!sanitized || sanitized.length === 0) {
|
|
12
|
-
sanitized = "unnamed-skill";
|
|
13
|
-
}
|
|
14
|
-
if (sanitized.length > 255) {
|
|
15
|
-
sanitized = sanitized.substring(0, 255);
|
|
16
|
-
}
|
|
17
|
-
return sanitized;
|
|
18
|
-
}
|
|
19
|
-
function isPathSafe(basePath, targetPath) {
|
|
20
|
-
const normalizedBase = normalize(resolve(basePath));
|
|
21
|
-
const normalizedTarget = normalize(resolve(targetPath));
|
|
22
|
-
return (normalizedTarget.startsWith(normalizedBase + sep) ||
|
|
23
|
-
normalizedTarget === normalizedBase);
|
|
24
|
-
}
|
|
25
|
-
function getCanonicalSkillsDir(global, cwd) {
|
|
26
|
-
const baseDir = global ? homedir() : cwd || process.cwd();
|
|
27
|
-
return join(baseDir, AGENTS_DIR, SKILLS_SUBDIR);
|
|
28
|
-
}
|
|
29
|
-
async function createSymlink(target, linkPath) {
|
|
30
|
-
try {
|
|
31
|
-
try {
|
|
32
|
-
const stats = await lstat(linkPath);
|
|
33
|
-
if (stats.isSymbolicLink()) {
|
|
34
|
-
const existingTarget = await readlink(linkPath);
|
|
35
|
-
if (resolve(existingTarget) === resolve(target)) {
|
|
36
|
-
return true;
|
|
37
|
-
}
|
|
38
|
-
await rm(linkPath);
|
|
39
|
-
}
|
|
40
|
-
else {
|
|
41
|
-
await rm(linkPath, { recursive: true });
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
catch (err) {
|
|
45
|
-
if (err &&
|
|
46
|
-
typeof err === "object" &&
|
|
47
|
-
"code" in err &&
|
|
48
|
-
err.code === "ELOOP") {
|
|
49
|
-
try {
|
|
50
|
-
await rm(linkPath, { force: true });
|
|
51
|
-
}
|
|
52
|
-
catch (_a) {
|
|
53
|
-
// Ignore cleanup errors
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
const linkDir = join(linkPath, "..");
|
|
58
|
-
await mkdir(linkDir, { recursive: true });
|
|
59
|
-
const relativePath = relative(linkDir, target);
|
|
60
|
-
const symlinkType = platform() === "win32" ? "junction" : undefined;
|
|
61
|
-
await symlink(relativePath, linkPath, symlinkType);
|
|
62
|
-
return true;
|
|
63
|
-
}
|
|
64
|
-
catch (_b) {
|
|
65
|
-
return false;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Write all skill files to a directory
|
|
70
|
-
* Structure:
|
|
71
|
-
* skill-name/
|
|
72
|
-
* ├── SKILL.md # Required: instructions + metadata
|
|
73
|
-
* ├── scripts/ # Optional: executable code
|
|
74
|
-
* ├── references/ # Optional: documentation
|
|
75
|
-
* └── assets/ # Optional: templates, resources
|
|
76
|
-
*/
|
|
77
|
-
async function writeSkillFiles(skill, targetDir) {
|
|
78
|
-
// Ensure the target directory exists
|
|
79
|
-
await mkdir(targetDir, { recursive: true });
|
|
80
|
-
// Write SKILL.md
|
|
81
|
-
const skillMdPath = join(targetDir, "SKILL.md");
|
|
82
|
-
await writeFile(skillMdPath, skill.content, "utf-8");
|
|
83
|
-
// Write scripts if present
|
|
84
|
-
if (skill.scripts && skill.scripts.length > 0) {
|
|
85
|
-
for (const script of skill.scripts) {
|
|
86
|
-
const scriptPath = join(targetDir, script.path);
|
|
87
|
-
const scriptDir = dirname(scriptPath);
|
|
88
|
-
await mkdir(scriptDir, { recursive: true });
|
|
89
|
-
await writeFile(scriptPath, script.content, "utf-8");
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
// Write references if present
|
|
93
|
-
if (skill.references && skill.references.length > 0) {
|
|
94
|
-
for (const reference of skill.references) {
|
|
95
|
-
const refPath = join(targetDir, reference.path);
|
|
96
|
-
const refDir = dirname(refPath);
|
|
97
|
-
await mkdir(refDir, { recursive: true });
|
|
98
|
-
await writeFile(refPath, reference.content, "utf-8");
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
// Write assets if present
|
|
102
|
-
if (skill.assets && skill.assets.length > 0) {
|
|
103
|
-
for (const asset of skill.assets) {
|
|
104
|
-
const assetPath = join(targetDir, asset.path);
|
|
105
|
-
const assetDir = dirname(assetPath);
|
|
106
|
-
await mkdir(assetDir, { recursive: true });
|
|
107
|
-
// Assets may be base64 encoded for binary files
|
|
108
|
-
if (asset.mimeType && !asset.mimeType.startsWith("text/")) {
|
|
109
|
-
await writeFile(assetPath, Buffer.from(asset.content, "base64"));
|
|
110
|
-
}
|
|
111
|
-
else {
|
|
112
|
-
await writeFile(assetPath, asset.content, "utf-8");
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
export async function installSkillForAgent(skill, agentType, options = {}) {
|
|
118
|
-
var _a, _b;
|
|
119
|
-
const agent = agents[agentType];
|
|
120
|
-
const isGlobal = (_a = options.global) !== null && _a !== void 0 ? _a : false;
|
|
121
|
-
const cwd = options.cwd || process.cwd();
|
|
122
|
-
const skillName = sanitizeName(skill.slug || skill.name);
|
|
123
|
-
const canonicalBase = getCanonicalSkillsDir(isGlobal, cwd);
|
|
124
|
-
const canonicalDir = join(canonicalBase, skillName);
|
|
125
|
-
const agentBase = isGlobal
|
|
126
|
-
? agent.globalSkillsDir
|
|
127
|
-
: join(cwd, agent.skillsDir);
|
|
128
|
-
const agentDir = join(agentBase, skillName);
|
|
129
|
-
const installMode = (_b = options.mode) !== null && _b !== void 0 ? _b : "symlink";
|
|
130
|
-
if (!isPathSafe(canonicalBase, canonicalDir)) {
|
|
131
|
-
return {
|
|
132
|
-
success: false,
|
|
133
|
-
path: agentDir,
|
|
134
|
-
mode: installMode,
|
|
135
|
-
error: "Invalid skill name: potential path traversal detected",
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
if (!isPathSafe(agentBase, agentDir)) {
|
|
139
|
-
return {
|
|
140
|
-
success: false,
|
|
141
|
-
path: agentDir,
|
|
142
|
-
mode: installMode,
|
|
143
|
-
error: "Invalid skill name: potential path traversal detected",
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
try {
|
|
147
|
-
if (installMode === "copy") {
|
|
148
|
-
await writeSkillFiles(skill, agentDir);
|
|
149
|
-
return {
|
|
150
|
-
success: true,
|
|
151
|
-
path: agentDir,
|
|
152
|
-
mode: "copy",
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
// Symlink mode
|
|
156
|
-
await writeSkillFiles(skill, canonicalDir);
|
|
157
|
-
const symlinkCreated = await createSymlink(canonicalDir, agentDir);
|
|
158
|
-
if (!symlinkCreated) {
|
|
159
|
-
// Fallback to copy
|
|
160
|
-
try {
|
|
161
|
-
await rm(agentDir, { recursive: true, force: true });
|
|
162
|
-
}
|
|
163
|
-
catch (_c) {
|
|
164
|
-
// Ignore
|
|
165
|
-
}
|
|
166
|
-
await writeSkillFiles(skill, agentDir);
|
|
167
|
-
return {
|
|
168
|
-
success: true,
|
|
169
|
-
path: agentDir,
|
|
170
|
-
canonicalPath: canonicalDir,
|
|
171
|
-
mode: "symlink",
|
|
172
|
-
symlinkFailed: true,
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
return {
|
|
176
|
-
success: true,
|
|
177
|
-
path: agentDir,
|
|
178
|
-
canonicalPath: canonicalDir,
|
|
179
|
-
mode: "symlink",
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
catch (error) {
|
|
183
|
-
return {
|
|
184
|
-
success: false,
|
|
185
|
-
path: agentDir,
|
|
186
|
-
mode: installMode,
|
|
187
|
-
error: error instanceof Error ? error.message : "Unknown error",
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
export async function isSkillInstalled(skillName, agentType, options = {}) {
|
|
192
|
-
const agent = agents[agentType];
|
|
193
|
-
const sanitized = sanitizeName(skillName);
|
|
194
|
-
const targetBase = options.global
|
|
195
|
-
? agent.globalSkillsDir
|
|
196
|
-
: join(options.cwd || process.cwd(), agent.skillsDir);
|
|
197
|
-
const skillDir = join(targetBase, sanitized);
|
|
198
|
-
if (!isPathSafe(targetBase, skillDir)) {
|
|
199
|
-
return false;
|
|
200
|
-
}
|
|
201
|
-
try {
|
|
202
|
-
await access(skillDir);
|
|
203
|
-
return true;
|
|
204
|
-
}
|
|
205
|
-
catch (_a) {
|
|
206
|
-
return false;
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
export function getInstallPath(skillName, agentType, options = {}) {
|
|
210
|
-
const agent = agents[agentType];
|
|
211
|
-
const cwd = options.cwd || process.cwd();
|
|
212
|
-
const sanitized = sanitizeName(skillName);
|
|
213
|
-
const targetBase = options.global
|
|
214
|
-
? agent.globalSkillsDir
|
|
215
|
-
: join(cwd, agent.skillsDir);
|
|
216
|
-
const installPath = join(targetBase, sanitized);
|
|
217
|
-
if (!isPathSafe(targetBase, installPath)) {
|
|
218
|
-
throw new Error("Invalid skill name: potential path traversal detected");
|
|
219
|
-
}
|
|
220
|
-
return installPath;
|
|
221
|
-
}
|
|
222
|
-
export function getCanonicalPath(skillName, options = {}) {
|
|
223
|
-
var _a;
|
|
224
|
-
const sanitized = sanitizeName(skillName);
|
|
225
|
-
const canonicalBase = getCanonicalSkillsDir((_a = options.global) !== null && _a !== void 0 ? _a : false, options.cwd);
|
|
226
|
-
const canonicalPath = join(canonicalBase, sanitized);
|
|
227
|
-
if (!isPathSafe(canonicalBase, canonicalPath)) {
|
|
228
|
-
throw new Error("Invalid skill name: potential path traversal detected");
|
|
229
|
-
}
|
|
230
|
-
return canonicalPath;
|
|
231
|
-
}
|
package/dist/types.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|