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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "myskillshub",
3
- "version": "1.0.2",
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
+ }
@@ -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('<directory>', 'Directory containing skill to publish')
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(directory)) {
26
- spinner.fail(chalk.red(`Directory not found: ${directory}`));
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 = path.join(directory, 'skill.md');
32
- if (!fs.existsSync(skillMdPath)) {
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(directory);
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 = {