skillhub 0.2.5 → 0.2.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 +39 -5
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3516,6 +3516,12 @@ var VALID_PLATFORMS = ["claude", "codex", "copilot", "cursor", "windsurf"];
3516
3516
  var NAME_PATTERN = /^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]$/;
3517
3517
  var MAX_DESCRIPTION_LENGTH = 1024;
3518
3518
  var MAX_NAME_LENGTH = 64;
3519
+ function sanitizeUtf8(input) {
3520
+ let result = input.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F]/g, "");
3521
+ result = Buffer.from(result, "utf8").toString("utf8");
3522
+ result = result.replace(/[\uD800-\uDFFF]/g, "");
3523
+ return result;
3524
+ }
3519
3525
  var INSTRUCTION_FILE_PATTERNS = [
3520
3526
  {
3521
3527
  format: "skill.md",
@@ -3600,8 +3606,8 @@ function parseSkillMd(content) {
3600
3606
  validateTriggers(frontmatter.triggers, warnings);
3601
3607
  }
3602
3608
  const metadata = {
3603
- name: String(frontmatter.name || ""),
3604
- description: String(frontmatter.description || ""),
3609
+ name: sanitizeUtf8(String(frontmatter.name || "")),
3610
+ description: sanitizeUtf8(String(frontmatter.description || "")),
3605
3611
  version: frontmatter.version ? String(frontmatter.version) : void 0,
3606
3612
  license: frontmatter.license ? String(frontmatter.license) : void 0,
3607
3613
  author: frontmatter.author ? String(frontmatter.author) : void 0,
@@ -3784,8 +3790,8 @@ function parseGenericInstructionFile(content, format, repoMeta) {
3784
3790
  const derivedDescription = frontmatter.description || repoMeta.description || extractFirstParagraph(body) || `${FORMAT_LABELS[format]} from ${repoMeta.owner}/${repoMeta.name}`;
3785
3791
  const inferredPlatform = pattern?.inferredPlatform || "claude";
3786
3792
  const metadata = {
3787
- name: derivedName,
3788
- description: derivedDescription.slice(0, MAX_DESCRIPTION_LENGTH),
3793
+ name: sanitizeUtf8(derivedName),
3794
+ description: sanitizeUtf8(derivedDescription.slice(0, MAX_DESCRIPTION_LENGTH)),
3789
3795
  version: frontmatter.version ? String(frontmatter.version) : void 0,
3790
3796
  license: frontmatter.license ? String(frontmatter.license) : void 0,
3791
3797
  author: frontmatter.author ? String(frontmatter.author) : repoMeta.owner,
@@ -3828,6 +3834,21 @@ function extractFirstParagraph(content) {
3828
3834
  }
3829
3835
  return null;
3830
3836
  }
3837
+ var TAG_KEYS = [
3838
+ "RATIONALE",
3839
+ "USE-CASES",
3840
+ "AUDIENCE",
3841
+ "COMPLEMENTS",
3842
+ "SEO-EN",
3843
+ "BUNDLE-FIT",
3844
+ "FRAMEWORK-LOCK",
3845
+ "CONTRIBUTING-REPO",
3846
+ "MATURITY",
3847
+ "COMPLEXITY",
3848
+ "DEPENDENCIES",
3849
+ "PLATFORM"
3850
+ ];
3851
+ var TAG_REGEX = new RegExp(`(${TAG_KEYS.join("|")}):\\s*`, "g");
3831
3852
 
3832
3853
  // src/utils/api.ts
3833
3854
  import https from "https";
@@ -4298,7 +4319,8 @@ async function install(skillId, options2) {
4298
4319
  try {
4299
4320
  skillInfo = await getSkill(skillId);
4300
4321
  if (skillInfo) {
4301
- spinner.succeed(`Found in registry: ${skillInfo.name}`);
4322
+ const reviewBadge = skillInfo.aiScore && skillInfo.reviewStatus === "ai-reviewed" ? chalk.dim(` | AI: ${skillInfo.aiScore}/100`) : skillInfo.reviewStatus === "verified" ? chalk.green(` | AI: ${skillInfo.aiScore}/100 \u2713`) : "";
4323
+ spinner.succeed(`Found in registry: ${skillInfo.name}${reviewBadge}`);
4302
4324
  spinner.start("Preparing installation...");
4303
4325
  }
4304
4326
  } catch (error) {
@@ -4344,6 +4366,12 @@ async function install(skillId, options2) {
4344
4366
  spinner.text = "Downloading skill files...";
4345
4367
  const cachedFiles = await getSkillFiles(skillInfo.id);
4346
4368
  if (cachedFiles && cachedFiles.files.length > 0) {
4369
+ if (cachedFiles.isStale) {
4370
+ spinner.warn(chalk.yellow(
4371
+ "This skill may have been removed from its GitHub repository.\n Files were served from the SkillHub cache and may be outdated."
4372
+ ));
4373
+ spinner.start("Installing from cached files...");
4374
+ }
4347
4375
  if (cachedFiles.sourceFormat) {
4348
4376
  sourceFormat = cachedFiles.sourceFormat;
4349
4377
  }
@@ -4610,6 +4638,12 @@ async function search(query, options2) {
4610
4638
  ` ${chalk2.yellow("\u2605")} ${skill.rating.toFixed(1)} ${chalk2.dim(`(${skill.ratingCount} ratings)`)}`
4611
4639
  );
4612
4640
  }
4641
+ if (skill.aiScore && skill.reviewStatus && skill.reviewStatus !== "unreviewed" && skill.reviewStatus !== "auto-scored") {
4642
+ const scoreColor = skill.aiScore >= 75 ? chalk2.green : skill.aiScore >= 50 ? chalk2.yellow : chalk2.dim;
4643
+ console.log(
4644
+ ` ${chalk2.magenta("AI")} ${scoreColor(String(skill.aiScore))} ${chalk2.dim(`(${skill.reviewStatus})`)}`
4645
+ );
4646
+ }
4613
4647
  console.log(chalk2.dim("\u2500".repeat(80)));
4614
4648
  }
4615
4649
  console.log();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skillhub",
3
- "version": "0.2.5",
3
+ "version": "0.2.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",