sophhub 0.1.3 → 0.1.4
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 +8 -1
- package/package.json +1 -1
- package/skills/VERSIONS.md +1 -1
- package/src/commands/download.js +68 -41
package/README.md
CHANGED
|
@@ -40,7 +40,7 @@ sophhub list --type store --json
|
|
|
40
40
|
|
|
41
41
|
### 下载 Skill
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
下载单个 Skill 到当前目录:
|
|
44
44
|
|
|
45
45
|
```bash
|
|
46
46
|
sophhub download weather
|
|
@@ -52,6 +52,13 @@ sophhub download weather
|
|
|
52
52
|
sophhub download didi-ride -o ./my-skills
|
|
53
53
|
```
|
|
54
54
|
|
|
55
|
+
批量下载某个类型的所有 Skill:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
sophhub download --type builtin -o ./skills
|
|
59
|
+
sophhub download --type store -o ./skills
|
|
60
|
+
```
|
|
61
|
+
|
|
55
62
|
### 查看版本
|
|
56
63
|
|
|
57
64
|
```bash
|
package/package.json
CHANGED
package/skills/VERSIONS.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
| Skill | Type | Version | Updated At | Display Name | Description |
|
|
4
4
|
| --- | --- | --- | --- | --- | --- |
|
|
5
|
-
| skillhub | builtin |
|
|
5
|
+
| skillhub | builtin | 1.0.0 | 2026-04-09 | | |
|
|
6
6
|
| flight-booking | builtin | 1.1.0 | 2026-04-08 | | |
|
|
7
7
|
| inventory-management | builtin | 1.0.0 | 2026-04-08 | | |
|
|
8
8
|
| schedule-reminder | builtin | 1.0.0 | 2026-04-08 | | |
|
package/src/commands/download.js
CHANGED
|
@@ -1,74 +1,101 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import fs from 'node:fs/promises';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
-
import
|
|
5
|
-
import { findSkill } from '../utils/versions.js';
|
|
4
|
+
import { findSkill, parseVersions } from '../utils/versions.js';
|
|
6
5
|
import { getSkillDir } from '../utils/paths.js';
|
|
7
6
|
import { loadConfig } from '../utils/config.js';
|
|
8
7
|
|
|
9
|
-
async function
|
|
10
|
-
const
|
|
8
|
+
async function downloadSingle(skillName, outputDir) {
|
|
9
|
+
const skill = await findSkill(skillName);
|
|
10
|
+
if (!skill) {
|
|
11
|
+
console.error(chalk.red(`Skill "${skillName}" not found.`));
|
|
12
|
+
console.error(chalk.gray('Run "sophhub list" to see all available skills.'));
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const destDir = path.join(outputDir, skillName);
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
await fs.access(destDir);
|
|
20
|
+
await fs.rm(destDir, { recursive: true, force: true });
|
|
21
|
+
} catch {
|
|
22
|
+
// dest does not exist
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const srcDir = getSkillDir(skill.type, skillName);
|
|
11
26
|
try {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
);
|
|
15
|
-
return answer.trim().toLowerCase() === 'y';
|
|
16
|
-
} finally {
|
|
17
|
-
rl.close();
|
|
27
|
+
await fs.access(srcDir);
|
|
28
|
+
} catch {
|
|
29
|
+
throw new Error(`Skill directory not found in package: ${srcDir}`);
|
|
18
30
|
}
|
|
31
|
+
|
|
32
|
+
await fs.cp(srcDir, destDir, { recursive: true });
|
|
33
|
+
|
|
34
|
+
console.log(chalk.green(` ✓ ${skill.name}`) + chalk.gray(` (${skill.version}) → ${destDir}`));
|
|
19
35
|
}
|
|
20
36
|
|
|
21
37
|
export function registerDownloadCommand(program) {
|
|
22
38
|
program
|
|
23
39
|
.command('download')
|
|
24
|
-
.description('Download
|
|
25
|
-
.argument('
|
|
40
|
+
.description('Download skill(s) to local directory')
|
|
41
|
+
.argument('[skill-name]', 'Name of the skill to download')
|
|
26
42
|
.option('-o, --output <dir>', 'Target directory (default: current directory)')
|
|
43
|
+
.option('-t, --type <type>', 'Download all skills of the given type (builtin/store)')
|
|
27
44
|
.action(async (skillName, opts) => {
|
|
28
45
|
try {
|
|
29
46
|
const config = await loadConfig();
|
|
30
47
|
const outputDir = path.resolve(opts.output || config.defaultOutput || '.');
|
|
48
|
+
await fs.mkdir(outputDir, { recursive: true });
|
|
31
49
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
50
|
+
if (opts.type) {
|
|
51
|
+
const typeFilter = opts.type.toLowerCase();
|
|
52
|
+
if (typeFilter !== 'builtin' && typeFilter !== 'store') {
|
|
53
|
+
console.error(chalk.red('\n --type must be "builtin" or "store"\n'));
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
38
56
|
|
|
39
|
-
|
|
57
|
+
const skills = await parseVersions();
|
|
58
|
+
const filtered = skills.filter((s) => s.type === typeFilter);
|
|
40
59
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const ok = await confirmOverwrite(destDir);
|
|
44
|
-
if (!ok) {
|
|
45
|
-
console.log(chalk.gray('Cancelled.'));
|
|
60
|
+
if (filtered.length === 0) {
|
|
61
|
+
console.log(chalk.yellow(`\n No skills found for type "${typeFilter}".\n`));
|
|
46
62
|
return;
|
|
47
63
|
}
|
|
48
|
-
await fs.rm(destDir, { recursive: true, force: true });
|
|
49
|
-
} catch {
|
|
50
|
-
// dest does not exist, proceed
|
|
51
|
-
}
|
|
52
64
|
|
|
53
|
-
|
|
65
|
+
console.log();
|
|
66
|
+
console.log(chalk.cyan(` Downloading all ${typeFilter} skills (${filtered.length})...`));
|
|
67
|
+
console.log();
|
|
54
68
|
|
|
55
|
-
|
|
56
|
-
|
|
69
|
+
let success = 0;
|
|
70
|
+
for (const skill of filtered) {
|
|
71
|
+
try {
|
|
72
|
+
await downloadSingle(skill.name, outputDir);
|
|
73
|
+
success++;
|
|
74
|
+
} catch (err) {
|
|
75
|
+
console.error(chalk.red(` ✗ ${skill.name}: ${err.message}`));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
57
78
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
throw new Error(`Skill directory not found in package: ${srcDir}`);
|
|
79
|
+
console.log();
|
|
80
|
+
console.log(chalk.green(` Done. ${success}/${filtered.length} skills downloaded to ${outputDir}`));
|
|
81
|
+
console.log();
|
|
82
|
+
return;
|
|
63
83
|
}
|
|
64
84
|
|
|
65
|
-
|
|
85
|
+
if (!skillName) {
|
|
86
|
+
console.error(chalk.red('\n Please specify a skill name or use --type to batch download.\n'));
|
|
87
|
+
console.error(chalk.gray(' Examples:'));
|
|
88
|
+
console.error(chalk.gray(' sophhub download <skill-name>'));
|
|
89
|
+
console.error(chalk.gray(' sophhub download --type builtin'));
|
|
90
|
+
console.error(chalk.gray(' sophhub download --type store\n'));
|
|
91
|
+
process.exit(1);
|
|
92
|
+
}
|
|
66
93
|
|
|
67
94
|
console.log();
|
|
68
|
-
console.log(chalk.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
95
|
+
console.log(chalk.gray(` Downloading ${skillName}...`));
|
|
96
|
+
|
|
97
|
+
await downloadSingle(skillName, outputDir);
|
|
98
|
+
|
|
72
99
|
console.log();
|
|
73
100
|
} catch (err) {
|
|
74
101
|
console.error(chalk.red(`\n Failed to download: ${err.message}\n`));
|