@hasnatools/skills 0.1.37 → 0.1.39
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 +739 -63
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -13018,7 +13018,7 @@ var require_prompt = __commonJS((exports, module) => {
|
|
|
13018
13018
|
|
|
13019
13019
|
// ../../node_modules/.bun/prompts@2.4.2/node_modules/prompts/dist/elements/text.js
|
|
13020
13020
|
var require_text = __commonJS((exports, module) => {
|
|
13021
|
-
function asyncGeneratorStep(gen,
|
|
13021
|
+
function asyncGeneratorStep(gen, resolve2, reject, _next, _throw, key, arg) {
|
|
13022
13022
|
try {
|
|
13023
13023
|
var info = gen[key](arg);
|
|
13024
13024
|
var value = info.value;
|
|
@@ -13027,7 +13027,7 @@ var require_text = __commonJS((exports, module) => {
|
|
|
13027
13027
|
return;
|
|
13028
13028
|
}
|
|
13029
13029
|
if (info.done) {
|
|
13030
|
-
|
|
13030
|
+
resolve2(value);
|
|
13031
13031
|
} else {
|
|
13032
13032
|
Promise.resolve(value).then(_next, _throw);
|
|
13033
13033
|
}
|
|
@@ -13035,13 +13035,13 @@ var require_text = __commonJS((exports, module) => {
|
|
|
13035
13035
|
function _asyncToGenerator(fn) {
|
|
13036
13036
|
return function() {
|
|
13037
13037
|
var self = this, args = arguments;
|
|
13038
|
-
return new Promise(function(
|
|
13038
|
+
return new Promise(function(resolve2, reject) {
|
|
13039
13039
|
var gen = fn.apply(self, args);
|
|
13040
13040
|
function _next(value) {
|
|
13041
|
-
asyncGeneratorStep(gen,
|
|
13041
|
+
asyncGeneratorStep(gen, resolve2, reject, _next, _throw, "next", value);
|
|
13042
13042
|
}
|
|
13043
13043
|
function _throw(err) {
|
|
13044
|
-
asyncGeneratorStep(gen,
|
|
13044
|
+
asyncGeneratorStep(gen, resolve2, reject, _next, _throw, "throw", err);
|
|
13045
13045
|
}
|
|
13046
13046
|
_next(undefined);
|
|
13047
13047
|
});
|
|
@@ -13755,7 +13755,7 @@ var require_dateparts = __commonJS((exports, module) => {
|
|
|
13755
13755
|
|
|
13756
13756
|
// ../../node_modules/.bun/prompts@2.4.2/node_modules/prompts/dist/elements/date.js
|
|
13757
13757
|
var require_date = __commonJS((exports, module) => {
|
|
13758
|
-
function asyncGeneratorStep(gen,
|
|
13758
|
+
function asyncGeneratorStep(gen, resolve2, reject, _next, _throw, key, arg) {
|
|
13759
13759
|
try {
|
|
13760
13760
|
var info = gen[key](arg);
|
|
13761
13761
|
var value = info.value;
|
|
@@ -13764,7 +13764,7 @@ var require_date = __commonJS((exports, module) => {
|
|
|
13764
13764
|
return;
|
|
13765
13765
|
}
|
|
13766
13766
|
if (info.done) {
|
|
13767
|
-
|
|
13767
|
+
resolve2(value);
|
|
13768
13768
|
} else {
|
|
13769
13769
|
Promise.resolve(value).then(_next, _throw);
|
|
13770
13770
|
}
|
|
@@ -13772,13 +13772,13 @@ var require_date = __commonJS((exports, module) => {
|
|
|
13772
13772
|
function _asyncToGenerator(fn) {
|
|
13773
13773
|
return function() {
|
|
13774
13774
|
var self = this, args = arguments;
|
|
13775
|
-
return new Promise(function(
|
|
13775
|
+
return new Promise(function(resolve2, reject) {
|
|
13776
13776
|
var gen = fn.apply(self, args);
|
|
13777
13777
|
function _next(value) {
|
|
13778
|
-
asyncGeneratorStep(gen,
|
|
13778
|
+
asyncGeneratorStep(gen, resolve2, reject, _next, _throw, "next", value);
|
|
13779
13779
|
}
|
|
13780
13780
|
function _throw(err) {
|
|
13781
|
-
asyncGeneratorStep(gen,
|
|
13781
|
+
asyncGeneratorStep(gen, resolve2, reject, _next, _throw, "throw", err);
|
|
13782
13782
|
}
|
|
13783
13783
|
_next(undefined);
|
|
13784
13784
|
});
|
|
@@ -13982,7 +13982,7 @@ ${i ? ` ` : figures.pointerSmall} ${color.red().italic(l)}`, ``);
|
|
|
13982
13982
|
|
|
13983
13983
|
// ../../node_modules/.bun/prompts@2.4.2/node_modules/prompts/dist/elements/number.js
|
|
13984
13984
|
var require_number = __commonJS((exports, module) => {
|
|
13985
|
-
function asyncGeneratorStep(gen,
|
|
13985
|
+
function asyncGeneratorStep(gen, resolve2, reject, _next, _throw, key, arg) {
|
|
13986
13986
|
try {
|
|
13987
13987
|
var info = gen[key](arg);
|
|
13988
13988
|
var value = info.value;
|
|
@@ -13991,7 +13991,7 @@ var require_number = __commonJS((exports, module) => {
|
|
|
13991
13991
|
return;
|
|
13992
13992
|
}
|
|
13993
13993
|
if (info.done) {
|
|
13994
|
-
|
|
13994
|
+
resolve2(value);
|
|
13995
13995
|
} else {
|
|
13996
13996
|
Promise.resolve(value).then(_next, _throw);
|
|
13997
13997
|
}
|
|
@@ -13999,13 +13999,13 @@ var require_number = __commonJS((exports, module) => {
|
|
|
13999
13999
|
function _asyncToGenerator(fn) {
|
|
14000
14000
|
return function() {
|
|
14001
14001
|
var self = this, args = arguments;
|
|
14002
|
-
return new Promise(function(
|
|
14002
|
+
return new Promise(function(resolve2, reject) {
|
|
14003
14003
|
var gen = fn.apply(self, args);
|
|
14004
14004
|
function _next(value) {
|
|
14005
|
-
asyncGeneratorStep(gen,
|
|
14005
|
+
asyncGeneratorStep(gen, resolve2, reject, _next, _throw, "next", value);
|
|
14006
14006
|
}
|
|
14007
14007
|
function _throw(err) {
|
|
14008
|
-
asyncGeneratorStep(gen,
|
|
14008
|
+
asyncGeneratorStep(gen, resolve2, reject, _next, _throw, "throw", err);
|
|
14009
14009
|
}
|
|
14010
14010
|
_next(undefined);
|
|
14011
14011
|
});
|
|
@@ -14441,7 +14441,7 @@ Instructions:
|
|
|
14441
14441
|
|
|
14442
14442
|
// ../../node_modules/.bun/prompts@2.4.2/node_modules/prompts/dist/elements/autocomplete.js
|
|
14443
14443
|
var require_autocomplete = __commonJS((exports, module) => {
|
|
14444
|
-
function asyncGeneratorStep(gen,
|
|
14444
|
+
function asyncGeneratorStep(gen, resolve2, reject, _next, _throw, key, arg) {
|
|
14445
14445
|
try {
|
|
14446
14446
|
var info = gen[key](arg);
|
|
14447
14447
|
var value = info.value;
|
|
@@ -14450,7 +14450,7 @@ var require_autocomplete = __commonJS((exports, module) => {
|
|
|
14450
14450
|
return;
|
|
14451
14451
|
}
|
|
14452
14452
|
if (info.done) {
|
|
14453
|
-
|
|
14453
|
+
resolve2(value);
|
|
14454
14454
|
} else {
|
|
14455
14455
|
Promise.resolve(value).then(_next, _throw);
|
|
14456
14456
|
}
|
|
@@ -14458,13 +14458,13 @@ var require_autocomplete = __commonJS((exports, module) => {
|
|
|
14458
14458
|
function _asyncToGenerator(fn) {
|
|
14459
14459
|
return function() {
|
|
14460
14460
|
var self = this, args = arguments;
|
|
14461
|
-
return new Promise(function(
|
|
14461
|
+
return new Promise(function(resolve2, reject) {
|
|
14462
14462
|
var gen = fn.apply(self, args);
|
|
14463
14463
|
function _next(value) {
|
|
14464
|
-
asyncGeneratorStep(gen,
|
|
14464
|
+
asyncGeneratorStep(gen, resolve2, reject, _next, _throw, "next", value);
|
|
14465
14465
|
}
|
|
14466
14466
|
function _throw(err) {
|
|
14467
|
-
asyncGeneratorStep(gen,
|
|
14467
|
+
asyncGeneratorStep(gen, resolve2, reject, _next, _throw, "throw", err);
|
|
14468
14468
|
}
|
|
14469
14469
|
_next(undefined);
|
|
14470
14470
|
});
|
|
@@ -15122,7 +15122,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
15122
15122
|
arr2[i] = arr[i];
|
|
15123
15123
|
return arr2;
|
|
15124
15124
|
}
|
|
15125
|
-
function asyncGeneratorStep(gen,
|
|
15125
|
+
function asyncGeneratorStep(gen, resolve2, reject, _next, _throw, key, arg) {
|
|
15126
15126
|
try {
|
|
15127
15127
|
var info = gen[key](arg);
|
|
15128
15128
|
var value = info.value;
|
|
@@ -15131,7 +15131,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
15131
15131
|
return;
|
|
15132
15132
|
}
|
|
15133
15133
|
if (info.done) {
|
|
15134
|
-
|
|
15134
|
+
resolve2(value);
|
|
15135
15135
|
} else {
|
|
15136
15136
|
Promise.resolve(value).then(_next, _throw);
|
|
15137
15137
|
}
|
|
@@ -15139,13 +15139,13 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
15139
15139
|
function _asyncToGenerator(fn) {
|
|
15140
15140
|
return function() {
|
|
15141
15141
|
var self = this, args = arguments;
|
|
15142
|
-
return new Promise(function(
|
|
15142
|
+
return new Promise(function(resolve2, reject) {
|
|
15143
15143
|
var gen = fn.apply(self, args);
|
|
15144
15144
|
function _next(value) {
|
|
15145
|
-
asyncGeneratorStep(gen,
|
|
15145
|
+
asyncGeneratorStep(gen, resolve2, reject, _next, _throw, "next", value);
|
|
15146
15146
|
}
|
|
15147
15147
|
function _throw(err) {
|
|
15148
|
-
asyncGeneratorStep(gen,
|
|
15148
|
+
asyncGeneratorStep(gen, resolve2, reject, _next, _throw, "throw", err);
|
|
15149
15149
|
}
|
|
15150
15150
|
_next(undefined);
|
|
15151
15151
|
});
|
|
@@ -19926,7 +19926,7 @@ class Conf {
|
|
|
19926
19926
|
|
|
19927
19927
|
// src/lib/config.ts
|
|
19928
19928
|
import { homedir as homedir2 } from "os";
|
|
19929
|
-
import { join } from "path";
|
|
19929
|
+
import { join, dirname, resolve } from "path";
|
|
19930
19930
|
import { existsSync, mkdirSync, writeFileSync as writeFileSync2 } from "fs";
|
|
19931
19931
|
var defaultConfig = {
|
|
19932
19932
|
version: "0.1.0",
|
|
@@ -20014,13 +20014,16 @@ function ensureSkillsDir(dir) {
|
|
|
20014
20014
|
}
|
|
20015
20015
|
}
|
|
20016
20016
|
function findProjectRoot(startDir = process.cwd()) {
|
|
20017
|
-
let currentDir = startDir;
|
|
20018
|
-
|
|
20019
|
-
while (currentDir !== root) {
|
|
20017
|
+
let currentDir = resolve(startDir);
|
|
20018
|
+
while (true) {
|
|
20020
20019
|
if (existsSync(join(currentDir, LOCAL_CONFIG_DIR, LOCAL_CONFIG_FILE))) {
|
|
20021
20020
|
return currentDir;
|
|
20022
20021
|
}
|
|
20023
|
-
|
|
20022
|
+
const parentDir = dirname(currentDir);
|
|
20023
|
+
if (parentDir === currentDir) {
|
|
20024
|
+
break;
|
|
20025
|
+
}
|
|
20026
|
+
currentDir = parentDir;
|
|
20024
20027
|
}
|
|
20025
20028
|
return null;
|
|
20026
20029
|
}
|
|
@@ -20031,6 +20034,23 @@ function getProjectSkillsOutputDir(startDir = process.cwd()) {
|
|
|
20031
20034
|
}
|
|
20032
20035
|
return null;
|
|
20033
20036
|
}
|
|
20037
|
+
function isValidSlug(slug) {
|
|
20038
|
+
if (!slug || typeof slug !== "string") {
|
|
20039
|
+
return false;
|
|
20040
|
+
}
|
|
20041
|
+
const validSlugPattern = /^[a-zA-Z0-9][a-zA-Z0-9_-]*$/;
|
|
20042
|
+
return validSlugPattern.test(slug) && slug.length <= 64;
|
|
20043
|
+
}
|
|
20044
|
+
function getSkillsDir(options = {}) {
|
|
20045
|
+
const target = options.target ?? getDefaultTarget();
|
|
20046
|
+
if (options.local) {
|
|
20047
|
+
const projectRoot = findProjectRoot();
|
|
20048
|
+
if (projectRoot) {
|
|
20049
|
+
return target === "claude" ? getProjectClaudeSkillsDir(projectRoot) : getProjectCodexSkillsDir(projectRoot);
|
|
20050
|
+
}
|
|
20051
|
+
}
|
|
20052
|
+
return target === "claude" ? getClaudeSkillsDir() : getCodexSkillsDir();
|
|
20053
|
+
}
|
|
20034
20054
|
|
|
20035
20055
|
// src/commands/init.ts
|
|
20036
20056
|
async function initCommand(options = {}) {
|
|
@@ -20557,19 +20577,19 @@ var baseOpen = async (options) => {
|
|
|
20557
20577
|
}
|
|
20558
20578
|
const subprocess = childProcess3.spawn(command, cliArguments, childProcessOptions);
|
|
20559
20579
|
if (options.wait) {
|
|
20560
|
-
return new Promise((
|
|
20580
|
+
return new Promise((resolve2, reject) => {
|
|
20561
20581
|
subprocess.once("error", reject);
|
|
20562
20582
|
subprocess.once("close", (exitCode) => {
|
|
20563
20583
|
if (!options.allowNonzeroExitCode && exitCode !== 0) {
|
|
20564
20584
|
reject(new Error(`Exited with code ${exitCode}`));
|
|
20565
20585
|
return;
|
|
20566
20586
|
}
|
|
20567
|
-
|
|
20587
|
+
resolve2(subprocess);
|
|
20568
20588
|
});
|
|
20569
20589
|
});
|
|
20570
20590
|
}
|
|
20571
20591
|
if (isFallbackAttempt) {
|
|
20572
|
-
return new Promise((
|
|
20592
|
+
return new Promise((resolve2, reject) => {
|
|
20573
20593
|
subprocess.once("error", reject);
|
|
20574
20594
|
subprocess.once("spawn", () => {
|
|
20575
20595
|
subprocess.once("close", (exitCode) => {
|
|
@@ -20579,17 +20599,17 @@ var baseOpen = async (options) => {
|
|
|
20579
20599
|
return;
|
|
20580
20600
|
}
|
|
20581
20601
|
subprocess.unref();
|
|
20582
|
-
|
|
20602
|
+
resolve2(subprocess);
|
|
20583
20603
|
});
|
|
20584
20604
|
});
|
|
20585
20605
|
});
|
|
20586
20606
|
}
|
|
20587
20607
|
subprocess.unref();
|
|
20588
|
-
return new Promise((
|
|
20608
|
+
return new Promise((resolve2, reject) => {
|
|
20589
20609
|
subprocess.once("error", reject);
|
|
20590
20610
|
subprocess.once("spawn", () => {
|
|
20591
20611
|
subprocess.off("error", reject);
|
|
20592
|
-
|
|
20612
|
+
resolve2(subprocess);
|
|
20593
20613
|
});
|
|
20594
20614
|
});
|
|
20595
20615
|
};
|
|
@@ -20675,25 +20695,40 @@ async function apiRequest(path6, options = {}) {
|
|
|
20675
20695
|
if (apiKey) {
|
|
20676
20696
|
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
20677
20697
|
}
|
|
20698
|
+
let response;
|
|
20678
20699
|
try {
|
|
20679
|
-
|
|
20700
|
+
response = await fetch(`${endpoint}${path6}`, {
|
|
20680
20701
|
...options,
|
|
20681
20702
|
headers
|
|
20682
20703
|
});
|
|
20683
|
-
|
|
20704
|
+
} catch (error) {
|
|
20705
|
+
return {
|
|
20706
|
+
error: error instanceof Error ? error.message : "Network error",
|
|
20707
|
+
status: 0
|
|
20708
|
+
};
|
|
20709
|
+
}
|
|
20710
|
+
let data;
|
|
20711
|
+
try {
|
|
20712
|
+
data = await response.json();
|
|
20713
|
+
} catch {
|
|
20684
20714
|
if (!response.ok) {
|
|
20685
20715
|
return {
|
|
20686
|
-
error:
|
|
20716
|
+
error: `Server error: ${response.status} ${response.statusText}`,
|
|
20687
20717
|
status: response.status
|
|
20688
20718
|
};
|
|
20689
20719
|
}
|
|
20690
|
-
return { data, status: response.status };
|
|
20691
|
-
} catch (error) {
|
|
20692
20720
|
return {
|
|
20693
|
-
error:
|
|
20694
|
-
status:
|
|
20721
|
+
error: "Invalid response from server",
|
|
20722
|
+
status: response.status
|
|
20723
|
+
};
|
|
20724
|
+
}
|
|
20725
|
+
if (!response.ok) {
|
|
20726
|
+
return {
|
|
20727
|
+
error: data.error || `Request failed: ${response.status}`,
|
|
20728
|
+
status: response.status
|
|
20695
20729
|
};
|
|
20696
20730
|
}
|
|
20731
|
+
return { data, status: response.status };
|
|
20697
20732
|
}
|
|
20698
20733
|
async function searchSkills(query) {
|
|
20699
20734
|
return apiRequest(`/skills?q=${encodeURIComponent(query)}`);
|
|
@@ -20706,9 +20741,27 @@ async function getMarketplaceSkills(options) {
|
|
|
20706
20741
|
params.set("page", options.page.toString());
|
|
20707
20742
|
if (options?.category)
|
|
20708
20743
|
params.set("category", options.category);
|
|
20744
|
+
if (options?.tag)
|
|
20745
|
+
params.set("tag", options.tag);
|
|
20709
20746
|
const query = params.toString();
|
|
20710
20747
|
return apiRequest(`/skills${query ? `?${query}` : ""}`);
|
|
20711
20748
|
}
|
|
20749
|
+
async function getSkillsByTag(tag) {
|
|
20750
|
+
const allSkills = [];
|
|
20751
|
+
let page = 1;
|
|
20752
|
+
const limit = 100;
|
|
20753
|
+
let totalPages = 1;
|
|
20754
|
+
while (page <= totalPages) {
|
|
20755
|
+
const result = await getMarketplaceSkills({ page, limit, tag });
|
|
20756
|
+
if (result.error || !result.data) {
|
|
20757
|
+
return { error: result.error || "Failed to fetch skills", status: result.status };
|
|
20758
|
+
}
|
|
20759
|
+
allSkills.push(...result.data.skills);
|
|
20760
|
+
totalPages = result.data.pagination.totalPages;
|
|
20761
|
+
page++;
|
|
20762
|
+
}
|
|
20763
|
+
return { data: { skills: allSkills, total: allSkills.length }, status: 200 };
|
|
20764
|
+
}
|
|
20712
20765
|
async function getAllMarketplaceSkills() {
|
|
20713
20766
|
const allSkills = [];
|
|
20714
20767
|
let page = 1;
|
|
@@ -20793,6 +20846,52 @@ async function makeApiRequest(path6, options = {}) {
|
|
|
20793
20846
|
headers
|
|
20794
20847
|
});
|
|
20795
20848
|
}
|
|
20849
|
+
async function listSchedules(options) {
|
|
20850
|
+
const params = new URLSearchParams;
|
|
20851
|
+
if (options?.status)
|
|
20852
|
+
params.set("status", options.status);
|
|
20853
|
+
if (options?.skill)
|
|
20854
|
+
params.set("skill", options.skill);
|
|
20855
|
+
if (options?.search)
|
|
20856
|
+
params.set("search", options.search);
|
|
20857
|
+
if (options?.limit)
|
|
20858
|
+
params.set("limit", options.limit.toString());
|
|
20859
|
+
if (options?.offset)
|
|
20860
|
+
params.set("offset", options.offset.toString());
|
|
20861
|
+
const query = params.toString();
|
|
20862
|
+
return apiRequest(`/schedules${query ? `?${query}` : ""}`);
|
|
20863
|
+
}
|
|
20864
|
+
async function getSchedule(id) {
|
|
20865
|
+
return apiRequest(`/schedules/${id}`);
|
|
20866
|
+
}
|
|
20867
|
+
async function createSchedule(input) {
|
|
20868
|
+
return apiRequest("/schedules", {
|
|
20869
|
+
method: "POST",
|
|
20870
|
+
body: JSON.stringify(input)
|
|
20871
|
+
});
|
|
20872
|
+
}
|
|
20873
|
+
async function updateSchedule(id, input) {
|
|
20874
|
+
return apiRequest(`/schedules/${id}`, {
|
|
20875
|
+
method: "PATCH",
|
|
20876
|
+
body: JSON.stringify(input)
|
|
20877
|
+
});
|
|
20878
|
+
}
|
|
20879
|
+
async function deleteSchedule(id) {
|
|
20880
|
+
return apiRequest(`/schedules/${id}`, {
|
|
20881
|
+
method: "DELETE"
|
|
20882
|
+
});
|
|
20883
|
+
}
|
|
20884
|
+
async function getScheduleRuns(id, options) {
|
|
20885
|
+
const params = new URLSearchParams;
|
|
20886
|
+
if (options?.status)
|
|
20887
|
+
params.set("status", options.status);
|
|
20888
|
+
if (options?.limit)
|
|
20889
|
+
params.set("limit", options.limit.toString());
|
|
20890
|
+
if (options?.offset)
|
|
20891
|
+
params.set("offset", options.offset.toString());
|
|
20892
|
+
const query = params.toString();
|
|
20893
|
+
return apiRequest(`/schedules/${id}/runs${query ? `?${query}` : ""}`);
|
|
20894
|
+
}
|
|
20796
20895
|
|
|
20797
20896
|
// src/commands/login.ts
|
|
20798
20897
|
async function loginCommand(options = {}) {
|
|
@@ -20985,7 +21084,7 @@ async function whoamiCommand() {
|
|
|
20985
21084
|
console.log();
|
|
20986
21085
|
}
|
|
20987
21086
|
function sleep(ms) {
|
|
20988
|
-
return new Promise((
|
|
21087
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
20989
21088
|
}
|
|
20990
21089
|
|
|
20991
21090
|
// src/commands/search.ts
|
|
@@ -21133,10 +21232,14 @@ async function installCommand(slug, options = {}) {
|
|
|
21133
21232
|
if (options.all) {
|
|
21134
21233
|
return installAllSkills(options);
|
|
21135
21234
|
}
|
|
21235
|
+
if (options.tag) {
|
|
21236
|
+
return installSkillsByTag(options.tag, options);
|
|
21237
|
+
}
|
|
21136
21238
|
if (!slug || slug.trim() === "") {
|
|
21137
21239
|
console.log(colors.warning("Please provide a skill name"));
|
|
21138
21240
|
console.log(colors.dim("Usage: skills install <name>"));
|
|
21139
21241
|
console.log(colors.dim(" skills install --all"));
|
|
21242
|
+
console.log(colors.dim(" skills install --tag <tag-name>"));
|
|
21140
21243
|
return;
|
|
21141
21244
|
}
|
|
21142
21245
|
const isLocal = options.local ?? false;
|
|
@@ -21299,6 +21402,141 @@ async function installAllSkills(options) {
|
|
|
21299
21402
|
console.error(colors.error(error instanceof Error ? error.message : "Unknown error"));
|
|
21300
21403
|
}
|
|
21301
21404
|
}
|
|
21405
|
+
async function installSkillsByTag(tag, options) {
|
|
21406
|
+
const isLocal = options.local ?? false;
|
|
21407
|
+
const target = options.target ?? getDefaultTarget();
|
|
21408
|
+
const apiKey = getApiKey();
|
|
21409
|
+
let installDir;
|
|
21410
|
+
if (isLocal) {
|
|
21411
|
+
const projectRoot = findProjectRoot();
|
|
21412
|
+
if (!projectRoot) {
|
|
21413
|
+
console.log(colors.warning("Not in a skills.md project"));
|
|
21414
|
+
console.log(colors.dim("Run `skills init` first or install globally (default)"));
|
|
21415
|
+
return;
|
|
21416
|
+
}
|
|
21417
|
+
installDir = target === "claude" ? getProjectClaudeSkillsDir(projectRoot) : getProjectCodexSkillsDir(projectRoot);
|
|
21418
|
+
} else {
|
|
21419
|
+
installDir = target === "claude" ? getClaudeSkillsDir() : getCodexSkillsDir();
|
|
21420
|
+
}
|
|
21421
|
+
banner(`Installing Skills by Tag: ${tag}`);
|
|
21422
|
+
const fetchSpinner = ora({
|
|
21423
|
+
text: `Fetching skills with tag "${tag}"...`,
|
|
21424
|
+
color: "magenta"
|
|
21425
|
+
}).start();
|
|
21426
|
+
try {
|
|
21427
|
+
const result = await getSkillsByTag(tag);
|
|
21428
|
+
if (result.error || !result.data) {
|
|
21429
|
+
fetchSpinner.fail(colors.error("Failed to fetch skills"));
|
|
21430
|
+
console.error(colors.error(result.error || "Could not fetch skills by tag"));
|
|
21431
|
+
return;
|
|
21432
|
+
}
|
|
21433
|
+
const skills = result.data.skills;
|
|
21434
|
+
const total = skills.length;
|
|
21435
|
+
if (total === 0) {
|
|
21436
|
+
fetchSpinner.warn(colors.warning(`No skills found with tag "${tag}"`));
|
|
21437
|
+
console.log();
|
|
21438
|
+
console.log(colors.dim("Try searching for available tags in the marketplace:"));
|
|
21439
|
+
console.log(` ${command("skills marketplace")}`);
|
|
21440
|
+
return;
|
|
21441
|
+
}
|
|
21442
|
+
fetchSpinner.succeed(colors.success(`Found ${count(total)} skill${total !== 1 ? "s" : ""} with tag "${tag}"`));
|
|
21443
|
+
console.log();
|
|
21444
|
+
console.log(keyValue("Tag", colors.primaryBold(tag)));
|
|
21445
|
+
console.log(keyValue("Target", colors.primaryBold(target)));
|
|
21446
|
+
console.log(keyValue("Scope", colors.primaryBold(isLocal ? "project" : "global")));
|
|
21447
|
+
console.log(keyValue("Directory", path6(installDir)));
|
|
21448
|
+
console.log();
|
|
21449
|
+
console.log(colors.dim("Skills to install:"));
|
|
21450
|
+
const displayCount = Math.min(skills.length, 15);
|
|
21451
|
+
for (let i = 0;i < displayCount; i++) {
|
|
21452
|
+
console.log(` ${colors.primary(symbols.bullet)} ${skillName(skills[i].name)} ${colors.dim(`(${skills[i].slug})`)}`);
|
|
21453
|
+
}
|
|
21454
|
+
if (skills.length > displayCount) {
|
|
21455
|
+
console.log(colors.dim(` ... and ${skills.length - displayCount} more`));
|
|
21456
|
+
}
|
|
21457
|
+
console.log();
|
|
21458
|
+
if (!options.force) {
|
|
21459
|
+
const prompts2 = (await Promise.resolve().then(() => __toESM(require_prompts3(), 1))).default;
|
|
21460
|
+
const response = await prompts2({
|
|
21461
|
+
type: "confirm",
|
|
21462
|
+
name: "confirm",
|
|
21463
|
+
message: `Install ${total} skill${total !== 1 ? "s" : ""} with tag "${tag}"?`,
|
|
21464
|
+
initial: true
|
|
21465
|
+
});
|
|
21466
|
+
if (!response.confirm) {
|
|
21467
|
+
console.log(colors.dim("Cancelled"));
|
|
21468
|
+
return;
|
|
21469
|
+
}
|
|
21470
|
+
console.log();
|
|
21471
|
+
}
|
|
21472
|
+
const results = {
|
|
21473
|
+
success: [],
|
|
21474
|
+
failed: [],
|
|
21475
|
+
skipped: []
|
|
21476
|
+
};
|
|
21477
|
+
for (let i = 0;i < skills.length; i++) {
|
|
21478
|
+
const skill = skills[i];
|
|
21479
|
+
const current = i + 1;
|
|
21480
|
+
const percent = Math.round(current / total * 100);
|
|
21481
|
+
const padWidth = String(total).length;
|
|
21482
|
+
const progress = `[${String(current).padStart(padWidth, " ")}/${total}]`;
|
|
21483
|
+
process.stdout.write(`\r${colors.dim(progress)} ${progressBar(percent)} ${colors.dim(`${percent}%`)} Installing ${colors.primary(skill.slug)}...`);
|
|
21484
|
+
process.stdout.write("\x1B[K");
|
|
21485
|
+
try {
|
|
21486
|
+
const skillResult = await installSkill(skill.slug);
|
|
21487
|
+
if (skillResult.error || !skillResult.data) {
|
|
21488
|
+
results.failed.push({ slug: skill.slug, error: skillResult.error || "Not found" });
|
|
21489
|
+
continue;
|
|
21490
|
+
}
|
|
21491
|
+
const skillData = skillResult.data;
|
|
21492
|
+
const skillDir = join3(installDir, `skill-${skill.slug}`);
|
|
21493
|
+
const exportsDir = join3(skillDir, "exports");
|
|
21494
|
+
const logsDir = join3(skillDir, "logs");
|
|
21495
|
+
ensureSkillsDir(skillDir);
|
|
21496
|
+
ensureSkillsDir(exportsDir);
|
|
21497
|
+
ensureSkillsDir(logsDir);
|
|
21498
|
+
writeFileSync3(join3(skillDir, "SKILL.md"), addSkillsMdMarker(skillData.skillMdContent));
|
|
21499
|
+
if (apiKey) {
|
|
21500
|
+
try {
|
|
21501
|
+
await installSkillRemote(skill.slug);
|
|
21502
|
+
} catch {}
|
|
21503
|
+
}
|
|
21504
|
+
results.success.push(skill.slug);
|
|
21505
|
+
} catch (error) {
|
|
21506
|
+
results.failed.push({
|
|
21507
|
+
slug: skill.slug,
|
|
21508
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
21509
|
+
});
|
|
21510
|
+
}
|
|
21511
|
+
}
|
|
21512
|
+
process.stdout.write("\r\x1B[K");
|
|
21513
|
+
completionBanner("Installation Complete");
|
|
21514
|
+
if (results.success.length > 0) {
|
|
21515
|
+
console.log(successItem(`Successfully installed: ${colors.successBold(String(results.success.length))} skills`));
|
|
21516
|
+
}
|
|
21517
|
+
if (results.failed.length > 0) {
|
|
21518
|
+
console.log(errorItem(`Failed to install: ${colors.errorBold(String(results.failed.length))} skills`));
|
|
21519
|
+
console.log();
|
|
21520
|
+
console.log(colors.dim("Failed skills:"));
|
|
21521
|
+
for (const fail of results.failed.slice(0, 10)) {
|
|
21522
|
+
console.log(colors.error(` ${symbols.bullet} ${fail.slug}: ${fail.error}`));
|
|
21523
|
+
}
|
|
21524
|
+
if (results.failed.length > 10) {
|
|
21525
|
+
console.log(colors.dim(` ... and ${results.failed.length - 10} more`));
|
|
21526
|
+
}
|
|
21527
|
+
}
|
|
21528
|
+
console.log();
|
|
21529
|
+
console.log(colors.dim("Installation directory:"));
|
|
21530
|
+
console.log(` ${path6(installDir)}`);
|
|
21531
|
+
console.log();
|
|
21532
|
+
console.log(colors.dim("Run any skill with:"));
|
|
21533
|
+
console.log(` ${command('skills run <skill-name> -- "your prompt"')}`);
|
|
21534
|
+
console.log();
|
|
21535
|
+
} catch (error) {
|
|
21536
|
+
fetchSpinner.fail(colors.error("Installation failed"));
|
|
21537
|
+
console.error(colors.error(error instanceof Error ? error.message : "Unknown error"));
|
|
21538
|
+
}
|
|
21539
|
+
}
|
|
21302
21540
|
function getInstalledSkillsWithStatus(installDir) {
|
|
21303
21541
|
const { readdirSync, statSync } = __require("fs");
|
|
21304
21542
|
if (!existsSync3(installDir)) {
|
|
@@ -21608,7 +21846,7 @@ async function uninstallAllSkills(installDir, target, isLocal, force) {
|
|
|
21608
21846
|
|
|
21609
21847
|
// src/commands/download.ts
|
|
21610
21848
|
import { existsSync as existsSync4, mkdirSync as mkdirSync3, writeFileSync as writeFileSync4 } from "fs";
|
|
21611
|
-
import { join as join4, normalize, basename, dirname, isAbsolute } from "path";
|
|
21849
|
+
import { join as join4, normalize, basename, dirname as dirname2, isAbsolute } from "path";
|
|
21612
21850
|
var indigo2 = source_default.hex("#6366f1");
|
|
21613
21851
|
function validateFilename(filename) {
|
|
21614
21852
|
if (!filename || filename.trim() === "") {
|
|
@@ -21747,7 +21985,7 @@ async function downloadCommand(slug, options = {}) {
|
|
|
21747
21985
|
filesSkipped++;
|
|
21748
21986
|
continue;
|
|
21749
21987
|
}
|
|
21750
|
-
const parentDir =
|
|
21988
|
+
const parentDir = dirname2(safePath);
|
|
21751
21989
|
if (!existsSync4(parentDir)) {
|
|
21752
21990
|
mkdirSync3(parentDir, { recursive: true });
|
|
21753
21991
|
}
|
|
@@ -22306,21 +22544,25 @@ function findLocalSkill(skillName2) {
|
|
|
22306
22544
|
}
|
|
22307
22545
|
return null;
|
|
22308
22546
|
}
|
|
22547
|
+
function escapeShellArg(arg) {
|
|
22548
|
+
return `'${arg.replace(/'/g, "'\\''")}'`;
|
|
22549
|
+
}
|
|
22309
22550
|
async function runLocalSkill(skillDir, args) {
|
|
22310
|
-
return new Promise((
|
|
22551
|
+
return new Promise((resolve2) => {
|
|
22311
22552
|
const skillMdPath = join7(skillDir, "SKILL.md");
|
|
22312
22553
|
if (!existsSync7(skillMdPath)) {
|
|
22313
|
-
|
|
22554
|
+
resolve2(false);
|
|
22314
22555
|
return;
|
|
22315
22556
|
}
|
|
22316
22557
|
const content = __require("fs").readFileSync(skillMdPath, "utf-8");
|
|
22317
22558
|
const match = content.match(/scripts:\s*\n\s*run:\s*(.+)/);
|
|
22318
22559
|
if (!match) {
|
|
22319
|
-
|
|
22560
|
+
resolve2(false);
|
|
22320
22561
|
return;
|
|
22321
22562
|
}
|
|
22322
22563
|
const runScript = match[1].trim();
|
|
22323
|
-
const
|
|
22564
|
+
const escapedArgs = args.map(escapeShellArg);
|
|
22565
|
+
const fullCommand = args.length > 0 ? `${runScript} ${escapedArgs.join(" ")}` : runScript;
|
|
22324
22566
|
const projectRoot = findProjectRoot();
|
|
22325
22567
|
const skillsOutputDir = projectRoot ? join7(projectRoot, ".skills") : null;
|
|
22326
22568
|
const child = spawn(fullCommand, {
|
|
@@ -22335,8 +22577,11 @@ async function runLocalSkill(skillDir, args) {
|
|
|
22335
22577
|
SKILLS_OUTPUT_DIR: skillsOutputDir || ""
|
|
22336
22578
|
}
|
|
22337
22579
|
});
|
|
22338
|
-
child.on("error", () =>
|
|
22339
|
-
|
|
22580
|
+
child.on("error", (err) => {
|
|
22581
|
+
console.error("Skill execution error:", err.message);
|
|
22582
|
+
resolve2(false);
|
|
22583
|
+
});
|
|
22584
|
+
child.on("exit", (code) => resolve2(code === 0));
|
|
22340
22585
|
});
|
|
22341
22586
|
}
|
|
22342
22587
|
async function generateCommand(mediaType, prompt, options = {}) {
|
|
@@ -22683,8 +22928,12 @@ async function localHistoryCommand(options) {
|
|
|
22683
22928
|
}
|
|
22684
22929
|
}
|
|
22685
22930
|
async function exportsCommand(slug, options = {}) {
|
|
22686
|
-
|
|
22687
|
-
|
|
22931
|
+
if (!isValidSlug(slug)) {
|
|
22932
|
+
console.log(source_default.red(`Invalid skill name: "${slug}"`));
|
|
22933
|
+
console.log(source_default.dim("Skill names can only contain letters, numbers, hyphens, and underscores"));
|
|
22934
|
+
return;
|
|
22935
|
+
}
|
|
22936
|
+
const skillsDir = getSkillsDir({ target: options.target });
|
|
22688
22937
|
let skillDir = join8(skillsDir, `skill-${slug}`);
|
|
22689
22938
|
if (!existsSync8(skillDir)) {
|
|
22690
22939
|
skillDir = join8(skillsDir, slug);
|
|
@@ -22723,8 +22972,12 @@ async function exportsCommand(slug, options = {}) {
|
|
|
22723
22972
|
console.log(source_default.dim(`Total: ${files.length} file(s)`));
|
|
22724
22973
|
}
|
|
22725
22974
|
async function logsCommand(slug, options = {}) {
|
|
22726
|
-
|
|
22727
|
-
|
|
22975
|
+
if (!isValidSlug(slug)) {
|
|
22976
|
+
console.log(source_default.red(`Invalid skill name: "${slug}"`));
|
|
22977
|
+
console.log(source_default.dim("Skill names can only contain letters, numbers, hyphens, and underscores"));
|
|
22978
|
+
return;
|
|
22979
|
+
}
|
|
22980
|
+
const skillsDir = getSkillsDir({ target: options.target });
|
|
22728
22981
|
let skillDir = join8(skillsDir, `skill-${slug}`);
|
|
22729
22982
|
if (!existsSync8(skillDir)) {
|
|
22730
22983
|
skillDir = join8(skillsDir, slug);
|
|
@@ -23739,10 +23992,383 @@ async function setupCommand(promptArg, options = {}) {
|
|
|
23739
23992
|
console.log(` ${command("skills list")}`);
|
|
23740
23993
|
}
|
|
23741
23994
|
|
|
23995
|
+
// src/commands/schedule.ts
|
|
23996
|
+
var indigo12 = source_default.hex("#6366f1");
|
|
23997
|
+
async function scheduleCreateCommand(skill, scheduleInput, options) {
|
|
23998
|
+
const apiKey = getApiKey();
|
|
23999
|
+
if (!apiKey) {
|
|
24000
|
+
console.log(source_default.red("Not logged in"));
|
|
24001
|
+
console.log(source_default.dim("Run `skills login` first"));
|
|
24002
|
+
return;
|
|
24003
|
+
}
|
|
24004
|
+
let scheduleConfig = {};
|
|
24005
|
+
if (options.cron) {
|
|
24006
|
+
scheduleConfig.cronExpression = options.cron;
|
|
24007
|
+
} else if (options.at) {
|
|
24008
|
+
scheduleConfig.scheduledAt = options.at;
|
|
24009
|
+
} else if (scheduleInput) {
|
|
24010
|
+
scheduleConfig.schedule = scheduleInput;
|
|
24011
|
+
} else {
|
|
24012
|
+
console.log(source_default.red("Please provide a schedule"));
|
|
24013
|
+
console.log(source_default.dim("Examples:"));
|
|
24014
|
+
console.log(source_default.dim(' skills schedule <skill> "every Monday at 9am"'));
|
|
24015
|
+
console.log(source_default.dim(' skills schedule <skill> --cron "0 9 * * 1"'));
|
|
24016
|
+
console.log(source_default.dim(' skills schedule <skill> --at "2025-01-15T09:00:00"'));
|
|
24017
|
+
return;
|
|
24018
|
+
}
|
|
24019
|
+
const spinner = ora("Creating schedule...").start();
|
|
24020
|
+
try {
|
|
24021
|
+
const result = await createSchedule({
|
|
24022
|
+
skillSlug: skill,
|
|
24023
|
+
name: options.name || `${skill} schedule`,
|
|
24024
|
+
...scheduleConfig,
|
|
24025
|
+
command: options.command,
|
|
24026
|
+
timezone: options.timezone || "UTC",
|
|
24027
|
+
maxRuns: options.maxRuns
|
|
24028
|
+
});
|
|
24029
|
+
if (result.error) {
|
|
24030
|
+
spinner.fail("Failed to create schedule");
|
|
24031
|
+
console.log(source_default.red(result.error));
|
|
24032
|
+
return;
|
|
24033
|
+
}
|
|
24034
|
+
spinner.succeed("Schedule created successfully");
|
|
24035
|
+
console.log();
|
|
24036
|
+
const schedule = result.data?.schedule;
|
|
24037
|
+
if (schedule) {
|
|
24038
|
+
printScheduleDetails(schedule);
|
|
24039
|
+
}
|
|
24040
|
+
} catch (error) {
|
|
24041
|
+
spinner.fail("Request failed");
|
|
24042
|
+
console.log(source_default.red(error instanceof Error ? error.message : "Unknown error"));
|
|
24043
|
+
}
|
|
24044
|
+
}
|
|
24045
|
+
async function scheduleListCommand(options = {}) {
|
|
24046
|
+
const apiKey = getApiKey();
|
|
24047
|
+
if (!apiKey) {
|
|
24048
|
+
console.log(source_default.red("Not logged in"));
|
|
24049
|
+
console.log(source_default.dim("Run `skills login` first"));
|
|
24050
|
+
return;
|
|
24051
|
+
}
|
|
24052
|
+
const spinner = ora("Fetching schedules...").start();
|
|
24053
|
+
try {
|
|
24054
|
+
const result = await listSchedules({
|
|
24055
|
+
status: options.status,
|
|
24056
|
+
skill: options.skill,
|
|
24057
|
+
limit: options.limit || 20
|
|
24058
|
+
});
|
|
24059
|
+
spinner.stop();
|
|
24060
|
+
if (result.error) {
|
|
24061
|
+
console.log(source_default.red(result.error));
|
|
24062
|
+
return;
|
|
24063
|
+
}
|
|
24064
|
+
const { schedules, stats } = result.data || { schedules: [], stats: { total: 0, active: 0, paused: 0, completed: 0, failed: 0, cancelled: 0 } };
|
|
24065
|
+
console.log();
|
|
24066
|
+
console.log(indigo12.bold("Scheduled Jobs"));
|
|
24067
|
+
console.log(source_default.dim(`Total: ${stats.total} | Active: ${stats.active} | Paused: ${stats.paused} | Completed: ${stats.completed} | Failed: ${stats.failed}`));
|
|
24068
|
+
console.log();
|
|
24069
|
+
if (schedules.length === 0) {
|
|
24070
|
+
console.log(source_default.dim("No schedules found"));
|
|
24071
|
+
console.log(source_default.dim('Create one with: skills schedule <skill> "every day at 9am"'));
|
|
24072
|
+
return;
|
|
24073
|
+
}
|
|
24074
|
+
for (const schedule of schedules) {
|
|
24075
|
+
printScheduleSummary(schedule);
|
|
24076
|
+
}
|
|
24077
|
+
console.log();
|
|
24078
|
+
console.log(source_default.dim("View all at: https://skills.md (go to your team dashboard)"));
|
|
24079
|
+
} catch (error) {
|
|
24080
|
+
spinner.fail("Request failed");
|
|
24081
|
+
console.log(source_default.red(error instanceof Error ? error.message : "Unknown error"));
|
|
24082
|
+
}
|
|
24083
|
+
}
|
|
24084
|
+
async function scheduleGetCommand(id) {
|
|
24085
|
+
const apiKey = getApiKey();
|
|
24086
|
+
if (!apiKey) {
|
|
24087
|
+
console.log(source_default.red("Not logged in"));
|
|
24088
|
+
console.log(source_default.dim("Run `skills login` first"));
|
|
24089
|
+
return;
|
|
24090
|
+
}
|
|
24091
|
+
const spinner = ora("Fetching schedule...").start();
|
|
24092
|
+
try {
|
|
24093
|
+
const result = await getSchedule(id);
|
|
24094
|
+
spinner.stop();
|
|
24095
|
+
if (result.error) {
|
|
24096
|
+
console.log(source_default.red(result.error));
|
|
24097
|
+
return;
|
|
24098
|
+
}
|
|
24099
|
+
const { schedule, recentRuns, stats } = result.data || {};
|
|
24100
|
+
if (!schedule) {
|
|
24101
|
+
console.log(source_default.red("Schedule not found"));
|
|
24102
|
+
return;
|
|
24103
|
+
}
|
|
24104
|
+
console.log();
|
|
24105
|
+
printScheduleDetails(schedule);
|
|
24106
|
+
if (stats) {
|
|
24107
|
+
console.log();
|
|
24108
|
+
console.log(indigo12.bold("Run Statistics"));
|
|
24109
|
+
console.log(` ${source_default.dim("Total Runs:")} ${stats.totalRuns}`);
|
|
24110
|
+
console.log(` ${source_default.dim("Successful:")} ${source_default.green(String(stats.successfulRuns))}`);
|
|
24111
|
+
console.log(` ${source_default.dim("Failed:")} ${source_default.red(String(stats.failedRuns))}`);
|
|
24112
|
+
console.log(` ${source_default.dim("Credits Used:")} ${indigo12(String(stats.totalCredits))}`);
|
|
24113
|
+
if (stats.avgDurationMs) {
|
|
24114
|
+
console.log(` ${source_default.dim("Avg Duration:")} ${formatDuration3(stats.avgDurationMs)}`);
|
|
24115
|
+
}
|
|
24116
|
+
}
|
|
24117
|
+
if (recentRuns && recentRuns.length > 0) {
|
|
24118
|
+
console.log();
|
|
24119
|
+
console.log(indigo12.bold("Recent Runs"));
|
|
24120
|
+
for (const run of recentRuns.slice(0, 5)) {
|
|
24121
|
+
printRunSummary(run);
|
|
24122
|
+
}
|
|
24123
|
+
}
|
|
24124
|
+
} catch (error) {
|
|
24125
|
+
spinner.fail("Request failed");
|
|
24126
|
+
console.log(source_default.red(error instanceof Error ? error.message : "Unknown error"));
|
|
24127
|
+
}
|
|
24128
|
+
}
|
|
24129
|
+
async function schedulePauseCommand(id) {
|
|
24130
|
+
const apiKey = getApiKey();
|
|
24131
|
+
if (!apiKey) {
|
|
24132
|
+
console.log(source_default.red("Not logged in"));
|
|
24133
|
+
console.log(source_default.dim("Run `skills login` first"));
|
|
24134
|
+
return;
|
|
24135
|
+
}
|
|
24136
|
+
const spinner = ora("Pausing schedule...").start();
|
|
24137
|
+
try {
|
|
24138
|
+
const result = await updateSchedule(id, { status: "paused" });
|
|
24139
|
+
if (result.error) {
|
|
24140
|
+
spinner.fail("Failed to pause schedule");
|
|
24141
|
+
console.log(source_default.red(result.error));
|
|
24142
|
+
return;
|
|
24143
|
+
}
|
|
24144
|
+
spinner.succeed("Schedule paused successfully");
|
|
24145
|
+
const schedule = result.data?.schedule;
|
|
24146
|
+
if (schedule) {
|
|
24147
|
+
console.log();
|
|
24148
|
+
console.log(` ${source_default.dim("Name:")} ${schedule.name}`);
|
|
24149
|
+
console.log(` ${source_default.dim("Status:")} ${formatStatus3(schedule.status)}`);
|
|
24150
|
+
}
|
|
24151
|
+
} catch (error) {
|
|
24152
|
+
spinner.fail("Request failed");
|
|
24153
|
+
console.log(source_default.red(error instanceof Error ? error.message : "Unknown error"));
|
|
24154
|
+
}
|
|
24155
|
+
}
|
|
24156
|
+
async function scheduleResumeCommand(id) {
|
|
24157
|
+
const apiKey = getApiKey();
|
|
24158
|
+
if (!apiKey) {
|
|
24159
|
+
console.log(source_default.red("Not logged in"));
|
|
24160
|
+
console.log(source_default.dim("Run `skills login` first"));
|
|
24161
|
+
return;
|
|
24162
|
+
}
|
|
24163
|
+
const spinner = ora("Resuming schedule...").start();
|
|
24164
|
+
try {
|
|
24165
|
+
const result = await updateSchedule(id, { status: "active" });
|
|
24166
|
+
if (result.error) {
|
|
24167
|
+
spinner.fail("Failed to resume schedule");
|
|
24168
|
+
console.log(source_default.red(result.error));
|
|
24169
|
+
return;
|
|
24170
|
+
}
|
|
24171
|
+
spinner.succeed("Schedule resumed successfully");
|
|
24172
|
+
const schedule = result.data?.schedule;
|
|
24173
|
+
if (schedule) {
|
|
24174
|
+
console.log();
|
|
24175
|
+
console.log(` ${source_default.dim("Name:")} ${schedule.name}`);
|
|
24176
|
+
console.log(` ${source_default.dim("Status:")} ${formatStatus3(schedule.status)}`);
|
|
24177
|
+
if (schedule.nextRunAt) {
|
|
24178
|
+
console.log(` ${source_default.dim("Next Run:")} ${formatDate(schedule.nextRunAt)}`);
|
|
24179
|
+
}
|
|
24180
|
+
}
|
|
24181
|
+
} catch (error) {
|
|
24182
|
+
spinner.fail("Request failed");
|
|
24183
|
+
console.log(source_default.red(error instanceof Error ? error.message : "Unknown error"));
|
|
24184
|
+
}
|
|
24185
|
+
}
|
|
24186
|
+
async function scheduleCancelCommand(id) {
|
|
24187
|
+
const apiKey = getApiKey();
|
|
24188
|
+
if (!apiKey) {
|
|
24189
|
+
console.log(source_default.red("Not logged in"));
|
|
24190
|
+
console.log(source_default.dim("Run `skills login` first"));
|
|
24191
|
+
return;
|
|
24192
|
+
}
|
|
24193
|
+
const spinner = ora("Cancelling schedule...").start();
|
|
24194
|
+
try {
|
|
24195
|
+
const result = await deleteSchedule(id);
|
|
24196
|
+
if (result.error) {
|
|
24197
|
+
spinner.fail("Failed to cancel schedule");
|
|
24198
|
+
console.log(source_default.red(result.error));
|
|
24199
|
+
return;
|
|
24200
|
+
}
|
|
24201
|
+
spinner.succeed("Schedule cancelled successfully");
|
|
24202
|
+
const schedule = result.data?.schedule;
|
|
24203
|
+
if (schedule) {
|
|
24204
|
+
console.log();
|
|
24205
|
+
console.log(` ${source_default.dim("Name:")} ${schedule.name}`);
|
|
24206
|
+
console.log(` ${source_default.dim("Status:")} ${formatStatus3(schedule.status)}`);
|
|
24207
|
+
}
|
|
24208
|
+
} catch (error) {
|
|
24209
|
+
spinner.fail("Request failed");
|
|
24210
|
+
console.log(source_default.red(error instanceof Error ? error.message : "Unknown error"));
|
|
24211
|
+
}
|
|
24212
|
+
}
|
|
24213
|
+
async function scheduleHistoryCommand(id, options = {}) {
|
|
24214
|
+
const apiKey = getApiKey();
|
|
24215
|
+
if (!apiKey) {
|
|
24216
|
+
console.log(source_default.red("Not logged in"));
|
|
24217
|
+
console.log(source_default.dim("Run `skills login` first"));
|
|
24218
|
+
return;
|
|
24219
|
+
}
|
|
24220
|
+
const spinner = ora("Fetching run history...").start();
|
|
24221
|
+
try {
|
|
24222
|
+
const result = await getScheduleRuns(id, {
|
|
24223
|
+
status: options.status,
|
|
24224
|
+
limit: options.limit || 20
|
|
24225
|
+
});
|
|
24226
|
+
spinner.stop();
|
|
24227
|
+
if (result.error) {
|
|
24228
|
+
console.log(source_default.red(result.error));
|
|
24229
|
+
return;
|
|
24230
|
+
}
|
|
24231
|
+
const { schedule, runs, stats } = result.data || {};
|
|
24232
|
+
if (!schedule) {
|
|
24233
|
+
console.log(source_default.red("Schedule not found"));
|
|
24234
|
+
return;
|
|
24235
|
+
}
|
|
24236
|
+
console.log();
|
|
24237
|
+
console.log(indigo12.bold(`Run History: ${schedule.name}`));
|
|
24238
|
+
console.log(source_default.dim(`Skill: ${schedule.skillSlug}`));
|
|
24239
|
+
console.log(source_default.dim(`Total: ${stats?.totalRuns || 0} | Success: ${stats?.successfulRuns || 0} | Failed: ${stats?.failedRuns || 0} | Success Rate: ${stats?.successRate || 0}%`));
|
|
24240
|
+
console.log();
|
|
24241
|
+
if (!runs || runs.length === 0) {
|
|
24242
|
+
console.log(source_default.dim("No runs yet"));
|
|
24243
|
+
return;
|
|
24244
|
+
}
|
|
24245
|
+
for (const run of runs) {
|
|
24246
|
+
printRunSummary(run);
|
|
24247
|
+
}
|
|
24248
|
+
} catch (error) {
|
|
24249
|
+
spinner.fail("Request failed");
|
|
24250
|
+
console.log(source_default.red(error instanceof Error ? error.message : "Unknown error"));
|
|
24251
|
+
}
|
|
24252
|
+
}
|
|
24253
|
+
function printScheduleSummary(schedule) {
|
|
24254
|
+
const statusIcon = getStatusIcon2(schedule.status);
|
|
24255
|
+
const nextRun = schedule.nextRunAt ? formatRelativeTime(schedule.nextRunAt) : "-";
|
|
24256
|
+
console.log(`${statusIcon} ${source_default.bold(schedule.name)} ${source_default.dim(`(${schedule.skillSlug})`)}`);
|
|
24257
|
+
console.log(` ${source_default.dim("ID:")} ${schedule.id.slice(0, 8)}...`);
|
|
24258
|
+
console.log(` ${source_default.dim("Schedule:")} ${schedule.scheduleDescription || schedule.cronExpression || "One-time"}`);
|
|
24259
|
+
console.log(` ${source_default.dim("Status:")} ${formatStatus3(schedule.status)}`);
|
|
24260
|
+
console.log(` ${source_default.dim("Next Run:")} ${nextRun}`);
|
|
24261
|
+
console.log(` ${source_default.dim("Runs:")} ${schedule.runCount}${schedule.maxRuns ? `/${schedule.maxRuns}` : ""}`);
|
|
24262
|
+
console.log();
|
|
24263
|
+
}
|
|
24264
|
+
function printScheduleDetails(schedule) {
|
|
24265
|
+
console.log(indigo12.bold("Schedule Details"));
|
|
24266
|
+
console.log(` ${source_default.dim("ID:")} ${schedule.id}`);
|
|
24267
|
+
console.log(` ${source_default.dim("Name:")} ${schedule.name}`);
|
|
24268
|
+
console.log(` ${source_default.dim("Skill:")} ${schedule.skillSlug}`);
|
|
24269
|
+
console.log(` ${source_default.dim("Status:")} ${formatStatus3(schedule.status)}`);
|
|
24270
|
+
console.log(` ${source_default.dim("Type:")} ${schedule.scheduleType === "cron" ? "Recurring" : "One-time"}`);
|
|
24271
|
+
console.log(` ${source_default.dim("Schedule:")} ${schedule.scheduleDescription || schedule.cronExpression || formatDate(schedule.scheduledAt)}`);
|
|
24272
|
+
console.log(` ${source_default.dim("Timezone:")} ${schedule.timezone}`);
|
|
24273
|
+
if (schedule.command) {
|
|
24274
|
+
console.log(` ${source_default.dim("Command:")} ${schedule.command}`);
|
|
24275
|
+
}
|
|
24276
|
+
console.log(` ${source_default.dim("Runs:")} ${schedule.runCount}${schedule.maxRuns ? `/${schedule.maxRuns}` : ""}`);
|
|
24277
|
+
if (schedule.nextRunAt) {
|
|
24278
|
+
console.log(` ${source_default.dim("Next Run:")} ${formatDate(schedule.nextRunAt)} (${formatRelativeTime(schedule.nextRunAt)})`);
|
|
24279
|
+
}
|
|
24280
|
+
if (schedule.lastRunAt) {
|
|
24281
|
+
console.log(` ${source_default.dim("Last Run:")} ${formatDate(schedule.lastRunAt)} - ${formatStatus3(schedule.lastRunStatus || "unknown")}`);
|
|
24282
|
+
}
|
|
24283
|
+
console.log(` ${source_default.dim("Created:")} ${formatDate(schedule.createdAt)}`);
|
|
24284
|
+
}
|
|
24285
|
+
function printRunSummary(run) {
|
|
24286
|
+
const statusIcon = run.status === "completed" ? source_default.green("✓") : source_default.red("✗");
|
|
24287
|
+
const duration = run.durationMs ? formatDuration3(run.durationMs) : "-";
|
|
24288
|
+
console.log(` ${statusIcon} Run #${run.runNumber} - ${formatStatus3(run.status)}`);
|
|
24289
|
+
console.log(` ${source_default.dim("Time:")} ${formatDate(run.createdAt)}`);
|
|
24290
|
+
console.log(` ${source_default.dim("Duration:")} ${duration}`);
|
|
24291
|
+
if (run.creditsUsed) {
|
|
24292
|
+
console.log(` ${source_default.dim("Credits:")} ${run.creditsUsed}`);
|
|
24293
|
+
}
|
|
24294
|
+
if (run.errorMessage) {
|
|
24295
|
+
console.log(` ${source_default.dim("Error:")} ${source_default.red(run.errorMessage)}`);
|
|
24296
|
+
}
|
|
24297
|
+
}
|
|
24298
|
+
function getStatusIcon2(status) {
|
|
24299
|
+
switch (status) {
|
|
24300
|
+
case "active":
|
|
24301
|
+
return source_default.green("●");
|
|
24302
|
+
case "paused":
|
|
24303
|
+
return source_default.yellow("◐");
|
|
24304
|
+
case "completed":
|
|
24305
|
+
return source_default.blue("✓");
|
|
24306
|
+
case "failed":
|
|
24307
|
+
return source_default.red("✗");
|
|
24308
|
+
case "cancelled":
|
|
24309
|
+
return source_default.dim("○");
|
|
24310
|
+
default:
|
|
24311
|
+
return source_default.dim("○");
|
|
24312
|
+
}
|
|
24313
|
+
}
|
|
24314
|
+
function formatStatus3(status) {
|
|
24315
|
+
switch (status) {
|
|
24316
|
+
case "active":
|
|
24317
|
+
return source_default.green("active");
|
|
24318
|
+
case "paused":
|
|
24319
|
+
return source_default.yellow("paused");
|
|
24320
|
+
case "completed":
|
|
24321
|
+
return source_default.blue("completed");
|
|
24322
|
+
case "failed":
|
|
24323
|
+
return source_default.red("failed");
|
|
24324
|
+
case "cancelled":
|
|
24325
|
+
return source_default.dim("cancelled");
|
|
24326
|
+
default:
|
|
24327
|
+
return source_default.dim(status || "unknown");
|
|
24328
|
+
}
|
|
24329
|
+
}
|
|
24330
|
+
function formatDate(dateString) {
|
|
24331
|
+
if (!dateString)
|
|
24332
|
+
return "-";
|
|
24333
|
+
const date = new Date(dateString);
|
|
24334
|
+
return date.toLocaleString();
|
|
24335
|
+
}
|
|
24336
|
+
function formatRelativeTime(dateString) {
|
|
24337
|
+
const date = new Date(dateString);
|
|
24338
|
+
const now = new Date;
|
|
24339
|
+
const diffMs = date.getTime() - now.getTime();
|
|
24340
|
+
const diffMins = Math.round(diffMs / 60000);
|
|
24341
|
+
const diffHours = Math.round(diffMs / 3600000);
|
|
24342
|
+
const diffDays = Math.round(diffMs / 86400000);
|
|
24343
|
+
if (diffMins < 0) {
|
|
24344
|
+
if (diffMins > -60)
|
|
24345
|
+
return `${Math.abs(diffMins)}m ago`;
|
|
24346
|
+
if (diffHours > -24)
|
|
24347
|
+
return `${Math.abs(diffHours)}h ago`;
|
|
24348
|
+
return `${Math.abs(diffDays)}d ago`;
|
|
24349
|
+
}
|
|
24350
|
+
if (diffMins < 60)
|
|
24351
|
+
return `in ${diffMins}m`;
|
|
24352
|
+
if (diffHours < 24)
|
|
24353
|
+
return `in ${diffHours}h`;
|
|
24354
|
+
return `in ${diffDays}d`;
|
|
24355
|
+
}
|
|
24356
|
+
function formatDuration3(ms) {
|
|
24357
|
+
if (ms < 1000) {
|
|
24358
|
+
return `${ms}ms`;
|
|
24359
|
+
} else if (ms < 60000) {
|
|
24360
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
24361
|
+
} else {
|
|
24362
|
+
const minutes = Math.floor(ms / 60000);
|
|
24363
|
+
const seconds = Math.floor(ms % 60000 / 1000);
|
|
24364
|
+
return `${minutes}m ${seconds}s`;
|
|
24365
|
+
}
|
|
24366
|
+
}
|
|
24367
|
+
|
|
23742
24368
|
// src/index.ts
|
|
23743
|
-
var
|
|
24369
|
+
var indigo13 = colors.primary;
|
|
23744
24370
|
var program2 = new Command;
|
|
23745
|
-
program2.name("skills").description("CLI for skills.md - AI Agent Skills Marketplace").version("0.1.
|
|
24371
|
+
program2.name("skills").description("CLI for skills.md - AI Agent Skills Marketplace").version("0.1.39");
|
|
23746
24372
|
program2.command("init").description("Initialize skills.md in current project").option("-f, --force", "Force re-initialization (removes existing .skills/)").action((options) => {
|
|
23747
24373
|
initCommand({ force: options.force });
|
|
23748
24374
|
});
|
|
@@ -23759,11 +24385,13 @@ program2.command("marketplace").alias("market").description("Browse skills from
|
|
|
23759
24385
|
category: options.category
|
|
23760
24386
|
});
|
|
23761
24387
|
});
|
|
23762
|
-
program2.command("install [name]").alias("i").description("Install a skill
|
|
24388
|
+
program2.command("install [name]").alias("i").description("Install a skill, all skills, or skills by tag (global by default)").option("-l, --local", "Install to current project instead of global").option("-t, --target <target>", "Target platform (claude, codex)").option("-a, --all", "Install all skills from marketplace").option("--tag <tag>", "Install all skills with a specific tag").option("-f, --force", "Skip confirmation prompt").action((name, options) => {
|
|
23763
24389
|
installCommand(name || "", {
|
|
23764
24390
|
local: options.local,
|
|
23765
24391
|
target: options.target,
|
|
23766
|
-
all: options.all
|
|
24392
|
+
all: options.all,
|
|
24393
|
+
tag: options.tag,
|
|
24394
|
+
force: options.force
|
|
23767
24395
|
});
|
|
23768
24396
|
});
|
|
23769
24397
|
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) => {
|
|
@@ -23847,8 +24475,36 @@ program2.command("update [skill]").description("Update installed skills (refresh
|
|
|
23847
24475
|
});
|
|
23848
24476
|
program2.command("upgrade").description("Upgrade the Skills CLI to the latest version").action(upgradeCommand);
|
|
23849
24477
|
program2.command("doctor").description("Check your environment and diagnose issues").action(doctorCommand);
|
|
24478
|
+
var scheduleCmd = program2.command("schedule").description("Schedule skills to run automatically");
|
|
24479
|
+
scheduleCmd.command("create <skill> [schedule]").description("Create a new schedule (use natural language or --cron/--at)").option("-c, --cron <expression>", "Cron expression (e.g., '0 9 * * 1' for every Monday at 9am)").option("-a, --at <datetime>", "One-time schedule (ISO 8601 format)").option("--command <command>", "Skill command to run").option("-t, --timezone <timezone>", "Timezone (default: UTC)").option("-m, --max-runs <number>", "Maximum number of runs").option("-n, --name <name>", "Schedule name").action((skill, schedule, options) => {
|
|
24480
|
+
scheduleCreateCommand(skill, schedule, {
|
|
24481
|
+
cron: options.cron,
|
|
24482
|
+
at: options.at,
|
|
24483
|
+
command: options.command,
|
|
24484
|
+
timezone: options.timezone,
|
|
24485
|
+
maxRuns: options.maxRuns ? parseInt(options.maxRuns, 10) : undefined,
|
|
24486
|
+
name: options.name
|
|
24487
|
+
});
|
|
24488
|
+
});
|
|
24489
|
+
scheduleCmd.command("list").alias("ls").description("List all schedules").option("-s, --status <status>", "Filter by status (active, paused, completed, failed, cancelled)").option("-k, --skill <skill>", "Filter by skill slug").option("-n, --limit <number>", "Limit number of results").action((options) => {
|
|
24490
|
+
scheduleListCommand({
|
|
24491
|
+
status: options.status,
|
|
24492
|
+
skill: options.skill,
|
|
24493
|
+
limit: options.limit ? parseInt(options.limit, 10) : undefined
|
|
24494
|
+
});
|
|
24495
|
+
});
|
|
24496
|
+
scheduleCmd.command("get <id>").description("Get schedule details").action(scheduleGetCommand);
|
|
24497
|
+
scheduleCmd.command("pause <id>").description("Pause a schedule").action(schedulePauseCommand);
|
|
24498
|
+
scheduleCmd.command("resume <id>").description("Resume a paused schedule").action(scheduleResumeCommand);
|
|
24499
|
+
scheduleCmd.command("cancel <id>").description("Cancel a schedule").action(scheduleCancelCommand);
|
|
24500
|
+
scheduleCmd.command("history <id>").description("View run history for a schedule").option("-s, --status <status>", "Filter by run status").option("-n, --limit <number>", "Limit number of results").action((id, options) => {
|
|
24501
|
+
scheduleHistoryCommand(id, {
|
|
24502
|
+
status: options.status,
|
|
24503
|
+
limit: options.limit ? parseInt(options.limit, 10) : undefined
|
|
24504
|
+
});
|
|
24505
|
+
});
|
|
23850
24506
|
program2.addHelpText("after", `
|
|
23851
|
-
${
|
|
24507
|
+
${indigo13.bold("Examples:")}
|
|
23852
24508
|
${source_default.dim("# Initialize in current project")}
|
|
23853
24509
|
$ skills init
|
|
23854
24510
|
|
|
@@ -23867,6 +24523,10 @@ ${indigo12.bold("Examples:")}
|
|
|
23867
24523
|
${source_default.dim("# Install globally for Claude Code")}
|
|
23868
24524
|
$ skills install code-review -g -t claude
|
|
23869
24525
|
|
|
24526
|
+
${source_default.dim("# Install all skills with a tag")}
|
|
24527
|
+
$ skills install --tag automation
|
|
24528
|
+
$ skills install --tag ai -f ${source_default.dim("# skip confirmation")}
|
|
24529
|
+
|
|
23870
24530
|
${source_default.dim("# AI-powered setup wizard")}
|
|
23871
24531
|
$ skills setup
|
|
23872
24532
|
$ skills setup "SaaS application with API"
|
|
@@ -23913,7 +24573,23 @@ ${indigo12.bold("Examples:")}
|
|
|
23913
24573
|
${source_default.dim("# Check environment")}
|
|
23914
24574
|
$ skills doctor
|
|
23915
24575
|
|
|
23916
|
-
${
|
|
23917
|
-
$
|
|
24576
|
+
${source_default.dim("# Schedule a skill (natural language)")}
|
|
24577
|
+
$ skills schedule create calendar-events "every Monday at 9am" --command list
|
|
24578
|
+
$ skills schedule create linear-issues "daily at midnight" --command sync
|
|
24579
|
+
|
|
24580
|
+
${source_default.dim("# Schedule a skill (cron expression)")}
|
|
24581
|
+
$ skills schedule create calendar-events --cron "0 9 * * 1-5" --command list
|
|
24582
|
+
|
|
24583
|
+
${source_default.dim("# Schedule a one-time run")}
|
|
24584
|
+
$ skills schedule create compose-gmail --at "2025-01-15T09:00:00"
|
|
24585
|
+
|
|
24586
|
+
${source_default.dim("# Manage schedules")}
|
|
24587
|
+
$ skills schedule list
|
|
24588
|
+
$ skills schedule pause <id>
|
|
24589
|
+
$ skills schedule resume <id>
|
|
24590
|
+
$ skills schedule history <id>
|
|
24591
|
+
|
|
24592
|
+
${indigo13.bold("Documentation:")}
|
|
24593
|
+
${indigo13("https://skills.md/docs")}
|
|
23918
24594
|
`);
|
|
23919
24595
|
program2.parse();
|