@hasnatools/skills 0.1.21 → 0.1.22

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 +208 -14
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -21278,12 +21278,22 @@ async function installAllSkills(options) {
21278
21278
  console.error(colors.error(error instanceof Error ? error.message : "Unknown error"));
21279
21279
  }
21280
21280
  }
21281
- async function uninstallCommand(slug, options = {}) {
21282
- if (!slug || slug.trim() === "") {
21283
- console.log(colors.warning("Please provide a skill name"));
21284
- console.log(colors.dim("Usage: skills uninstall <name>"));
21285
- return;
21281
+ function getInstalledSkills2(installDir) {
21282
+ const { readdirSync, statSync } = __require("fs");
21283
+ if (!existsSync3(installDir)) {
21284
+ return [];
21285
+ }
21286
+ try {
21287
+ const entries = readdirSync(installDir);
21288
+ return entries.filter((entry) => {
21289
+ const fullPath = join3(installDir, entry);
21290
+ return statSync(fullPath).isDirectory() && entry.startsWith("skill-");
21291
+ }).map((entry) => entry.replace(/^skill-/, ""));
21292
+ } catch {
21293
+ return [];
21286
21294
  }
21295
+ }
21296
+ async function uninstallCommand(slug, options = {}) {
21287
21297
  const isLocal = options.local ?? false;
21288
21298
  const target = options.target ?? getDefaultTarget();
21289
21299
  let installDir;
@@ -21297,22 +21307,50 @@ async function uninstallCommand(slug, options = {}) {
21297
21307
  } else {
21298
21308
  installDir = target === "claude" ? getClaudeSkillsDir() : getCodexSkillsDir();
21299
21309
  }
21300
- const skillDir = join3(installDir, `skill-${slug}`);
21310
+ if (options.all) {
21311
+ return uninstallAllSkills(installDir, target, isLocal, options.force);
21312
+ }
21313
+ if (!slug || slug.trim() === "") {
21314
+ console.log(colors.warning("Please provide a skill name"));
21315
+ console.log();
21316
+ console.log(colors.dim("Usage:"));
21317
+ console.log(` ${command("skills uninstall <name>")} ${colors.dim("Uninstall a specific skill")}`);
21318
+ console.log(` ${command("skills uninstall --all")} ${colors.dim("Uninstall all skills")}`);
21319
+ console.log(` ${command("skills uninstall --all -f")} ${colors.dim("Uninstall all without confirmation")}`);
21320
+ return;
21321
+ }
21322
+ const slugs = slug.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
21323
+ if (slugs.length > 1) {
21324
+ return uninstallMultipleSkills(slugs, installDir, target, isLocal, options.force);
21325
+ }
21326
+ const skillSlug = slugs[0];
21327
+ const skillDir = join3(installDir, `skill-${skillSlug}`);
21301
21328
  if (!existsSync3(skillDir)) {
21302
- const oldSkillDir = join3(installDir, slug);
21329
+ const oldSkillDir = join3(installDir, skillSlug);
21303
21330
  if (!existsSync3(oldSkillDir)) {
21304
- console.log(colors.warning(`Skill "${slug}" is not installed`));
21331
+ console.log(colors.warning(`Skill "${skillSlug}" is not installed`));
21332
+ console.log();
21333
+ const installed = getInstalledSkills2(installDir);
21334
+ if (installed.length > 0) {
21335
+ console.log(colors.dim("Installed skills:"));
21336
+ installed.slice(0, 10).forEach((s) => {
21337
+ console.log(` ${colors.dim(symbols.bullet)} ${skillName(s)}`);
21338
+ });
21339
+ if (installed.length > 10) {
21340
+ console.log(colors.dim(` ... and ${installed.length - 10} more`));
21341
+ }
21342
+ }
21305
21343
  return;
21306
21344
  }
21307
21345
  }
21308
21346
  const spinner = ora({
21309
- text: `Uninstalling "${slug}"...`,
21347
+ text: `Uninstalling "${skillSlug}"...`,
21310
21348
  color: "magenta"
21311
21349
  }).start();
21312
21350
  try {
21313
21351
  const { rmSync: rmSync2 } = await import("fs");
21314
21352
  rmSync2(skillDir, { recursive: true, force: true });
21315
- spinner.succeed(colors.success(`Uninstalled ${skillName(slug)}`));
21353
+ spinner.succeed(colors.success(`Uninstalled ${skillName(skillSlug)}`));
21316
21354
  console.log();
21317
21355
  console.log(successItem(`Removed from ${path6(skillDir)}`));
21318
21356
  } catch (error) {
@@ -21320,6 +21358,160 @@ async function uninstallCommand(slug, options = {}) {
21320
21358
  console.error(colors.error(error instanceof Error ? error.message : "Unknown error"));
21321
21359
  }
21322
21360
  }
21361
+ async function uninstallMultipleSkills(slugs, installDir, target, isLocal, force) {
21362
+ const total = slugs.length;
21363
+ banner("Uninstalling Skills");
21364
+ console.log(keyValue("Target", colors.primaryBold(target)));
21365
+ console.log(keyValue("Scope", colors.primaryBold(isLocal ? "project" : "global")));
21366
+ console.log(keyValue("Skills", count(total)));
21367
+ console.log();
21368
+ console.log(colors.dim("Skills to uninstall:"));
21369
+ slugs.forEach((s) => {
21370
+ const skillDir = join3(installDir, `skill-${s}`);
21371
+ const exists = existsSync3(skillDir);
21372
+ if (exists) {
21373
+ console.log(` ${colors.warning(symbols.bullet)} ${skillName(s)}`);
21374
+ } else {
21375
+ console.log(` ${colors.dim(symbols.bullet)} ${s} ${colors.dim("(not installed)")}`);
21376
+ }
21377
+ });
21378
+ console.log();
21379
+ if (!force) {
21380
+ const prompts2 = (await Promise.resolve().then(() => __toESM(require_prompts3(), 1))).default;
21381
+ const response = await prompts2({
21382
+ type: "confirm",
21383
+ name: "confirm",
21384
+ message: `Uninstall ${slugs.length} skill(s)?`,
21385
+ initial: false
21386
+ });
21387
+ if (!response.confirm) {
21388
+ console.log(colors.dim("Cancelled"));
21389
+ return;
21390
+ }
21391
+ console.log();
21392
+ }
21393
+ const results = {
21394
+ success: [],
21395
+ failed: [],
21396
+ notFound: []
21397
+ };
21398
+ for (let i = 0;i < slugs.length; i++) {
21399
+ const slug = slugs[i];
21400
+ const current = i + 1;
21401
+ const percent = Math.round(current / total * 100);
21402
+ const padWidth = String(total).length;
21403
+ const progress = `[${String(current).padStart(padWidth, " ")}/${total}]`;
21404
+ process.stdout.write(`\r${colors.dim(progress)} ${progressBar(percent)} ${colors.dim(`${percent}%`)} Removing ${colors.primary(slug)}...`);
21405
+ process.stdout.write("\x1B[K");
21406
+ const skillDir = join3(installDir, `skill-${slug}`);
21407
+ if (!existsSync3(skillDir)) {
21408
+ results.notFound.push(slug);
21409
+ continue;
21410
+ }
21411
+ try {
21412
+ const { rmSync: rmSync2 } = await import("fs");
21413
+ rmSync2(skillDir, { recursive: true, force: true });
21414
+ results.success.push(slug);
21415
+ } catch (error) {
21416
+ results.failed.push({
21417
+ slug,
21418
+ error: error instanceof Error ? error.message : "Unknown error"
21419
+ });
21420
+ }
21421
+ }
21422
+ process.stdout.write("\r\x1B[K");
21423
+ completionBanner("Uninstall Complete");
21424
+ if (results.success.length > 0) {
21425
+ console.log(successItem(`Uninstalled: ${colors.successBold(String(results.success.length))} skills`));
21426
+ }
21427
+ if (results.notFound.length > 0) {
21428
+ console.log(colors.dim(`${symbols.info} Not found: ${results.notFound.length} skills`));
21429
+ }
21430
+ if (results.failed.length > 0) {
21431
+ console.log(errorItem(`Failed: ${colors.errorBold(String(results.failed.length))} skills`));
21432
+ }
21433
+ }
21434
+ async function uninstallAllSkills(installDir, target, isLocal, force) {
21435
+ const installed = getInstalledSkills2(installDir);
21436
+ if (installed.length === 0) {
21437
+ console.log(colors.dim("No skills installed"));
21438
+ return;
21439
+ }
21440
+ banner("Uninstall All Skills");
21441
+ console.log(keyValue("Target", colors.primaryBold(target)));
21442
+ console.log(keyValue("Scope", colors.primaryBold(isLocal ? "project" : "global")));
21443
+ console.log(keyValue("Directory", path6(installDir)));
21444
+ console.log(keyValue("Skills found", count(installed.length)));
21445
+ console.log();
21446
+ console.log(colors.warning("The following skills will be removed:"));
21447
+ console.log();
21448
+ const displayCount = Math.min(installed.length, 15);
21449
+ for (let i = 0;i < displayCount; i++) {
21450
+ console.log(` ${colors.warning(symbols.bullet)} ${skillName(installed[i])}`);
21451
+ }
21452
+ if (installed.length > displayCount) {
21453
+ console.log(colors.dim(` ... and ${installed.length - displayCount} more`));
21454
+ }
21455
+ console.log();
21456
+ if (!force) {
21457
+ const prompts2 = (await Promise.resolve().then(() => __toESM(require_prompts3(), 1))).default;
21458
+ const response = await prompts2({
21459
+ type: "confirm",
21460
+ name: "confirm",
21461
+ message: `Uninstall all ${installed.length} skill(s)?`,
21462
+ initial: false
21463
+ });
21464
+ if (!response.confirm) {
21465
+ console.log(colors.dim("Cancelled"));
21466
+ return;
21467
+ }
21468
+ console.log();
21469
+ }
21470
+ const total = installed.length;
21471
+ const results = {
21472
+ success: [],
21473
+ failed: []
21474
+ };
21475
+ for (let i = 0;i < installed.length; i++) {
21476
+ const slug = installed[i];
21477
+ const current = i + 1;
21478
+ const percent = Math.round(current / total * 100);
21479
+ const padWidth = String(total).length;
21480
+ const progress = `[${String(current).padStart(padWidth, " ")}/${total}]`;
21481
+ process.stdout.write(`\r${colors.dim(progress)} ${progressBar(percent)} ${colors.dim(`${percent}%`)} Removing ${colors.primary(slug)}...`);
21482
+ process.stdout.write("\x1B[K");
21483
+ const skillDir = join3(installDir, `skill-${slug}`);
21484
+ try {
21485
+ const { rmSync: rmSync2 } = await import("fs");
21486
+ rmSync2(skillDir, { recursive: true, force: true });
21487
+ results.success.push(slug);
21488
+ } catch (error) {
21489
+ results.failed.push({
21490
+ slug,
21491
+ error: error instanceof Error ? error.message : "Unknown error"
21492
+ });
21493
+ }
21494
+ }
21495
+ process.stdout.write("\r\x1B[K");
21496
+ completionBanner("Uninstall Complete");
21497
+ if (results.success.length > 0) {
21498
+ console.log(successItem(`Uninstalled: ${colors.successBold(String(results.success.length))} skills`));
21499
+ }
21500
+ if (results.failed.length > 0) {
21501
+ console.log(errorItem(`Failed: ${colors.errorBold(String(results.failed.length))} skills`));
21502
+ console.log();
21503
+ console.log(colors.dim("Failed skills:"));
21504
+ for (const fail of results.failed.slice(0, 5)) {
21505
+ console.log(colors.error(` ${symbols.bullet} ${fail.slug}: ${fail.error}`));
21506
+ }
21507
+ if (results.failed.length > 5) {
21508
+ console.log(colors.dim(` ... and ${results.failed.length - 5} more`));
21509
+ }
21510
+ }
21511
+ console.log();
21512
+ console.log(colors.dim("Reinstall skills with:"));
21513
+ console.log(` ${command("skills install --all")}`);
21514
+ }
21323
21515
 
21324
21516
  // src/commands/download.ts
21325
21517
  import { existsSync as existsSync4, mkdirSync as mkdirSync3, writeFileSync as writeFileSync4 } from "fs";
@@ -23137,7 +23329,7 @@ async function doctorCommand() {
23137
23329
  // src/index.ts
23138
23330
  var indigo12 = colors.primary;
23139
23331
  var program2 = new Command;
23140
- program2.name("skills").description("CLI for skills.md - AI Agent Skills Marketplace").version("0.1.21");
23332
+ program2.name("skills").description("CLI for skills.md - AI Agent Skills Marketplace").version("0.1.22");
23141
23333
  program2.command("init").description("Initialize skills.md in current project").option("-f, --force", "Force re-initialization (removes existing .skills/)").action((options) => {
23142
23334
  initCommand({ force: options.force });
23143
23335
  });
@@ -23161,10 +23353,12 @@ program2.command("install [name]").alias("i").description("Install a skill or al
23161
23353
  all: options.all
23162
23354
  });
23163
23355
  });
23164
- program2.command("uninstall <name>").alias("remove").description("Uninstall a skill (global by default)").option("-l, --local", "Uninstall from current project instead of global").option("-t, --target <target>", "Target platform (claude, codex)").action((name, options) => {
23165
- uninstallCommand(name, {
23356
+ program2.command("uninstall [name]").alias("remove").description("Uninstall skill(s) - single, comma-separated, or all").option("-l, --local", "Uninstall from current project instead of global").option("-t, --target <target>", "Target platform (claude, codex)").option("-a, --all", "Uninstall all installed skills").option("-f, --force", "Skip confirmation prompt").action((name, options) => {
23357
+ uninstallCommand(name || "", {
23166
23358
  local: options.local,
23167
- target: options.target
23359
+ target: options.target,
23360
+ all: options.all,
23361
+ force: options.force
23168
23362
  });
23169
23363
  });
23170
23364
  program2.command("download <name>").alias("dl").description("Download a skill with full source code (if available)").option("-l, --local", "Download to current project instead of global").option("-t, --target <target>", "Target platform (claude, codex)").action((name, options) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasnatools/skills",
3
- "version": "0.1.21",
3
+ "version": "0.1.22",
4
4
  "description": "CLI for skills.md - AI Agent Skills Marketplace",
5
5
  "type": "module",
6
6
  "bin": {