@hasnatools/skills 0.1.10 → 0.1.12

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 +272 -43
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -20747,6 +20747,21 @@ async function installSkillRemote(slug) {
20747
20747
  body: JSON.stringify({ skillSlug: slug })
20748
20748
  });
20749
20749
  }
20750
+ async function getCLI2FASettings() {
20751
+ return apiRequest("/me/settings/cli-2fa");
20752
+ }
20753
+ async function setCLI2FASettings(enabled) {
20754
+ return apiRequest("/me/settings/cli-2fa", {
20755
+ method: "PUT",
20756
+ body: JSON.stringify({ enabled })
20757
+ });
20758
+ }
20759
+ async function purchaseCredits(amountCents, totpCode) {
20760
+ return apiRequest("/cli/credits/purchase", {
20761
+ method: "POST",
20762
+ body: JSON.stringify({ amountCents, totpCode })
20763
+ });
20764
+ }
20750
20765
  async function makeApiRequest(path6, options = {}) {
20751
20766
  const apiKey = getApiKey();
20752
20767
  const endpoint = getApiEndpoint();
@@ -21368,6 +21383,7 @@ function parseFrontmatter(content) {
21368
21383
  }
21369
21384
 
21370
21385
  // src/commands/config.ts
21386
+ var indigo3 = source_default.hex("#6366f1");
21371
21387
  async function configCommand(options) {
21372
21388
  if (!options.get && !options.set) {
21373
21389
  const config = getConfig();
@@ -21464,6 +21480,90 @@ function getNestedValue(obj, path6) {
21464
21480
  }
21465
21481
  return current;
21466
21482
  }
21483
+ async function cli2faCommand(action) {
21484
+ const apiKey = getApiKey();
21485
+ if (!apiKey) {
21486
+ console.log(source_default.yellow("Not logged in"));
21487
+ console.log(source_default.dim("Run `skills login` to authenticate"));
21488
+ return;
21489
+ }
21490
+ const normalizedAction = action?.toLowerCase();
21491
+ if (normalizedAction && normalizedAction !== "on" && normalizedAction !== "off") {
21492
+ console.log(source_default.red("Invalid action. Use 'on' or 'off'."));
21493
+ console.log();
21494
+ console.log("Usage:");
21495
+ console.log(" skills config cli-2fa " + source_default.dim("Show current setting"));
21496
+ console.log(" skills config cli-2fa on " + source_default.dim("Enable 2FA for CLI purchases"));
21497
+ console.log(" skills config cli-2fa off " + source_default.dim("Disable 2FA for CLI purchases"));
21498
+ return;
21499
+ }
21500
+ const spinner = ora("Fetching 2FA settings...").start();
21501
+ const result = await getCLI2FASettings();
21502
+ if (result.error || !result.data) {
21503
+ spinner.fail("Failed to fetch 2FA settings");
21504
+ console.error(source_default.red(result.error || "Unknown error"));
21505
+ return;
21506
+ }
21507
+ const { enabled, has2FASetup } = result.data;
21508
+ if (!normalizedAction) {
21509
+ spinner.stop();
21510
+ console.log();
21511
+ console.log(indigo3.bold("CLI 2FA Settings"));
21512
+ console.log();
21513
+ console.log(" 2FA for CLI purchases: " + (enabled ? source_default.green("enabled") : source_default.dim("disabled")));
21514
+ console.log(" Account 2FA setup: " + (has2FASetup ? source_default.green("yes") : source_default.dim("no")));
21515
+ console.log();
21516
+ if (!has2FASetup) {
21517
+ console.log(source_default.yellow("⚠") + " You must set up 2FA on your account before enabling this feature.");
21518
+ console.log(" Visit: " + indigo3("https://skills.md/dashboard/settings"));
21519
+ } else if (!enabled) {
21520
+ console.log(source_default.dim("Enable 2FA for CLI purchases: skills config cli-2fa on"));
21521
+ }
21522
+ console.log();
21523
+ return;
21524
+ }
21525
+ if (normalizedAction === "on") {
21526
+ if (!has2FASetup) {
21527
+ spinner.fail("Cannot enable - 2FA not set up on your account");
21528
+ console.log();
21529
+ console.log("You must set up 2FA on your account first.");
21530
+ console.log("Visit: " + indigo3("https://skills.md/dashboard/settings"));
21531
+ return;
21532
+ }
21533
+ if (enabled) {
21534
+ spinner.info("2FA for CLI purchases is already enabled");
21535
+ return;
21536
+ }
21537
+ spinner.text = "Enabling 2FA for CLI purchases...";
21538
+ const updateResult = await setCLI2FASettings(true);
21539
+ if (updateResult.error) {
21540
+ spinner.fail("Failed to enable 2FA");
21541
+ console.error(source_default.red(updateResult.error));
21542
+ return;
21543
+ }
21544
+ spinner.succeed("2FA enabled for CLI purchases");
21545
+ console.log();
21546
+ console.log(source_default.dim("You will now be prompted for a 2FA code when purchasing credits via CLI."));
21547
+ return;
21548
+ }
21549
+ if (normalizedAction === "off") {
21550
+ if (!enabled) {
21551
+ spinner.info("2FA for CLI purchases is already disabled");
21552
+ return;
21553
+ }
21554
+ spinner.text = "Disabling 2FA for CLI purchases...";
21555
+ const updateResult = await setCLI2FASettings(false);
21556
+ if (updateResult.error) {
21557
+ spinner.fail("Failed to disable 2FA");
21558
+ console.error(source_default.red(updateResult.error));
21559
+ return;
21560
+ }
21561
+ spinner.succeed("2FA disabled for CLI purchases");
21562
+ console.log();
21563
+ console.log(source_default.yellow("⚠") + " CLI credit purchases will no longer require 2FA verification.");
21564
+ return;
21565
+ }
21566
+ }
21467
21567
 
21468
21568
  // src/commands/run.ts
21469
21569
  import { existsSync as existsSync6, readFileSync as readFileSync3, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, appendFileSync } from "fs";
@@ -21915,7 +22015,7 @@ function formatStatus(status) {
21915
22015
  // src/commands/history.ts
21916
22016
  import { existsSync as existsSync8, readFileSync as readFileSync4, readdirSync as readdirSync2, statSync } from "fs";
21917
22017
  import { join as join8 } from "path";
21918
- var indigo3 = source_default.hex("#6366f1");
22018
+ var indigo4 = source_default.hex("#6366f1");
21919
22019
  async function historyCommand(options = {}) {
21920
22020
  if (options.local) {
21921
22021
  return localHistoryCommand(options);
@@ -21948,7 +22048,7 @@ async function historyCommand(options = {}) {
21948
22048
  spinner.stop();
21949
22049
  const { executions, pagination, counts } = result;
21950
22050
  console.log();
21951
- console.log(indigo3.bold("Execution History"));
22051
+ console.log(indigo4.bold("Execution History"));
21952
22052
  console.log(source_default.dim(`Total: ${counts.all} | Completed: ${counts.completed} | Failed: ${counts.failed} | Pending: ${counts.pending}`));
21953
22053
  console.log();
21954
22054
  if (executions.length === 0) {
@@ -21967,7 +22067,7 @@ async function historyCommand(options = {}) {
21967
22067
  console.log(` ${source_default.dim("Status:")} ${formatStatus2(exec.status)}`);
21968
22068
  console.log(` ${source_default.dim("Duration:")} ${durationStr}`);
21969
22069
  if (exec.creditsUsed > 0) {
21970
- console.log(` ${source_default.dim("Credits:")} ${indigo3(String(exec.creditsUsed))}`);
22070
+ console.log(` ${source_default.dim("Credits:")} ${indigo4(String(exec.creditsUsed))}`);
21971
22071
  }
21972
22072
  if (exec.outputType) {
21973
22073
  console.log(` ${source_default.dim("Output:")} ${exec.outputType}`);
@@ -22052,7 +22152,7 @@ async function localHistoryCommand(options) {
22052
22152
  return;
22053
22153
  }
22054
22154
  console.log();
22055
- console.log(indigo3.bold("Local Execution History"));
22155
+ console.log(indigo4.bold("Local Execution History"));
22056
22156
  console.log(source_default.dim(`Showing ${entries.length} most recent execution(s)`));
22057
22157
  console.log();
22058
22158
  for (const entry of entries) {
@@ -22103,7 +22203,7 @@ async function exportsCommand(slug, options = {}) {
22103
22203
  return;
22104
22204
  }
22105
22205
  console.log();
22106
- console.log(indigo3.bold(`Exports for ${slug}`));
22206
+ console.log(indigo4.bold(`Exports for ${slug}`));
22107
22207
  console.log(source_default.dim(`Directory: ${exportsDir}`));
22108
22208
  console.log();
22109
22209
  const fileInfos = files.map((file) => {
@@ -22146,7 +22246,7 @@ async function logsCommand(slug, options = {}) {
22146
22246
  const latestLog = files[0];
22147
22247
  const logPath = join8(logsDir, latestLog);
22148
22248
  console.log();
22149
- console.log(indigo3.bold(`Latest Log for ${slug}`));
22249
+ console.log(indigo4.bold(`Latest Log for ${slug}`));
22150
22250
  console.log(source_default.dim(`File: ${logPath}`));
22151
22251
  console.log(source_default.dim("─".repeat(60)));
22152
22252
  console.log();
@@ -22186,7 +22286,7 @@ function formatBytes(bytes) {
22186
22286
  }
22187
22287
 
22188
22288
  // src/commands/marketplace.ts
22189
- var indigo4 = source_default.hex("#6366f1");
22289
+ var indigo5 = source_default.hex("#6366f1");
22190
22290
  async function marketplaceCommand(options = {}) {
22191
22291
  const spinner = ora("Fetching skills from marketplace...").start();
22192
22292
  const limit = options.limit || 20;
@@ -22209,36 +22309,36 @@ async function marketplaceCommand(options = {}) {
22209
22309
  return;
22210
22310
  }
22211
22311
  console.log();
22212
- console.log(indigo4.bold(`Skills Marketplace`) + source_default.dim(` (page ${page}/${totalPages}, ${total} total skills)`));
22312
+ console.log(indigo5.bold(`Skills Marketplace`) + source_default.dim(` (page ${page}/${totalPages}, ${total} total skills)`));
22213
22313
  console.log();
22214
22314
  for (const skill of skills) {
22215
- const verified = skill.isVerified ? indigo4(" ✓") : "";
22315
+ const verified = skill.isVerified ? indigo5(" ✓") : "";
22216
22316
  const downloads = skill.downloadCount > 0 ? source_default.dim(` (${skill.downloadCount} installs)`) : "";
22217
22317
  console.log(" " + source_default.bold(skill.name) + verified + source_default.dim(` v${skill.version}`) + downloads);
22218
22318
  console.log(" " + source_default.dim(skill.description || "No description"));
22219
- console.log(" " + indigo4(`skills install ${skill.slug}`));
22319
+ console.log(" " + indigo5(`skills install ${skill.slug}`));
22220
22320
  console.log();
22221
22321
  }
22222
22322
  console.log(source_default.dim("─".repeat(50)));
22223
22323
  if (totalPages > 1) {
22224
22324
  const navHints = [];
22225
22325
  if (page > 1) {
22226
- navHints.push(`${indigo4(`skills marketplace -p ${page - 1}`)} for previous`);
22326
+ navHints.push(`${indigo5(`skills marketplace -p ${page - 1}`)} for previous`);
22227
22327
  }
22228
22328
  if (page < totalPages) {
22229
- navHints.push(`${indigo4(`skills marketplace -p ${page + 1}`)} for next`);
22329
+ navHints.push(`${indigo5(`skills marketplace -p ${page + 1}`)} for next`);
22230
22330
  }
22231
22331
  if (navHints.length > 0) {
22232
22332
  console.log(source_default.dim(navHints.join(" | ")));
22233
22333
  }
22234
22334
  }
22235
- console.log(source_default.dim(`Run ${indigo4("skills install <name>")} to install a skill`));
22236
- console.log(source_default.dim(`Run ${indigo4("skills search <query>")} to search for specific skills`));
22335
+ console.log(source_default.dim(`Run ${indigo5("skills install <name>")} to install a skill`));
22336
+ console.log(source_default.dim(`Run ${indigo5("skills search <query>")} to search for specific skills`));
22237
22337
  }
22238
22338
 
22239
22339
  // src/commands/feedback.ts
22240
22340
  var import_prompts2 = __toESM(require_prompts3(), 1);
22241
- var indigo5 = source_default.hex("#6366f1");
22341
+ var indigo6 = source_default.hex("#6366f1");
22242
22342
  var indigoBold = source_default.hex("#6366f1").bold;
22243
22343
  async function submitFeedback(type, title, description) {
22244
22344
  const spinner = ora("Submitting feedback...").start();
@@ -22260,7 +22360,7 @@ async function submitFeedback(type, title, description) {
22260
22360
  }
22261
22361
  spinner.succeed("Feedback submitted!");
22262
22362
  console.log();
22263
- console.log(indigo5(" Thank you for your feedback! \uD83D\uDE4F"));
22363
+ console.log(indigo6(" Thank you for your feedback! \uD83D\uDE4F"));
22264
22364
  console.log(source_default.dim(" We'll review it and get back to you if needed."));
22265
22365
  return true;
22266
22366
  } catch (error) {
@@ -22276,7 +22376,7 @@ async function feedbackCommand(options = {}) {
22276
22376
  const apiKey = getApiKey();
22277
22377
  if (!apiKey) {
22278
22378
  console.log(source_default.yellow("⚠") + " You need to be logged in to submit feedback.");
22279
- console.log(source_default.dim(" Run ") + indigo5("skills login") + source_default.dim(" first."));
22379
+ console.log(source_default.dim(" Run ") + indigo6("skills login") + source_default.dim(" first."));
22280
22380
  console.log();
22281
22381
  return;
22282
22382
  }
@@ -22329,7 +22429,7 @@ Feedback cancelled.`));
22329
22429
  }
22330
22430
 
22331
22431
  // src/commands/info.ts
22332
- var indigo6 = source_default.hex("#6366f1");
22432
+ var indigo7 = source_default.hex("#6366f1");
22333
22433
  async function infoCommand(name) {
22334
22434
  const spinner = ora("Fetching skill info...").start();
22335
22435
  const result = await getSkill(name);
@@ -22341,7 +22441,7 @@ async function infoCommand(name) {
22341
22441
  spinner.stop();
22342
22442
  const skill = result.data;
22343
22443
  console.log();
22344
- console.log(indigo6.bold(skill.name) + (skill.isVerified ? indigo6(" ✓") : ""));
22444
+ console.log(indigo7.bold(skill.name) + (skill.isVerified ? indigo7(" ✓") : ""));
22345
22445
  console.log(source_default.dim(`v${skill.version}`));
22346
22446
  console.log();
22347
22447
  if (skill.description) {
@@ -22358,7 +22458,7 @@ async function infoCommand(name) {
22358
22458
  ["Downloads", skill.downloadCount.toLocaleString()],
22359
22459
  ["Verified", skill.isVerified ? source_default.green("Yes") : "No"],
22360
22460
  ["Remote Execution", skill.isRemoteExecution ? source_default.green("Yes") : "No"],
22361
- ["Credits/Run", (skill.creditsPerExecution ?? 0) > 0 ? indigo6(String(skill.creditsPerExecution)) : source_default.green("Free")]
22461
+ ["Credits/Run", (skill.creditsPerExecution ?? 0) > 0 ? indigo7(String(skill.creditsPerExecution)) : source_default.green("Free")]
22362
22462
  ];
22363
22463
  for (const [label, value] of details) {
22364
22464
  console.log(` ${source_default.dim(label.padEnd(18))} ${value}`);
@@ -22370,15 +22470,19 @@ async function infoCommand(name) {
22370
22470
  console.log();
22371
22471
  console.log(source_default.dim("─".repeat(50)));
22372
22472
  console.log();
22373
- console.log(` ${source_default.dim("Install:")} ${indigo6(`skills install ${skill.slug}`)}`);
22473
+ console.log(` ${source_default.dim("Install:")} ${indigo7(`skills install ${skill.slug}`)}`);
22374
22474
  if (skill.isRemoteExecution) {
22375
- console.log(` ${source_default.dim("Run:")} ${indigo6(`skills run ${skill.slug}`)}`);
22475
+ console.log(` ${source_default.dim("Run:")} ${indigo7(`skills run ${skill.slug}`)}`);
22376
22476
  }
22377
22477
  console.log();
22378
22478
  }
22379
22479
 
22380
22480
  // src/commands/credits.ts
22381
- var indigo7 = source_default.hex("#6366f1");
22481
+ var import_prompts3 = __toESM(require_prompts3(), 1);
22482
+ var indigo8 = source_default.hex("#6366f1");
22483
+ var MIN_PURCHASE_DOLLARS = 5;
22484
+ var MAX_PURCHASE_DOLLARS = 500;
22485
+ var CENTS_PER_CREDIT = 10;
22382
22486
  async function creditsCommand() {
22383
22487
  const apiKey = getApiKey();
22384
22488
  if (!apiKey) {
@@ -22396,23 +22500,138 @@ async function creditsCommand() {
22396
22500
  spinner.stop();
22397
22501
  const { creditsBalance, plan, tenantName } = result.data;
22398
22502
  console.log();
22399
- console.log(indigo7.bold("Credits Balance"));
22503
+ console.log(indigo8.bold("Credits Balance"));
22400
22504
  console.log();
22401
- console.log(" " + indigo7.bold(creditsBalance.toLocaleString()) + " credits");
22505
+ console.log(" " + indigo8.bold(creditsBalance.toLocaleString()) + " credits");
22402
22506
  console.log();
22403
22507
  console.log(source_default.dim("─".repeat(30)));
22404
22508
  console.log();
22405
22509
  console.log(" Plan: " + source_default.bold(plan));
22406
22510
  console.log(" Org: " + (tenantName || source_default.dim("Personal")));
22407
22511
  console.log();
22408
- console.log(source_default.dim("Purchase more at https://skills.md/billing"));
22512
+ console.log(source_default.dim("Purchase more at https://skills.md/billing or run `skills credits buy <amount>`"));
22513
+ console.log();
22514
+ }
22515
+ async function buyCreditsCommand(amount) {
22516
+ const apiKey = getApiKey();
22517
+ if (!apiKey) {
22518
+ console.log(source_default.yellow("Not logged in"));
22519
+ console.log(source_default.dim("Run `skills login` to authenticate"));
22520
+ return;
22521
+ }
22522
+ const dollars = parseFloat(amount);
22523
+ if (isNaN(dollars)) {
22524
+ console.log(source_default.red("Invalid amount. Please enter a number (e.g., 10, 25.50)"));
22525
+ return;
22526
+ }
22527
+ if (dollars < MIN_PURCHASE_DOLLARS) {
22528
+ console.log(source_default.red(`Minimum purchase is $${MIN_PURCHASE_DOLLARS.toFixed(2)}`));
22529
+ return;
22530
+ }
22531
+ if (dollars > MAX_PURCHASE_DOLLARS) {
22532
+ console.log(source_default.red(`Maximum purchase is $${MAX_PURCHASE_DOLLARS.toFixed(2)}`));
22533
+ return;
22534
+ }
22535
+ const amountCents = Math.round(dollars * 100);
22536
+ const credits = Math.floor(amountCents / CENTS_PER_CREDIT);
22537
+ console.log();
22538
+ console.log(indigo8.bold("Purchase Credits"));
22539
+ console.log();
22540
+ console.log(" Amount: " + source_default.bold(`$${(amountCents / 100).toFixed(2)}`));
22541
+ console.log(" Credits: " + source_default.bold(credits.toLocaleString()));
22542
+ console.log();
22543
+ const spinner = ora("Checking purchase requirements...").start();
22544
+ const settingsResult = await getCLI2FASettings();
22545
+ if (settingsResult.error) {
22546
+ spinner.fail("Failed to check settings");
22547
+ console.error(source_default.red(settingsResult.error));
22548
+ return;
22549
+ }
22550
+ spinner.stop();
22551
+ let totpCode;
22552
+ if (settingsResult.data?.enabled) {
22553
+ console.log(source_default.yellow("2FA verification required for CLI purchases."));
22554
+ console.log();
22555
+ const response = await import_prompts3.default({
22556
+ type: "text",
22557
+ name: "code",
22558
+ message: "Enter 2FA code:",
22559
+ validate: (value) => {
22560
+ const normalized = value.replace(/[\s-]/g, "");
22561
+ if (/^\d{6}$/.test(normalized) || /^[A-Fa-f0-9]{8}$/.test(normalized)) {
22562
+ return true;
22563
+ }
22564
+ return "Enter a 6-digit authenticator code or 8-character backup code";
22565
+ }
22566
+ });
22567
+ if (!response.code) {
22568
+ console.log(source_default.yellow("Purchase cancelled."));
22569
+ return;
22570
+ }
22571
+ totpCode = response.code.replace(/[\s-]/g, "");
22572
+ }
22573
+ const confirmResponse = await import_prompts3.default({
22574
+ type: "confirm",
22575
+ name: "confirmed",
22576
+ message: `Purchase ${credits.toLocaleString()} credits for $${(amountCents / 100).toFixed(2)}?`,
22577
+ initial: true
22578
+ });
22579
+ if (!confirmResponse.confirmed) {
22580
+ console.log(source_default.yellow("Purchase cancelled."));
22581
+ return;
22582
+ }
22583
+ const purchaseSpinner = ora("Processing purchase...").start();
22584
+ const result = await purchaseCredits(amountCents, totpCode);
22585
+ if (result.error || !result.data) {
22586
+ purchaseSpinner.fail("Purchase failed");
22587
+ console.log();
22588
+ const errorData = result;
22589
+ const errorCode = errorData.data?.code;
22590
+ switch (errorCode) {
22591
+ case "2FA_REQUIRED":
22592
+ console.log(source_default.red("2FA verification is required for CLI purchases."));
22593
+ console.log(source_default.dim("Enable 2FA in your account settings first."));
22594
+ break;
22595
+ case "INVALID_2FA":
22596
+ console.log(source_default.red("Invalid 2FA code. Please try again."));
22597
+ break;
22598
+ case "NO_PAYMENT_METHOD":
22599
+ console.log(source_default.red("No payment method on file."));
22600
+ console.log(source_default.dim("Add a card at: " + indigo8("https://skills.md/dashboard/billing")));
22601
+ break;
22602
+ case "CARD_DECLINED":
22603
+ console.log(source_default.red("Card was declined. Please check your card or try a different payment method."));
22604
+ break;
22605
+ case "INSUFFICIENT_FUNDS":
22606
+ console.log(source_default.red("Insufficient funds. Please try a different payment method."));
22607
+ break;
22608
+ case "EXPIRED_CARD":
22609
+ console.log(source_default.red("Card has expired. Please update your payment method."));
22610
+ break;
22611
+ case "REQUIRES_ACTION":
22612
+ console.log(source_default.red("Payment requires additional verification."));
22613
+ console.log(source_default.dim("Please complete the purchase via the web dashboard."));
22614
+ break;
22615
+ case "SPENDING_LIMIT_EXCEEDED":
22616
+ console.log(source_default.red("Monthly spending limit would be exceeded."));
22617
+ break;
22618
+ default:
22619
+ console.log(source_default.red(result.error || "Unknown error"));
22620
+ }
22621
+ return;
22622
+ }
22623
+ purchaseSpinner.succeed("Purchase successful!");
22624
+ console.log();
22625
+ console.log(source_default.green("✓") + " Credits added: " + source_default.bold(result.data.creditsAdded.toLocaleString()));
22626
+ console.log(source_default.green("✓") + " New balance: " + source_default.bold(result.data.newBalance.toLocaleString()) + " credits");
22627
+ console.log(source_default.dim(" Transaction: " + result.data.transactionId));
22409
22628
  console.log();
22410
22629
  }
22411
22630
 
22412
22631
  // src/commands/update.ts
22413
22632
  import { existsSync as existsSync9, readdirSync as readdirSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync6 } from "fs";
22414
22633
  import { join as join9 } from "path";
22415
- var indigo8 = source_default.hex("#6366f1");
22634
+ var indigo9 = source_default.hex("#6366f1");
22416
22635
  function parseFrontmatter2(content) {
22417
22636
  const result = {};
22418
22637
  const match = content.match(/^---\n([\s\S]*?)\n---/);
@@ -22472,7 +22691,7 @@ async function updateCommand(skillName, options = {}) {
22472
22691
  return;
22473
22692
  }
22474
22693
  console.log();
22475
- console.log(indigo8.bold("Updating Skills"));
22694
+ console.log(indigo9.bold("Updating Skills"));
22476
22695
  console.log();
22477
22696
  let updated = 0;
22478
22697
  let upToDate = 0;
@@ -22490,7 +22709,7 @@ async function updateCommand(skillName, options = {}) {
22490
22709
  const currentVersion = skill.version;
22491
22710
  if (newVersion !== currentVersion) {
22492
22711
  writeFileSync6(join9(skill.dir, "SKILL.md"), result.data.skillMdContent);
22493
- spinner.succeed(`${skill.name}: ${source_default.dim(currentVersion)} ${indigo8("→")} ${indigo8(newVersion)}`);
22712
+ spinner.succeed(`${skill.name}: ${source_default.dim(currentVersion)} ${indigo9("→")} ${indigo9(newVersion)}`);
22494
22713
  updated++;
22495
22714
  } else {
22496
22715
  spinner.succeed(`${skill.name}: ${source_default.dim(`v${currentVersion}`)} ${source_default.green("(up to date)")}`);
@@ -22506,7 +22725,7 @@ async function updateCommand(skillName, options = {}) {
22506
22725
  console.log();
22507
22726
  const summary = [];
22508
22727
  if (updated > 0)
22509
- summary.push(indigo8(`${updated} updated`));
22728
+ summary.push(indigo9(`${updated} updated`));
22510
22729
  if (upToDate > 0)
22511
22730
  summary.push(source_default.green(`${upToDate} up to date`));
22512
22731
  if (failed > 0)
@@ -22517,11 +22736,11 @@ async function updateCommand(skillName, options = {}) {
22517
22736
 
22518
22737
  // src/commands/upgrade.ts
22519
22738
  import { execSync } from "child_process";
22520
- var indigo9 = source_default.hex("#6366f1");
22739
+ var indigo10 = source_default.hex("#6366f1");
22521
22740
  var PACKAGE_NAME = "@hasnatools/skills";
22522
22741
  async function upgradeCommand() {
22523
22742
  console.log();
22524
- console.log(indigo9.bold("Upgrade Skills CLI"));
22743
+ console.log(indigo10.bold("Upgrade Skills CLI"));
22525
22744
  console.log();
22526
22745
  const currentVersion = process.env.npm_package_version || getInstalledVersion();
22527
22746
  console.log(` Current: ${source_default.dim(`v${currentVersion}`)}`);
@@ -22542,7 +22761,7 @@ async function upgradeCommand() {
22542
22761
  execSync(upgradeCmd, {
22543
22762
  stdio: ["pipe", "pipe", "pipe"]
22544
22763
  });
22545
- spinner.succeed(`Upgraded to ${indigo9(`v${latestVersion}`)}`);
22764
+ spinner.succeed(`Upgraded to ${indigo10(`v${latestVersion}`)}`);
22546
22765
  console.log();
22547
22766
  console.log(source_default.dim(" Restart your terminal to use the new version"));
22548
22767
  console.log();
@@ -22586,10 +22805,10 @@ function detectPackageManager() {
22586
22805
  // src/commands/doctor.ts
22587
22806
  import { existsSync as existsSync10 } from "fs";
22588
22807
  import { execSync as execSync2 } from "child_process";
22589
- var indigo10 = source_default.hex("#6366f1");
22808
+ var indigo11 = source_default.hex("#6366f1");
22590
22809
  async function doctorCommand() {
22591
22810
  console.log();
22592
- console.log(indigo10.bold("Skills Doctor"));
22811
+ console.log(indigo11.bold("Skills Doctor"));
22593
22812
  console.log(source_default.dim("Checking your environment..."));
22594
22813
  console.log();
22595
22814
  const results = [];
@@ -22693,7 +22912,7 @@ async function doctorCommand() {
22693
22912
  console.log(source_default.yellow(` ${warnCount} warning(s)`));
22694
22913
  }
22695
22914
  if (okCount === results.length) {
22696
- console.log(indigo10.bold(" All checks passed!"));
22915
+ console.log(indigo11.bold(" All checks passed!"));
22697
22916
  }
22698
22917
  console.log();
22699
22918
  if (!apiKey) {
@@ -22703,9 +22922,9 @@ async function doctorCommand() {
22703
22922
  }
22704
22923
 
22705
22924
  // src/index.ts
22706
- var indigo11 = source_default.hex("#6366f1");
22925
+ var indigo12 = source_default.hex("#6366f1");
22707
22926
  var program2 = new Command;
22708
- program2.name("skills").description("CLI for skills.md - AI Agent Skills Marketplace").version("0.1.10");
22927
+ program2.name("skills").description("CLI for skills.md - AI Agent Skills Marketplace").version("0.1.11");
22709
22928
  program2.command("init").description("Initialize skills.md in current project").option("-f, --force", "Force re-initialization (removes existing .skills/)").action((options) => {
22710
22929
  initCommand({ force: options.force });
22711
22930
  });
@@ -22753,12 +22972,13 @@ program2.command("run <name> [args...]").description("Run a skill").option("-t,
22753
22972
  args
22754
22973
  });
22755
22974
  });
22756
- program2.command("config").description("View or modify configuration").option("--get <key>", "Get a config value").option("--set <key=value>", "Set a config value").action((options) => {
22975
+ var configCmd = program2.command("config").description("View or modify configuration").option("--get <key>", "Get a config value").option("--set <key=value>", "Set a config value").action((options) => {
22757
22976
  configCommand({
22758
22977
  get: options.get,
22759
22978
  set: options.set
22760
22979
  });
22761
22980
  });
22981
+ configCmd.command("cli-2fa [action]").description("Enable/disable 2FA for CLI purchases (on/off)").action(cli2faCommand);
22762
22982
  program2.command("target [platform]").description("Get or set default target platform").action(targetCommand);
22763
22983
  program2.command("generate <mediaType> <prompt>").alias("gen").description("Generate content (image, video, audio, text)").option("-o, --output <path>", "Save output to file").option("-p, --provider <provider>", "Specify provider (e.g., fal, replicate)").option("-a, --async", "Run asynchronously and return job ID").action((mediaType, prompt, options) => {
22764
22984
  generateCommand(mediaType, prompt, {
@@ -22794,14 +23014,17 @@ program2.command("feedback").description("Submit feedback, bug reports, or featu
22794
23014
  });
22795
23015
  });
22796
23016
  program2.command("info <name>").description("Show detailed information about a skill").action(infoCommand);
22797
- program2.command("credits").description("Check your credits balance").action(creditsCommand);
23017
+ var creditsCmd = program2.command("credits").description("Manage credits");
23018
+ creditsCmd.command("balance").alias("bal").description("Check your credits balance").action(creditsCommand);
23019
+ creditsCmd.command("buy <amount>").description("Purchase credits ($5-$500)").action(buyCreditsCommand);
23020
+ creditsCmd.action(creditsCommand);
22798
23021
  program2.command("update [skill]").description("Update installed skills to latest versions").option("-t, --target <target>", "Target platform (claude, codex)").action((skill, options) => {
22799
23022
  updateCommand(skill, { target: options.target });
22800
23023
  });
22801
23024
  program2.command("upgrade").description("Upgrade the Skills CLI to the latest version").action(upgradeCommand);
22802
23025
  program2.command("doctor").description("Check your environment and diagnose issues").action(doctorCommand);
22803
23026
  program2.addHelpText("after", `
22804
- ${indigo11.bold("Examples:")}
23027
+ ${indigo12.bold("Examples:")}
22805
23028
  ${source_default.dim("# Initialize in current project")}
22806
23029
  $ skills init
22807
23030
 
@@ -22847,6 +23070,12 @@ ${indigo11.bold("Examples:")}
22847
23070
  ${source_default.dim("# Check credits balance")}
22848
23071
  $ skills credits
22849
23072
 
23073
+ ${source_default.dim("# Purchase credits")}
23074
+ $ skills credits buy 25
23075
+
23076
+ ${source_default.dim("# Enable 2FA for CLI purchases")}
23077
+ $ skills config cli-2fa on
23078
+
22850
23079
  ${source_default.dim("# Update installed skills")}
22851
23080
  $ skills update
22852
23081
 
@@ -22856,7 +23085,7 @@ ${indigo11.bold("Examples:")}
22856
23085
  ${source_default.dim("# Check environment")}
22857
23086
  $ skills doctor
22858
23087
 
22859
- ${indigo11.bold("Documentation:")}
22860
- ${indigo11("https://skills.md/docs")}
23088
+ ${indigo12.bold("Documentation:")}
23089
+ ${indigo12("https://skills.md/docs")}
22861
23090
  `);
22862
23091
  program2.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasnatools/skills",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "description": "CLI for skills.md - AI Agent Skills Marketplace",
5
5
  "type": "module",
6
6
  "bin": {