itismyskillmarket 1.3.0 → 1.3.2

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.
Files changed (49) hide show
  1. package/.github/workflows/publish-npm.yml +59 -0
  2. package/.github/workflows/publish-skill.yml +72 -0
  3. package/5e51cb7aa8b8e60d49d86f4689f5d4d1.png +0 -0
  4. package/CHANGELOG.md +410 -0
  5. package/DEVELOPMENT.md +376 -0
  6. package/README.md +75 -6
  7. package/SKILLMARKET-GUIDE.md +288 -0
  8. package/dist/index.js +733 -212
  9. package/docs/WEEKLY-UPDATE-2026-04-23.md +43 -0
  10. package/docs/plans/2026-04-01-skillmarket-design.md +267 -0
  11. package/docs/plans/2026-04-01-skillmarket-implementation.md +1031 -0
  12. package/docs/plans/2026-04-15-cross-platform-adapter-design.md +416 -0
  13. package/docs/plans/2026-04-15-cross-platform-adapter-plan.md +833 -0
  14. package/docs/plans/2026-04-16-keyword-search-design.md +143 -0
  15. package/docs/plans/2026-04-29-weekly-update.md +57 -0
  16. package/package.json +1 -6
  17. package/skills/README.md +54 -0
  18. package/skills/test-skill/SKILL.md +25 -0
  19. package/skills/test-skill/index.js +66 -0
  20. package/skills/test-skill/metadata.json +9 -0
  21. package/skills/test-skill/package.json +19 -0
  22. package/skills/test-skill-1/SKILL.md +24 -0
  23. package/skills/test-skill-1/index.js +13 -0
  24. package/skills/test-skill-1/metadata.json +9 -0
  25. package/skills/test-skill-1/package.json +16 -0
  26. package/skills/test-skill-2/SKILL.md +25 -0
  27. package/skills/test-skill-2/index.js +13 -0
  28. package/skills/test-skill-2/metadata.json +9 -0
  29. package/skills/test-skill-2/package.json +16 -0
  30. package/src/adapters/base.ts +87 -0
  31. package/src/adapters/claude.ts +31 -0
  32. package/src/adapters/index.ts +9 -0
  33. package/src/adapters/opencode.ts +40 -0
  34. package/src/adapters/registry.ts +77 -0
  35. package/src/adapters/vscode.ts +62 -0
  36. package/src/cli.ts +189 -75
  37. package/src/commands/info.ts +4 -15
  38. package/src/commands/install.ts +93 -54
  39. package/src/commands/ls.ts +182 -17
  40. package/src/commands/npm.ts +118 -16
  41. package/src/commands/search.ts +12 -7
  42. package/src/commands/sync.ts +6 -27
  43. package/src/commands/uninstall.ts +313 -15
  44. package/src/commands/update.ts +2 -2
  45. package/src/index.ts +27 -0
  46. package/src/types.ts +35 -0
  47. package/tsconfig.json +10 -0
  48. package/tsup.config.ts +22 -0
  49. package/wanxuchen-skillmarket-1.0.1.tgz +0 -0
@@ -0,0 +1,40 @@
1
+ /**
2
+ * =============================================================================
3
+ * OpenCode Platform Adapter
4
+ * =============================================================================
5
+ *
6
+ * Handles skill installation for OpenCode AI coding tool.
7
+ * Skills are installed to ~/.config/opencode/skills/<skill-id>/
8
+ */
9
+
10
+ import path from 'path';
11
+ import os from 'os';
12
+ import fs from 'fs-extra';
13
+ import { BaseAdapter } from './base.js';
14
+
15
+ export class OpenCodeAdapter extends BaseAdapter {
16
+ readonly id = 'opencode';
17
+ readonly name = 'OpenCode';
18
+
19
+ get skillDir(): string {
20
+ // Respect OPENCODE_CONFIG_DIR environment variable
21
+ const configDir = process.env.OPENCODE_CONFIG_DIR
22
+ || path.join(os.homedir(), '.config', 'opencode');
23
+ return path.join(configDir, 'skills');
24
+ }
25
+
26
+ async isAvailable(): Promise<boolean> {
27
+ // Check for environment variable or directory
28
+ if (process.env.OPENCODE) return true;
29
+
30
+ const configDir = process.env.OPENCODE_CONFIG_DIR
31
+ || path.join(os.homedir(), '.config', 'opencode');
32
+
33
+ try {
34
+ await fs.ensureDir(path.join(configDir, 'skills'));
35
+ return true;
36
+ } catch {
37
+ return false;
38
+ }
39
+ }
40
+ }
@@ -0,0 +1,77 @@
1
+ /**
2
+ * =============================================================================
3
+ * Platform Registry
4
+ * =============================================================================
5
+ *
6
+ * Central registry for platform adapters.
7
+ * Handles platform detection and selection.
8
+ */
9
+
10
+ import { OpenCodeAdapter } from './opencode.js';
11
+ import { ClaudeAdapter } from './claude.js';
12
+ import { VSCodeAdapter } from './vscode.js';
13
+ import type { PlatformAdapter } from '../types.js';
14
+ import type { Platform } from '../constants.js';
15
+
16
+ const adapters: Map<string, PlatformAdapter> = new Map();
17
+
18
+ /**
19
+ * Register all built-in platform adapters
20
+ */
21
+ function registerAdapters(): void {
22
+ const opencode = new OpenCodeAdapter();
23
+ const claude = new ClaudeAdapter();
24
+ const vscode = new VSCodeAdapter();
25
+
26
+ adapters.set(opencode.id, opencode);
27
+ adapters.set(claude.id, claude);
28
+ adapters.set(vscode.id, vscode);
29
+ }
30
+
31
+ // Register adapters on module load
32
+ registerAdapters();
33
+
34
+ /**
35
+ * Detect which platforms are available on the current system
36
+ */
37
+ export async function detectPlatforms(): Promise<PlatformAdapter[]> {
38
+ const available: PlatformAdapter[] = [];
39
+
40
+ for (const adapter of adapters.values()) {
41
+ if (await adapter.isAvailable()) {
42
+ available.push(adapter);
43
+ }
44
+ }
45
+
46
+ return available;
47
+ }
48
+
49
+ /**
50
+ * Get adapter for a specific platform
51
+ */
52
+ export function getPlatformAdapter(platformId: string): PlatformAdapter | undefined {
53
+ return adapters.get(platformId);
54
+ }
55
+
56
+ /**
57
+ * Get all registered adapters
58
+ */
59
+ export function getAllAdapters(): PlatformAdapter[] {
60
+ return Array.from(adapters.values());
61
+ }
62
+
63
+ /**
64
+ * Get adapter by platform type
65
+ */
66
+ export function getAdapterByPlatform(platform: Platform): PlatformAdapter | undefined {
67
+ const idMap: Record<Platform, string> = {
68
+ opencode: 'opencode',
69
+ claude: 'claude',
70
+ vscode: 'vscode',
71
+ cursor: 'opencode', // Cursor uses OpenCode-compatible structure
72
+ codex: 'opencode', // Codex uses OpenCode-compatible structure
73
+ antigravity: 'opencode', // Antigravity uses OpenCode-compatible structure
74
+ };
75
+
76
+ return adapters.get(idMap[platform]);
77
+ }
@@ -0,0 +1,62 @@
1
+ /**
2
+ * =============================================================================
3
+ * VSCode (Copilot) Platform Adapter
4
+ * =============================================================================
5
+ *
6
+ * Handles skill installation for VSCode GitHub Copilot Agent Skills.
7
+ * Skills are installed to ~/.copilot/skills/<skill-id>/
8
+ *
9
+ * Note: Also supports ~/.claude/skills/ for cross-compatibility.
10
+ */
11
+
12
+ import path from 'path';
13
+ import os from 'os';
14
+ import fs from 'fs-extra';
15
+ import { BaseAdapter } from './base.js';
16
+
17
+ export class VSCodeAdapter extends BaseAdapter {
18
+ readonly id = 'vscode';
19
+ readonly name = 'VSCode';
20
+
21
+ get skillDir(): string {
22
+ // Try ~/.copilot/skills first, fallback to ~/.claude/skills
23
+ return path.join(os.homedir(), '.copilot', 'skills');
24
+ }
25
+
26
+ async isAvailable(): Promise<boolean> {
27
+ // Check multiple possible locations
28
+ const possibleDirs = [
29
+ path.join(os.homedir(), '.copilot', 'skills'),
30
+ path.join(os.homedir(), '.claude', 'skills'),
31
+ ];
32
+
33
+ for (const dir of possibleDirs) {
34
+ try {
35
+ await fs.ensureDir(dir);
36
+ return true;
37
+ } catch {
38
+ continue;
39
+ }
40
+ }
41
+
42
+ return false;
43
+ }
44
+
45
+ async install(skillId: string, sourceDir: string): Promise<void> {
46
+ // Install to ~/.copilot/skills, but also create symlink in ~/.claude/skills
47
+ await super.install(skillId, sourceDir);
48
+
49
+ // Create cross-compatible symlink in ~/.claude/skills
50
+ const claudeSkillDir = path.join(os.homedir(), '.claude', 'skills');
51
+ const targetPath = this.getSkillPath(skillId);
52
+ const claudeTargetPath = path.join(claudeSkillDir, skillId);
53
+
54
+ try {
55
+ await fs.ensureDir(claudeSkillDir);
56
+ await fs.remove(claudeTargetPath);
57
+ await fs.symlink(targetPath, claudeTargetPath, 'junction');
58
+ } catch {
59
+ // Silently fail if symlink not possible (cross-platform compatibility)
60
+ }
61
+ }
62
+ }
package/src/cli.ts CHANGED
@@ -14,10 +14,11 @@
14
14
  * - skm ls 列出可用的 skills
15
15
  * - skm ls --installed 列出已安装的 skills
16
16
  * - skm info <skill> 显示 skill 详情
17
- * - skm install <skill> 安装 skill
18
- * - skm uninstall <skill> 卸载 skill
17
+ * - skm install <skill> 安装 skill(支持 --platform)
18
+ * - skm uninstall <skill> 卸载 skill(支持 --platform)
19
19
  * - skm update [skill] 更新 skill(s)
20
20
  * - skm sync 同步平台链接
21
+ * - skm platforms 显示可用平台
21
22
  *
22
23
  * @module cli
23
24
  */
@@ -28,16 +29,26 @@
28
29
 
29
30
  // Commander.js - 轻量级的命令行界面框架
30
31
  import { Command } from 'commander';
32
+ import { readFileSync } from 'fs';
33
+ import { fileURLToPath } from 'url';
34
+ import { dirname, resolve } from 'path';
35
+
36
+ // 获取 package.json 中的版本号
37
+ const __filename = fileURLToPath(import.meta.url);
38
+ const __dirname = dirname(__filename);
39
+ const packageJson = JSON.parse(readFileSync(resolve(__dirname, '../package.json'), 'utf-8'));
40
+ const VERSION = packageJson.version || '1.3.1';
31
41
 
32
42
  // 内部模块导入
33
43
  import { PLATFORMS } from './constants.js'; // 平台常量
34
44
  import { listSkills } from './commands/ls.js'; // 列表命令
45
+ import { searchSkills } from './commands/search.js'; // 搜索命令
35
46
  import { showSkillInfo } from './commands/info.js'; // 信息命令
36
47
  import { installSkill } from './commands/install.js'; // 安装命令
37
48
  import { syncPlatformLinks } from './commands/sync.js'; // 同步命令
38
49
  import { updateSkill } from './commands/update.js'; // 更新命令
39
- import { uninstallSkill } from './commands/uninstall.js'; // 卸载命令
40
- import { searchSkills } from './commands/search.js'; // 搜索命令
50
+ import { uninstallSkill, uninstallAll } from './commands/uninstall.js'; // 卸载命令
51
+ import { detectPlatforms, getAllAdapters, OpenCodeAdapter, ClaudeAdapter, VSCodeAdapter } from './adapters/index.js'; // 平台适配器
41
52
 
42
53
  // -----------------------------------------------------------------------------
43
54
  // 创建命令程序实例
@@ -64,7 +75,7 @@ const program = new Command();
64
75
  program
65
76
  .name('skm')
66
77
  .description('SkillMarket - Cross-platform skill manager for AI coding tools')
67
- .version('1.2.10');
78
+ .version(VERSION);
68
79
 
69
80
  // -----------------------------------------------------------------------------
70
81
  // 帮助命令 (-h, --help)
@@ -75,38 +86,58 @@ program
75
86
  *
76
87
  * 显示详细的使用说明和命令示例
77
88
  */
78
- const helpCmd = program.command('help').description('Display help information');
79
- helpCmd.action(() => {
89
+ program
90
+ .hook('preAction', (thisCommand) => {
91
+ if (thisCommand.opts().help) {
80
92
  console.log(`
81
93
  SkillMarket CLI
82
94
 
83
95
  Usage: skm <command> [options]
84
96
 
85
97
  Commands:
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
+ ls [options] List available skills
99
+ --installed Show only installed skills
100
+ --updates Check for updates
101
+ --page <n> Page number (default: 1)
102
+ --limit <n> Items per page (default: 20)
103
+ -s, --search Search by keyword
104
+ info <skill-id> Display skill information
105
+ install <skill> Install a skill
106
+ @version Install specific version
107
+ --platform Target platforms (opencode,claude,vscode)
108
+ --force Overwrite if already installed
109
+ uninstall <skill> Remove an installed skill
110
+ --platform Target platforms
111
+ --all Uninstall ALL installed skills
112
+ --dry-run Preview without deleting
113
+ -y, --yes Skip confirmation
114
+ update [options] Update skills
115
+ --all Update all skills
116
+ sync Synchronize platform links
117
+ platforms Show available platforms
99
118
 
100
119
  Examples:
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
- skm --sync Sync platform links
108
- `);
109
- });
120
+ skm ls List all available skills (page 1)
121
+ skm ls --page 2 Go to page 2
122
+ skm ls --limit 10 Show 10 items per page
123
+ skm ls --search brain Search skills by keyword
124
+ skm ls -s brain Search with short form
125
+ skm ls --installed Show installed skills only
126
+ skm ls --installed --search test Search installed skills
127
+ skm ls --installed --page 2
128
+ skm info brainstorming View skill details
129
+ skm install brainstorming Install to all platforms
130
+ skm install brainstorming --platform opencode Install to OpenCode only
131
+ skm install brainstorming --platform claude,vscode Install to multiple
132
+ skm uninstall brainstorming
133
+ skm uninstall --all Uninstall all skills (with confirmation)
134
+ skm uninstall --all --yes Force uninstall all without confirmation
135
+ skm uninstall brainstorming --dry-run Preview uninstall
136
+ skm platforms Show available platforms
137
+ `);
138
+ process.exit(0);
139
+ }
140
+ });
110
141
 
111
142
  // -----------------------------------------------------------------------------
112
143
  // 列表命令 (skm ls)
@@ -126,8 +157,41 @@ const lsCmd = program.command('ls').description('List available skills');
126
157
  lsCmd
127
158
  .option('--installed', 'Show only installed skills')
128
159
  .option('--updates', 'Check for updates')
160
+ .option('-p, --page <number>', 'Page number (default: 1)', parseInt)
161
+ .option('-l, --limit <number>', 'Items per page (default: 20)', parseInt)
162
+ .option('-s, --search <keyword>', 'Search by keyword (id, displayName, description)')
129
163
  .action((opts) => {
130
- listSkills(opts);
164
+ // Ensure numeric options have default values if not provided
165
+ const options = {
166
+ ...opts,
167
+ page: opts.page ?? 1,
168
+ limit: opts.limit ?? 20,
169
+ search: opts.search
170
+ };
171
+ listSkills(options);
172
+ });
173
+
174
+ // -----------------------------------------------------------------------------
175
+ // 搜索命令 (skm search)
176
+ // -----------------------------------------------------------------------------
177
+
178
+ /**
179
+ * 搜索命令
180
+ *
181
+ * 独立搜索 npm 上的 skills
182
+ *
183
+ * 用法: skm search <keyword>
184
+ *
185
+ * @example
186
+ * skm search brain
187
+ */
188
+ const searchCmd = program.command('search').description('Search skills from npm registry');
189
+ searchCmd
190
+ .argument('<keyword>', 'Keyword to search')
191
+ .option('-l, --limit <number>', 'Max results to show (default: 20)', parseInt)
192
+ .action(async (keyword, opts) => {
193
+ const limit = opts.limit ?? 20;
194
+ await searchSkills(keyword, limit);
131
195
  });
132
196
 
133
197
  // -----------------------------------------------------------------------------
@@ -158,25 +222,36 @@ infoCmd
158
222
  /**
159
223
  * 安装命令
160
224
  *
161
- * 从 npm 安装指定的 skill 到本地
225
+ * 从 npm 安装指定的 skill 到本地和跨平台目录
162
226
  *
163
227
  * 用法:
164
- * - skm install <skill> 安装最新版本
228
+ * - skm install <skill> 安装到所有检测到的平台
165
229
  * - skm install <skill>@<ver> 安装指定版本
166
- * - skm install --all 安装所有可用 skills(预留)
230
+ * - skm install --platform opencode 安装到特定平台
231
+ * - skm install --platform claude,vscode 安装到多个平台
232
+ * - skm install --force 强制覆盖
167
233
  *
168
234
  * @example
169
235
  * skm install brainstorming
170
236
  * skm install brainstorming@1.0.0
237
+ * skm install brainstorming --platform opencode
171
238
  */
172
- const installCmd = program.command('install').description('Install a skill');
239
+ const installCmd = program.command('install').description('Install a skill to local and platform directories');
173
240
  installCmd
174
241
  .argument('<skill>', 'Skill ID to install (e.g., brainstorming or @scope/name)')
175
- .option('--all', 'Install all available skills')
176
- .option('-p, --platform <platform>', `Target platform (${PLATFORMS.join(', ')})`)
242
+ .option('-p, --platform <platforms>', 'Target platforms (comma-separated: opencode,claude,vscode)')
243
+ .option('-f, --force', 'Overwrite if already installed')
244
+ .option('-v, --version <version>', 'Specific version to install')
177
245
  .action(async (skill, opts) => {
178
246
  try {
179
- await installSkill(skill, undefined, opts.platform);
247
+ const platforms = opts.platform
248
+ ? opts.platform.split(',').map((p: string) => p.trim())
249
+ : undefined;
250
+
251
+ await installSkill(skill, opts.version, {
252
+ platforms,
253
+ force: opts.force
254
+ });
180
255
  } catch (err) {
181
256
  console.error('Installation failed:', err);
182
257
  process.exit(1);
@@ -190,19 +265,60 @@ installCmd
190
265
  /**
191
266
  * 卸载命令
192
267
  *
193
- * 移除本地已安装的 skill
268
+ * 移除本地已安装的 skill 及各平台的文件
194
269
  *
195
- * 用法: skm uninstall <skill-id>
270
+ * 用法:
271
+ * - skm uninstall <skill> 卸载所有平台
272
+ * - skm uninstall <skill> --platform opencode 卸载特定平台
273
+ * - skm uninstall --all 卸载所有已安装的 skills
274
+ * - skm uninstall --dry-run 预览删除内容
275
+ *
276
+ * 新增 (v1.4.0):
277
+ * --all: 卸载所有已安装的 skills(需要确认)
278
+ * --dry-run: 预览模式,不实际删除
279
+ * -y, --yes: 跳过确认提示
196
280
  *
197
281
  * @example
198
282
  * skm uninstall brainstorming
283
+ * skm uninstall brainstorming --platform claude
284
+ * skm uninstall --all
285
+ * skm uninstall --all --yes
286
+ * skm uninstall brainstorming --dry-run
199
287
  */
200
- const uninstallCmd = program.command('uninstall').description('Remove an installed skill');
288
+ const uninstallCmd = program.command('uninstall').description('Remove an installed skill from local and platform directories');
201
289
  uninstallCmd
202
- .argument('<skill>', 'Skill ID to uninstall')
203
- .action(async (skill) => {
290
+ .argument('[skill]', 'Skill ID to uninstall (required unless using --all)')
291
+ .option('-p, --platform <platforms>', 'Target platforms (comma-separated)')
292
+ .option('-a, --all', 'Uninstall ALL installed skills (requires confirmation)')
293
+ .option('-d, --dry-run', 'Preview what would be uninstalled without actually deleting')
294
+ .option('-y, --yes', 'Skip confirmation prompts')
295
+ .action(async (skill, opts) => {
204
296
  try {
205
- await uninstallSkill(skill);
297
+ const platforms = opts.platform
298
+ ? opts.platform.split(',').map((p: string) => p.trim())
299
+ : undefined;
300
+
301
+ // 处理 --all 选项
302
+ if (opts.all) {
303
+ await uninstallAll({
304
+ platforms,
305
+ dryRun: opts.dryRun,
306
+ yes: opts.yes
307
+ });
308
+ return;
309
+ }
310
+
311
+ // skill 参数是必需的(除非使用 --all)
312
+ if (!skill) {
313
+ console.error('Error: Skill ID is required (or use --all to uninstall all)');
314
+ process.exit(1);
315
+ }
316
+
317
+ await uninstallSkill(skill, {
318
+ platforms,
319
+ dryRun: opts.dryRun,
320
+ yes: opts.yes
321
+ });
206
322
  } catch (err) {
207
323
  console.error('Uninstall failed:', err);
208
324
  process.exit(1);
@@ -269,46 +385,44 @@ program
269
385
  });
270
386
 
271
387
  // -----------------------------------------------------------------------------
272
- // 平台命令 (skm platform)
388
+ // 平台命令 (skm platforms)
273
389
  // -----------------------------------------------------------------------------
274
390
 
275
391
  /**
276
- * 平台命令(预留)
392
+ * 平台命令
277
393
  *
278
- * 设置默认目标平台
394
+ * 显示所有支持的平台及其状态
279
395
  *
280
- * 用法: skm platform <name>
396
+ * 用法: skm platforms
281
397
  */
282
- const platformCmd = program.command('platform').description('Set target platform');
283
- platformCmd
284
- .argument('<name>', 'Platform name')
285
- .action((name) => {
286
- console.log('Platform command - name:', name);
287
- });
288
-
289
- // -----------------------------------------------------------------------------
290
- // 搜索命令 (skm search)
291
- // -----------------------------------------------------------------------------
292
-
293
- /**
294
- * 搜索命令
295
- *
296
- * 在 npm registry 上搜索匹配的 skills
297
- * 只返回包名包含关键词的 skill
298
- *
299
- * 用法: skm search <keyword>
300
- *
301
- * @example
302
- * skm search test
303
- */
304
- const searchCmd = program.command('search').description('Search skills from npm registry');
305
- searchCmd
306
- .argument('<keyword>', 'Keyword to search')
307
- .action(async (keyword) => {
398
+ const platformsCmd = program.command('platforms').description('Show available platforms');
399
+ platformsCmd
400
+ .action(async () => {
308
401
  try {
309
- await searchSkills(keyword);
402
+ const available = await detectPlatforms();
403
+
404
+ console.log('\n📍 Available Platforms:\n');
405
+
406
+ const allPlatforms = [
407
+ { name: 'OpenCode', adapter: new OpenCodeAdapter() },
408
+ { name: 'Claude Code', adapter: new ClaudeAdapter() },
409
+ { name: 'VSCode', adapter: new VSCodeAdapter() },
410
+ ];
411
+
412
+ for (const { name, adapter } of allPlatforms) {
413
+ const isAvailable = available.find(a => a.id === adapter.id);
414
+ const installed = await adapter.listInstalled();
415
+
416
+ if (isAvailable) {
417
+ console.log(`${name.padEnd(12)} ✅ Available (${installed.length} skills installed)`);
418
+ } else {
419
+ console.log(`${name.padEnd(12)} ❌ Not detected`);
420
+ }
421
+ }
422
+
423
+ console.log('');
310
424
  } catch (err) {
311
- console.error('Search failed:', err);
425
+ console.error('Failed to list platforms:', err);
312
426
  process.exit(1);
313
427
  }
314
428
  });
@@ -19,7 +19,7 @@
19
19
  // 导入依赖
20
20
  // -----------------------------------------------------------------------------
21
21
 
22
- import { fetchNpmPackage } from './npm.js'; // npm registry 查询
22
+ import { fetchSkillPackage } from './npm.js'; // npm registry 查询
23
23
  import {
24
24
  isSkillInstalled, // 检查 skill 是否已安装
25
25
  getInstalledSkills // 获取已安装 skills 列表
@@ -49,25 +49,14 @@ export async function showSkillInfo(skillId: string): Promise<void> {
49
49
  // 处理包名格式
50
50
  // -------------------------------------------------------------------------
51
51
 
52
- /**
53
- * 转换 skillId 为完整的 npm 包名格式
54
- *
55
- * 支持两种输入格式:
56
- * 1. 短格式: "brainstorming" → "@skillmarket/brainstorming"
57
- * 2. 完整格式: "@custom/skill" → "@custom/skill"
58
- */
59
- const packageName = skillId.startsWith('@')
60
- ? skillId // 已经是 scoped 包名
61
- : `@skillmarket/${skillId}`; // 转换为 scoped 包名
62
-
63
- console.log(`Fetching info for: ${packageName}\n`);
52
+ console.log(`Fetching info for: ${skillId}\n`);
64
53
 
65
54
  try {
66
55
  // -------------------------------------------------------------------------
67
- // 从 npm 获取包信息
56
+ // 从 npm 获取包信息(自动尝试多个可能的 scope)
68
57
  // -------------------------------------------------------------------------
69
58
 
70
- const info = await fetchNpmPackage(packageName);
59
+ const info = await fetchSkillPackage(skillId);
71
60
 
72
61
  // 包不存在
73
62
  if (!info) {