@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/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 {};