skillhub 0.1.4 → 0.1.6

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 (2) hide show
  1. package/dist/index.js +55 -13
  2. package/package.json +13 -3
package/dist/index.js CHANGED
@@ -140,7 +140,11 @@ function getOctokit() {
140
140
  if (!octokit) {
141
141
  octokit = new Octokit({
142
142
  auth: process.env.GITHUB_TOKEN,
143
- userAgent: "SkillHub-CLI/1.0"
143
+ userAgent: "SkillHub-CLI/1.0",
144
+ request: {
145
+ timeout: 3e4
146
+ // 30 second timeout
147
+ }
144
148
  });
145
149
  }
146
150
  return octokit;
@@ -148,12 +152,23 @@ function getOctokit() {
148
152
  async function fetchSkillContent(owner, repo, skillPath, branch = "main") {
149
153
  const client = getOctokit();
150
154
  const skillMdPath = skillPath ? `${skillPath}/SKILL.md` : "SKILL.md";
151
- const skillMdResponse = await client.repos.getContent({
152
- owner,
153
- repo,
154
- path: skillMdPath,
155
- ref: branch
156
- });
155
+ let skillMdResponse;
156
+ try {
157
+ skillMdResponse = await client.repos.getContent({
158
+ owner,
159
+ repo,
160
+ path: skillMdPath,
161
+ ref: branch
162
+ });
163
+ } catch (error) {
164
+ if (error.status === 404) {
165
+ throw new Error(`SKILL.md not found at ${owner}/${repo}/${skillMdPath}`);
166
+ }
167
+ if (error.message?.includes("timeout")) {
168
+ throw new Error(`GitHub request timeout. Check your internet connection or try again later.`);
169
+ }
170
+ throw new Error(`Failed to fetch from GitHub: ${error.message}`);
171
+ }
157
172
  if (!("content" in skillMdResponse.data)) {
158
173
  throw new Error("SKILL.md not found");
159
174
  }
@@ -240,17 +255,30 @@ async function install(skillId, options) {
240
255
  process.exit(1);
241
256
  }
242
257
  const [owner, repo, ...rest] = parts;
243
- const skillPath = rest.join("/");
244
- const skillInfo = await getSkill(skillId);
258
+ let skillPath = rest.join("/");
259
+ let skillInfo;
260
+ try {
261
+ skillInfo = await getSkill(skillId);
262
+ } catch (error) {
263
+ spinner.warn(`API error: ${error.message}`);
264
+ spinner.start("Falling back to direct GitHub fetch...");
265
+ }
245
266
  let skillName;
246
267
  let branch = "main";
247
268
  if (skillInfo) {
248
269
  skillName = skillInfo.name;
270
+ skillPath = skillInfo.skillPath;
271
+ branch = skillInfo.branch || "main";
249
272
  spinner.text = `Found skill: ${chalk.cyan(skillName)}`;
250
273
  } else {
251
274
  spinner.text = "Skill not in registry, fetching from GitHub...";
252
- branch = await getDefaultBranch(owner, repo);
253
- skillName = skillPath || repo;
275
+ try {
276
+ branch = await getDefaultBranch(owner, repo);
277
+ skillName = skillPath || repo;
278
+ } catch (error) {
279
+ spinner.fail("Failed to connect to GitHub");
280
+ throw error;
281
+ }
254
282
  }
255
283
  const installed = await isSkillInstalled(options.platform, skillName, options.project);
256
284
  if (installed && !options.force) {
@@ -260,8 +288,22 @@ async function install(skillId, options) {
260
288
  process.exit(1);
261
289
  }
262
290
  await ensureSkillsDir(options.platform, options.project);
263
- spinner.text = "Downloading skill files...";
264
- const content = await fetchSkillContent(owner, repo, skillPath, branch);
291
+ spinner.text = `Downloading from ${owner}/${repo}/${skillPath || ""}...`;
292
+ let content;
293
+ try {
294
+ content = await fetchSkillContent(owner, repo, skillPath, branch);
295
+ spinner.text = `Downloaded ${content.scripts.length} scripts, ${content.references.length} references`;
296
+ } catch (error) {
297
+ spinner.fail("Failed to download skill files");
298
+ console.error(chalk.red(error.message));
299
+ console.log();
300
+ console.log(chalk.yellow("Troubleshooting tips:"));
301
+ console.log(chalk.dim(" 1. Check your internet connection"));
302
+ console.log(chalk.dim(" 2. If behind a proxy, configure HTTP_PROXY/HTTPS_PROXY environment variables"));
303
+ console.log(chalk.dim(" 3. Try again in a few minutes (GitHub API might be rate-limited)"));
304
+ console.log(chalk.dim(" 4. Set GITHUB_TOKEN environment variable for higher rate limits"));
305
+ process.exit(1);
306
+ }
265
307
  const parsed = parseSkillMd(content.skillMd);
266
308
  if (!parsed.validation.isValid) {
267
309
  spinner.warn("Skill has validation issues:");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skillhub",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "CLI tool for managing AI Agent skills - search, install, and update skills for Claude, Codex, Copilot, and more",
5
5
  "author": "SkillHub Contributors",
6
6
  "license": "MIT",
@@ -14,7 +14,9 @@
14
14
  "bin": {
15
15
  "skillhub": "./dist/index.js"
16
16
  },
17
- "files": ["dist"],
17
+ "files": [
18
+ "dist"
19
+ ],
18
20
  "scripts": {
19
21
  "build": "tsup src/index.ts --format esm --target node20 --clean",
20
22
  "dev": "tsx src/index.ts",
@@ -45,5 +47,13 @@
45
47
  "engines": {
46
48
  "node": ">=18.0.0"
47
49
  },
48
- "keywords": ["ai", "agent", "skills", "cli", "claude", "codex", "copilot"]
50
+ "keywords": [
51
+ "ai",
52
+ "agent",
53
+ "skills",
54
+ "cli",
55
+ "claude",
56
+ "codex",
57
+ "copilot"
58
+ ]
49
59
  }