@nodeskai/skillshub 0.1.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.
Files changed (45) hide show
  1. package/dist/commands/delete.d.ts +4 -0
  2. package/dist/commands/delete.d.ts.map +1 -0
  3. package/dist/commands/delete.js +37 -0
  4. package/dist/commands/delete.js.map +1 -0
  5. package/dist/commands/install.d.ts +4 -0
  6. package/dist/commands/install.d.ts.map +1 -0
  7. package/dist/commands/install.js +42 -0
  8. package/dist/commands/install.js.map +1 -0
  9. package/dist/commands/publish.d.ts +2 -0
  10. package/dist/commands/publish.d.ts.map +1 -0
  11. package/dist/commands/publish.js +95 -0
  12. package/dist/commands/publish.js.map +1 -0
  13. package/dist/commands/search.d.ts +2 -0
  14. package/dist/commands/search.d.ts.map +1 -0
  15. package/dist/commands/search.js +25 -0
  16. package/dist/commands/search.js.map +1 -0
  17. package/dist/commands/star.d.ts +3 -0
  18. package/dist/commands/star.d.ts.map +1 -0
  19. package/dist/commands/star.js +35 -0
  20. package/dist/commands/star.js.map +1 -0
  21. package/dist/commands/sync.d.ts +2 -0
  22. package/dist/commands/sync.d.ts.map +1 -0
  23. package/dist/commands/sync.js +73 -0
  24. package/dist/commands/sync.js.map +1 -0
  25. package/dist/commands/token.d.ts +4 -0
  26. package/dist/commands/token.d.ts.map +1 -0
  27. package/dist/commands/token.js +73 -0
  28. package/dist/commands/token.js.map +1 -0
  29. package/dist/index.d.ts +3 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +80 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/lib/api.d.ts +3 -0
  34. package/dist/lib/api.d.ts.map +1 -0
  35. package/dist/lib/api.js +34 -0
  36. package/dist/lib/api.js.map +1 -0
  37. package/dist/lib/auth.d.ts +6 -0
  38. package/dist/lib/auth.d.ts.map +1 -0
  39. package/dist/lib/auth.js +13 -0
  40. package/dist/lib/auth.js.map +1 -0
  41. package/dist/lib/config.d.ts +10 -0
  42. package/dist/lib/config.d.ts.map +1 -0
  43. package/dist/lib/config.js +32 -0
  44. package/dist/lib/config.js.map +1 -0
  45. package/package.json +41 -0
@@ -0,0 +1,4 @@
1
+ export declare function deleteCommand(slug: string, opts: {
2
+ force?: boolean;
3
+ }): Promise<void>;
4
+ //# sourceMappingURL=delete.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../src/commands/delete.ts"],"names":[],"mappings":"AAgBA,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,iBAsB1E"}
@@ -0,0 +1,37 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { createInterface } from 'node:readline';
4
+ import { apiRequest } from '../lib/api.js';
5
+ import { isAuthenticated } from '../lib/auth.js';
6
+ async function confirm(message) {
7
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
8
+ return new Promise((resolve) => {
9
+ rl.question(`${message} (y/N) `, (answer) => {
10
+ rl.close();
11
+ resolve(answer.toLowerCase() === 'y');
12
+ });
13
+ });
14
+ }
15
+ export async function deleteCommand(slug, opts) {
16
+ if (!isAuthenticated()) {
17
+ console.error(chalk.red('请先登录:skillshub login <token>'));
18
+ process.exit(1);
19
+ }
20
+ if (!opts.force) {
21
+ const yes = await confirm(chalk.yellow(`确定要删除 Skill "${slug}" 吗?删除后 slug 将保留 90 天。`));
22
+ if (!yes) {
23
+ console.log('已取消');
24
+ return;
25
+ }
26
+ }
27
+ const spinner = ora(`删除 ${slug}...`).start();
28
+ try {
29
+ await apiRequest(`/skills/${slug}`, { method: 'DELETE' });
30
+ spinner.succeed(chalk.green(`已删除: ${slug}`));
31
+ }
32
+ catch (err) {
33
+ spinner.fail(chalk.red(`删除失败: ${err instanceof Error ? err.message : err}`));
34
+ process.exit(1);
35
+ }
36
+ }
37
+ //# sourceMappingURL=delete.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete.js","sourceRoot":"","sources":["../../src/commands/delete.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,GAAG,MAAM,KAAK,CAAA;AACrB,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAEhD,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,aAAa,CAAC,IAAY,EAAE,IAAyB;IACzE,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;QACvB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC,CAAA;QACxD,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,gBAAgB,IAAI,wBAAwB,CAAC,CAAC,CAAA;QACrF,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,UAAU,CAAC,WAAW,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAA;QACzD,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 installCommand(slug: string, options: {
2
+ dir?: string;
3
+ }): Promise<void>;
4
+ //# sourceMappingURL=install.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,42 @@
1
+ import { mkdirSync } from 'node:fs';
2
+ import ora from 'ora';
3
+ import chalk from 'chalk';
4
+ import AdmZip from 'adm-zip';
5
+ import { loadConfig } from '../lib/config.js';
6
+ export async function installCommand(slug, options) {
7
+ const spinner = ora(`获取 ${slug} 信息...`).start();
8
+ try {
9
+ const config = loadConfig();
10
+ const apiUrl = config.apiUrl;
11
+ const skillResp = await fetch(`${apiUrl}/api/v1/skills/${slug}`);
12
+ const skillData = (await skillResp.json());
13
+ if (!skillData.success || !skillData.data?.latestVersion) {
14
+ spinner.fail('Skill 未找到或无可用版本');
15
+ process.exit(1);
16
+ }
17
+ const version = skillData.data.latestVersion.version;
18
+ spinner.text = `下载 ${slug}@${version}...`;
19
+ const downloadUrl = `${apiUrl}/api/v1/skills/${slug}/versions/${version}/download`;
20
+ const resp = await fetch(downloadUrl);
21
+ if (!resp.ok) {
22
+ spinner.fail(`下载失败: ${resp.status}`);
23
+ process.exit(1);
24
+ }
25
+ const buffer = Buffer.from(await resp.arrayBuffer());
26
+ const outDir = options.dir || slug;
27
+ mkdirSync(outDir, { recursive: true });
28
+ spinner.text = `解压到 ${outDir}...`;
29
+ const zip = new AdmZip(buffer);
30
+ zip.extractAllTo(outDir, true);
31
+ fetch(`${apiUrl}/api/v1/skills/${slug}/install`, { method: 'POST' }).catch(() => { });
32
+ spinner.succeed(chalk.green(`已安装: ${slug}@${version} → ${outDir}/`));
33
+ const entries = zip.getEntries();
34
+ const fileCount = entries.filter((e) => !e.isDirectory).length;
35
+ console.log(chalk.dim(` ${fileCount} 个文件`));
36
+ }
37
+ catch (err) {
38
+ spinner.fail(chalk.red(`安装失败: ${err instanceof Error ? err.message : err}`));
39
+ process.exit(1);
40
+ }
41
+ }
42
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
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 publishCommand(dir: string): Promise<void>;
2
+ //# sourceMappingURL=publish.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../../src/commands/publish.ts"],"names":[],"mappings":"AASA,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,iBA8E/C"}
@@ -0,0 +1,95 @@
1
+ import { readFileSync, statSync } from 'node:fs';
2
+ import { join, basename } from 'node:path';
3
+ import { createHash } from 'node:crypto';
4
+ import { glob } from 'glob';
5
+ import ora from 'ora';
6
+ import chalk from 'chalk';
7
+ import { apiRequest, uploadFile } from '../lib/api.js';
8
+ import { isAuthenticated } from '../lib/auth.js';
9
+ export async function publishCommand(dir) {
10
+ if (!isAuthenticated()) {
11
+ console.error(chalk.red('请先登录:skillshub login <token>'));
12
+ process.exit(1);
13
+ }
14
+ const targetDir = dir || process.cwd();
15
+ const spinner = ora('读取 SKILL.md...').start();
16
+ try {
17
+ const skillMdPath = join(targetDir, 'SKILL.md');
18
+ let skillMd;
19
+ try {
20
+ skillMd = readFileSync(skillMdPath, 'utf-8');
21
+ }
22
+ catch {
23
+ spinner.fail('未找到 SKILL.md 文件');
24
+ process.exit(1);
25
+ }
26
+ const frontmatter = parseFrontmatter(skillMd);
27
+ if (!frontmatter.slug || !frontmatter.version) {
28
+ spinner.fail('SKILL.md frontmatter 缺少 slug 或 version');
29
+ process.exit(1);
30
+ }
31
+ spinner.text = '扫描文件...';
32
+ const allFiles = await glob('**/*', {
33
+ cwd: targetDir,
34
+ nodir: true,
35
+ ignore: ['.git/**', 'node_modules/**', '.DS_Store', '*.swp'],
36
+ });
37
+ spinner.text = `找到 ${allFiles.length} 个文件,开始上传...`;
38
+ const uploadedFiles = [];
39
+ for (const filePath of allFiles) {
40
+ spinner.text = `上传: ${filePath}`;
41
+ const fullPath = join(targetDir, filePath);
42
+ const stat = statSync(fullPath);
43
+ const content = readFileSync(fullPath);
44
+ const sha256 = createHash('sha256').update(content).digest('hex');
45
+ const { uploadUrl, storageKey } = await apiRequest('/skills/upload-url', {
46
+ method: 'POST',
47
+ body: JSON.stringify({ filename: basename(filePath) }),
48
+ });
49
+ await uploadFile(uploadUrl, fullPath);
50
+ uploadedFiles.push({
51
+ path: filePath,
52
+ size: stat.size,
53
+ storageKey,
54
+ sha256,
55
+ });
56
+ }
57
+ spinner.text = '发布中...';
58
+ const result = await apiRequest('/skills', {
59
+ method: 'POST',
60
+ body: JSON.stringify({
61
+ slug: frontmatter.slug,
62
+ displayName: frontmatter.displayName || frontmatter.slug,
63
+ version: frontmatter.version,
64
+ summary: frontmatter.summary,
65
+ tags: frontmatter.tags,
66
+ files: uploadedFiles,
67
+ }),
68
+ });
69
+ spinner.succeed(chalk.green(`发布成功: ${frontmatter.slug}@${frontmatter.version}`));
70
+ }
71
+ catch (err) {
72
+ spinner.fail(chalk.red(`发布失败: ${err instanceof Error ? err.message : err}`));
73
+ process.exit(1);
74
+ }
75
+ }
76
+ function parseFrontmatter(content) {
77
+ const match = content.match(/^---\n([\s\S]*?)\n---/);
78
+ if (!match)
79
+ return {};
80
+ const result = {};
81
+ for (const line of match[1].split('\n')) {
82
+ const [key, ...rest] = line.split(':');
83
+ if (key && rest.length) {
84
+ const value = rest.join(':').trim();
85
+ if (key.trim() === 'tags') {
86
+ result.tags = value.split(',').map((t) => t.trim()).filter(Boolean);
87
+ }
88
+ else {
89
+ result[key.trim()] = value;
90
+ }
91
+ }
92
+ }
93
+ return result;
94
+ }
95
+ //# sourceMappingURL=publish.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish.js","sourceRoot":"","sources":["../../src/commands/publish.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAChD,OAAO,EAAE,IAAI,EAAY,QAAQ,EAAE,MAAM,WAAW,CAAA;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAC3B,OAAO,GAAG,MAAM,KAAK,CAAA;AACrB,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAEhD,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAW;IAC9C,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;QACvB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC,CAAA;QACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,SAAS,GAAG,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAA;IACtC,MAAM,OAAO,GAAG,GAAG,CAAC,gBAAgB,CAAC,CAAC,KAAK,EAAE,CAAA;IAE7C,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAA;QAC/C,IAAI,OAAe,CAAA;QACnB,IAAI,CAAC;YACH,OAAO,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;QAC9C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA;YAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;QAED,MAAM,WAAW,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAA;QAC7C,IAAI,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;YAC9C,OAAO,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAA;YACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;QAED,OAAO,CAAC,IAAI,GAAG,SAAS,CAAA;QACxB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE;YAClC,GAAG,EAAE,SAAS;YACd,KAAK,EAAE,IAAI;YACX,MAAM,EAAE,CAAC,SAAS,EAAE,iBAAiB,EAAE,WAAW,EAAE,OAAO,CAAC;SAC7D,CAAC,CAAA;QAEF,OAAO,CAAC,IAAI,GAAG,MAAM,QAAQ,CAAC,MAAM,cAAc,CAAA;QAElD,MAAM,aAAa,GAEd,EAAE,CAAA;QAEP,KAAK,MAAM,QAAQ,IAAI,QAAQ,EAAE,CAAC;YAChC,OAAO,CAAC,IAAI,GAAG,OAAO,QAAQ,EAAE,CAAA;YAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAA;YAC1C,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAA;YAC/B,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAA;YACtC,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;YAEjE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,MAAM,UAAU,CAAC,oBAAoB,EAAE;gBACvE,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;aACvD,CAA8C,CAAA;YAE/C,MAAM,UAAU,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAA;YAErC,aAAa,CAAC,IAAI,CAAC;gBACjB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,UAAU;gBACV,MAAM;aACP,CAAC,CAAA;QACJ,CAAC;QAED,OAAO,CAAC,IAAI,GAAG,QAAQ,CAAA;QACvB,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,SAAS,EAAE;YACzC,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,IAAI,EAAE,WAAW,CAAC,IAAI;gBACtB,WAAW,EAAE,WAAW,CAAC,WAAW,IAAI,WAAW,CAAC,IAAI;gBACxD,OAAO,EAAE,WAAW,CAAC,OAAO;gBAC5B,OAAO,EAAE,WAAW,CAAC,OAAO;gBAC5B,IAAI,EAAE,WAAW,CAAC,IAAI;gBACtB,KAAK,EAAE,aAAa;aACrB,CAAC;SACH,CAAC,CAAA;QAEF,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,WAAW,CAAC,IAAI,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;IAClF,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;AAED,SAAS,gBAAgB,CAAC,OAAe;IACvC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAA;IACpD,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAA;IAErB,MAAM,MAAM,GAA4B,EAAE,CAAA;IAC1C,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,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAA;YACnC,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,MAAM,EAAE,CAAC;gBAC1B,MAAM,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;YACrE,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,KAAK,CAAA;YAC5B,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function searchCommand(query: string): Promise<void>;
2
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"AAeA,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,iBAuBhD"}
@@ -0,0 +1,25 @@
1
+ import chalk from 'chalk';
2
+ import { apiRequest } from '../lib/api.js';
3
+ export async function searchCommand(query) {
4
+ try {
5
+ const result = await apiRequest(`/search?q=${encodeURIComponent(query)}&pageSize=20`);
6
+ if (!result.items.length) {
7
+ console.log(chalk.yellow('未找到匹配的 Skills'));
8
+ return;
9
+ }
10
+ console.log(chalk.bold(`搜索 "${query}" 找到 ${result.total} 个结果:\n`));
11
+ for (const item of result.items) {
12
+ console.log(` ${chalk.cyan(item.slug)} ${chalk.dim(`by ${item.ownerHandle}`)}`);
13
+ console.log(` ${item.displayName}`);
14
+ if (item.summary) {
15
+ console.log(` ${chalk.gray(item.summary.slice(0, 80))}`);
16
+ }
17
+ console.log(` ${chalk.yellow(`★ ${item.stars}`)} ${chalk.green(`↓ ${item.downloads}`)}\n`);
18
+ }
19
+ }
20
+ catch (err) {
21
+ console.error(chalk.red(`搜索失败: ${err instanceof Error ? err.message : err}`));
22
+ process.exit(1);
23
+ }
24
+ }
25
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAc1C,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,KAAa;IAC/C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,aAAa,kBAAkB,CAAC,KAAK,CAAC,cAAc,CAAiB,CAAA;QAErG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAA;YAC1C,OAAM;QACR,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,QAAQ,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,CAAA;QAElE,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,CAAA;YAChF,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,CAAA;YACtC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACjB,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAA;YAC7D,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,CAAA;QAChG,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;QAC7E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function starCommand(slug: string): Promise<void>;
2
+ export declare function unstarCommand(slug: string): Promise<void>;
3
+ //# sourceMappingURL=star.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"star.d.ts","sourceRoot":"","sources":["../../src/commands/star.ts"],"names":[],"mappings":"AAKA,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,iBAc7C;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,iBAc/C"}
@@ -0,0 +1,35 @@
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 starCommand(slug) {
6
+ if (!isAuthenticated()) {
7
+ console.error(chalk.red('请先登录:skillshub login <token>'));
8
+ process.exit(1);
9
+ }
10
+ const spinner = ora(`收藏 ${slug}...`).start();
11
+ try {
12
+ await apiRequest(`/skills/${slug}/star`, { method: 'POST' });
13
+ spinner.succeed(chalk.green(`已收藏: ${slug}`));
14
+ }
15
+ catch (err) {
16
+ spinner.fail(chalk.red(`收藏失败: ${err instanceof Error ? err.message : err}`));
17
+ process.exit(1);
18
+ }
19
+ }
20
+ export async function unstarCommand(slug) {
21
+ if (!isAuthenticated()) {
22
+ console.error(chalk.red('请先登录:skillshub login <token>'));
23
+ process.exit(1);
24
+ }
25
+ const spinner = ora(`取消收藏 ${slug}...`).start();
26
+ try {
27
+ await apiRequest(`/skills/${slug}/star`, { method: 'DELETE' });
28
+ spinner.succeed(chalk.green(`已取消收藏: ${slug}`));
29
+ }
30
+ catch (err) {
31
+ spinner.fail(chalk.red(`操作失败: ${err instanceof Error ? err.message : err}`));
32
+ process.exit(1);
33
+ }
34
+ }
35
+ //# sourceMappingURL=star.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"star.js","sourceRoot":"","sources":["../../src/commands/star.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,WAAW,CAAC,IAAY;IAC5C,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;QACvB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC,CAAA;QACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,KAAK,EAAE,CAAA;IAC5C,IAAI,CAAC;QACH,MAAM,UAAU,CAAC,WAAW,IAAI,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;QAC5D,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;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAY;IAC9C,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;QACvB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC,CAAA;QACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,IAAI,KAAK,CAAC,CAAC,KAAK,EAAE,CAAA;IAC9C,IAAI,CAAC;QACH,MAAM,UAAU,CAAC,WAAW,IAAI,OAAO,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAA;QAC9D,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,CAAA;IAChD,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,2 @@
1
+ export declare function syncCommand(dir: string): Promise<void>;
2
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AAQA,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,iBAsD5C"}
@@ -0,0 +1,73 @@
1
+ import { readFileSync, existsSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import chalk from 'chalk';
4
+ import ora from 'ora';
5
+ import { apiRequest } from '../lib/api.js';
6
+ import { isAuthenticated } from '../lib/auth.js';
7
+ import { publishCommand } from './publish.js';
8
+ export async function syncCommand(dir) {
9
+ if (!isAuthenticated()) {
10
+ console.error(chalk.red('请先登录:skillshub login <token>'));
11
+ process.exit(1);
12
+ }
13
+ const targetDir = dir || process.cwd();
14
+ const skillMdPath = join(targetDir, 'SKILL.md');
15
+ if (!existsSync(skillMdPath)) {
16
+ console.error(chalk.red('未找到 SKILL.md 文件'));
17
+ process.exit(1);
18
+ }
19
+ const content = readFileSync(skillMdPath, 'utf-8');
20
+ const frontmatter = parseFrontmatter(content);
21
+ if (!frontmatter.slug || !frontmatter.version) {
22
+ console.error(chalk.red('SKILL.md frontmatter 缺少 slug 或 version'));
23
+ process.exit(1);
24
+ }
25
+ const spinner = ora('检查远端版本...').start();
26
+ try {
27
+ const remote = await apiRequest(`/skills/${frontmatter.slug}`);
28
+ const remoteVersion = remote?.latestVersion?.version;
29
+ const localVersion = frontmatter.version;
30
+ if (remoteVersion === localVersion) {
31
+ spinner.info(chalk.blue(`本地版本 (${localVersion}) 与远端一致,无需同步`));
32
+ return;
33
+ }
34
+ if (remoteVersion) {
35
+ spinner.info(chalk.yellow(`远端: ${remoteVersion} → 本地: ${localVersion},开始发布...`));
36
+ }
37
+ else {
38
+ spinner.info(chalk.yellow(`远端无版本记录,开始首次发布...`));
39
+ }
40
+ await publishCommand(targetDir);
41
+ }
42
+ catch (err) {
43
+ const msg = err instanceof Error ? err.message : String(err);
44
+ if (msg.includes('Skill not found')) {
45
+ spinner.info(chalk.yellow('远端尚无此 Skill,开始首次发布...'));
46
+ await publishCommand(targetDir);
47
+ }
48
+ else {
49
+ spinner.fail(chalk.red(`同步失败: ${msg}`));
50
+ process.exit(1);
51
+ }
52
+ }
53
+ }
54
+ function parseFrontmatter(content) {
55
+ const match = content.match(/^---\n([\s\S]*?)\n---/);
56
+ if (!match)
57
+ return {};
58
+ const result = {};
59
+ for (const line of match[1].split('\n')) {
60
+ const [key, ...rest] = line.split(':');
61
+ if (key && rest.length) {
62
+ const value = rest.join(':').trim();
63
+ if (key.trim() === 'tags') {
64
+ result.tags = value.split(',').map((t) => t.trim()).filter(Boolean);
65
+ }
66
+ else {
67
+ result[key.trim()] = value;
68
+ }
69
+ }
70
+ }
71
+ return result;
72
+ }
73
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare function tokenCreateCommand(label: string): Promise<void>;
2
+ export declare function tokenListCommand(): Promise<void>;
3
+ export declare function tokenRevokeCommand(tokenId: string): Promise<void>;
4
+ //# sourceMappingURL=token.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../src/commands/token.ts"],"names":[],"mappings":"AAKA,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,MAAM,iBA0BrD;AAED,wBAAsB,gBAAgB,kBAyCrC;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,MAAM,iBAUvD"}
@@ -0,0 +1,73 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { apiRequest } from '../lib/api.js';
4
+ import { saveConfig, loadConfig } from '../lib/config.js';
5
+ export async function tokenCreateCommand(label) {
6
+ const spinner = ora('创建 API Token...').start();
7
+ try {
8
+ const result = (await apiRequest('/tokens', {
9
+ method: 'POST',
10
+ body: JSON.stringify({ label }),
11
+ }));
12
+ spinner.succeed('Token 创建成功');
13
+ console.log('');
14
+ console.log(chalk.green('Token:'), chalk.bold(result.token));
15
+ console.log('');
16
+ console.log(chalk.yellow('⚠ 请立即复制保存此 Token,它仅显示一次。'));
17
+ console.log('');
18
+ const config = loadConfig();
19
+ if (!config.token || !config.token.startsWith('sk-')) {
20
+ saveConfig({ token: result.token });
21
+ console.log(chalk.gray('已自动保存到 ~/.skillshub/config.json'));
22
+ }
23
+ }
24
+ catch (error) {
25
+ spinner.fail('创建失败');
26
+ console.error(chalk.red(error instanceof Error ? error.message : String(error)));
27
+ process.exit(1);
28
+ }
29
+ }
30
+ export async function tokenListCommand() {
31
+ const spinner = ora('获取 Token 列表...').start();
32
+ try {
33
+ const tokens = (await apiRequest('/tokens'));
34
+ spinner.stop();
35
+ if (tokens.length === 0) {
36
+ console.log(chalk.gray('暂无 API Token'));
37
+ return;
38
+ }
39
+ console.log('');
40
+ console.log(chalk.bold('API Tokens:'));
41
+ console.log('');
42
+ for (const token of tokens) {
43
+ const status = token.revokedAt ? chalk.red('已撤销') : chalk.green('活跃');
44
+ const lastUsed = token.lastUsedAt
45
+ ? new Date(token.lastUsedAt).toLocaleDateString('zh-CN')
46
+ : '从未使用';
47
+ console.log(` ${status} ${chalk.bold(token.label)}`);
48
+ console.log(` ID: ${token.id}`);
49
+ console.log(` 前缀: ${token.prefix}...`);
50
+ console.log(` 最后使用: ${lastUsed}`);
51
+ console.log(` 创建时间: ${new Date(token.createdAt).toLocaleDateString('zh-CN')}`);
52
+ console.log('');
53
+ }
54
+ }
55
+ catch (error) {
56
+ spinner.fail('获取失败');
57
+ console.error(chalk.red(error instanceof Error ? error.message : String(error)));
58
+ process.exit(1);
59
+ }
60
+ }
61
+ export async function tokenRevokeCommand(tokenId) {
62
+ const spinner = ora('撤销 Token...').start();
63
+ try {
64
+ await apiRequest(`/tokens/${tokenId}`, { method: 'DELETE' });
65
+ spinner.succeed('Token 已撤销');
66
+ }
67
+ catch (error) {
68
+ spinner.fail('撤销失败');
69
+ console.error(chalk.red(error instanceof Error ? error.message : String(error)));
70
+ process.exit(1);
71
+ }
72
+ }
73
+ //# sourceMappingURL=token.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/commands/token.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { publishCommand } from './commands/publish.js';
4
+ import { searchCommand } from './commands/search.js';
5
+ import { installCommand } from './commands/install.js';
6
+ import { tokenCreateCommand, tokenListCommand, tokenRevokeCommand } from './commands/token.js';
7
+ import { starCommand, unstarCommand } from './commands/star.js';
8
+ import { deleteCommand } from './commands/delete.js';
9
+ import { syncCommand } from './commands/sync.js';
10
+ import { login } from './lib/auth.js';
11
+ import { saveConfig } from './lib/config.js';
12
+ const program = new Command();
13
+ program
14
+ .name('skillshub')
15
+ .description('SkillsHub CLI — publish, search, and install skills')
16
+ .version('0.1.0');
17
+ program
18
+ .command('login <token>')
19
+ .description('Save authentication token (JWT or API Token)')
20
+ .action((token) => {
21
+ login(token);
22
+ console.log('Token saved successfully.');
23
+ });
24
+ program
25
+ .command('config')
26
+ .description('Set API URL')
27
+ .option('--api-url <url>', 'API base URL')
28
+ .action((opts) => {
29
+ if (opts.apiUrl) {
30
+ saveConfig({ apiUrl: opts.apiUrl });
31
+ console.log(`API URL set to: ${opts.apiUrl}`);
32
+ }
33
+ });
34
+ program
35
+ .command('publish [dir]')
36
+ .description('Publish a skill from a directory')
37
+ .action(publishCommand);
38
+ program
39
+ .command('search <query>')
40
+ .description('Search for skills')
41
+ .action(searchCommand);
42
+ program
43
+ .command('install <slug>')
44
+ .description('Download and install a skill')
45
+ .option('-d, --dir <dir>', 'Target directory')
46
+ .action(installCommand);
47
+ const tokenCmd = program
48
+ .command('token')
49
+ .description('Manage API tokens');
50
+ tokenCmd
51
+ .command('create <label>')
52
+ .description('Create a new API token')
53
+ .action(tokenCreateCommand);
54
+ tokenCmd
55
+ .command('list')
56
+ .description('List all API tokens')
57
+ .action(tokenListCommand);
58
+ tokenCmd
59
+ .command('revoke <id>')
60
+ .description('Revoke an API token')
61
+ .action(tokenRevokeCommand);
62
+ program
63
+ .command('star <slug>')
64
+ .description('Star a skill')
65
+ .action(starCommand);
66
+ program
67
+ .command('unstar <slug>')
68
+ .description('Unstar a skill')
69
+ .action(unstarCommand);
70
+ program
71
+ .command('delete <slug>')
72
+ .description('Delete a skill you own')
73
+ .option('-f, --force', 'Skip confirmation prompt')
74
+ .action(deleteCommand);
75
+ program
76
+ .command('sync [dir]')
77
+ .description('Sync local SKILL.md to remote (publish if version differs)')
78
+ .action(syncCommand);
79
+ program.parse();
80
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function apiRequest(path: string, options?: RequestInit): Promise<unknown>;
2
+ export declare function uploadFile(url: string, filePath: string): Promise<void>;
3
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"AAEA,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CA0B1F;AAED,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAY7E"}
@@ -0,0 +1,34 @@
1
+ import { loadConfig, getToken } from './config.js';
2
+ export async function apiRequest(path, options = {}) {
3
+ const config = loadConfig();
4
+ const url = `${config.apiUrl}/api/v1${path}`;
5
+ const token = getToken();
6
+ const headers = {
7
+ 'Content-Type': 'application/json',
8
+ ...(options.headers || {}),
9
+ };
10
+ if (token) {
11
+ headers.Authorization = `Bearer ${token}`;
12
+ }
13
+ const response = await fetch(url, {
14
+ ...options,
15
+ headers,
16
+ });
17
+ const data = await response.json();
18
+ if (!data.success) {
19
+ throw new Error(data.error?.message || `API error: ${response.status}`);
20
+ }
21
+ return data.data;
22
+ }
23
+ export async function uploadFile(url, filePath) {
24
+ const { readFileSync } = await import('node:fs');
25
+ const buffer = readFileSync(filePath);
26
+ const response = await fetch(url, {
27
+ method: 'PUT',
28
+ body: buffer,
29
+ });
30
+ if (!response.ok) {
31
+ throw new Error(`Upload failed: ${response.status}`);
32
+ }
33
+ }
34
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAElD,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAY,EAAE,UAAuB,EAAE;IACtE,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;IAC3B,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC,MAAM,UAAU,IAAI,EAAE,CAAA;IAC5C,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAA;IAExB,MAAM,OAAO,GAA2B;QACtC,cAAc,EAAE,kBAAkB;QAClC,GAAG,CAAE,OAAO,CAAC,OAAkC,IAAI,EAAE,CAAC;KACvD,CAAA;IAED,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,CAAC,aAAa,GAAG,UAAU,KAAK,EAAE,CAAA;IAC3C,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAChC,GAAG,OAAO;QACV,OAAO;KACR,CAAC,CAAA;IAEF,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAuE,CAAA;IAEvG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,IAAI,cAAc,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;IACzE,CAAC;IAED,OAAO,IAAI,CAAC,IAAI,CAAA;AAClB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAW,EAAE,QAAgB;IAC5D,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAA;IAChD,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAA;IAErC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAChC,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,MAAM;KACb,CAAC,CAAA;IAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,kBAAkB,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;IACtD,CAAC;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { getToken } from './config.js';
2
+ export declare function login(token: string): void;
3
+ export declare function isAuthenticated(): boolean;
4
+ export declare function isApiToken(): boolean;
5
+ export { getToken };
6
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyB,QAAQ,EAAE,MAAM,aAAa,CAAA;AAE7D,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,QAElC;AAED,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED,wBAAgB,UAAU,IAAI,OAAO,CAGpC;AAED,OAAO,EAAE,QAAQ,EAAE,CAAA"}
@@ -0,0 +1,13 @@
1
+ import { setToken as saveToken, getToken } from './config.js';
2
+ export function login(token) {
3
+ saveToken(token);
4
+ }
5
+ export function isAuthenticated() {
6
+ return !!getToken();
7
+ }
8
+ export function isApiToken() {
9
+ const token = getToken();
10
+ return !!token && token.startsWith('sk-');
11
+ }
12
+ export { getToken };
13
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,SAAS,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAE7D,MAAM,UAAU,KAAK,CAAC,KAAa;IACjC,SAAS,CAAC,KAAK,CAAC,CAAA;AAClB,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAA;AACrB,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAA;IACxB,OAAO,CAAC,CAAC,KAAK,IAAI,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;AAC3C,CAAC;AAED,OAAO,EAAE,QAAQ,EAAE,CAAA"}
@@ -0,0 +1,10 @@
1
+ interface Config {
2
+ apiUrl: string;
3
+ token?: string;
4
+ }
5
+ export declare function loadConfig(): Config;
6
+ export declare function saveConfig(config: Partial<Config>): void;
7
+ export declare function getToken(): string | undefined;
8
+ export declare function setToken(token: string): void;
9
+ export {};
10
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAOA,UAAU,MAAM;IACd,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAMD,wBAAgB,UAAU,IAAI,MAAM,CAQnC;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,QAKjD;AAED,wBAAgB,QAAQ,IAAI,MAAM,GAAG,SAAS,CAE7C;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,QAErC"}
@@ -0,0 +1,32 @@
1
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { homedir } from 'node:os';
4
+ const CONFIG_DIR = join(homedir(), '.skillshub');
5
+ const CONFIG_FILE = join(CONFIG_DIR, 'config.json');
6
+ const DEFAULT_CONFIG = {
7
+ apiUrl: 'https://skills.nodeskai.com',
8
+ };
9
+ export function loadConfig() {
10
+ if (!existsSync(CONFIG_FILE))
11
+ return DEFAULT_CONFIG;
12
+ try {
13
+ const raw = readFileSync(CONFIG_FILE, 'utf-8');
14
+ return { ...DEFAULT_CONFIG, ...JSON.parse(raw) };
15
+ }
16
+ catch {
17
+ return DEFAULT_CONFIG;
18
+ }
19
+ }
20
+ export function saveConfig(config) {
21
+ const existing = loadConfig();
22
+ const merged = { ...existing, ...config };
23
+ mkdirSync(CONFIG_DIR, { recursive: true });
24
+ writeFileSync(CONFIG_FILE, JSON.stringify(merged, null, 2));
25
+ }
26
+ export function getToken() {
27
+ return loadConfig().token;
28
+ }
29
+ export function setToken(token) {
30
+ saveConfig({ token });
31
+ }
32
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAC5E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAEjC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,YAAY,CAAC,CAAA;AAChD,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAA;AAOnD,MAAM,cAAc,GAAW;IAC7B,MAAM,EAAE,6BAA6B;CACtC,CAAA;AAED,MAAM,UAAU,UAAU;IACxB,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,cAAc,CAAA;IACnD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;QAC9C,OAAO,EAAE,GAAG,cAAc,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAA;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,cAAc,CAAA;IACvB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAuB;IAChD,MAAM,QAAQ,GAAG,UAAU,EAAE,CAAA;IAC7B,MAAM,MAAM,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,MAAM,EAAE,CAAA;IACzC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAC1C,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;AAC7D,CAAC;AAED,MAAM,UAAU,QAAQ;IACtB,OAAO,UAAU,EAAE,CAAC,KAAK,CAAA;AAC3B,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,KAAa;IACpC,UAAU,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;AACvB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@nodeskai/skillshub",
3
+ "version": "0.1.0",
4
+ "description": "SkillsHub CLI — publish, search, and install AI agent skills",
5
+ "type": "module",
6
+ "bin": {
7
+ "skillshub": "./dist/index.js"
8
+ },
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "keywords": [
13
+ "skills",
14
+ "ai",
15
+ "agent",
16
+ "cli",
17
+ "skillshub"
18
+ ],
19
+ "license": "MIT",
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "https://github.com/user/skillshub",
23
+ "directory": "packages/cli"
24
+ },
25
+ "scripts": {
26
+ "build": "tsc",
27
+ "dev": "tsc --watch"
28
+ },
29
+ "dependencies": {
30
+ "commander": "^12.0.0",
31
+ "ora": "^8.0.0",
32
+ "chalk": "^5.0.0",
33
+ "glob": "^11.0.0",
34
+ "adm-zip": "^0.5.16"
35
+ },
36
+ "devDependencies": {
37
+ "typescript": "^5.7.0",
38
+ "@types/node": "^22.0.0",
39
+ "@types/adm-zip": "^0.5.6"
40
+ }
41
+ }