@hasnatools/skills 0.1.9 → 0.1.11
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.
- package/dist/index.js +385 -48
- 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";
|
|
@@ -21785,7 +21885,7 @@ async function generateCommand(mediaType, prompt, options = {}) {
|
|
|
21785
21885
|
console.log();
|
|
21786
21886
|
const spinner = ora("Sending request...").start();
|
|
21787
21887
|
try {
|
|
21788
|
-
const response = await makeApiRequest("/
|
|
21888
|
+
const response = await makeApiRequest("/generate", {
|
|
21789
21889
|
method: "POST",
|
|
21790
21890
|
body: JSON.stringify({
|
|
21791
21891
|
mediaType,
|
|
@@ -21839,7 +21939,7 @@ async function jobsCommand(jobId) {
|
|
|
21839
21939
|
}
|
|
21840
21940
|
const spinner = ora("Fetching jobs...").start();
|
|
21841
21941
|
try {
|
|
21842
|
-
const endpoint = jobId ? `/
|
|
21942
|
+
const endpoint = jobId ? `/jobs/${jobId}` : "/jobs";
|
|
21843
21943
|
const response = await makeApiRequest(endpoint);
|
|
21844
21944
|
if (!response.ok) {
|
|
21845
21945
|
const error = await response.json();
|
|
@@ -21915,7 +22015,111 @@ 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";
|
|
22018
|
+
var indigo4 = source_default.hex("#6366f1");
|
|
21918
22019
|
async function historyCommand(options = {}) {
|
|
22020
|
+
if (options.local) {
|
|
22021
|
+
return localHistoryCommand(options);
|
|
22022
|
+
}
|
|
22023
|
+
const apiKey = getApiKey();
|
|
22024
|
+
if (!apiKey) {
|
|
22025
|
+
console.log(source_default.yellow("Not logged in - showing local history only"));
|
|
22026
|
+
console.log(source_default.dim("Run `skills login` to see remote execution history"));
|
|
22027
|
+
console.log();
|
|
22028
|
+
return localHistoryCommand(options);
|
|
22029
|
+
}
|
|
22030
|
+
const spinner = ora("Fetching execution history...").start();
|
|
22031
|
+
try {
|
|
22032
|
+
const params = new URLSearchParams;
|
|
22033
|
+
if (options.skill)
|
|
22034
|
+
params.set("skill", options.skill);
|
|
22035
|
+
if (options.limit)
|
|
22036
|
+
params.set("limit", String(options.limit));
|
|
22037
|
+
if (options.status)
|
|
22038
|
+
params.set("status", options.status);
|
|
22039
|
+
const query = params.toString();
|
|
22040
|
+
const response = await makeApiRequest(`/me/executions${query ? `?${query}` : ""}`);
|
|
22041
|
+
if (!response.ok) {
|
|
22042
|
+
const error = await response.json().catch(() => ({ error: "Unknown error" }));
|
|
22043
|
+
spinner.fail("Failed to fetch history");
|
|
22044
|
+
console.log(source_default.red(error.error));
|
|
22045
|
+
return;
|
|
22046
|
+
}
|
|
22047
|
+
const result = await response.json();
|
|
22048
|
+
spinner.stop();
|
|
22049
|
+
const { executions, pagination, counts } = result;
|
|
22050
|
+
console.log();
|
|
22051
|
+
console.log(indigo4.bold("Execution History"));
|
|
22052
|
+
console.log(source_default.dim(`Total: ${counts.all} | Completed: ${counts.completed} | Failed: ${counts.failed} | Pending: ${counts.pending}`));
|
|
22053
|
+
console.log();
|
|
22054
|
+
if (executions.length === 0) {
|
|
22055
|
+
console.log(source_default.dim("No executions found"));
|
|
22056
|
+
console.log(source_default.dim("Run a skill with `skills run <name>` to start tracking"));
|
|
22057
|
+
return;
|
|
22058
|
+
}
|
|
22059
|
+
for (const exec of executions) {
|
|
22060
|
+
const date = new Date(exec.createdAt);
|
|
22061
|
+
const dateStr = date.toLocaleDateString();
|
|
22062
|
+
const timeStr = date.toLocaleTimeString();
|
|
22063
|
+
const statusIcon = getStatusIcon(exec.status);
|
|
22064
|
+
const durationStr = exec.durationMs ? formatDuration2(exec.durationMs) : "-";
|
|
22065
|
+
console.log(`${statusIcon} ${source_default.bold(exec.skillSlug || exec.skillName || "Unknown")} ${source_default.dim(`(${dateStr} ${timeStr})`)}`);
|
|
22066
|
+
console.log(` ${source_default.dim("ID:")} ${exec.id.slice(0, 8)}...`);
|
|
22067
|
+
console.log(` ${source_default.dim("Status:")} ${formatStatus2(exec.status)}`);
|
|
22068
|
+
console.log(` ${source_default.dim("Duration:")} ${durationStr}`);
|
|
22069
|
+
if (exec.creditsUsed > 0) {
|
|
22070
|
+
console.log(` ${source_default.dim("Credits:")} ${indigo4(String(exec.creditsUsed))}`);
|
|
22071
|
+
}
|
|
22072
|
+
if (exec.outputType) {
|
|
22073
|
+
console.log(` ${source_default.dim("Output:")} ${exec.outputType}`);
|
|
22074
|
+
}
|
|
22075
|
+
if (exec.exports && exec.exports.length > 0) {
|
|
22076
|
+
console.log(` ${source_default.dim("Exports:")} ${exec.exports.length} file(s)`);
|
|
22077
|
+
if (options.verbose) {
|
|
22078
|
+
for (const exp of exec.exports) {
|
|
22079
|
+
console.log(` ${source_default.dim("→")} ${exp.filename}`);
|
|
22080
|
+
}
|
|
22081
|
+
}
|
|
22082
|
+
}
|
|
22083
|
+
if (exec.errorMessage && options.verbose) {
|
|
22084
|
+
console.log(` ${source_default.dim("Error:")} ${source_default.red(exec.errorMessage)}`);
|
|
22085
|
+
}
|
|
22086
|
+
console.log();
|
|
22087
|
+
}
|
|
22088
|
+
if (pagination.hasMore) {
|
|
22089
|
+
console.log(source_default.dim(`Showing ${executions.length} of ${pagination.total} executions`));
|
|
22090
|
+
console.log(source_default.dim(`Use --limit to see more`));
|
|
22091
|
+
}
|
|
22092
|
+
console.log(source_default.dim("View all at: https://skills.md/dashboard/executions"));
|
|
22093
|
+
} catch (error) {
|
|
22094
|
+
spinner.fail("Request failed");
|
|
22095
|
+
console.log(source_default.red(error instanceof Error ? error.message : "Unknown error"));
|
|
22096
|
+
}
|
|
22097
|
+
}
|
|
22098
|
+
function getStatusIcon(status) {
|
|
22099
|
+
switch (status) {
|
|
22100
|
+
case "completed":
|
|
22101
|
+
return source_default.green("✓");
|
|
22102
|
+
case "failed":
|
|
22103
|
+
return source_default.red("✗");
|
|
22104
|
+
case "pending":
|
|
22105
|
+
return source_default.yellow("◌");
|
|
22106
|
+
default:
|
|
22107
|
+
return source_default.dim("○");
|
|
22108
|
+
}
|
|
22109
|
+
}
|
|
22110
|
+
function formatStatus2(status) {
|
|
22111
|
+
switch (status) {
|
|
22112
|
+
case "completed":
|
|
22113
|
+
return source_default.green("completed");
|
|
22114
|
+
case "failed":
|
|
22115
|
+
return source_default.red("failed");
|
|
22116
|
+
case "pending":
|
|
22117
|
+
return source_default.yellow("pending");
|
|
22118
|
+
default:
|
|
22119
|
+
return source_default.dim(status || "unknown");
|
|
22120
|
+
}
|
|
22121
|
+
}
|
|
22122
|
+
async function localHistoryCommand(options) {
|
|
21919
22123
|
const projectOutputDir = getProjectSkillsOutputDir();
|
|
21920
22124
|
if (!projectOutputDir) {
|
|
21921
22125
|
console.log(source_default.yellow("No project initialized"));
|
|
@@ -21924,7 +22128,7 @@ async function historyCommand(options = {}) {
|
|
|
21924
22128
|
}
|
|
21925
22129
|
const historyFile = join8(projectOutputDir, "execution-history.jsonl");
|
|
21926
22130
|
if (!existsSync8(historyFile)) {
|
|
21927
|
-
console.log(source_default.dim("No execution history found"));
|
|
22131
|
+
console.log(source_default.dim("No local execution history found"));
|
|
21928
22132
|
console.log(source_default.dim("Run a skill with `skills run <name>` to start tracking"));
|
|
21929
22133
|
return;
|
|
21930
22134
|
}
|
|
@@ -21948,7 +22152,7 @@ async function historyCommand(options = {}) {
|
|
|
21948
22152
|
return;
|
|
21949
22153
|
}
|
|
21950
22154
|
console.log();
|
|
21951
|
-
console.log(
|
|
22155
|
+
console.log(indigo4.bold("Local Execution History"));
|
|
21952
22156
|
console.log(source_default.dim(`Showing ${entries.length} most recent execution(s)`));
|
|
21953
22157
|
console.log();
|
|
21954
22158
|
for (const entry of entries) {
|
|
@@ -21999,7 +22203,7 @@ async function exportsCommand(slug, options = {}) {
|
|
|
21999
22203
|
return;
|
|
22000
22204
|
}
|
|
22001
22205
|
console.log();
|
|
22002
|
-
console.log(
|
|
22206
|
+
console.log(indigo4.bold(`Exports for ${slug}`));
|
|
22003
22207
|
console.log(source_default.dim(`Directory: ${exportsDir}`));
|
|
22004
22208
|
console.log();
|
|
22005
22209
|
const fileInfos = files.map((file) => {
|
|
@@ -22042,17 +22246,17 @@ async function logsCommand(slug, options = {}) {
|
|
|
22042
22246
|
const latestLog = files[0];
|
|
22043
22247
|
const logPath = join8(logsDir, latestLog);
|
|
22044
22248
|
console.log();
|
|
22045
|
-
console.log(
|
|
22249
|
+
console.log(indigo4.bold(`Latest Log for ${slug}`));
|
|
22046
22250
|
console.log(source_default.dim(`File: ${logPath}`));
|
|
22047
22251
|
console.log(source_default.dim("─".repeat(60)));
|
|
22048
22252
|
console.log();
|
|
22049
22253
|
const content = readFileSync4(logPath, "utf-8");
|
|
22050
|
-
const
|
|
22254
|
+
const logLines = content.split(`
|
|
22051
22255
|
`);
|
|
22052
22256
|
const tailLines = options.tail || 50;
|
|
22053
|
-
if (
|
|
22257
|
+
if (logLines.length > tailLines) {
|
|
22054
22258
|
console.log(source_default.dim(`... (showing last ${tailLines} lines)`));
|
|
22055
|
-
console.log(
|
|
22259
|
+
console.log(logLines.slice(-tailLines).join(`
|
|
22056
22260
|
`));
|
|
22057
22261
|
} else {
|
|
22058
22262
|
console.log(content);
|
|
@@ -22082,7 +22286,7 @@ function formatBytes(bytes) {
|
|
|
22082
22286
|
}
|
|
22083
22287
|
|
|
22084
22288
|
// src/commands/marketplace.ts
|
|
22085
|
-
var
|
|
22289
|
+
var indigo5 = source_default.hex("#6366f1");
|
|
22086
22290
|
async function marketplaceCommand(options = {}) {
|
|
22087
22291
|
const spinner = ora("Fetching skills from marketplace...").start();
|
|
22088
22292
|
const limit = options.limit || 20;
|
|
@@ -22105,36 +22309,36 @@ async function marketplaceCommand(options = {}) {
|
|
|
22105
22309
|
return;
|
|
22106
22310
|
}
|
|
22107
22311
|
console.log();
|
|
22108
|
-
console.log(
|
|
22312
|
+
console.log(indigo5.bold(`Skills Marketplace`) + source_default.dim(` (page ${page}/${totalPages}, ${total} total skills)`));
|
|
22109
22313
|
console.log();
|
|
22110
22314
|
for (const skill of skills) {
|
|
22111
|
-
const verified = skill.isVerified ?
|
|
22315
|
+
const verified = skill.isVerified ? indigo5(" ✓") : "";
|
|
22112
22316
|
const downloads = skill.downloadCount > 0 ? source_default.dim(` (${skill.downloadCount} installs)`) : "";
|
|
22113
22317
|
console.log(" " + source_default.bold(skill.name) + verified + source_default.dim(` v${skill.version}`) + downloads);
|
|
22114
22318
|
console.log(" " + source_default.dim(skill.description || "No description"));
|
|
22115
|
-
console.log(" " +
|
|
22319
|
+
console.log(" " + indigo5(`skills install ${skill.slug}`));
|
|
22116
22320
|
console.log();
|
|
22117
22321
|
}
|
|
22118
22322
|
console.log(source_default.dim("─".repeat(50)));
|
|
22119
22323
|
if (totalPages > 1) {
|
|
22120
22324
|
const navHints = [];
|
|
22121
22325
|
if (page > 1) {
|
|
22122
|
-
navHints.push(`${
|
|
22326
|
+
navHints.push(`${indigo5(`skills marketplace -p ${page - 1}`)} for previous`);
|
|
22123
22327
|
}
|
|
22124
22328
|
if (page < totalPages) {
|
|
22125
|
-
navHints.push(`${
|
|
22329
|
+
navHints.push(`${indigo5(`skills marketplace -p ${page + 1}`)} for next`);
|
|
22126
22330
|
}
|
|
22127
22331
|
if (navHints.length > 0) {
|
|
22128
22332
|
console.log(source_default.dim(navHints.join(" | ")));
|
|
22129
22333
|
}
|
|
22130
22334
|
}
|
|
22131
|
-
console.log(source_default.dim(`Run ${
|
|
22132
|
-
console.log(source_default.dim(`Run ${
|
|
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`));
|
|
22133
22337
|
}
|
|
22134
22338
|
|
|
22135
22339
|
// src/commands/feedback.ts
|
|
22136
22340
|
var import_prompts2 = __toESM(require_prompts3(), 1);
|
|
22137
|
-
var
|
|
22341
|
+
var indigo6 = source_default.hex("#6366f1");
|
|
22138
22342
|
var indigoBold = source_default.hex("#6366f1").bold;
|
|
22139
22343
|
async function submitFeedback(type, title, description) {
|
|
22140
22344
|
const spinner = ora("Submitting feedback...").start();
|
|
@@ -22156,7 +22360,7 @@ async function submitFeedback(type, title, description) {
|
|
|
22156
22360
|
}
|
|
22157
22361
|
spinner.succeed("Feedback submitted!");
|
|
22158
22362
|
console.log();
|
|
22159
|
-
console.log(
|
|
22363
|
+
console.log(indigo6(" Thank you for your feedback! \uD83D\uDE4F"));
|
|
22160
22364
|
console.log(source_default.dim(" We'll review it and get back to you if needed."));
|
|
22161
22365
|
return true;
|
|
22162
22366
|
} catch (error) {
|
|
@@ -22172,7 +22376,7 @@ async function feedbackCommand(options = {}) {
|
|
|
22172
22376
|
const apiKey = getApiKey();
|
|
22173
22377
|
if (!apiKey) {
|
|
22174
22378
|
console.log(source_default.yellow("⚠") + " You need to be logged in to submit feedback.");
|
|
22175
|
-
console.log(source_default.dim(" Run ") +
|
|
22379
|
+
console.log(source_default.dim(" Run ") + indigo6("skills login") + source_default.dim(" first."));
|
|
22176
22380
|
console.log();
|
|
22177
22381
|
return;
|
|
22178
22382
|
}
|
|
@@ -22225,7 +22429,7 @@ Feedback cancelled.`));
|
|
|
22225
22429
|
}
|
|
22226
22430
|
|
|
22227
22431
|
// src/commands/info.ts
|
|
22228
|
-
var
|
|
22432
|
+
var indigo7 = source_default.hex("#6366f1");
|
|
22229
22433
|
async function infoCommand(name) {
|
|
22230
22434
|
const spinner = ora("Fetching skill info...").start();
|
|
22231
22435
|
const result = await getSkill(name);
|
|
@@ -22237,7 +22441,7 @@ async function infoCommand(name) {
|
|
|
22237
22441
|
spinner.stop();
|
|
22238
22442
|
const skill = result.data;
|
|
22239
22443
|
console.log();
|
|
22240
|
-
console.log(
|
|
22444
|
+
console.log(indigo7.bold(skill.name) + (skill.isVerified ? indigo7(" ✓") : ""));
|
|
22241
22445
|
console.log(source_default.dim(`v${skill.version}`));
|
|
22242
22446
|
console.log();
|
|
22243
22447
|
if (skill.description) {
|
|
@@ -22254,7 +22458,7 @@ async function infoCommand(name) {
|
|
|
22254
22458
|
["Downloads", skill.downloadCount.toLocaleString()],
|
|
22255
22459
|
["Verified", skill.isVerified ? source_default.green("Yes") : "No"],
|
|
22256
22460
|
["Remote Execution", skill.isRemoteExecution ? source_default.green("Yes") : "No"],
|
|
22257
|
-
["Credits/Run", (skill.creditsPerExecution ?? 0) > 0 ?
|
|
22461
|
+
["Credits/Run", (skill.creditsPerExecution ?? 0) > 0 ? indigo7(String(skill.creditsPerExecution)) : source_default.green("Free")]
|
|
22258
22462
|
];
|
|
22259
22463
|
for (const [label, value] of details) {
|
|
22260
22464
|
console.log(` ${source_default.dim(label.padEnd(18))} ${value}`);
|
|
@@ -22266,15 +22470,19 @@ async function infoCommand(name) {
|
|
|
22266
22470
|
console.log();
|
|
22267
22471
|
console.log(source_default.dim("─".repeat(50)));
|
|
22268
22472
|
console.log();
|
|
22269
|
-
console.log(` ${source_default.dim("Install:")} ${
|
|
22473
|
+
console.log(` ${source_default.dim("Install:")} ${indigo7(`skills install ${skill.slug}`)}`);
|
|
22270
22474
|
if (skill.isRemoteExecution) {
|
|
22271
|
-
console.log(` ${source_default.dim("Run:")} ${
|
|
22475
|
+
console.log(` ${source_default.dim("Run:")} ${indigo7(`skills run ${skill.slug}`)}`);
|
|
22272
22476
|
}
|
|
22273
22477
|
console.log();
|
|
22274
22478
|
}
|
|
22275
22479
|
|
|
22276
22480
|
// src/commands/credits.ts
|
|
22277
|
-
var
|
|
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;
|
|
22278
22486
|
async function creditsCommand() {
|
|
22279
22487
|
const apiKey = getApiKey();
|
|
22280
22488
|
if (!apiKey) {
|
|
@@ -22292,23 +22500,138 @@ async function creditsCommand() {
|
|
|
22292
22500
|
spinner.stop();
|
|
22293
22501
|
const { creditsBalance, plan, tenantName } = result.data;
|
|
22294
22502
|
console.log();
|
|
22295
|
-
console.log(
|
|
22503
|
+
console.log(indigo8.bold("Credits Balance"));
|
|
22296
22504
|
console.log();
|
|
22297
|
-
console.log(" " +
|
|
22505
|
+
console.log(" " + indigo8.bold(creditsBalance.toLocaleString()) + " credits");
|
|
22298
22506
|
console.log();
|
|
22299
22507
|
console.log(source_default.dim("─".repeat(30)));
|
|
22300
22508
|
console.log();
|
|
22301
22509
|
console.log(" Plan: " + source_default.bold(plan));
|
|
22302
22510
|
console.log(" Org: " + (tenantName || source_default.dim("Personal")));
|
|
22303
22511
|
console.log();
|
|
22304
|
-
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));
|
|
22305
22628
|
console.log();
|
|
22306
22629
|
}
|
|
22307
22630
|
|
|
22308
22631
|
// src/commands/update.ts
|
|
22309
22632
|
import { existsSync as existsSync9, readdirSync as readdirSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync6 } from "fs";
|
|
22310
22633
|
import { join as join9 } from "path";
|
|
22311
|
-
var
|
|
22634
|
+
var indigo9 = source_default.hex("#6366f1");
|
|
22312
22635
|
function parseFrontmatter2(content) {
|
|
22313
22636
|
const result = {};
|
|
22314
22637
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
@@ -22368,7 +22691,7 @@ async function updateCommand(skillName, options = {}) {
|
|
|
22368
22691
|
return;
|
|
22369
22692
|
}
|
|
22370
22693
|
console.log();
|
|
22371
|
-
console.log(
|
|
22694
|
+
console.log(indigo9.bold("Updating Skills"));
|
|
22372
22695
|
console.log();
|
|
22373
22696
|
let updated = 0;
|
|
22374
22697
|
let upToDate = 0;
|
|
@@ -22386,7 +22709,7 @@ async function updateCommand(skillName, options = {}) {
|
|
|
22386
22709
|
const currentVersion = skill.version;
|
|
22387
22710
|
if (newVersion !== currentVersion) {
|
|
22388
22711
|
writeFileSync6(join9(skill.dir, "SKILL.md"), result.data.skillMdContent);
|
|
22389
|
-
spinner.succeed(`${skill.name}: ${source_default.dim(currentVersion)} ${
|
|
22712
|
+
spinner.succeed(`${skill.name}: ${source_default.dim(currentVersion)} ${indigo9("→")} ${indigo9(newVersion)}`);
|
|
22390
22713
|
updated++;
|
|
22391
22714
|
} else {
|
|
22392
22715
|
spinner.succeed(`${skill.name}: ${source_default.dim(`v${currentVersion}`)} ${source_default.green("(up to date)")}`);
|
|
@@ -22402,7 +22725,7 @@ async function updateCommand(skillName, options = {}) {
|
|
|
22402
22725
|
console.log();
|
|
22403
22726
|
const summary = [];
|
|
22404
22727
|
if (updated > 0)
|
|
22405
|
-
summary.push(
|
|
22728
|
+
summary.push(indigo9(`${updated} updated`));
|
|
22406
22729
|
if (upToDate > 0)
|
|
22407
22730
|
summary.push(source_default.green(`${upToDate} up to date`));
|
|
22408
22731
|
if (failed > 0)
|
|
@@ -22413,11 +22736,11 @@ async function updateCommand(skillName, options = {}) {
|
|
|
22413
22736
|
|
|
22414
22737
|
// src/commands/upgrade.ts
|
|
22415
22738
|
import { execSync } from "child_process";
|
|
22416
|
-
var
|
|
22739
|
+
var indigo10 = source_default.hex("#6366f1");
|
|
22417
22740
|
var PACKAGE_NAME = "@hasnatools/skills";
|
|
22418
22741
|
async function upgradeCommand() {
|
|
22419
22742
|
console.log();
|
|
22420
|
-
console.log(
|
|
22743
|
+
console.log(indigo10.bold("Upgrade Skills CLI"));
|
|
22421
22744
|
console.log();
|
|
22422
22745
|
const currentVersion = process.env.npm_package_version || getInstalledVersion();
|
|
22423
22746
|
console.log(` Current: ${source_default.dim(`v${currentVersion}`)}`);
|
|
@@ -22438,7 +22761,7 @@ async function upgradeCommand() {
|
|
|
22438
22761
|
execSync(upgradeCmd, {
|
|
22439
22762
|
stdio: ["pipe", "pipe", "pipe"]
|
|
22440
22763
|
});
|
|
22441
|
-
spinner.succeed(`Upgraded to ${
|
|
22764
|
+
spinner.succeed(`Upgraded to ${indigo10(`v${latestVersion}`)}`);
|
|
22442
22765
|
console.log();
|
|
22443
22766
|
console.log(source_default.dim(" Restart your terminal to use the new version"));
|
|
22444
22767
|
console.log();
|
|
@@ -22482,10 +22805,10 @@ function detectPackageManager() {
|
|
|
22482
22805
|
// src/commands/doctor.ts
|
|
22483
22806
|
import { existsSync as existsSync10 } from "fs";
|
|
22484
22807
|
import { execSync as execSync2 } from "child_process";
|
|
22485
|
-
var
|
|
22808
|
+
var indigo11 = source_default.hex("#6366f1");
|
|
22486
22809
|
async function doctorCommand() {
|
|
22487
22810
|
console.log();
|
|
22488
|
-
console.log(
|
|
22811
|
+
console.log(indigo11.bold("Skills Doctor"));
|
|
22489
22812
|
console.log(source_default.dim("Checking your environment..."));
|
|
22490
22813
|
console.log();
|
|
22491
22814
|
const results = [];
|
|
@@ -22589,7 +22912,7 @@ async function doctorCommand() {
|
|
|
22589
22912
|
console.log(source_default.yellow(` ${warnCount} warning(s)`));
|
|
22590
22913
|
}
|
|
22591
22914
|
if (okCount === results.length) {
|
|
22592
|
-
console.log(
|
|
22915
|
+
console.log(indigo11.bold(" All checks passed!"));
|
|
22593
22916
|
}
|
|
22594
22917
|
console.log();
|
|
22595
22918
|
if (!apiKey) {
|
|
@@ -22599,9 +22922,9 @@ async function doctorCommand() {
|
|
|
22599
22922
|
}
|
|
22600
22923
|
|
|
22601
22924
|
// src/index.ts
|
|
22602
|
-
var
|
|
22925
|
+
var indigo12 = source_default.hex("#6366f1");
|
|
22603
22926
|
var program2 = new Command;
|
|
22604
|
-
program2.name("skills").description("CLI for skills.md - AI Agent Skills Marketplace").version("0.1.
|
|
22927
|
+
program2.name("skills").description("CLI for skills.md - AI Agent Skills Marketplace").version("0.1.11");
|
|
22605
22928
|
program2.command("init").description("Initialize skills.md in current project").option("-f, --force", "Force re-initialization (removes existing .skills/)").action((options) => {
|
|
22606
22929
|
initCommand({ force: options.force });
|
|
22607
22930
|
});
|
|
@@ -22649,12 +22972,13 @@ program2.command("run <name> [args...]").description("Run a skill").option("-t,
|
|
|
22649
22972
|
args
|
|
22650
22973
|
});
|
|
22651
22974
|
});
|
|
22652
|
-
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) => {
|
|
22653
22976
|
configCommand({
|
|
22654
22977
|
get: options.get,
|
|
22655
22978
|
set: options.set
|
|
22656
22979
|
});
|
|
22657
22980
|
});
|
|
22981
|
+
configCmd.command("cli-2fa [action]").description("Enable/disable 2FA for CLI purchases (on/off)").action(cli2faCommand);
|
|
22658
22982
|
program2.command("target [platform]").description("Get or set default target platform").action(targetCommand);
|
|
22659
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) => {
|
|
22660
22984
|
generateCommand(mediaType, prompt, {
|
|
@@ -22664,11 +22988,13 @@ program2.command("generate <mediaType> <prompt>").alias("gen").description("Gene
|
|
|
22664
22988
|
});
|
|
22665
22989
|
});
|
|
22666
22990
|
program2.command("jobs [jobId]").description("List generation jobs or view job details").action(jobsCommand);
|
|
22667
|
-
program2.command("history").description("View execution history").option("-s, --skill <name>", "Filter by skill name").option("-n, --limit <number>", "Limit number of entries", "20").option("-v, --verbose", "Show detailed output").action((options) => {
|
|
22991
|
+
program2.command("history").description("View execution history").option("-s, --skill <name>", "Filter by skill name").option("-n, --limit <number>", "Limit number of entries", "20").option("-v, --verbose", "Show detailed output").option("--status <status>", "Filter by status (completed, failed, pending)").option("-l, --local", "Show local history only (skip API)").action((options) => {
|
|
22668
22992
|
historyCommand({
|
|
22669
22993
|
skill: options.skill,
|
|
22670
22994
|
limit: parseInt(options.limit, 10),
|
|
22671
|
-
verbose: options.verbose
|
|
22995
|
+
verbose: options.verbose,
|
|
22996
|
+
status: options.status,
|
|
22997
|
+
local: options.local
|
|
22672
22998
|
});
|
|
22673
22999
|
});
|
|
22674
23000
|
program2.command("exports <skill>").description("View exported files for a skill").option("-t, --target <target>", "Target platform (claude, codex)").action((skill, options) => {
|
|
@@ -22688,14 +23014,17 @@ program2.command("feedback").description("Submit feedback, bug reports, or featu
|
|
|
22688
23014
|
});
|
|
22689
23015
|
});
|
|
22690
23016
|
program2.command("info <name>").description("Show detailed information about a skill").action(infoCommand);
|
|
22691
|
-
program2.command("credits").description("
|
|
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);
|
|
22692
23021
|
program2.command("update [skill]").description("Update installed skills to latest versions").option("-t, --target <target>", "Target platform (claude, codex)").action((skill, options) => {
|
|
22693
23022
|
updateCommand(skill, { target: options.target });
|
|
22694
23023
|
});
|
|
22695
23024
|
program2.command("upgrade").description("Upgrade the Skills CLI to the latest version").action(upgradeCommand);
|
|
22696
23025
|
program2.command("doctor").description("Check your environment and diagnose issues").action(doctorCommand);
|
|
22697
23026
|
program2.addHelpText("after", `
|
|
22698
|
-
${
|
|
23027
|
+
${indigo12.bold("Examples:")}
|
|
22699
23028
|
${source_default.dim("# Initialize in current project")}
|
|
22700
23029
|
$ skills init
|
|
22701
23030
|
|
|
@@ -22723,6 +23052,8 @@ ${indigo10.bold("Examples:")}
|
|
|
22723
23052
|
${source_default.dim("# View execution history")}
|
|
22724
23053
|
$ skills history
|
|
22725
23054
|
$ skills history --skill image-generator
|
|
23055
|
+
$ skills history --status completed
|
|
23056
|
+
$ skills history --local
|
|
22726
23057
|
|
|
22727
23058
|
${source_default.dim("# View exports for a skill")}
|
|
22728
23059
|
$ skills exports image-generator
|
|
@@ -22739,6 +23070,12 @@ ${indigo10.bold("Examples:")}
|
|
|
22739
23070
|
${source_default.dim("# Check credits balance")}
|
|
22740
23071
|
$ skills credits
|
|
22741
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
|
+
|
|
22742
23079
|
${source_default.dim("# Update installed skills")}
|
|
22743
23080
|
$ skills update
|
|
22744
23081
|
|
|
@@ -22748,7 +23085,7 @@ ${indigo10.bold("Examples:")}
|
|
|
22748
23085
|
${source_default.dim("# Check environment")}
|
|
22749
23086
|
$ skills doctor
|
|
22750
23087
|
|
|
22751
|
-
${
|
|
22752
|
-
${
|
|
23088
|
+
${indigo12.bold("Documentation:")}
|
|
23089
|
+
${indigo12("https://skills.md/docs")}
|
|
22753
23090
|
`);
|
|
22754
23091
|
program2.parse();
|