@nodeskai/skillshub 0.2.0 → 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
@@ -1 +1 @@
1
- {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAoBA,wBAAgB,WAAW,SAgD1B"}
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAGA,wBAAgB,WAAW,SAqB1B"}
@@ -1,64 +1,21 @@
1
- import { readdirSync, readFileSync, existsSync, statSync } from 'node:fs';
2
- import { join } from 'node:path';
3
- import { homedir } from 'node:os';
4
1
  import chalk from 'chalk';
5
- const DEFAULT_SKILLS_DIR = join(homedir(), '.openclaw', 'skills');
6
- function parseFrontmatter(content) {
7
- const match = content.match(/^---\n([\s\S]*?)\n---/);
8
- if (!match)
9
- return {};
10
- const result = {};
11
- for (const line of match[1].split('\n')) {
12
- const [key, ...rest] = line.split(':');
13
- if (key && rest.length) {
14
- result[key.trim()] = rest.join(':').trim();
15
- }
16
- }
17
- return result;
18
- }
2
+ import { scanLocalSkills, DEFAULT_SKILLS_DIR } from '../lib/local-skills.js';
19
3
  export function listCommand() {
20
- const skillsDir = DEFAULT_SKILLS_DIR;
21
- if (!existsSync(skillsDir)) {
4
+ const localSkills = scanLocalSkills();
5
+ if (localSkills.length === 0) {
22
6
  console.log(chalk.gray('尚未安装任何 Skill'));
23
- console.log(chalk.dim(` 安装目录: ${skillsDir}`));
7
+ console.log(chalk.dim(` 安装目录: ${DEFAULT_SKILLS_DIR}`));
24
8
  return;
25
9
  }
26
- const entries = readdirSync(skillsDir).filter((name) => {
27
- const fullPath = join(skillsDir, name);
28
- return statSync(fullPath).isDirectory() && !name.startsWith('.');
29
- });
30
- if (entries.length === 0) {
31
- console.log(chalk.gray('尚未安装任何 Skill'));
32
- console.log(chalk.dim(` 安装目录: ${skillsDir}`));
33
- return;
34
- }
35
- console.log(chalk.bold(`已安装的 Skills (${entries.length}):\n`));
36
- for (const dir of entries) {
37
- const skillMdPath = join(skillsDir, dir, 'SKILL.md');
38
- let version = '-';
39
- let name = dir;
40
- if (existsSync(skillMdPath)) {
41
- try {
42
- const content = readFileSync(skillMdPath, 'utf-8');
43
- const fm = parseFrontmatter(content);
44
- if (fm.version)
45
- version = fm.version;
46
- if (fm.displayName)
47
- name = fm.displayName;
48
- else if (fm.name)
49
- name = fm.name;
50
- }
51
- catch {
52
- // ignore read errors
53
- }
54
- }
55
- const versionLabel = version !== '-' ? chalk.dim(` v${version}`) : '';
56
- console.log(` ${chalk.cyan(dir)}${versionLabel}`);
57
- if (name !== dir) {
58
- console.log(` ${name}`);
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}`);
59
16
  }
60
17
  }
61
18
  console.log('');
62
- console.log(chalk.dim(`安装目录: ${skillsDir}`));
19
+ console.log(chalk.dim(`安装目录: ${DEFAULT_SKILLS_DIR}`));
63
20
  }
64
21
  //# sourceMappingURL=list.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"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"}
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 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":"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"}
package/dist/index.js CHANGED
@@ -10,6 +10,8 @@ import { syncCommand } from './commands/sync.js';
10
10
  import { whoamiCommand } from './commands/whoami.js';
11
11
  import { inspectCommand } from './commands/inspect.js';
12
12
  import { listCommand } from './commands/list.js';
13
+ import { outdatedCommand } from './commands/outdated.js';
14
+ import { updateCommand } from './commands/update.js';
13
15
  import { uninstallCommand } from './commands/uninstall.js';
14
16
  import { login } from './lib/auth.js';
15
17
  import { saveConfig } from './lib/config.js';
@@ -17,7 +19,7 @@ const program = new Command();
17
19
  program
18
20
  .name('skillshub')
19
21
  .description('SkillsHub CLI — publish, search, and install skills')
20
- .version('0.2.0');
22
+ .version('0.3.0');
21
23
  program
22
24
  .command('login <token>')
23
25
  .description('Save authentication token (JWT or API Token)')
@@ -59,6 +61,15 @@ program
59
61
  .alias('ls')
60
62
  .description('List locally installed skills')
61
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);
62
73
  program
63
74
  .command('uninstall <slug>')
64
75
  .alias('rm')
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.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "SkillsHub CLI — publish, search, and install AI agent skills",
5
5
  "type": "module",
6
6
  "bin": {