itismyskillmarket 1.1.0 → 1.1.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/LICENSE +21 -0
- package/README.md +2 -2
- package/dist/index.js +138 -141
- package/package.json +7 -2
- package/src/cli.ts +27 -27
- package/src/commands/info.ts +2 -2
- package/src/commands/install.ts +48 -15
- package/src/commands/ls.ts +8 -34
- package/src/commands/npm.ts +4 -34
- package/src/commands/sync.ts +27 -6
- package/src/commands/update.ts +2 -2
- package/src/index.ts +0 -27
- package/.github/workflows/publish-npm.yml +0 -54
- package/.github/workflows/publish-skill.yml +0 -70
- package/5e51cb7aa8b8e60d49d86f4689f5d4d1.png +0 -0
- package/DEVELOPMENT.md +0 -376
- package/SKILLMARKET-GUIDE.md +0 -277
- package/docs/plans/2026-04-01-skillmarket-design.md +0 -267
- package/docs/plans/2026-04-01-skillmarket-implementation.md +0 -1031
- package/skills/README.md +0 -52
- package/skills/test-skill/SKILL.md +0 -25
- package/skills/test-skill/index.js +0 -66
- package/skills/test-skill/metadata.json +0 -9
- package/skills/test-skill/package.json +0 -19
- package/tsconfig.json +0 -10
- package/tsup.config.ts +0 -22
- package/wanxuchen-skillmarket-1.0.1.tgz +0 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 DevTools Assistant Plugin
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -5,13 +5,13 @@ Cross-platform skill manager for AI coding tools (Cursor, VSCode, Codex, OpenCod
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npm install -g
|
|
8
|
+
npm install -g skillmarket
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
Or use directly:
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
npx
|
|
14
|
+
npx skillmarket --help
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
## Usage
|
package/dist/index.js
CHANGED
|
@@ -96,21 +96,7 @@ import https from "https";
|
|
|
96
96
|
import { URL } from "url";
|
|
97
97
|
async function fetchNpmPackage(packageName) {
|
|
98
98
|
return new Promise((resolve, reject) => {
|
|
99
|
-
const
|
|
100
|
-
let encodedName;
|
|
101
|
-
if (isScoped) {
|
|
102
|
-
const scopeAndName = packageName.substring(1);
|
|
103
|
-
const slashIndex = scopeAndName.indexOf("/");
|
|
104
|
-
if (slashIndex > 0) {
|
|
105
|
-
const scope = scopeAndName.substring(0, slashIndex);
|
|
106
|
-
const name = scopeAndName.substring(slashIndex + 1);
|
|
107
|
-
encodedName = `@${encodeURIComponent(scope)}%2F${encodeURIComponent(name)}`;
|
|
108
|
-
} else {
|
|
109
|
-
encodedName = packageName;
|
|
110
|
-
}
|
|
111
|
-
} else {
|
|
112
|
-
encodedName = encodeURIComponent(packageName);
|
|
113
|
-
}
|
|
99
|
+
const encodedName = packageName.replace("@", "");
|
|
114
100
|
const url = new URL(`https://registry.npmjs.org/${encodedName}`);
|
|
115
101
|
const req = https.get(url.toString(), { timeout: 1e4 }, (res) => {
|
|
116
102
|
let data = "";
|
|
@@ -151,12 +137,8 @@ async function searchSkillmarketPackages() {
|
|
|
151
137
|
res.on("end", () => {
|
|
152
138
|
try {
|
|
153
139
|
const result = JSON.parse(data);
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
if (item?.package?.name) {
|
|
157
|
-
packages.push(item.package.name);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
140
|
+
for (const item of result.objects || []) {
|
|
141
|
+
packages.push(item.package.name);
|
|
160
142
|
}
|
|
161
143
|
resolve(packages);
|
|
162
144
|
} catch {
|
|
@@ -200,27 +182,12 @@ async function listSkills(options) {
|
|
|
200
182
|
console.log(`Found ${packages.length} skill(s):
|
|
201
183
|
`);
|
|
202
184
|
for (const pkgName of packages) {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
}
|
|
210
|
-
const latestVersion = info["dist-tags"]?.latest || "unknown";
|
|
211
|
-
const pkg = info.versions?.[latestVersion];
|
|
212
|
-
const skillMeta = pkg?.skillmarket;
|
|
213
|
-
console.log(`\u{1F4E6} ${info.name}@${latestVersion}`);
|
|
214
|
-
const displayName = skillMeta?.displayName || info.name;
|
|
215
|
-
console.log(` \u540D\u79F0: ${displayName}`);
|
|
216
|
-
console.log(` \u63CF\u8FF0: ${pkg?.description || "N/A"}`);
|
|
217
|
-
const platforms = skillMeta?.platforms || [];
|
|
218
|
-
console.log(` \u5E73\u53F0: ${platforms.length > 0 ? platforms.join(", ") : "N/A"}`);
|
|
219
|
-
const npmLink = pkg?.links?.npm || `https://www.npmjs.com/package/${info.name}`;
|
|
220
|
-
console.log(` \u94FE\u63A5: ${npmLink}`);
|
|
221
|
-
console.log();
|
|
222
|
-
} catch (e) {
|
|
223
|
-
console.log(`\u{1F4E6} ${pkgName} (\u83B7\u53D6\u5931\u8D25: ${e})`);
|
|
185
|
+
const info = await fetchNpmPackage(pkgName);
|
|
186
|
+
if (info) {
|
|
187
|
+
const latestVersion = info["dist-tags"]?.latest;
|
|
188
|
+
const pkg = info.versions[latestVersion];
|
|
189
|
+
console.log(` ${info.name}@${latestVersion}`);
|
|
190
|
+
console.log(` ${pkg?.description || "No description"}`);
|
|
224
191
|
console.log();
|
|
225
192
|
}
|
|
226
193
|
}
|
|
@@ -231,7 +198,7 @@ async function listSkills(options) {
|
|
|
231
198
|
|
|
232
199
|
// src/commands/info.ts
|
|
233
200
|
async function showSkillInfo(skillId) {
|
|
234
|
-
const packageName = skillId.startsWith("@") ? skillId : `@
|
|
201
|
+
const packageName = skillId.startsWith("@") ? skillId : `@skillmarket/${skillId}`;
|
|
235
202
|
console.log(`Fetching info for: ${packageName}
|
|
236
203
|
`);
|
|
237
204
|
try {
|
|
@@ -275,8 +242,8 @@ Status: Not installed (use skm install ${skillId} to install)`);
|
|
|
275
242
|
}
|
|
276
243
|
|
|
277
244
|
// src/commands/install.ts
|
|
278
|
-
import
|
|
279
|
-
import
|
|
245
|
+
import fs4 from "fs-extra";
|
|
246
|
+
import path3 from "path";
|
|
280
247
|
import { exec } from "child_process";
|
|
281
248
|
import { promisify } from "util";
|
|
282
249
|
|
|
@@ -289,17 +256,69 @@ function detectPlatform() {
|
|
|
289
256
|
if (process.env.ANTIGRAVITY) return "antigravity";
|
|
290
257
|
return "codex";
|
|
291
258
|
}
|
|
259
|
+
function isValidPlatform(name) {
|
|
260
|
+
return PLATFORMS.includes(name);
|
|
261
|
+
}
|
|
262
|
+
function getPlatformFromInput(name) {
|
|
263
|
+
const lowerName = name.toLowerCase();
|
|
264
|
+
if (isValidPlatform(lowerName)) {
|
|
265
|
+
return lowerName;
|
|
266
|
+
}
|
|
267
|
+
return null;
|
|
268
|
+
}
|
|
292
269
|
|
|
293
|
-
// src/commands/
|
|
294
|
-
|
|
295
|
-
|
|
270
|
+
// src/commands/sync.ts
|
|
271
|
+
import fs3 from "fs-extra";
|
|
272
|
+
import path2 from "path";
|
|
273
|
+
async function syncPlatformLinks(targetPlatform) {
|
|
296
274
|
await ensureMarketDirs();
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
275
|
+
const skillsDir = getSkillsDir();
|
|
276
|
+
const platformLinksDir = getPlatformLinksDir();
|
|
277
|
+
const registry = await loadRegistry();
|
|
278
|
+
let platformsToSync;
|
|
279
|
+
if (targetPlatform) {
|
|
280
|
+
const parsed = getPlatformFromInput(targetPlatform);
|
|
281
|
+
if (!parsed) {
|
|
282
|
+
console.warn(`Invalid platform: ${targetPlatform}, syncing all platforms`);
|
|
283
|
+
platformsToSync = PLATFORMS;
|
|
284
|
+
} else {
|
|
285
|
+
platformsToSync = [parsed];
|
|
286
|
+
}
|
|
300
287
|
} else {
|
|
301
|
-
|
|
288
|
+
platformsToSync = PLATFORMS;
|
|
289
|
+
}
|
|
290
|
+
const targetDesc = targetPlatform ? targetPlatform : "all platforms";
|
|
291
|
+
console.log(`Syncing platform links to ${targetDesc}...
|
|
292
|
+
`);
|
|
293
|
+
for (const platform of platformsToSync) {
|
|
294
|
+
const platformDir = path2.join(platformLinksDir, platform, "skills");
|
|
295
|
+
await fs3.ensureDir(platformDir);
|
|
296
|
+
for (const [skillId, skillInfo] of Object.entries(registry.skills)) {
|
|
297
|
+
const skillLatestLink = path2.join(skillsDir, skillId, LATEST_LINK);
|
|
298
|
+
const targetPlatformDir = path2.join(skillLatestLink, platform);
|
|
299
|
+
const platformSkillDir = path2.join(platformDir, skillId);
|
|
300
|
+
if (await fs3.pathExists(skillLatestLink)) {
|
|
301
|
+
if (await fs3.pathExists(targetPlatformDir)) {
|
|
302
|
+
try {
|
|
303
|
+
await fs3.remove(platformSkillDir);
|
|
304
|
+
await fs3.symlink(targetPlatformDir, platformSkillDir, "junction");
|
|
305
|
+
console.log(` Linked: ${platform}/${skillId}`);
|
|
306
|
+
} catch {
|
|
307
|
+
await fs3.copy(targetPlatformDir, platformSkillDir, { overwrite: true });
|
|
308
|
+
console.log(` Copied: ${platform}/${skillId}`);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
302
313
|
}
|
|
314
|
+
console.log("\n\u2705 Sync complete!");
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// src/commands/install.ts
|
|
318
|
+
var execAsync = promisify(exec);
|
|
319
|
+
async function installSkill(skillId, version, targetPlatform) {
|
|
320
|
+
await ensureMarketDirs();
|
|
321
|
+
const packageName = skillId.startsWith("@") ? skillId : `@skillmarket/${skillId}`;
|
|
303
322
|
console.log(`Installing ${packageName}${version ? `@${version}` : ""}...`);
|
|
304
323
|
const pkgInfo = await fetchNpmPackage(packageName);
|
|
305
324
|
if (!pkgInfo) {
|
|
@@ -310,104 +329,85 @@ async function installSkill(skillId, version) {
|
|
|
310
329
|
throw new Error(`No version found for ${packageName}`);
|
|
311
330
|
}
|
|
312
331
|
const cacheDir = getCacheDir();
|
|
313
|
-
const targetDir =
|
|
314
|
-
if (!await
|
|
332
|
+
const targetDir = path3.join(cacheDir, `${packageName}@${targetVersion}`);
|
|
333
|
+
if (!await fs4.pathExists(targetDir)) {
|
|
315
334
|
console.log("Downloading package...");
|
|
316
|
-
await
|
|
335
|
+
await fs4.ensureDir(cacheDir);
|
|
317
336
|
try {
|
|
318
337
|
await execAsync(`npm pack ${packageName}@${targetVersion} --pack-destination ${cacheDir}`);
|
|
319
|
-
const files = await
|
|
338
|
+
const files = await fs4.readdir(cacheDir);
|
|
320
339
|
const tarball = files.find(
|
|
321
340
|
(f) => f.endsWith(".tgz") && f.includes(packageName.replace("/", "-"))
|
|
322
341
|
);
|
|
323
342
|
if (tarball) {
|
|
324
|
-
await execAsync(`tar -xzf "${
|
|
325
|
-
await
|
|
326
|
-
const extractedDir =
|
|
343
|
+
await execAsync(`tar -xzf "${path3.join(cacheDir, tarball)}" -C "${cacheDir}"`);
|
|
344
|
+
await fs4.remove(path3.join(cacheDir, tarball));
|
|
345
|
+
const extractedDir = path3.join(cacheDir, "package");
|
|
327
346
|
const finalDir = targetDir;
|
|
328
|
-
await
|
|
347
|
+
await fs4.move(extractedDir, finalDir, { overwrite: true });
|
|
329
348
|
}
|
|
330
349
|
} catch (err) {
|
|
331
350
|
throw new Error(`Failed to download package: ${err}`);
|
|
332
351
|
}
|
|
333
352
|
}
|
|
334
353
|
const skillsDir = getSkillsDir();
|
|
335
|
-
const skillVersionDir =
|
|
354
|
+
const skillVersionDir = path3.join(skillsDir, `${skillId}@${targetVersion}`);
|
|
336
355
|
console.log("Setting up skill...");
|
|
337
|
-
await
|
|
356
|
+
await fs4.ensureDir(skillVersionDir);
|
|
338
357
|
const pkgRoot = targetDir;
|
|
339
|
-
if (await
|
|
340
|
-
await
|
|
341
|
-
|
|
342
|
-
|
|
358
|
+
if (await fs4.pathExists(path3.join(pkgRoot, "SKILL.md"))) {
|
|
359
|
+
await fs4.copy(
|
|
360
|
+
path3.join(pkgRoot, "SKILL.md"),
|
|
361
|
+
path3.join(skillVersionDir, "SKILL.md")
|
|
343
362
|
);
|
|
344
363
|
}
|
|
345
|
-
if (await
|
|
346
|
-
await
|
|
347
|
-
|
|
348
|
-
|
|
364
|
+
if (await fs4.pathExists(path3.join(pkgRoot, "metadata.json"))) {
|
|
365
|
+
await fs4.copy(
|
|
366
|
+
path3.join(pkgRoot, "metadata.json"),
|
|
367
|
+
path3.join(skillVersionDir, "metadata.json")
|
|
349
368
|
);
|
|
350
369
|
}
|
|
351
|
-
const skillDir =
|
|
352
|
-
await
|
|
353
|
-
const latestLink =
|
|
370
|
+
const skillDir = path3.join(skillsDir, skillId);
|
|
371
|
+
await fs4.ensureDir(skillDir);
|
|
372
|
+
const latestLink = path3.join(skillDir, LATEST_LINK);
|
|
354
373
|
try {
|
|
355
|
-
await
|
|
356
|
-
await
|
|
374
|
+
await fs4.remove(latestLink);
|
|
375
|
+
await fs4.symlink(skillVersionDir, latestLink, "junction");
|
|
357
376
|
} catch {
|
|
358
|
-
await
|
|
377
|
+
await fs4.copy(skillVersionDir, path3.join(skillDir, LATEST_LINK), { overwrite: true });
|
|
359
378
|
}
|
|
379
|
+
let finalPlatform;
|
|
380
|
+
if (targetPlatform) {
|
|
381
|
+
const parsed = getPlatformFromInput(targetPlatform);
|
|
382
|
+
if (!parsed) {
|
|
383
|
+
throw new Error(`Invalid platform: ${targetPlatform}. Valid platforms: ${PLATFORMS.join(", ")}`);
|
|
384
|
+
}
|
|
385
|
+
finalPlatform = parsed;
|
|
386
|
+
} else {
|
|
387
|
+
finalPlatform = detectPlatform();
|
|
388
|
+
}
|
|
389
|
+
console.log(`Target platform: ${finalPlatform}`);
|
|
360
390
|
const registry = await loadRegistry();
|
|
361
|
-
const
|
|
391
|
+
const existingSkill = registry.skills[skillId];
|
|
392
|
+
const existingPlatforms = existingSkill?.platforms || [];
|
|
362
393
|
registry.skills[skillId] = {
|
|
363
394
|
id: skillId,
|
|
364
395
|
version: targetVersion,
|
|
365
396
|
installedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
366
|
-
platforms: [
|
|
397
|
+
platforms: existingPlatforms.includes(finalPlatform) ? existingPlatforms : [...existingPlatforms, finalPlatform]
|
|
367
398
|
};
|
|
368
399
|
await saveRegistry(registry);
|
|
400
|
+
console.log(`Syncing to ${finalPlatform}...`);
|
|
401
|
+
await syncPlatformLinks(finalPlatform);
|
|
369
402
|
console.log(`
|
|
370
403
|
\u2705 ${skillId}@${targetVersion} installed successfully!`);
|
|
371
404
|
console.log(` Use "skm info ${skillId}" for more details`);
|
|
372
405
|
}
|
|
373
406
|
|
|
374
|
-
// src/commands/sync.ts
|
|
375
|
-
import fs4 from "fs-extra";
|
|
376
|
-
import path3 from "path";
|
|
377
|
-
async function syncPlatformLinks() {
|
|
378
|
-
await ensureMarketDirs();
|
|
379
|
-
const skillsDir = getSkillsDir();
|
|
380
|
-
const platformLinksDir = getPlatformLinksDir();
|
|
381
|
-
const registry = await loadRegistry();
|
|
382
|
-
console.log("Syncing platform links...\n");
|
|
383
|
-
for (const platform of PLATFORMS) {
|
|
384
|
-
const platformDir = path3.join(platformLinksDir, platform, "skills");
|
|
385
|
-
await fs4.ensureDir(platformDir);
|
|
386
|
-
for (const [skillId, skillInfo] of Object.entries(registry.skills)) {
|
|
387
|
-
const skillLatestLink = path3.join(skillsDir, skillId, LATEST_LINK);
|
|
388
|
-
const targetPlatformDir = path3.join(skillLatestLink, platform);
|
|
389
|
-
const platformSkillDir = path3.join(platformDir, skillId);
|
|
390
|
-
if (await fs4.pathExists(skillLatestLink)) {
|
|
391
|
-
if (await fs4.pathExists(targetPlatformDir)) {
|
|
392
|
-
try {
|
|
393
|
-
await fs4.remove(platformSkillDir);
|
|
394
|
-
await fs4.symlink(targetPlatformDir, platformSkillDir, "junction");
|
|
395
|
-
console.log(` Linked: ${platform}/${skillId}`);
|
|
396
|
-
} catch {
|
|
397
|
-
await fs4.copy(targetPlatformDir, platformSkillDir, { overwrite: true });
|
|
398
|
-
console.log(` Copied: ${platform}/${skillId}`);
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
console.log("\n\u2705 Sync complete!");
|
|
405
|
-
}
|
|
406
|
-
|
|
407
407
|
// src/commands/update.ts
|
|
408
408
|
async function updateSkill(skillId) {
|
|
409
409
|
if (skillId) {
|
|
410
|
-
const pkgInfo = await fetchNpmPackage(`@
|
|
410
|
+
const pkgInfo = await fetchNpmPackage(`@skillmarket/${skillId}`);
|
|
411
411
|
if (pkgInfo) {
|
|
412
412
|
const latestVersion = pkgInfo["dist-tags"]?.latest;
|
|
413
413
|
console.log(`Updating ${skillId} to ${latestVersion}...`);
|
|
@@ -424,7 +424,7 @@ async function updateSkill(skillId) {
|
|
|
424
424
|
`);
|
|
425
425
|
let hasUpdates = false;
|
|
426
426
|
for (const skill of installed) {
|
|
427
|
-
const pkgInfo = await fetchNpmPackage(`@
|
|
427
|
+
const pkgInfo = await fetchNpmPackage(`@skillmarket/${skill.id}`);
|
|
428
428
|
if (pkgInfo) {
|
|
429
429
|
const latestVersion = pkgInfo["dist-tags"]?.latest;
|
|
430
430
|
if (latestVersion && latestVersion !== skill.version) {
|
|
@@ -475,40 +475,37 @@ async function uninstallSkill(skillId) {
|
|
|
475
475
|
// src/cli.ts
|
|
476
476
|
var program = new Command();
|
|
477
477
|
program.name("skm").description("SkillMarket - Cross-platform skill manager for AI coding tools").version("1.0.0");
|
|
478
|
-
program.
|
|
479
|
-
|
|
480
|
-
console.log(`
|
|
478
|
+
program.option("-h, --help", "Display help information").action(() => {
|
|
479
|
+
console.log(`
|
|
481
480
|
SkillMarket CLI
|
|
482
481
|
|
|
483
482
|
Usage: skm <command> [options]
|
|
484
483
|
|
|
485
484
|
Commands:
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
485
|
+
--help, -h Display this help message
|
|
486
|
+
--ls [options] List available skills
|
|
487
|
+
--installed Show only installed skills
|
|
488
|
+
--updates Check for updates
|
|
489
|
+
--info <skill-id> Display skill information
|
|
490
|
+
--install <skill> Install a skill (e.g., skm --install brainstorming)
|
|
491
|
+
@version Install specific version
|
|
492
|
+
--all Install all available skills
|
|
493
|
+
--uninstall <skill> Remove an installed skill
|
|
494
|
+
--update [options] Update skills
|
|
495
|
+
--all Update all skills
|
|
496
|
+
--sync Synchronize platform links
|
|
497
|
+
--platform <name> Set target platform (${PLATFORMS.join(", ")})
|
|
498
498
|
|
|
499
499
|
Examples:
|
|
500
|
-
skm ls
|
|
501
|
-
skm ls --installed
|
|
502
|
-
skm info brainstorming View skill details
|
|
503
|
-
skm install brainstorming
|
|
504
|
-
skm install brainstorming@1.0.0 Install specific version
|
|
505
|
-
skm update --all Update all installed skills
|
|
506
|
-
|
|
507
|
-
process.exit(0);
|
|
508
|
-
}
|
|
500
|
+
skm --ls List all available skills
|
|
501
|
+
skm --ls --installed Show installed skills only
|
|
502
|
+
skm --info brainstorming View skill details
|
|
503
|
+
skm --install brainstorming Install a skill
|
|
504
|
+
skm --install brainstorming@1.0.0 Install specific version
|
|
505
|
+
skm --update --all Update all installed skills
|
|
506
|
+
`);
|
|
509
507
|
});
|
|
510
|
-
|
|
511
|
-
lsCmd.option("--installed", "Show only installed skills").option("--updates", "Check for updates").action((opts) => {
|
|
508
|
+
program.option("-ls, --ls", "List available skills").option("--installed", "Show only installed skills").option("--updates", "Check for updates").action((opts) => {
|
|
512
509
|
listSkills(opts);
|
|
513
510
|
});
|
|
514
511
|
var infoCmd = program.command("info").description("Display skill information");
|
|
@@ -516,9 +513,9 @@ infoCmd.argument("<skill-id>", "Skill ID to show info").action((skillId) => {
|
|
|
516
513
|
showSkillInfo(skillId);
|
|
517
514
|
});
|
|
518
515
|
var installCmd = program.command("install").description("Install a skill");
|
|
519
|
-
installCmd.argument("<skill>", "Skill ID to install (e.g., brainstorming or @scope/name)").option("--all", "Install all available skills").action(async (skill, opts) => {
|
|
516
|
+
installCmd.argument("<skill>", "Skill ID to install (e.g., brainstorming or @scope/name)").option("--all", "Install all available skills").option("-p, --platform <platform>", `Target platform (${PLATFORMS.join(", ")})`).action(async (skill, opts) => {
|
|
520
517
|
try {
|
|
521
|
-
await installSkill(skill);
|
|
518
|
+
await installSkill(skill, void 0, opts.platform);
|
|
522
519
|
} catch (err) {
|
|
523
520
|
console.error("Installation failed:", err);
|
|
524
521
|
process.exit(1);
|
package/package.json
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "itismyskillmarket",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Cross-platform skill manager for AI coding tools",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist",
|
|
8
|
+
"src",
|
|
9
|
+
"README.md"
|
|
10
|
+
],
|
|
6
11
|
"bin": {
|
|
7
|
-
"skm": "dist/index.js"
|
|
12
|
+
"skm": "./dist/index.js"
|
|
8
13
|
},
|
|
9
14
|
"scripts": {
|
|
10
15
|
"build": "tsup",
|
package/src/cli.ts
CHANGED
|
@@ -75,37 +75,36 @@ program
|
|
|
75
75
|
* 显示详细的使用说明和命令示例
|
|
76
76
|
*/
|
|
77
77
|
program
|
|
78
|
-
.
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
.option('-h, --help', 'Display help information')
|
|
79
|
+
.action(() => {
|
|
80
|
+
console.log(`
|
|
81
81
|
SkillMarket CLI
|
|
82
82
|
|
|
83
83
|
Usage: skm <command> [options]
|
|
84
84
|
|
|
85
85
|
Commands:
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
86
|
+
--help, -h Display this help message
|
|
87
|
+
--ls [options] List available skills
|
|
88
|
+
--installed Show only installed skills
|
|
89
|
+
--updates Check for updates
|
|
90
|
+
--info <skill-id> Display skill information
|
|
91
|
+
--install <skill> Install a skill (e.g., skm --install brainstorming)
|
|
92
|
+
@version Install specific version
|
|
93
|
+
--all Install all available skills
|
|
94
|
+
--uninstall <skill> Remove an installed skill
|
|
95
|
+
--update [options] Update skills
|
|
96
|
+
--all Update all skills
|
|
97
|
+
--sync Synchronize platform links
|
|
98
|
+
--platform <name> Set target platform (${PLATFORMS.join(', ')})
|
|
98
99
|
|
|
99
100
|
Examples:
|
|
100
|
-
skm ls
|
|
101
|
-
skm ls --installed
|
|
102
|
-
skm info brainstorming View skill details
|
|
103
|
-
skm install brainstorming
|
|
104
|
-
skm install brainstorming@1.0.0 Install specific version
|
|
105
|
-
skm update --all Update all installed skills
|
|
106
|
-
|
|
107
|
-
process.exit(0);
|
|
108
|
-
}
|
|
101
|
+
skm --ls List all available skills
|
|
102
|
+
skm --ls --installed Show installed skills only
|
|
103
|
+
skm --info brainstorming View skill details
|
|
104
|
+
skm --install brainstorming Install a skill
|
|
105
|
+
skm --install brainstorming@1.0.0 Install specific version
|
|
106
|
+
skm --update --all Update all installed skills
|
|
107
|
+
`);
|
|
109
108
|
});
|
|
110
109
|
|
|
111
110
|
// -----------------------------------------------------------------------------
|
|
@@ -122,8 +121,8 @@ Examples:
|
|
|
122
121
|
* - skm ls --installed 列出已安装的 skills
|
|
123
122
|
* - skm ls --updates 检查更新
|
|
124
123
|
*/
|
|
125
|
-
|
|
126
|
-
|
|
124
|
+
program
|
|
125
|
+
.option('-ls, --ls', 'List available skills')
|
|
127
126
|
.option('--installed', 'Show only installed skills')
|
|
128
127
|
.option('--updates', 'Check for updates')
|
|
129
128
|
.action((opts) => {
|
|
@@ -173,9 +172,10 @@ const installCmd = program.command('install').description('Install a skill');
|
|
|
173
172
|
installCmd
|
|
174
173
|
.argument('<skill>', 'Skill ID to install (e.g., brainstorming or @scope/name)')
|
|
175
174
|
.option('--all', 'Install all available skills')
|
|
175
|
+
.option('-p, --platform <platform>', `Target platform (${PLATFORMS.join(', ')})`)
|
|
176
176
|
.action(async (skill, opts) => {
|
|
177
177
|
try {
|
|
178
|
-
await installSkill(skill);
|
|
178
|
+
await installSkill(skill, undefined, opts.platform);
|
|
179
179
|
} catch (err) {
|
|
180
180
|
console.error('Installation failed:', err);
|
|
181
181
|
process.exit(1);
|
package/src/commands/info.ts
CHANGED
|
@@ -53,12 +53,12 @@ export async function showSkillInfo(skillId: string): Promise<void> {
|
|
|
53
53
|
* 转换 skillId 为完整的 npm 包名格式
|
|
54
54
|
*
|
|
55
55
|
* 支持两种输入格式:
|
|
56
|
-
* 1. 短格式: "brainstorming" → "@
|
|
56
|
+
* 1. 短格式: "brainstorming" → "@skillmarket/brainstorming"
|
|
57
57
|
* 2. 完整格式: "@custom/skill" → "@custom/skill"
|
|
58
58
|
*/
|
|
59
59
|
const packageName = skillId.startsWith('@')
|
|
60
60
|
? skillId // 已经是 scoped 包名
|
|
61
|
-
: `@
|
|
61
|
+
: `@skillmarket/${skillId}`; // 转换为 scoped 包名
|
|
62
62
|
|
|
63
63
|
console.log(`Fetching info for: ${packageName}\n`);
|
|
64
64
|
|