myskillshub 1.0.2 → 1.0.3
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/package.json +3 -2
- package/scripts/auto-bump-version.js +123 -0
- package/src/commands/publish.js +19 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "myskillshub",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "CLI tool for SkillHub skill management",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
"scripts": {
|
|
10
10
|
"test": "jest",
|
|
11
11
|
"lint": "eslint src/**/*.js",
|
|
12
|
-
"start": "node src/index.js"
|
|
12
|
+
"start": "node src/index.js",
|
|
13
|
+
"prepublishOnly": "node scripts/auto-bump-version.js"
|
|
13
14
|
},
|
|
14
15
|
"keywords": [
|
|
15
16
|
"cli",
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const os = require('os');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const { spawnSync } = require('child_process');
|
|
7
|
+
|
|
8
|
+
const PACKAGE_JSON_PATH = path.join(__dirname, '..', 'package.json');
|
|
9
|
+
const PACKAGE_LOCK_PATH = path.join(__dirname, '..', 'package-lock.json');
|
|
10
|
+
|
|
11
|
+
function parseSemver(version) {
|
|
12
|
+
const match = /^(\d+)\.(\d+)\.(\d+)$/.exec(String(version || '').trim());
|
|
13
|
+
if (!match) {
|
|
14
|
+
throw new Error(`Invalid semver version: ${version}`);
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
major: Number(match[1]),
|
|
18
|
+
minor: Number(match[2]),
|
|
19
|
+
patch: Number(match[3]),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function compareSemver(left, right) {
|
|
24
|
+
if (left.major !== right.major) return left.major - right.major;
|
|
25
|
+
if (left.minor !== right.minor) return left.minor - right.minor;
|
|
26
|
+
return left.patch - right.patch;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function bumpPatch(version) {
|
|
30
|
+
const parsed = parseSemver(version);
|
|
31
|
+
return `${parsed.major}.${parsed.minor}.${parsed.patch + 1}`;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function readJson(filePath) {
|
|
35
|
+
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function writeJson(filePath, data) {
|
|
39
|
+
fs.writeFileSync(filePath, `${JSON.stringify(data, null, 2)}\n`, 'utf8');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function fetchPublishedVersion(packageName) {
|
|
43
|
+
const cacheDir = path.join(os.tmpdir(), 'myskillshub-npm-cache');
|
|
44
|
+
fs.mkdirSync(cacheDir, { recursive: true });
|
|
45
|
+
|
|
46
|
+
const result = spawnSync(
|
|
47
|
+
'npm',
|
|
48
|
+
['view', packageName, 'version', '--json'],
|
|
49
|
+
{
|
|
50
|
+
encoding: 'utf8',
|
|
51
|
+
env: {
|
|
52
|
+
...process.env,
|
|
53
|
+
npm_config_cache: cacheDir,
|
|
54
|
+
},
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
if (result.status === 0) {
|
|
59
|
+
const stdout = String(result.stdout || '').trim();
|
|
60
|
+
if (!stdout) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
const parsed = JSON.parse(stdout);
|
|
64
|
+
return Array.isArray(parsed) ? parsed[parsed.length - 1] : String(parsed);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const stderr = String(result.stderr || '');
|
|
68
|
+
if (stderr.includes('E404') || stderr.includes('Not Found')) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
throw new Error(`Failed to query published version: ${stderr || result.stdout}`);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function main() {
|
|
76
|
+
const pkg = readJson(PACKAGE_JSON_PATH);
|
|
77
|
+
const packageName = pkg.name;
|
|
78
|
+
const currentVersion = pkg.version;
|
|
79
|
+
|
|
80
|
+
if (!packageName) {
|
|
81
|
+
throw new Error('package.json name is required');
|
|
82
|
+
}
|
|
83
|
+
if (!currentVersion) {
|
|
84
|
+
throw new Error('package.json version is required');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const publishedVersion = fetchPublishedVersion(packageName);
|
|
88
|
+
if (!publishedVersion) {
|
|
89
|
+
console.log(`[auto-bump] ${packageName} has no published version yet, keep ${currentVersion}`);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const currentParsed = parseSemver(currentVersion);
|
|
94
|
+
const publishedParsed = parseSemver(publishedVersion);
|
|
95
|
+
const shouldBump = compareSemver(currentParsed, publishedParsed) <= 0;
|
|
96
|
+
|
|
97
|
+
if (!shouldBump) {
|
|
98
|
+
console.log(`[auto-bump] local version ${currentVersion} is newer than published ${publishedVersion}, keep current`);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const nextVersion = bumpPatch(publishedVersion);
|
|
103
|
+
pkg.version = nextVersion;
|
|
104
|
+
writeJson(PACKAGE_JSON_PATH, pkg);
|
|
105
|
+
|
|
106
|
+
if (fs.existsSync(PACKAGE_LOCK_PATH)) {
|
|
107
|
+
const lock = readJson(PACKAGE_LOCK_PATH);
|
|
108
|
+
lock.version = nextVersion;
|
|
109
|
+
if (lock.packages && lock.packages['']) {
|
|
110
|
+
lock.packages[''].version = nextVersion;
|
|
111
|
+
}
|
|
112
|
+
writeJson(PACKAGE_LOCK_PATH, lock);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
console.log(`[auto-bump] bumped ${packageName} version: ${currentVersion} -> ${nextVersion}`);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
try {
|
|
119
|
+
main();
|
|
120
|
+
} catch (error) {
|
|
121
|
+
console.error(`[auto-bump] ${error.message}`);
|
|
122
|
+
process.exit(1);
|
|
123
|
+
}
|
package/src/commands/publish.js
CHANGED
|
@@ -14,23 +14,24 @@ const program = new Command();
|
|
|
14
14
|
program
|
|
15
15
|
.name('publish')
|
|
16
16
|
.description('Publish a skill from local directory')
|
|
17
|
-
.argument('
|
|
17
|
+
.argument('[directory]', 'Directory containing skill to publish (default: current directory)')
|
|
18
18
|
.option('--verbose', 'Verbose output')
|
|
19
19
|
.option('-a, --api-url <url>', 'SkillHub API URL', 'http://localhost:3000')
|
|
20
20
|
.action(async (directory, options) => {
|
|
21
|
+
const targetDirectory = directory || '.';
|
|
21
22
|
const spinner = ora('Starting publish process...').start();
|
|
22
23
|
|
|
23
24
|
try {
|
|
24
25
|
// Validate directory exists
|
|
25
|
-
if (!fs.existsSync(
|
|
26
|
-
spinner.fail(chalk.red(`Directory not found: ${
|
|
26
|
+
if (!fs.existsSync(targetDirectory)) {
|
|
27
|
+
spinner.fail(chalk.red(`Directory not found: ${targetDirectory}`));
|
|
27
28
|
process.exit(1);
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
// Find skill.md file
|
|
31
|
-
const skillMdPath =
|
|
32
|
-
if (!
|
|
33
|
-
spinner.fail(chalk.red('skill.md not found in the directory'));
|
|
32
|
+
const skillMdPath = resolveSkillFilePath(targetDirectory);
|
|
33
|
+
if (!skillMdPath) {
|
|
34
|
+
spinner.fail(chalk.red('SKILL.md or skill.md not found in the directory'));
|
|
34
35
|
process.exit(1);
|
|
35
36
|
}
|
|
36
37
|
|
|
@@ -43,7 +44,7 @@ program
|
|
|
43
44
|
|
|
44
45
|
// Create ZIP package
|
|
45
46
|
spinner.text = 'Creating ZIP package...';
|
|
46
|
-
const zipPath = await createZipPackage(
|
|
47
|
+
const zipPath = await createZipPackage(targetDirectory);
|
|
47
48
|
spinner.succeed(chalk.green(`ZIP package created: ${zipPath}`));
|
|
48
49
|
|
|
49
50
|
// Upload to SkillHub API
|
|
@@ -63,6 +64,17 @@ program
|
|
|
63
64
|
}
|
|
64
65
|
});
|
|
65
66
|
|
|
67
|
+
function resolveSkillFilePath(directory) {
|
|
68
|
+
const candidates = ['SKILL.md', 'skill.md'];
|
|
69
|
+
for (const fileName of candidates) {
|
|
70
|
+
const fullPath = path.join(directory, fileName);
|
|
71
|
+
if (fs.existsSync(fullPath)) {
|
|
72
|
+
return fullPath;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
|
|
66
78
|
function parseSkillMd(content) {
|
|
67
79
|
const lines = content.split('\n');
|
|
68
80
|
const skillData = {
|