findskill 0.1.0 → 0.1.2

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 +51 -15
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -11290,9 +11290,11 @@ function formatSkillRow(skill) {
11290
11290
  const installs = import_picocolors.default.green(`↓ ${skill.installs}`);
11291
11291
  const name = import_picocolors.default.bold(import_picocolors.default.cyan(skill.name));
11292
11292
  const tags = skill.tags.map((t4) => import_picocolors.default.dim(`#${t4}`)).join(" ");
11293
+ const link = import_picocolors.default.dim(import_picocolors.default.underline(skill.github_url));
11293
11294
  return `${name} ${stars} ${installs}
11294
11295
  ${import_picocolors.default.dim(skill.description)}
11295
- ${tags}`;
11296
+ ${tags}
11297
+ ${link}`;
11296
11298
  }
11297
11299
  function formatSkillDetail(skill) {
11298
11300
  const lines = [
@@ -11318,11 +11320,11 @@ function getInstalledSkills(skillsDir) {
11318
11320
  const dir = getSkillsDir(skillsDir);
11319
11321
  if (!existsSync(dir))
11320
11322
  return [];
11321
- return readdirSync(dir).filter((f4) => f4.endsWith(".md")).map((f4) => f4.replace(/\.md$/, ""));
11323
+ return readdirSync(dir, { withFileTypes: true }).filter((f4) => f4.isDirectory() && existsSync(join(dir, f4.name, "SKILL.md"))).map((f4) => f4.name);
11322
11324
  }
11323
11325
  function isSkillInstalled(name, skillsDir) {
11324
11326
  const dir = getSkillsDir(skillsDir);
11325
- return existsSync(join(dir, `${name}.md`));
11327
+ return existsSync(join(dir, name, "SKILL.md"));
11326
11328
  }
11327
11329
 
11328
11330
  // src/commands/search.ts
@@ -11381,27 +11383,61 @@ var infoCommand = new Command("info").description("Show detailed information abo
11381
11383
 
11382
11384
  // src/commands/install.ts
11383
11385
  var import_picocolors4 = __toESM(require_picocolors(), 1);
11384
- import { writeFileSync } from "fs";
11386
+ import { execSync } from "child_process";
11387
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2, cpSync, rmSync } from "fs";
11385
11388
  import { join as join2 } from "path";
11389
+ import { tmpdir } from "os";
11390
+ function parseGitHubUrl(url) {
11391
+ const match = url.match(/github\.com\/([^/]+)\/([^/]+)\/(blob|tree)\/([^/]+)\/(.+)/);
11392
+ if (!match)
11393
+ return null;
11394
+ const [, owner, repo, , branch, path] = match;
11395
+ return {
11396
+ repoUrl: `https://github.com/${owner}/${repo}.git`,
11397
+ branch,
11398
+ path
11399
+ };
11400
+ }
11386
11401
  var installCommand = new Command("install").description("Install a skill to your skills directory").argument("<name>", "Skill name or ID").option("--path <path>", "Custom skills directory").option("-f, --force", "Overwrite if already installed").action(async (name, options) => {
11387
11402
  const skillsDir = getSkillsDir(options.path);
11388
11403
  const spinner = ora("Fetching skill...").start();
11389
11404
  try {
11390
11405
  const skill = await getSkill(name);
11406
+ const destDir = join2(skillsDir, skill.name);
11391
11407
  if (isSkillInstalled(skill.name, options.path) && !options.force) {
11392
11408
  spinner.stop();
11393
11409
  consola.warn(`Skill "${skill.name}" is already installed. Use --force to overwrite.`);
11394
11410
  return;
11395
11411
  }
11396
- spinner.text = "Downloading skill content...";
11397
- const content = await getSkillContent(name);
11398
- const filePath = join2(skillsDir, `${skill.name}.md`);
11399
- writeFileSync(filePath, content);
11400
- spinner.stop();
11401
- console.log("");
11402
- console.log(import_picocolors4.default.green(` ✓ Installed ${import_picocolors4.default.bold(skill.name)}`));
11403
- console.log(import_picocolors4.default.dim(` ${filePath}`));
11404
- console.log("");
11412
+ const parsed = parseGitHubUrl(skill.github_url);
11413
+ if (!parsed) {
11414
+ spinner.stop();
11415
+ consola.error("Invalid GitHub URL format");
11416
+ process.exit(1);
11417
+ }
11418
+ spinner.text = "Cloning skill folder...";
11419
+ const tempDir = join2(tmpdir(), `findskill-${Date.now()}`);
11420
+ mkdirSync2(tempDir, { recursive: true });
11421
+ try {
11422
+ execSync(`git clone --filter=blob:none --sparse --branch ${parsed.branch} --depth 1 ${parsed.repoUrl} .`, { cwd: tempDir, stdio: "pipe" });
11423
+ execSync(`git sparse-checkout set ${parsed.path}`, { cwd: tempDir, stdio: "pipe" });
11424
+ const sourceDir = join2(tempDir, parsed.path);
11425
+ if (!existsSync2(sourceDir)) {
11426
+ throw new Error("Skill folder not found in repository");
11427
+ }
11428
+ if (existsSync2(destDir) && options.force) {
11429
+ rmSync(destDir, { recursive: true });
11430
+ }
11431
+ mkdirSync2(destDir, { recursive: true });
11432
+ cpSync(sourceDir, destDir, { recursive: true });
11433
+ spinner.stop();
11434
+ console.log("");
11435
+ console.log(import_picocolors4.default.green(` ✓ Installed ${import_picocolors4.default.bold(skill.name)}`));
11436
+ console.log(import_picocolors4.default.dim(` ${destDir}`));
11437
+ console.log("");
11438
+ } finally {
11439
+ rmSync(tempDir, { recursive: true, force: true });
11440
+ }
11405
11441
  } catch (error) {
11406
11442
  spinner.stop();
11407
11443
  consola.error("Install failed:", error instanceof Error ? error.message : "Unknown error");
@@ -11433,7 +11469,7 @@ var listCommand = new Command("list").description("List installed skills").optio
11433
11469
 
11434
11470
  // src/commands/update.ts
11435
11471
  var import_picocolors6 = __toESM(require_picocolors(), 1);
11436
- import { writeFileSync as writeFileSync2 } from "fs";
11472
+ import { writeFileSync } from "fs";
11437
11473
  import { join as join3 } from "path";
11438
11474
  var updateCommand = new Command("update").description("Update installed skills to latest versions").argument("[name]", "Specific skill to update (optional)").option("--path <path>", "Custom skills directory").action(async (name, options) => {
11439
11475
  const skillsDir = getSkillsDir(options.path);
@@ -11453,7 +11489,7 @@ var updateCommand = new Command("update").description("Update installed skills t
11453
11489
  const skill = await getSkill(skillName);
11454
11490
  const content = await getSkillContent(skillName);
11455
11491
  const filePath = join3(skillsDir, `${skill.name}.md`);
11456
- writeFileSync2(filePath, content);
11492
+ writeFileSync(filePath, content);
11457
11493
  spinner.succeed(import_picocolors6.default.green(` Updated ${skillName}`));
11458
11494
  updated++;
11459
11495
  } catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "findskill",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "CLI for discovering and installing skill.md format skills",
5
5
  "type": "module",
6
6
  "bin": {