skillhub 0.1.8 → 0.1.10

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 +75 -20
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -176,7 +176,6 @@ async function fetchSkillContent(owner, repo, skillPath, branch = "main") {
176
176
  const client = getOctokit();
177
177
  const skillMdPath = skillPath ? `${skillPath}/SKILL.md` : "SKILL.md";
178
178
  let skillMdResponse;
179
- let lastError;
180
179
  const pathsToTry = [
181
180
  skillMdPath,
182
181
  // Common skill directories
@@ -194,7 +193,6 @@ async function fetchSkillContent(owner, repo, skillPath, branch = "main") {
194
193
  });
195
194
  break;
196
195
  } catch (error) {
197
- lastError = error;
198
196
  if (error.message?.includes("timeout") || error.message?.includes("network")) {
199
197
  try {
200
198
  const rawContent = await fetchRawFile(owner, repo, pathToTry, branch);
@@ -371,6 +369,28 @@ async function install(skillId, options) {
371
369
  }
372
370
  const actualName = parsed.metadata.name || skillName;
373
371
  const installPath = getSkillPath(options.platform, actualName, options.project);
372
+ const metadataPath = path.join(installPath, ".skillhub.json");
373
+ if (await fs.pathExists(metadataPath)) {
374
+ try {
375
+ const existingMetadata = await fs.readJson(metadataPath);
376
+ if (existingMetadata.skillId && existingMetadata.skillId !== skillId) {
377
+ spinner.warn(`Name collision detected!`);
378
+ console.log(chalk.yellow(`
379
+ A different skill is already installed with the name "${actualName}":`));
380
+ console.log(chalk.dim(` Existing: ${existingMetadata.skillId}`));
381
+ console.log(chalk.dim(` New: ${skillId}`));
382
+ console.log();
383
+ if (!options.force) {
384
+ console.log(chalk.red("Installation cancelled to prevent overwriting."));
385
+ console.log(chalk.dim("Use --force to overwrite the existing skill."));
386
+ process.exit(1);
387
+ } else {
388
+ console.log(chalk.yellow("Overwriting existing skill (--force flag used).\n"));
389
+ }
390
+ }
391
+ } catch {
392
+ }
393
+ }
374
394
  if (installed && options.force) {
375
395
  await fs.remove(installPath);
376
396
  }
@@ -509,34 +529,69 @@ var ALL_PLATFORMS = ["claude", "codex", "copilot", "cursor", "windsurf"];
509
529
  async function list(options) {
510
530
  const platforms = options.platform ? [options.platform] : ALL_PLATFORMS;
511
531
  let totalSkills = 0;
512
- for (const platform of platforms) {
513
- const skills = await getInstalledSkills(platform);
514
- if (skills.length === 0) {
515
- continue;
532
+ const checkGlobal = options.all || !options.project;
533
+ const checkProject = options.all || options.project;
534
+ if (checkGlobal) {
535
+ for (const platform of platforms) {
536
+ const skills = await getInstalledSkills(platform, false);
537
+ if (skills.length === 0) {
538
+ continue;
539
+ }
540
+ totalSkills += skills.length;
541
+ const header = options.all ? `${getPlatformName2(platform)} - Global (${skills.length} skills)` : `${getPlatformName2(platform)} (${skills.length} skills)`;
542
+ console.log(chalk3.bold(`
543
+ ${header}:`));
544
+ console.log(chalk3.dim("\u2500".repeat(60)));
545
+ for (const skill of skills) {
546
+ const version = skill.version ? chalk3.dim(`v${skill.version}`) : "";
547
+ console.log(` ${chalk3.cyan(skill.name.padEnd(25))} ${version}`);
548
+ if (skill.description) {
549
+ console.log(` ${chalk3.dim(skill.description.slice(0, 55))}${skill.description.length > 55 ? "..." : ""}`);
550
+ }
551
+ }
516
552
  }
517
- totalSkills += skills.length;
518
- console.log(chalk3.bold(`
519
- ${getPlatformName2(platform)} (${skills.length} skills):`));
520
- console.log(chalk3.dim("\u2500".repeat(60)));
521
- for (const skill of skills) {
522
- const version = skill.version ? chalk3.dim(`v${skill.version}`) : "";
523
- console.log(` ${chalk3.cyan(skill.name.padEnd(25))} ${version}`);
524
- if (skill.description) {
525
- console.log(` ${chalk3.dim(skill.description.slice(0, 55))}${skill.description.length > 55 ? "..." : ""}`);
553
+ }
554
+ if (checkProject) {
555
+ for (const platform of platforms) {
556
+ const skills = await getInstalledSkills(platform, true);
557
+ if (skills.length === 0) {
558
+ continue;
559
+ }
560
+ totalSkills += skills.length;
561
+ const header = options.all ? `${getPlatformName2(platform)} - Project (${skills.length} skills)` : `${getPlatformName2(platform)} (${skills.length} skills)`;
562
+ console.log(chalk3.bold(`
563
+ ${header}:`));
564
+ console.log(chalk3.dim("\u2500".repeat(60)));
565
+ console.log(chalk3.dim(` Path: ${getSkillsPath(platform, true)}`));
566
+ for (const skill of skills) {
567
+ const version = skill.version ? chalk3.dim(`v${skill.version}`) : "";
568
+ console.log(` ${chalk3.cyan(skill.name.padEnd(25))} ${version}`);
569
+ if (skill.description) {
570
+ console.log(` ${chalk3.dim(skill.description.slice(0, 55))}${skill.description.length > 55 ? "..." : ""}`);
571
+ }
526
572
  }
527
573
  }
528
574
  }
529
575
  if (totalSkills === 0) {
530
- console.log(chalk3.yellow("\nNo skills installed."));
531
- console.log(chalk3.dim("Search for skills with: npx skillhub search <query>"));
576
+ if (options.project) {
577
+ console.log(chalk3.yellow("\nNo skills installed in project."));
578
+ console.log(chalk3.dim("Install a skill with: npx skillhub install <skill-id> --project"));
579
+ } else if (options.all) {
580
+ console.log(chalk3.yellow("\nNo skills installed (global or project)."));
581
+ } else {
582
+ console.log(chalk3.yellow("\nNo skills installed globally."));
583
+ console.log(chalk3.dim("Use --project to list project-level skills"));
584
+ console.log(chalk3.dim("Use --all to list both global and project skills"));
585
+ }
586
+ console.log(chalk3.dim("\nSearch for skills with: npx skillhub search <query>"));
532
587
  console.log(chalk3.dim("Install a skill with: npx skillhub install <skill-id>"));
533
588
  } else {
534
589
  console.log(chalk3.dim(`
535
590
  ${totalSkills} total skill(s) installed.`));
536
591
  }
537
592
  }
538
- async function getInstalledSkills(platform) {
539
- const skillsPath = getSkillsPath(platform);
593
+ async function getInstalledSkills(platform, project = false) {
594
+ const skillsPath = getSkillsPath(platform, project);
540
595
  const skills = [];
541
596
  if (!await fs2.pathExists(skillsPath)) {
542
597
  return skills;
@@ -652,7 +707,7 @@ program.command("install <skill-id>").description("Install a skill from the regi
652
707
  program.command("search <query>").description("Search for skills in the registry").option("-p, --platform <platform>", "Filter by platform").option("-l, --limit <number>", "Number of results", "10").action(async (query, options) => {
653
708
  await search(query, options);
654
709
  });
655
- program.command("list").description("List installed skills").option("-p, --platform <platform>", "Filter by platform").action(async (options) => {
710
+ program.command("list").description("List installed skills").option("-p, --platform <platform>", "Filter by platform").option("--project", "List skills in the current project").option("--all", "List both global and project skills").action(async (options) => {
656
711
  await list(options);
657
712
  });
658
713
  program.command("config").description("Manage CLI configuration").option("--set <key=value>", "Set a configuration value").option("--get <key>", "Get a configuration value").option("--list", "List all configuration values").action(async (options) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skillhub",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
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",