@nodeskai/skillshub 0.1.2 → 0.3.0

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 CHANGED
@@ -18,11 +18,23 @@ npx @nodeskai/skillshub <command>
18
18
  # 搜索 skills
19
19
  skillshub search agent
20
20
 
21
- # 安装 skill 到当前目录
21
+ # 安装 skill(默认安装到 ~/.openclaw/skills/<slug>/)
22
22
  skillshub install free-ride
23
23
 
24
- # 安装到指定目录
24
+ # 安装指定版本
25
+ skillshub install free-ride -v 1.0.0
26
+
27
+ # 安装到自定义目录
25
28
  skillshub install free-ride -d ./my-skills/free-ride
29
+
30
+ # 查看当前登录用户
31
+ skillshub whoami
32
+
33
+ # 查看 skill 详情
34
+ skillshub inspect free-ride
35
+
36
+ # 列出本地已安装的 skills
37
+ skillshub list
26
38
  ```
27
39
 
28
40
  ## 命令一览
@@ -38,10 +50,57 @@ skillshub search <关键词>
38
50
  ### 安装
39
51
 
40
52
  ```bash
41
- skillshub install <slug> [-d <目录>]
53
+ skillshub install <slug> [选项]
54
+ ```
55
+
56
+ 下载 skill 并自动解压到本地。默认安装到 `~/.openclaw/skills/<slug>/`。
57
+
58
+ | 选项 | 说明 |
59
+ |------|------|
60
+ | `-d, --dir <目录>` | 安装到自定义目录 |
61
+ | `-v, --version <版本>` | 安装指定版本(默认最新) |
62
+ | `--cwd` | 安装到当前工作目录下的 `<slug>/` |
63
+
64
+ ### 查看详情
65
+
66
+ ```bash
67
+ skillshub inspect <slug>
68
+ ```
69
+
70
+ 查看 skill 的详细信息,包括版本列表、文件、标签、下载量和收藏数。
71
+
72
+ ### 查看当前用户
73
+
74
+ ```bash
75
+ skillshub whoami
42
76
  ```
43
77
 
44
- 下载 skill 最新版本并自动解压到本地目录。默认解压到以 slug 命名的文件夹。
78
+ 显示当前登录用户的 handle、昵称和角色。
79
+
80
+ ### 本地管理
81
+
82
+ ```bash
83
+ skillshub list # 列出本地已安装的 skills(别名: ls)
84
+ skillshub uninstall <slug> # 卸载本地 skill(别名: rm)
85
+ skillshub uninstall <slug> -f # 跳过确认直接卸载
86
+ ```
87
+
88
+ 扫描 `~/.openclaw/skills/` 目录,读取每个 skill 的 SKILL.md 展示信息。
89
+
90
+ ### 检查更新
91
+
92
+ ```bash
93
+ skillshub outdated # 检查所有已安装 skill 是否有可用更新
94
+ ```
95
+
96
+ 批量比对本地版本与远端最新版本,列出有更新的 skills。
97
+
98
+ ### 更新
99
+
100
+ ```bash
101
+ skillshub update <slug> # 更新指定 skill 到最新版本
102
+ skillshub update --all # 更新所有有可用更新的 skills
103
+ ```
45
104
 
46
105
  ### 发布
47
106
 
@@ -100,7 +159,7 @@ skillshub token revoke <id> # 撤销 Token
100
159
 
101
160
  ## 认证
102
161
 
103
- 需要登录的命令(publish、sync、star、delete、token)需要先配置认证:
162
+ 需要登录的命令(publish、sync、star、delete、token、whoami)需要先配置认证:
104
163
 
105
164
  1. 在 [SkillsHub](https://skills.nodeskai.com) 网站登录
106
165
  2. 进入用户中心,创建 API Token
@@ -0,0 +1,2 @@
1
+ export declare function inspectCommand(slug: string): Promise<void>;
2
+ //# sourceMappingURL=inspect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect.d.ts","sourceRoot":"","sources":["../../src/commands/inspect.ts"],"names":[],"mappings":"AAuBA,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,iBAmDhD"}
@@ -0,0 +1,59 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { apiRequest } from '../lib/api.js';
4
+ function formatSize(bytes) {
5
+ if (bytes < 1024)
6
+ return `${bytes}B`;
7
+ if (bytes < 1024 * 1024)
8
+ return `${(bytes / 1024).toFixed(1)}KB`;
9
+ return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
10
+ }
11
+ export async function inspectCommand(slug) {
12
+ const spinner = ora(`获取 ${slug} 详情...`).start();
13
+ try {
14
+ const skill = (await apiRequest(`/skills/${slug}`));
15
+ spinner.stop();
16
+ console.log('');
17
+ console.log(chalk.bold.cyan(skill.slug) + chalk.dim(` by ${skill.owner.handle || 'unknown'}`));
18
+ console.log(chalk.bold(skill.displayName));
19
+ if (skill.summary) {
20
+ console.log(chalk.gray(skill.summary));
21
+ }
22
+ console.log('');
23
+ if (skill.tags.length > 0) {
24
+ console.log(chalk.dim('标签: ') + skill.tags.map((t) => chalk.blue(t)).join(', '));
25
+ }
26
+ console.log(chalk.dim('收藏: ') + chalk.yellow(`★ ${skill.statsStars}`));
27
+ console.log(chalk.dim('下载: ') + chalk.green(`↓ ${skill.statsDownloads}`));
28
+ console.log('');
29
+ if (skill.versions.length > 0) {
30
+ console.log(chalk.bold('版本:'));
31
+ for (const v of skill.versions.slice(0, 10)) {
32
+ const date = new Date(v.createdAt).toLocaleDateString('zh-CN');
33
+ const latest = skill.latestVersion?.version === v.version ? chalk.green(' (latest)') : '';
34
+ console.log(` ${chalk.white(v.version)}${latest} ${chalk.dim(date)}`);
35
+ if (v.changelog) {
36
+ console.log(` ${chalk.gray(v.changelog)}`);
37
+ }
38
+ }
39
+ if (skill.versions.length > 10) {
40
+ console.log(chalk.dim(` ... 共 ${skill.versions.length} 个版本`));
41
+ }
42
+ console.log('');
43
+ }
44
+ if (skill.files.length > 0) {
45
+ console.log(chalk.bold('文件:'));
46
+ for (const f of skill.files) {
47
+ console.log(` ${chalk.white(f.path)} ${chalk.dim(formatSize(f.size))}`);
48
+ }
49
+ const totalSize = skill.files.reduce((sum, f) => sum + f.size, 0);
50
+ console.log(chalk.dim(` 共 ${skill.files.length} 个文件, ${formatSize(totalSize)}`));
51
+ console.log('');
52
+ }
53
+ }
54
+ catch (err) {
55
+ spinner.fail(chalk.red(`查看失败: ${err instanceof Error ? err.message : err}`));
56
+ process.exit(1);
57
+ }
58
+ }
59
+ //# sourceMappingURL=inspect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect.js","sourceRoot":"","sources":["../../src/commands/inspect.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,6 @@
1
1
  export declare function installCommand(slug: string, options: {
2
2
  dir?: string;
3
+ version?: string;
4
+ cwd?: boolean;
3
5
  }): Promise<void>;
4
6
  //# sourceMappingURL=install.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAMA,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,iBA+C3E"}
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAUA,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAA;CAAE,iBA6D5G"}
@@ -1,8 +1,11 @@
1
1
  import { mkdirSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { homedir } from 'node:os';
2
4
  import ora from 'ora';
3
5
  import chalk from 'chalk';
4
6
  import AdmZip from 'adm-zip';
5
7
  import { loadConfig } from '../lib/config.js';
8
+ const DEFAULT_SKILLS_DIR = join(homedir(), '.openclaw', 'skills');
6
9
  export async function installCommand(slug, options) {
7
10
  const spinner = ora(`获取 ${slug} 信息...`).start();
8
11
  try {
@@ -14,7 +17,18 @@ export async function installCommand(slug, options) {
14
17
  spinner.fail('Skill 未找到或无可用版本');
15
18
  process.exit(1);
16
19
  }
17
- const version = skillData.data.latestVersion.version;
20
+ let version;
21
+ if (options.version) {
22
+ const match = skillData.data.versions.find((v) => v.version === options.version);
23
+ if (!match) {
24
+ spinner.fail(`版本 ${options.version} 不存在。可用版本: ${skillData.data.versions.map((v) => v.version).join(', ')}`);
25
+ process.exit(1);
26
+ }
27
+ version = match.version;
28
+ }
29
+ else {
30
+ version = skillData.data.latestVersion.version;
31
+ }
18
32
  spinner.text = `下载 ${slug}@${version}...`;
19
33
  const downloadUrl = `${apiUrl}/api/v1/skills/${slug}/versions/${version}/download`;
20
34
  const resp = await fetch(downloadUrl);
@@ -23,7 +37,7 @@ export async function installCommand(slug, options) {
23
37
  process.exit(1);
24
38
  }
25
39
  const buffer = Buffer.from(await resp.arrayBuffer());
26
- const outDir = options.dir || slug;
40
+ const outDir = options.dir || (options.cwd ? slug : join(DEFAULT_SKILLS_DIR, slug));
27
41
  mkdirSync(outDir, { recursive: true });
28
42
  spinner.text = `解压到 ${outDir}...`;
29
43
  const zip = new AdmZip(buffer);
@@ -1 +1 @@
1
- {"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function listCommand(): void;
2
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAGA,wBAAgB,WAAW,SAqB1B"}
@@ -0,0 +1,21 @@
1
+ import chalk from 'chalk';
2
+ import { scanLocalSkills, DEFAULT_SKILLS_DIR } from '../lib/local-skills.js';
3
+ export function listCommand() {
4
+ const localSkills = scanLocalSkills();
5
+ if (localSkills.length === 0) {
6
+ console.log(chalk.gray('尚未安装任何 Skill'));
7
+ console.log(chalk.dim(` 安装目录: ${DEFAULT_SKILLS_DIR}`));
8
+ return;
9
+ }
10
+ console.log(chalk.bold(`已安装的 Skills (${localSkills.length}):\n`));
11
+ for (const skill of localSkills) {
12
+ const versionLabel = skill.version ? chalk.dim(` v${skill.version}`) : '';
13
+ console.log(` ${chalk.cyan(skill.slug)}${versionLabel}`);
14
+ if (skill.displayName && skill.displayName !== skill.slug) {
15
+ console.log(` ${skill.displayName}`);
16
+ }
17
+ }
18
+ console.log('');
19
+ console.log(chalk.dim(`安装目录: ${DEFAULT_SKILLS_DIR}`));
20
+ }
21
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAE5E,MAAM,UAAU,WAAW;IACzB,MAAM,WAAW,GAAG,eAAe,EAAE,CAAA;IAErC,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAA;QACvC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,kBAAkB,EAAE,CAAC,CAAC,CAAA;QACvD,OAAM;IACR,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,WAAW,CAAC,MAAM,MAAM,CAAC,CAAC,CAAA;IAEjE,KAAK,MAAM,KAAK,IAAI,WAAW,EAAE,CAAC;QAChC,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QACzE,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,YAAY,EAAE,CAAC,CAAA;QACzD,IAAI,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,WAAW,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC;YAC1D,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC,CAAA;QACzC,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,kBAAkB,EAAE,CAAC,CAAC,CAAA;AACvD,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function outdatedCommand(): Promise<void>;
2
+ //# sourceMappingURL=outdated.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outdated.d.ts","sourceRoot":"","sources":["../../src/commands/outdated.ts"],"names":[],"mappings":"AAaA,wBAAsB,eAAe,kBAqDpC"}
@@ -0,0 +1,48 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { apiRequest } from '../lib/api.js';
4
+ import { scanLocalSkills } from '../lib/local-skills.js';
5
+ export async function outdatedCommand() {
6
+ const localSkills = scanLocalSkills();
7
+ if (localSkills.length === 0) {
8
+ console.log(chalk.gray('尚未安装任何 Skill'));
9
+ return;
10
+ }
11
+ const withVersion = localSkills.filter((s) => s.version);
12
+ if (withVersion.length === 0) {
13
+ console.log(chalk.gray('已安装的 Skill 均未包含版本信息,无法检查更新'));
14
+ return;
15
+ }
16
+ const spinner = ora(`检查 ${withVersion.length} 个已安装 Skill 的更新...`).start();
17
+ try {
18
+ const payload = {
19
+ skills: withVersion.map((s) => ({ slug: s.slug, currentVersion: s.version })),
20
+ };
21
+ const data = (await apiRequest('/skills/check-updates', {
22
+ method: 'POST',
23
+ body: JSON.stringify(payload),
24
+ }));
25
+ const updates = data.results.filter((r) => r.hasUpdate);
26
+ spinner.stop();
27
+ if (updates.length === 0) {
28
+ console.log(chalk.green('所有 Skill 已是最新版本'));
29
+ return;
30
+ }
31
+ console.log(chalk.bold(`\n有可用更新 (${updates.length}):\n`));
32
+ const maxSlugLen = Math.max(...updates.map((u) => u.slug.length));
33
+ const maxCurLen = Math.max(...updates.map((u) => u.currentVersion.length));
34
+ for (const u of updates) {
35
+ const slug = chalk.cyan(u.slug.padEnd(maxSlugLen));
36
+ const cur = chalk.dim(u.currentVersion.padEnd(maxCurLen));
37
+ const latest = chalk.green(u.latestVersion);
38
+ console.log(` ${slug} ${cur} → ${latest}`);
39
+ }
40
+ console.log('');
41
+ console.log(chalk.dim('运行 skillshub update <slug> 来更新'));
42
+ }
43
+ catch (err) {
44
+ spinner.fail(chalk.red(`检查更新失败: ${err instanceof Error ? err.message : err}`));
45
+ process.exit(1);
46
+ }
47
+ }
48
+ //# sourceMappingURL=outdated.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outdated.js","sourceRoot":"","sources":["../../src/commands/outdated.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare function uninstallCommand(slug: string, opts: {
2
+ force?: boolean;
3
+ }): Promise<void>;
4
+ //# sourceMappingURL=uninstall.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uninstall.d.ts","sourceRoot":"","sources":["../../src/commands/uninstall.ts"],"names":[],"mappings":"AAmBA,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,iBAwB7E"}
@@ -0,0 +1,40 @@
1
+ import { existsSync, rmSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { homedir } from 'node:os';
4
+ import { createInterface } from 'node:readline';
5
+ import chalk from 'chalk';
6
+ import ora from 'ora';
7
+ const DEFAULT_SKILLS_DIR = join(homedir(), '.openclaw', 'skills');
8
+ async function confirm(message) {
9
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
10
+ return new Promise((resolve) => {
11
+ rl.question(`${message} (y/N) `, (answer) => {
12
+ rl.close();
13
+ resolve(answer.toLowerCase() === 'y');
14
+ });
15
+ });
16
+ }
17
+ export async function uninstallCommand(slug, opts) {
18
+ const skillDir = join(DEFAULT_SKILLS_DIR, slug);
19
+ if (!existsSync(skillDir)) {
20
+ console.error(chalk.red(`Skill "${slug}" 未安装 (${skillDir})`));
21
+ process.exit(1);
22
+ }
23
+ if (!opts.force) {
24
+ const yes = await confirm(chalk.yellow(`确定要卸载 "${slug}" 吗?`));
25
+ if (!yes) {
26
+ console.log('已取消');
27
+ return;
28
+ }
29
+ }
30
+ const spinner = ora(`卸载 ${slug}...`).start();
31
+ try {
32
+ rmSync(skillDir, { recursive: true, force: true });
33
+ spinner.succeed(chalk.green(`已卸载: ${slug}`));
34
+ }
35
+ catch (err) {
36
+ spinner.fail(chalk.red(`卸载失败: ${err instanceof Error ? err.message : err}`));
37
+ process.exit(1);
38
+ }
39
+ }
40
+ //# sourceMappingURL=uninstall.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uninstall.js","sourceRoot":"","sources":["../../src/commands/uninstall.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC/C,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,GAAG,MAAM,KAAK,CAAA;AAErB,MAAM,kBAAkB,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAA;AAEjE,KAAK,UAAU,OAAO,CAAC,OAAe;IACpC,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;IAC5E,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,EAAE,CAAC,QAAQ,CAAC,GAAG,OAAO,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE;YAC1C,EAAE,CAAC,KAAK,EAAE,CAAA;YACV,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,CAAA;QACvC,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAY,EAAE,IAAyB;IAC5E,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAA;IAE/C,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,IAAI,UAAU,QAAQ,GAAG,CAAC,CAAC,CAAA;QAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAChB,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,CAAC,CAAA;QAC7D,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;YAClB,OAAM;QACR,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,KAAK,EAAE,CAAA;IAC5C,IAAI,CAAC;QACH,MAAM,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;QAClD,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAA;IAC9C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;QAC5E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;AACH,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function updateCommand(slug: string | undefined, options: {
2
+ all?: boolean;
3
+ }): Promise<void>;
4
+ //# sourceMappingURL=update.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAcA,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,OAAO,CAAA;CAAE,iBAiEvF"}
@@ -0,0 +1,63 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { apiRequest } from '../lib/api.js';
4
+ import { scanLocalSkills } from '../lib/local-skills.js';
5
+ import { installCommand } from './install.js';
6
+ export async function updateCommand(slug, options) {
7
+ if (slug) {
8
+ await installCommand(slug, {});
9
+ return;
10
+ }
11
+ if (!options.all) {
12
+ console.log(chalk.yellow('请指定要更新的 Skill,或使用 --all 更新全部'));
13
+ console.log(chalk.dim(' skillshub update <slug>'));
14
+ console.log(chalk.dim(' skillshub update --all'));
15
+ return;
16
+ }
17
+ const localSkills = scanLocalSkills();
18
+ const withVersion = localSkills.filter((s) => s.version);
19
+ if (withVersion.length === 0) {
20
+ console.log(chalk.gray('尚未安装任何包含版本信息的 Skill'));
21
+ return;
22
+ }
23
+ const spinner = ora('检查更新...').start();
24
+ let updates;
25
+ try {
26
+ const payload = {
27
+ skills: withVersion.map((s) => ({ slug: s.slug, currentVersion: s.version })),
28
+ };
29
+ const data = (await apiRequest('/skills/check-updates', {
30
+ method: 'POST',
31
+ body: JSON.stringify(payload),
32
+ }));
33
+ updates = data.results.filter((r) => r.hasUpdate);
34
+ }
35
+ catch (err) {
36
+ spinner.fail(chalk.red(`检查更新失败: ${err instanceof Error ? err.message : err}`));
37
+ process.exit(1);
38
+ }
39
+ if (updates.length === 0) {
40
+ spinner.succeed(chalk.green('所有 Skill 已是最新版本'));
41
+ return;
42
+ }
43
+ spinner.info(chalk.blue(`发现 ${updates.length} 个可更新的 Skill\n`));
44
+ let successCount = 0;
45
+ for (const u of updates) {
46
+ try {
47
+ console.log(chalk.dim(`更新 ${u.slug} ${u.currentVersion} → ${u.latestVersion}...`));
48
+ await installCommand(u.slug, {});
49
+ successCount++;
50
+ }
51
+ catch {
52
+ console.log(chalk.red(` 更新 ${u.slug} 失败`));
53
+ }
54
+ }
55
+ console.log('');
56
+ if (successCount > 0) {
57
+ console.log(chalk.green(`已更新 ${successCount} 个 Skill`));
58
+ }
59
+ if (successCount < updates.length) {
60
+ console.log(chalk.yellow(`${updates.length - successCount} 个 Skill 更新失败`));
61
+ }
62
+ }
63
+ //# sourceMappingURL=update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,GAAG,MAAM,KAAK,CAAA;AACrB,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAU7C,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAwB,EAAE,OAA0B;IACtF,IAAI,IAAI,EAAE,CAAC;QACT,MAAM,cAAc,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;QAC9B,OAAM;IACR,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,8BAA8B,CAAC,CAAC,CAAA;QACzD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC,CAAA;QACnD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC,CAAA;QAClD,OAAM;IACR,CAAC;IAED,MAAM,WAAW,GAAG,eAAe,EAAE,CAAA;IACrC,MAAM,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;IAExD,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAA;QAC9C,OAAM;IACR,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,CAAA;IAEtC,IAAI,OAA4B,CAAA;IAChC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG;YACd,MAAM,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC,OAAQ,EAAE,CAAC,CAAC;SAC/E,CAAA;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,UAAU,CAAC,uBAAuB,EAAE;YACtD,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;SAC9B,CAAC,CAAqC,CAAA;QAEvC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;IACnD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;QAC9E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAA;QAC/C,OAAM;IACR,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,OAAO,CAAC,MAAM,gBAAgB,CAAC,CAAC,CAAA;IAE9D,IAAI,YAAY,GAAG,CAAC,CAAA;IACpB,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC;YACH,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,cAAc,MAAM,CAAC,CAAC,aAAa,KAAK,CAAC,CAAC,CAAA;YAClF,MAAM,cAAc,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;YAChC,YAAY,EAAE,CAAA;QAChB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAA;QAC7C,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACf,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,YAAY,UAAU,CAAC,CAAC,CAAA;IACzD,CAAC;IACD,IAAI,YAAY,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,YAAY,eAAe,CAAC,CAAC,CAAA;IAC5E,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function whoamiCommand(): Promise<void>;
2
+ //# sourceMappingURL=whoami.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whoami.d.ts","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAKA,wBAAsB,aAAa,kBA0BlC"}
@@ -0,0 +1,26 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { apiRequest } from '../lib/api.js';
4
+ import { isAuthenticated } from '../lib/auth.js';
5
+ export async function whoamiCommand() {
6
+ if (!isAuthenticated()) {
7
+ console.error(chalk.red('未登录。请先运行: skillshub login <token>'));
8
+ process.exit(1);
9
+ }
10
+ const spinner = ora('获取用户信息...').start();
11
+ try {
12
+ const user = (await apiRequest('/users/me'));
13
+ spinner.stop();
14
+ console.log('');
15
+ console.log(chalk.bold('当前登录用户:'));
16
+ console.log(` Handle: ${user.handle ? chalk.cyan(user.handle) : chalk.dim('未设置')}`);
17
+ console.log(` 昵称: ${user.displayName || chalk.dim('未设置')}`);
18
+ console.log(` 角色: ${user.role}`);
19
+ console.log('');
20
+ }
21
+ catch (err) {
22
+ spinner.fail(chalk.red(`获取失败: ${err instanceof Error ? err.message : err}`));
23
+ process.exit(1);
24
+ }
25
+ }
26
+ //# sourceMappingURL=whoami.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,GAAG,MAAM,KAAK,CAAA;AACrB,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAEhD,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;QACvB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC,CAAA;QAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,KAAK,EAAE,CAAA;IACxC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,CAAC,MAAM,UAAU,CAAC,WAAW,CAAC,CAK1C,CAAA;QAED,OAAO,CAAC,IAAI,EAAE,CAAA;QACd,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAA;QAClC,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QACrF,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,CAAC,WAAW,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QAC/D,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;QACpC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACjB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;QAC5E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;AACH,CAAC"}
package/dist/index.js CHANGED
@@ -7,13 +7,19 @@ import { tokenCreateCommand, tokenListCommand, tokenRevokeCommand } from './comm
7
7
  import { starCommand, unstarCommand } from './commands/star.js';
8
8
  import { deleteCommand } from './commands/delete.js';
9
9
  import { syncCommand } from './commands/sync.js';
10
+ import { whoamiCommand } from './commands/whoami.js';
11
+ import { inspectCommand } from './commands/inspect.js';
12
+ import { listCommand } from './commands/list.js';
13
+ import { outdatedCommand } from './commands/outdated.js';
14
+ import { updateCommand } from './commands/update.js';
15
+ import { uninstallCommand } from './commands/uninstall.js';
10
16
  import { login } from './lib/auth.js';
11
17
  import { saveConfig } from './lib/config.js';
12
18
  const program = new Command();
13
19
  program
14
20
  .name('skillshub')
15
21
  .description('SkillsHub CLI — publish, search, and install skills')
16
- .version('0.1.2');
22
+ .version('0.3.0');
17
23
  program
18
24
  .command('login <token>')
19
25
  .description('Save authentication token (JWT or API Token)')
@@ -21,6 +27,10 @@ program
21
27
  login(token);
22
28
  console.log('Token saved successfully.');
23
29
  });
30
+ program
31
+ .command('whoami')
32
+ .description('Show current logged-in user')
33
+ .action(whoamiCommand);
24
34
  program
25
35
  .command('config')
26
36
  .description('Set API URL')
@@ -31,19 +41,49 @@ program
31
41
  console.log(`API URL set to: ${opts.apiUrl}`);
32
42
  }
33
43
  });
34
- program
35
- .command('publish [dir]')
36
- .description('Publish a skill from a directory')
37
- .action(publishCommand);
38
44
  program
39
45
  .command('search <query>')
40
46
  .description('Search for skills')
41
47
  .action(searchCommand);
48
+ program
49
+ .command('inspect <slug>')
50
+ .description('View skill details (versions, files, stats)')
51
+ .action(inspectCommand);
42
52
  program
43
53
  .command('install <slug>')
44
- .description('Download and install a skill')
45
- .option('-d, --dir <dir>', 'Target directory')
54
+ .description('Download and install a skill to ~/.openclaw/skills/')
55
+ .option('-d, --dir <dir>', 'Custom install directory')
56
+ .option('-v, --version <version>', 'Install a specific version')
57
+ .option('--cwd', 'Install to current directory instead')
46
58
  .action(installCommand);
59
+ program
60
+ .command('list')
61
+ .alias('ls')
62
+ .description('List locally installed skills')
63
+ .action(listCommand);
64
+ program
65
+ .command('outdated')
66
+ .description('Check for available updates of installed skills')
67
+ .action(outdatedCommand);
68
+ program
69
+ .command('update [slug]')
70
+ .description('Update an installed skill (or all with --all)')
71
+ .option('-a, --all', 'Update all outdated skills')
72
+ .action(updateCommand);
73
+ program
74
+ .command('uninstall <slug>')
75
+ .alias('rm')
76
+ .description('Remove a locally installed skill')
77
+ .option('-f, --force', 'Skip confirmation prompt')
78
+ .action(uninstallCommand);
79
+ program
80
+ .command('publish [dir]')
81
+ .description('Publish a skill from a directory')
82
+ .action(publishCommand);
83
+ program
84
+ .command('sync [dir]')
85
+ .description('Sync local SKILL.md to remote (publish if version differs)')
86
+ .action(syncCommand);
47
87
  const tokenCmd = program
48
88
  .command('token')
49
89
  .description('Manage API tokens');
@@ -69,12 +109,8 @@ program
69
109
  .action(unstarCommand);
70
110
  program
71
111
  .command('delete <slug>')
72
- .description('Delete a skill you own')
112
+ .description('Delete a skill you own from the registry')
73
113
  .option('-f, --force', 'Skip confirmation prompt')
74
114
  .action(deleteCommand);
75
- program
76
- .command('sync [dir]')
77
- .description('Sync local SKILL.md to remote (publish if version differs)')
78
- .action(syncCommand);
79
115
  program.parse();
80
116
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export declare const DEFAULT_SKILLS_DIR: string;
2
+ export interface LocalSkill {
3
+ slug: string;
4
+ dir: string;
5
+ version: string | null;
6
+ displayName: string | null;
7
+ }
8
+ export declare function parseFrontmatter(content: string): Record<string, string>;
9
+ export declare function scanLocalSkills(skillsDir?: string): LocalSkill[];
10
+ //# sourceMappingURL=local-skills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-skills.d.ts","sourceRoot":"","sources":["../../src/lib/local-skills.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,kBAAkB,QAAyC,CAAA;AAExE,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAC3B;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAWxE;AAED,wBAAgB,eAAe,CAAC,SAAS,SAAqB,GAAG,UAAU,EAAE,CA2B5E"}
@@ -0,0 +1,47 @@
1
+ import { readdirSync, readFileSync, existsSync, statSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { homedir } from 'node:os';
4
+ export const DEFAULT_SKILLS_DIR = join(homedir(), '.openclaw', 'skills');
5
+ export function parseFrontmatter(content) {
6
+ const match = content.match(/^---\n([\s\S]*?)\n---/);
7
+ if (!match)
8
+ return {};
9
+ const result = {};
10
+ for (const line of match[1].split('\n')) {
11
+ const [key, ...rest] = line.split(':');
12
+ if (key && rest.length) {
13
+ result[key.trim()] = rest.join(':').trim();
14
+ }
15
+ }
16
+ return result;
17
+ }
18
+ export function scanLocalSkills(skillsDir = DEFAULT_SKILLS_DIR) {
19
+ if (!existsSync(skillsDir))
20
+ return [];
21
+ const entries = readdirSync(skillsDir).filter((name) => {
22
+ const fullPath = join(skillsDir, name);
23
+ return statSync(fullPath).isDirectory() && !name.startsWith('.');
24
+ });
25
+ return entries.map((dir) => {
26
+ const skillMdPath = join(skillsDir, dir, 'SKILL.md');
27
+ let version = null;
28
+ let displayName = null;
29
+ if (existsSync(skillMdPath)) {
30
+ try {
31
+ const content = readFileSync(skillMdPath, 'utf-8');
32
+ const fm = parseFrontmatter(content);
33
+ if (fm.version)
34
+ version = fm.version;
35
+ if (fm.displayName)
36
+ displayName = fm.displayName;
37
+ else if (fm.name)
38
+ displayName = fm.name;
39
+ }
40
+ catch {
41
+ // ignore read errors
42
+ }
43
+ }
44
+ return { slug: dir, dir: join(skillsDir, dir), version, displayName };
45
+ });
46
+ }
47
+ //# sourceMappingURL=local-skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-skills.js","sourceRoot":"","sources":["../../src/lib/local-skills.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AACzE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAEjC,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAA;AASxE,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAA;IACpD,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAA;IACrB,MAAM,MAAM,GAA2B,EAAE,CAAA;IACzC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QACtC,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACvB,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAA;QAC5C,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,SAAS,GAAG,kBAAkB;IAC5D,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,EAAE,CAAA;IAErC,MAAM,OAAO,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;QACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;QACtC,OAAO,QAAQ,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;IAClE,CAAC,CAAC,CAAA;IAEF,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACzB,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,UAAU,CAAC,CAAA;QACpD,IAAI,OAAO,GAAkB,IAAI,CAAA;QACjC,IAAI,WAAW,GAAkB,IAAI,CAAA;QAErC,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC5B,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;gBAClD,MAAM,EAAE,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAA;gBACpC,IAAI,EAAE,CAAC,OAAO;oBAAE,OAAO,GAAG,EAAE,CAAC,OAAO,CAAA;gBACpC,IAAI,EAAE,CAAC,WAAW;oBAAE,WAAW,GAAG,EAAE,CAAC,WAAW,CAAA;qBAC3C,IAAI,EAAE,CAAC,IAAI;oBAAE,WAAW,GAAG,EAAE,CAAC,IAAI,CAAA;YACzC,CAAC;YAAC,MAAM,CAAC;gBACP,qBAAqB;YACvB,CAAC;QACH,CAAC;QAED,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,CAAA;IACvE,CAAC,CAAC,CAAA;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nodeskai/skillshub",
3
- "version": "0.1.2",
3
+ "version": "0.3.0",
4
4
  "description": "SkillsHub CLI — publish, search, and install AI agent skills",
5
5
  "type": "module",
6
6
  "bin": {