@hasnatools/skills 0.1.36 → 0.1.38
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 +474 -9
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -20793,6 +20793,52 @@ async function makeApiRequest(path6, options = {}) {
|
|
|
20793
20793
|
headers
|
|
20794
20794
|
});
|
|
20795
20795
|
}
|
|
20796
|
+
async function listSchedules(options) {
|
|
20797
|
+
const params = new URLSearchParams;
|
|
20798
|
+
if (options?.status)
|
|
20799
|
+
params.set("status", options.status);
|
|
20800
|
+
if (options?.skill)
|
|
20801
|
+
params.set("skill", options.skill);
|
|
20802
|
+
if (options?.search)
|
|
20803
|
+
params.set("search", options.search);
|
|
20804
|
+
if (options?.limit)
|
|
20805
|
+
params.set("limit", options.limit.toString());
|
|
20806
|
+
if (options?.offset)
|
|
20807
|
+
params.set("offset", options.offset.toString());
|
|
20808
|
+
const query = params.toString();
|
|
20809
|
+
return apiRequest(`/schedules${query ? `?${query}` : ""}`);
|
|
20810
|
+
}
|
|
20811
|
+
async function getSchedule(id) {
|
|
20812
|
+
return apiRequest(`/schedules/${id}`);
|
|
20813
|
+
}
|
|
20814
|
+
async function createSchedule(input) {
|
|
20815
|
+
return apiRequest("/schedules", {
|
|
20816
|
+
method: "POST",
|
|
20817
|
+
body: JSON.stringify(input)
|
|
20818
|
+
});
|
|
20819
|
+
}
|
|
20820
|
+
async function updateSchedule(id, input) {
|
|
20821
|
+
return apiRequest(`/schedules/${id}`, {
|
|
20822
|
+
method: "PATCH",
|
|
20823
|
+
body: JSON.stringify(input)
|
|
20824
|
+
});
|
|
20825
|
+
}
|
|
20826
|
+
async function deleteSchedule(id) {
|
|
20827
|
+
return apiRequest(`/schedules/${id}`, {
|
|
20828
|
+
method: "DELETE"
|
|
20829
|
+
});
|
|
20830
|
+
}
|
|
20831
|
+
async function getScheduleRuns(id, options) {
|
|
20832
|
+
const params = new URLSearchParams;
|
|
20833
|
+
if (options?.status)
|
|
20834
|
+
params.set("status", options.status);
|
|
20835
|
+
if (options?.limit)
|
|
20836
|
+
params.set("limit", options.limit.toString());
|
|
20837
|
+
if (options?.offset)
|
|
20838
|
+
params.set("offset", options.offset.toString());
|
|
20839
|
+
const query = params.toString();
|
|
20840
|
+
return apiRequest(`/schedules/${id}/runs${query ? `?${query}` : ""}`);
|
|
20841
|
+
}
|
|
20796
20842
|
|
|
20797
20843
|
// src/commands/login.ts
|
|
20798
20844
|
async function loginCommand(options = {}) {
|
|
@@ -23587,8 +23633,10 @@ async function setupCommand(promptArg, options = {}) {
|
|
|
23587
23633
|
console.log(keyValue("Scope", colors.primaryBold(isLocal ? "project" : "global")));
|
|
23588
23634
|
console.log(keyValue("Directory", path6(installDir)));
|
|
23589
23635
|
console.log();
|
|
23590
|
-
let projectPrompt
|
|
23591
|
-
if (
|
|
23636
|
+
let projectPrompt;
|
|
23637
|
+
if (typeof promptArg === "string" && promptArg.trim().length > 0) {
|
|
23638
|
+
projectPrompt = promptArg.trim();
|
|
23639
|
+
} else {
|
|
23592
23640
|
console.log(colors.dim("Describe your project and I'll recommend the best skills to install."));
|
|
23593
23641
|
console.log(colors.dim("Examples: 'SaaS application', 'Mobile app backend', 'Data analysis project'"));
|
|
23594
23642
|
console.log();
|
|
@@ -23598,11 +23646,11 @@ async function setupCommand(promptArg, options = {}) {
|
|
|
23598
23646
|
message: "What are you building?",
|
|
23599
23647
|
validate: (value) => value.length > 0 ? true : "Please describe your project"
|
|
23600
23648
|
});
|
|
23601
|
-
if (
|
|
23649
|
+
if (typeof response.prompt !== "string" || response.prompt.trim().length === 0) {
|
|
23602
23650
|
console.log(colors.dim("Setup cancelled"));
|
|
23603
23651
|
return;
|
|
23604
23652
|
}
|
|
23605
|
-
projectPrompt = response.prompt;
|
|
23653
|
+
projectPrompt = response.prompt.trim();
|
|
23606
23654
|
}
|
|
23607
23655
|
const fetchSpinner = ora({
|
|
23608
23656
|
text: "Fetching available skills...",
|
|
@@ -23737,10 +23785,383 @@ async function setupCommand(promptArg, options = {}) {
|
|
|
23737
23785
|
console.log(` ${command("skills list")}`);
|
|
23738
23786
|
}
|
|
23739
23787
|
|
|
23788
|
+
// src/commands/schedule.ts
|
|
23789
|
+
var indigo12 = source_default.hex("#6366f1");
|
|
23790
|
+
async function scheduleCreateCommand(skill, scheduleInput, options) {
|
|
23791
|
+
const apiKey = getApiKey();
|
|
23792
|
+
if (!apiKey) {
|
|
23793
|
+
console.log(source_default.red("Not logged in"));
|
|
23794
|
+
console.log(source_default.dim("Run `skills login` first"));
|
|
23795
|
+
return;
|
|
23796
|
+
}
|
|
23797
|
+
let scheduleConfig = {};
|
|
23798
|
+
if (options.cron) {
|
|
23799
|
+
scheduleConfig.cronExpression = options.cron;
|
|
23800
|
+
} else if (options.at) {
|
|
23801
|
+
scheduleConfig.scheduledAt = options.at;
|
|
23802
|
+
} else if (scheduleInput) {
|
|
23803
|
+
scheduleConfig.schedule = scheduleInput;
|
|
23804
|
+
} else {
|
|
23805
|
+
console.log(source_default.red("Please provide a schedule"));
|
|
23806
|
+
console.log(source_default.dim("Examples:"));
|
|
23807
|
+
console.log(source_default.dim(' skills schedule <skill> "every Monday at 9am"'));
|
|
23808
|
+
console.log(source_default.dim(' skills schedule <skill> --cron "0 9 * * 1"'));
|
|
23809
|
+
console.log(source_default.dim(' skills schedule <skill> --at "2025-01-15T09:00:00"'));
|
|
23810
|
+
return;
|
|
23811
|
+
}
|
|
23812
|
+
const spinner = ora("Creating schedule...").start();
|
|
23813
|
+
try {
|
|
23814
|
+
const result = await createSchedule({
|
|
23815
|
+
skillSlug: skill,
|
|
23816
|
+
name: options.name || `${skill} schedule`,
|
|
23817
|
+
...scheduleConfig,
|
|
23818
|
+
command: options.command,
|
|
23819
|
+
timezone: options.timezone || "UTC",
|
|
23820
|
+
maxRuns: options.maxRuns
|
|
23821
|
+
});
|
|
23822
|
+
if (result.error) {
|
|
23823
|
+
spinner.fail("Failed to create schedule");
|
|
23824
|
+
console.log(source_default.red(result.error));
|
|
23825
|
+
return;
|
|
23826
|
+
}
|
|
23827
|
+
spinner.succeed("Schedule created successfully");
|
|
23828
|
+
console.log();
|
|
23829
|
+
const schedule = result.data?.schedule;
|
|
23830
|
+
if (schedule) {
|
|
23831
|
+
printScheduleDetails(schedule);
|
|
23832
|
+
}
|
|
23833
|
+
} catch (error) {
|
|
23834
|
+
spinner.fail("Request failed");
|
|
23835
|
+
console.log(source_default.red(error instanceof Error ? error.message : "Unknown error"));
|
|
23836
|
+
}
|
|
23837
|
+
}
|
|
23838
|
+
async function scheduleListCommand(options = {}) {
|
|
23839
|
+
const apiKey = getApiKey();
|
|
23840
|
+
if (!apiKey) {
|
|
23841
|
+
console.log(source_default.red("Not logged in"));
|
|
23842
|
+
console.log(source_default.dim("Run `skills login` first"));
|
|
23843
|
+
return;
|
|
23844
|
+
}
|
|
23845
|
+
const spinner = ora("Fetching schedules...").start();
|
|
23846
|
+
try {
|
|
23847
|
+
const result = await listSchedules({
|
|
23848
|
+
status: options.status,
|
|
23849
|
+
skill: options.skill,
|
|
23850
|
+
limit: options.limit || 20
|
|
23851
|
+
});
|
|
23852
|
+
spinner.stop();
|
|
23853
|
+
if (result.error) {
|
|
23854
|
+
console.log(source_default.red(result.error));
|
|
23855
|
+
return;
|
|
23856
|
+
}
|
|
23857
|
+
const { schedules, stats } = result.data || { schedules: [], stats: { total: 0, active: 0, paused: 0, completed: 0, failed: 0, cancelled: 0 } };
|
|
23858
|
+
console.log();
|
|
23859
|
+
console.log(indigo12.bold("Scheduled Jobs"));
|
|
23860
|
+
console.log(source_default.dim(`Total: ${stats.total} | Active: ${stats.active} | Paused: ${stats.paused} | Completed: ${stats.completed} | Failed: ${stats.failed}`));
|
|
23861
|
+
console.log();
|
|
23862
|
+
if (schedules.length === 0) {
|
|
23863
|
+
console.log(source_default.dim("No schedules found"));
|
|
23864
|
+
console.log(source_default.dim('Create one with: skills schedule <skill> "every day at 9am"'));
|
|
23865
|
+
return;
|
|
23866
|
+
}
|
|
23867
|
+
for (const schedule of schedules) {
|
|
23868
|
+
printScheduleSummary(schedule);
|
|
23869
|
+
}
|
|
23870
|
+
console.log();
|
|
23871
|
+
console.log(source_default.dim("View all at: https://skills.md/dashboard/schedules"));
|
|
23872
|
+
} catch (error) {
|
|
23873
|
+
spinner.fail("Request failed");
|
|
23874
|
+
console.log(source_default.red(error instanceof Error ? error.message : "Unknown error"));
|
|
23875
|
+
}
|
|
23876
|
+
}
|
|
23877
|
+
async function scheduleGetCommand(id) {
|
|
23878
|
+
const apiKey = getApiKey();
|
|
23879
|
+
if (!apiKey) {
|
|
23880
|
+
console.log(source_default.red("Not logged in"));
|
|
23881
|
+
console.log(source_default.dim("Run `skills login` first"));
|
|
23882
|
+
return;
|
|
23883
|
+
}
|
|
23884
|
+
const spinner = ora("Fetching schedule...").start();
|
|
23885
|
+
try {
|
|
23886
|
+
const result = await getSchedule(id);
|
|
23887
|
+
spinner.stop();
|
|
23888
|
+
if (result.error) {
|
|
23889
|
+
console.log(source_default.red(result.error));
|
|
23890
|
+
return;
|
|
23891
|
+
}
|
|
23892
|
+
const { schedule, recentRuns, stats } = result.data || {};
|
|
23893
|
+
if (!schedule) {
|
|
23894
|
+
console.log(source_default.red("Schedule not found"));
|
|
23895
|
+
return;
|
|
23896
|
+
}
|
|
23897
|
+
console.log();
|
|
23898
|
+
printScheduleDetails(schedule);
|
|
23899
|
+
if (stats) {
|
|
23900
|
+
console.log();
|
|
23901
|
+
console.log(indigo12.bold("Run Statistics"));
|
|
23902
|
+
console.log(` ${source_default.dim("Total Runs:")} ${stats.totalRuns}`);
|
|
23903
|
+
console.log(` ${source_default.dim("Successful:")} ${source_default.green(String(stats.successfulRuns))}`);
|
|
23904
|
+
console.log(` ${source_default.dim("Failed:")} ${source_default.red(String(stats.failedRuns))}`);
|
|
23905
|
+
console.log(` ${source_default.dim("Credits Used:")} ${indigo12(String(stats.totalCredits))}`);
|
|
23906
|
+
if (stats.avgDurationMs) {
|
|
23907
|
+
console.log(` ${source_default.dim("Avg Duration:")} ${formatDuration3(stats.avgDurationMs)}`);
|
|
23908
|
+
}
|
|
23909
|
+
}
|
|
23910
|
+
if (recentRuns && recentRuns.length > 0) {
|
|
23911
|
+
console.log();
|
|
23912
|
+
console.log(indigo12.bold("Recent Runs"));
|
|
23913
|
+
for (const run of recentRuns.slice(0, 5)) {
|
|
23914
|
+
printRunSummary(run);
|
|
23915
|
+
}
|
|
23916
|
+
}
|
|
23917
|
+
} catch (error) {
|
|
23918
|
+
spinner.fail("Request failed");
|
|
23919
|
+
console.log(source_default.red(error instanceof Error ? error.message : "Unknown error"));
|
|
23920
|
+
}
|
|
23921
|
+
}
|
|
23922
|
+
async function schedulePauseCommand(id) {
|
|
23923
|
+
const apiKey = getApiKey();
|
|
23924
|
+
if (!apiKey) {
|
|
23925
|
+
console.log(source_default.red("Not logged in"));
|
|
23926
|
+
console.log(source_default.dim("Run `skills login` first"));
|
|
23927
|
+
return;
|
|
23928
|
+
}
|
|
23929
|
+
const spinner = ora("Pausing schedule...").start();
|
|
23930
|
+
try {
|
|
23931
|
+
const result = await updateSchedule(id, { status: "paused" });
|
|
23932
|
+
if (result.error) {
|
|
23933
|
+
spinner.fail("Failed to pause schedule");
|
|
23934
|
+
console.log(source_default.red(result.error));
|
|
23935
|
+
return;
|
|
23936
|
+
}
|
|
23937
|
+
spinner.succeed("Schedule paused successfully");
|
|
23938
|
+
const schedule = result.data?.schedule;
|
|
23939
|
+
if (schedule) {
|
|
23940
|
+
console.log();
|
|
23941
|
+
console.log(` ${source_default.dim("Name:")} ${schedule.name}`);
|
|
23942
|
+
console.log(` ${source_default.dim("Status:")} ${formatStatus3(schedule.status)}`);
|
|
23943
|
+
}
|
|
23944
|
+
} catch (error) {
|
|
23945
|
+
spinner.fail("Request failed");
|
|
23946
|
+
console.log(source_default.red(error instanceof Error ? error.message : "Unknown error"));
|
|
23947
|
+
}
|
|
23948
|
+
}
|
|
23949
|
+
async function scheduleResumeCommand(id) {
|
|
23950
|
+
const apiKey = getApiKey();
|
|
23951
|
+
if (!apiKey) {
|
|
23952
|
+
console.log(source_default.red("Not logged in"));
|
|
23953
|
+
console.log(source_default.dim("Run `skills login` first"));
|
|
23954
|
+
return;
|
|
23955
|
+
}
|
|
23956
|
+
const spinner = ora("Resuming schedule...").start();
|
|
23957
|
+
try {
|
|
23958
|
+
const result = await updateSchedule(id, { status: "active" });
|
|
23959
|
+
if (result.error) {
|
|
23960
|
+
spinner.fail("Failed to resume schedule");
|
|
23961
|
+
console.log(source_default.red(result.error));
|
|
23962
|
+
return;
|
|
23963
|
+
}
|
|
23964
|
+
spinner.succeed("Schedule resumed successfully");
|
|
23965
|
+
const schedule = result.data?.schedule;
|
|
23966
|
+
if (schedule) {
|
|
23967
|
+
console.log();
|
|
23968
|
+
console.log(` ${source_default.dim("Name:")} ${schedule.name}`);
|
|
23969
|
+
console.log(` ${source_default.dim("Status:")} ${formatStatus3(schedule.status)}`);
|
|
23970
|
+
if (schedule.nextRunAt) {
|
|
23971
|
+
console.log(` ${source_default.dim("Next Run:")} ${formatDate(schedule.nextRunAt)}`);
|
|
23972
|
+
}
|
|
23973
|
+
}
|
|
23974
|
+
} catch (error) {
|
|
23975
|
+
spinner.fail("Request failed");
|
|
23976
|
+
console.log(source_default.red(error instanceof Error ? error.message : "Unknown error"));
|
|
23977
|
+
}
|
|
23978
|
+
}
|
|
23979
|
+
async function scheduleCancelCommand(id) {
|
|
23980
|
+
const apiKey = getApiKey();
|
|
23981
|
+
if (!apiKey) {
|
|
23982
|
+
console.log(source_default.red("Not logged in"));
|
|
23983
|
+
console.log(source_default.dim("Run `skills login` first"));
|
|
23984
|
+
return;
|
|
23985
|
+
}
|
|
23986
|
+
const spinner = ora("Cancelling schedule...").start();
|
|
23987
|
+
try {
|
|
23988
|
+
const result = await deleteSchedule(id);
|
|
23989
|
+
if (result.error) {
|
|
23990
|
+
spinner.fail("Failed to cancel schedule");
|
|
23991
|
+
console.log(source_default.red(result.error));
|
|
23992
|
+
return;
|
|
23993
|
+
}
|
|
23994
|
+
spinner.succeed("Schedule cancelled successfully");
|
|
23995
|
+
const schedule = result.data?.schedule;
|
|
23996
|
+
if (schedule) {
|
|
23997
|
+
console.log();
|
|
23998
|
+
console.log(` ${source_default.dim("Name:")} ${schedule.name}`);
|
|
23999
|
+
console.log(` ${source_default.dim("Status:")} ${formatStatus3(schedule.status)}`);
|
|
24000
|
+
}
|
|
24001
|
+
} catch (error) {
|
|
24002
|
+
spinner.fail("Request failed");
|
|
24003
|
+
console.log(source_default.red(error instanceof Error ? error.message : "Unknown error"));
|
|
24004
|
+
}
|
|
24005
|
+
}
|
|
24006
|
+
async function scheduleHistoryCommand(id, options = {}) {
|
|
24007
|
+
const apiKey = getApiKey();
|
|
24008
|
+
if (!apiKey) {
|
|
24009
|
+
console.log(source_default.red("Not logged in"));
|
|
24010
|
+
console.log(source_default.dim("Run `skills login` first"));
|
|
24011
|
+
return;
|
|
24012
|
+
}
|
|
24013
|
+
const spinner = ora("Fetching run history...").start();
|
|
24014
|
+
try {
|
|
24015
|
+
const result = await getScheduleRuns(id, {
|
|
24016
|
+
status: options.status,
|
|
24017
|
+
limit: options.limit || 20
|
|
24018
|
+
});
|
|
24019
|
+
spinner.stop();
|
|
24020
|
+
if (result.error) {
|
|
24021
|
+
console.log(source_default.red(result.error));
|
|
24022
|
+
return;
|
|
24023
|
+
}
|
|
24024
|
+
const { schedule, runs, stats } = result.data || {};
|
|
24025
|
+
if (!schedule) {
|
|
24026
|
+
console.log(source_default.red("Schedule not found"));
|
|
24027
|
+
return;
|
|
24028
|
+
}
|
|
24029
|
+
console.log();
|
|
24030
|
+
console.log(indigo12.bold(`Run History: ${schedule.name}`));
|
|
24031
|
+
console.log(source_default.dim(`Skill: ${schedule.skillSlug}`));
|
|
24032
|
+
console.log(source_default.dim(`Total: ${stats?.totalRuns || 0} | Success: ${stats?.successfulRuns || 0} | Failed: ${stats?.failedRuns || 0} | Success Rate: ${stats?.successRate || 0}%`));
|
|
24033
|
+
console.log();
|
|
24034
|
+
if (!runs || runs.length === 0) {
|
|
24035
|
+
console.log(source_default.dim("No runs yet"));
|
|
24036
|
+
return;
|
|
24037
|
+
}
|
|
24038
|
+
for (const run of runs) {
|
|
24039
|
+
printRunSummary(run);
|
|
24040
|
+
}
|
|
24041
|
+
} catch (error) {
|
|
24042
|
+
spinner.fail("Request failed");
|
|
24043
|
+
console.log(source_default.red(error instanceof Error ? error.message : "Unknown error"));
|
|
24044
|
+
}
|
|
24045
|
+
}
|
|
24046
|
+
function printScheduleSummary(schedule) {
|
|
24047
|
+
const statusIcon = getStatusIcon2(schedule.status);
|
|
24048
|
+
const nextRun = schedule.nextRunAt ? formatRelativeTime(schedule.nextRunAt) : "-";
|
|
24049
|
+
console.log(`${statusIcon} ${source_default.bold(schedule.name)} ${source_default.dim(`(${schedule.skillSlug})`)}`);
|
|
24050
|
+
console.log(` ${source_default.dim("ID:")} ${schedule.id.slice(0, 8)}...`);
|
|
24051
|
+
console.log(` ${source_default.dim("Schedule:")} ${schedule.scheduleDescription || schedule.cronExpression || "One-time"}`);
|
|
24052
|
+
console.log(` ${source_default.dim("Status:")} ${formatStatus3(schedule.status)}`);
|
|
24053
|
+
console.log(` ${source_default.dim("Next Run:")} ${nextRun}`);
|
|
24054
|
+
console.log(` ${source_default.dim("Runs:")} ${schedule.runCount}${schedule.maxRuns ? `/${schedule.maxRuns}` : ""}`);
|
|
24055
|
+
console.log();
|
|
24056
|
+
}
|
|
24057
|
+
function printScheduleDetails(schedule) {
|
|
24058
|
+
console.log(indigo12.bold("Schedule Details"));
|
|
24059
|
+
console.log(` ${source_default.dim("ID:")} ${schedule.id}`);
|
|
24060
|
+
console.log(` ${source_default.dim("Name:")} ${schedule.name}`);
|
|
24061
|
+
console.log(` ${source_default.dim("Skill:")} ${schedule.skillSlug}`);
|
|
24062
|
+
console.log(` ${source_default.dim("Status:")} ${formatStatus3(schedule.status)}`);
|
|
24063
|
+
console.log(` ${source_default.dim("Type:")} ${schedule.scheduleType === "cron" ? "Recurring" : "One-time"}`);
|
|
24064
|
+
console.log(` ${source_default.dim("Schedule:")} ${schedule.scheduleDescription || schedule.cronExpression || formatDate(schedule.scheduledAt)}`);
|
|
24065
|
+
console.log(` ${source_default.dim("Timezone:")} ${schedule.timezone}`);
|
|
24066
|
+
if (schedule.command) {
|
|
24067
|
+
console.log(` ${source_default.dim("Command:")} ${schedule.command}`);
|
|
24068
|
+
}
|
|
24069
|
+
console.log(` ${source_default.dim("Runs:")} ${schedule.runCount}${schedule.maxRuns ? `/${schedule.maxRuns}` : ""}`);
|
|
24070
|
+
if (schedule.nextRunAt) {
|
|
24071
|
+
console.log(` ${source_default.dim("Next Run:")} ${formatDate(schedule.nextRunAt)} (${formatRelativeTime(schedule.nextRunAt)})`);
|
|
24072
|
+
}
|
|
24073
|
+
if (schedule.lastRunAt) {
|
|
24074
|
+
console.log(` ${source_default.dim("Last Run:")} ${formatDate(schedule.lastRunAt)} - ${formatStatus3(schedule.lastRunStatus || "unknown")}`);
|
|
24075
|
+
}
|
|
24076
|
+
console.log(` ${source_default.dim("Created:")} ${formatDate(schedule.createdAt)}`);
|
|
24077
|
+
}
|
|
24078
|
+
function printRunSummary(run) {
|
|
24079
|
+
const statusIcon = run.status === "completed" ? source_default.green("✓") : source_default.red("✗");
|
|
24080
|
+
const duration = run.durationMs ? formatDuration3(run.durationMs) : "-";
|
|
24081
|
+
console.log(` ${statusIcon} Run #${run.runNumber} - ${formatStatus3(run.status)}`);
|
|
24082
|
+
console.log(` ${source_default.dim("Time:")} ${formatDate(run.createdAt)}`);
|
|
24083
|
+
console.log(` ${source_default.dim("Duration:")} ${duration}`);
|
|
24084
|
+
if (run.creditsUsed) {
|
|
24085
|
+
console.log(` ${source_default.dim("Credits:")} ${run.creditsUsed}`);
|
|
24086
|
+
}
|
|
24087
|
+
if (run.errorMessage) {
|
|
24088
|
+
console.log(` ${source_default.dim("Error:")} ${source_default.red(run.errorMessage)}`);
|
|
24089
|
+
}
|
|
24090
|
+
}
|
|
24091
|
+
function getStatusIcon2(status) {
|
|
24092
|
+
switch (status) {
|
|
24093
|
+
case "active":
|
|
24094
|
+
return source_default.green("●");
|
|
24095
|
+
case "paused":
|
|
24096
|
+
return source_default.yellow("◐");
|
|
24097
|
+
case "completed":
|
|
24098
|
+
return source_default.blue("✓");
|
|
24099
|
+
case "failed":
|
|
24100
|
+
return source_default.red("✗");
|
|
24101
|
+
case "cancelled":
|
|
24102
|
+
return source_default.dim("○");
|
|
24103
|
+
default:
|
|
24104
|
+
return source_default.dim("○");
|
|
24105
|
+
}
|
|
24106
|
+
}
|
|
24107
|
+
function formatStatus3(status) {
|
|
24108
|
+
switch (status) {
|
|
24109
|
+
case "active":
|
|
24110
|
+
return source_default.green("active");
|
|
24111
|
+
case "paused":
|
|
24112
|
+
return source_default.yellow("paused");
|
|
24113
|
+
case "completed":
|
|
24114
|
+
return source_default.blue("completed");
|
|
24115
|
+
case "failed":
|
|
24116
|
+
return source_default.red("failed");
|
|
24117
|
+
case "cancelled":
|
|
24118
|
+
return source_default.dim("cancelled");
|
|
24119
|
+
default:
|
|
24120
|
+
return source_default.dim(status || "unknown");
|
|
24121
|
+
}
|
|
24122
|
+
}
|
|
24123
|
+
function formatDate(dateString) {
|
|
24124
|
+
if (!dateString)
|
|
24125
|
+
return "-";
|
|
24126
|
+
const date = new Date(dateString);
|
|
24127
|
+
return date.toLocaleString();
|
|
24128
|
+
}
|
|
24129
|
+
function formatRelativeTime(dateString) {
|
|
24130
|
+
const date = new Date(dateString);
|
|
24131
|
+
const now = new Date;
|
|
24132
|
+
const diffMs = date.getTime() - now.getTime();
|
|
24133
|
+
const diffMins = Math.round(diffMs / 60000);
|
|
24134
|
+
const diffHours = Math.round(diffMs / 3600000);
|
|
24135
|
+
const diffDays = Math.round(diffMs / 86400000);
|
|
24136
|
+
if (diffMins < 0) {
|
|
24137
|
+
if (diffMins > -60)
|
|
24138
|
+
return `${Math.abs(diffMins)}m ago`;
|
|
24139
|
+
if (diffHours > -24)
|
|
24140
|
+
return `${Math.abs(diffHours)}h ago`;
|
|
24141
|
+
return `${Math.abs(diffDays)}d ago`;
|
|
24142
|
+
}
|
|
24143
|
+
if (diffMins < 60)
|
|
24144
|
+
return `in ${diffMins}m`;
|
|
24145
|
+
if (diffHours < 24)
|
|
24146
|
+
return `in ${diffHours}h`;
|
|
24147
|
+
return `in ${diffDays}d`;
|
|
24148
|
+
}
|
|
24149
|
+
function formatDuration3(ms) {
|
|
24150
|
+
if (ms < 1000) {
|
|
24151
|
+
return `${ms}ms`;
|
|
24152
|
+
} else if (ms < 60000) {
|
|
24153
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
24154
|
+
} else {
|
|
24155
|
+
const minutes = Math.floor(ms / 60000);
|
|
24156
|
+
const seconds = Math.floor(ms % 60000 / 1000);
|
|
24157
|
+
return `${minutes}m ${seconds}s`;
|
|
24158
|
+
}
|
|
24159
|
+
}
|
|
24160
|
+
|
|
23740
24161
|
// src/index.ts
|
|
23741
|
-
var
|
|
24162
|
+
var indigo13 = colors.primary;
|
|
23742
24163
|
var program2 = new Command;
|
|
23743
|
-
program2.name("skills").description("CLI for skills.md - AI Agent Skills Marketplace").version("0.1.
|
|
24164
|
+
program2.name("skills").description("CLI for skills.md - AI Agent Skills Marketplace").version("0.1.38");
|
|
23744
24165
|
program2.command("init").description("Initialize skills.md in current project").option("-f, --force", "Force re-initialization (removes existing .skills/)").action((options) => {
|
|
23745
24166
|
initCommand({ force: options.force });
|
|
23746
24167
|
});
|
|
@@ -23845,8 +24266,36 @@ program2.command("update [skill]").description("Update installed skills (refresh
|
|
|
23845
24266
|
});
|
|
23846
24267
|
program2.command("upgrade").description("Upgrade the Skills CLI to the latest version").action(upgradeCommand);
|
|
23847
24268
|
program2.command("doctor").description("Check your environment and diagnose issues").action(doctorCommand);
|
|
24269
|
+
var scheduleCmd = program2.command("schedule").description("Schedule skills to run automatically");
|
|
24270
|
+
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) => {
|
|
24271
|
+
scheduleCreateCommand(skill, schedule, {
|
|
24272
|
+
cron: options.cron,
|
|
24273
|
+
at: options.at,
|
|
24274
|
+
command: options.command,
|
|
24275
|
+
timezone: options.timezone,
|
|
24276
|
+
maxRuns: options.maxRuns ? parseInt(options.maxRuns, 10) : undefined,
|
|
24277
|
+
name: options.name
|
|
24278
|
+
});
|
|
24279
|
+
});
|
|
24280
|
+
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) => {
|
|
24281
|
+
scheduleListCommand({
|
|
24282
|
+
status: options.status,
|
|
24283
|
+
skill: options.skill,
|
|
24284
|
+
limit: options.limit ? parseInt(options.limit, 10) : undefined
|
|
24285
|
+
});
|
|
24286
|
+
});
|
|
24287
|
+
scheduleCmd.command("get <id>").description("Get schedule details").action(scheduleGetCommand);
|
|
24288
|
+
scheduleCmd.command("pause <id>").description("Pause a schedule").action(schedulePauseCommand);
|
|
24289
|
+
scheduleCmd.command("resume <id>").description("Resume a paused schedule").action(scheduleResumeCommand);
|
|
24290
|
+
scheduleCmd.command("cancel <id>").description("Cancel a schedule").action(scheduleCancelCommand);
|
|
24291
|
+
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) => {
|
|
24292
|
+
scheduleHistoryCommand(id, {
|
|
24293
|
+
status: options.status,
|
|
24294
|
+
limit: options.limit ? parseInt(options.limit, 10) : undefined
|
|
24295
|
+
});
|
|
24296
|
+
});
|
|
23848
24297
|
program2.addHelpText("after", `
|
|
23849
|
-
${
|
|
24298
|
+
${indigo13.bold("Examples:")}
|
|
23850
24299
|
${source_default.dim("# Initialize in current project")}
|
|
23851
24300
|
$ skills init
|
|
23852
24301
|
|
|
@@ -23911,7 +24360,23 @@ ${indigo12.bold("Examples:")}
|
|
|
23911
24360
|
${source_default.dim("# Check environment")}
|
|
23912
24361
|
$ skills doctor
|
|
23913
24362
|
|
|
23914
|
-
${
|
|
23915
|
-
$
|
|
24363
|
+
${source_default.dim("# Schedule a skill (natural language)")}
|
|
24364
|
+
$ skills schedule create calendar-events "every Monday at 9am" --command list
|
|
24365
|
+
$ skills schedule create linear-issues "daily at midnight" --command sync
|
|
24366
|
+
|
|
24367
|
+
${source_default.dim("# Schedule a skill (cron expression)")}
|
|
24368
|
+
$ skills schedule create calendar-events --cron "0 9 * * 1-5" --command list
|
|
24369
|
+
|
|
24370
|
+
${source_default.dim("# Schedule a one-time run")}
|
|
24371
|
+
$ skills schedule create compose-gmail --at "2025-01-15T09:00:00"
|
|
24372
|
+
|
|
24373
|
+
${source_default.dim("# Manage schedules")}
|
|
24374
|
+
$ skills schedule list
|
|
24375
|
+
$ skills schedule pause <id>
|
|
24376
|
+
$ skills schedule resume <id>
|
|
24377
|
+
$ skills schedule history <id>
|
|
24378
|
+
|
|
24379
|
+
${indigo13.bold("Documentation:")}
|
|
24380
|
+
${indigo13("https://skills.md/docs")}
|
|
23916
24381
|
`);
|
|
23917
24382
|
program2.parse();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hasnatools/skills",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.38",
|
|
4
4
|
"description": "CLI for skills.md - AI Agent Skills Marketplace",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
"prompts": "^2.4.2"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
+
"bun-types": "^1.3.5",
|
|
25
26
|
"@types/node": "^20",
|
|
26
27
|
"@types/prompts": "^2.4.9",
|
|
27
28
|
"typescript": "^5"
|