@orth/cli 0.2.20 → 0.2.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,9 @@
1
1
  export declare function skillsListCommand(options: {
2
2
  limit: string;
3
3
  }): Promise<void>;
4
+ export declare function skillsMineCommand(options: {
5
+ limit: string;
6
+ }): Promise<void>;
4
7
  export declare function skillsSearchCommand(query: string, options: {
5
8
  limit: string;
6
9
  }): Promise<void>;
@@ -37,6 +37,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.skillsListCommand = skillsListCommand;
40
+ exports.skillsMineCommand = skillsMineCommand;
40
41
  exports.skillsSearchCommand = skillsSearchCommand;
41
42
  exports.skillsShowCommand = skillsShowCommand;
42
43
  exports.skillsCreateCommand = skillsCreateCommand;
@@ -105,6 +106,38 @@ async function skillsListCommand(options) {
105
106
  }
106
107
  }
107
108
  // ─────────────────────────────────────────────────────────────────────────────
109
+ // orth skills mine
110
+ // ─────────────────────────────────────────────────────────────────────────────
111
+ async function skillsMineCommand(options) {
112
+ const spinner = (0, ora_1.default)("Loading your skills...").start();
113
+ try {
114
+ const limit = parseInt(options.limit, 10) || 50;
115
+ const data = await (0, api_js_1.apiRequest)(`/skills/mine?limit=${limit}`);
116
+ spinner.stop();
117
+ if (!data.skills || data.skills.length === 0) {
118
+ console.log(chalk_1.default.gray("\n No skills yet. Create one with: orth skills init\n"));
119
+ return;
120
+ }
121
+ console.log(chalk_1.default.bold(`\nYour Skills (${data.total} total):\n`));
122
+ for (const skill of data.skills) {
123
+ const verified = skill.verified ? chalk_1.default.blue(" ✓") : "";
124
+ const discoverable = skill.discoverable ? chalk_1.default.green(" [public]") : chalk_1.default.gray(" [private]");
125
+ const files = chalk_1.default.gray(`${skill.fileCount} files`);
126
+ console.log(` ${chalk_1.default.cyan.bold(skill.name)}${verified}${discoverable} ${files}`);
127
+ console.log(` Slug: ${chalk_1.default.white(skill.slug)}`);
128
+ if (skill.description) {
129
+ console.log(chalk_1.default.gray(` ${skill.description.slice(0, 100)}${skill.description.length > 100 ? "..." : ""}`));
130
+ }
131
+ console.log();
132
+ }
133
+ }
134
+ catch (error) {
135
+ spinner.stop();
136
+ console.error(chalk_1.default.red("Failed to load skills:"), error instanceof Error ? error.message : String(error));
137
+ process.exit(1);
138
+ }
139
+ }
140
+ // ─────────────────────────────────────────────────────────────────────────────
108
141
  // orth skills search <query>
109
142
  // ─────────────────────────────────────────────────────────────────────────────
110
143
  async function skillsSearchCommand(query, options) {
@@ -0,0 +1,15 @@
1
+ export declare function tasksListCommand(): Promise<void>;
2
+ export declare function tasksCreateCommand(options: {
3
+ skill: string;
4
+ name?: string;
5
+ schedule?: string;
6
+ input?: string[];
7
+ }): Promise<void>;
8
+ export declare function tasksShowCommand(taskId: string): Promise<void>;
9
+ export declare function tasksDeleteCommand(taskId: string): Promise<void>;
10
+ export declare function tasksPauseCommand(taskId: string): Promise<void>;
11
+ export declare function tasksResumeCommand(taskId: string): Promise<void>;
12
+ export declare function tasksTriggerCommand(taskId: string): Promise<void>;
13
+ export declare function tasksLogsCommand(taskId: string, options: {
14
+ limit?: string;
15
+ }): Promise<void>;
@@ -0,0 +1,227 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.tasksListCommand = tasksListCommand;
7
+ exports.tasksCreateCommand = tasksCreateCommand;
8
+ exports.tasksShowCommand = tasksShowCommand;
9
+ exports.tasksDeleteCommand = tasksDeleteCommand;
10
+ exports.tasksPauseCommand = tasksPauseCommand;
11
+ exports.tasksResumeCommand = tasksResumeCommand;
12
+ exports.tasksTriggerCommand = tasksTriggerCommand;
13
+ exports.tasksLogsCommand = tasksLogsCommand;
14
+ const chalk_1 = __importDefault(require("chalk"));
15
+ const ora_1 = __importDefault(require("ora"));
16
+ const api_js_1 = require("../api.js");
17
+ // Common cron presets
18
+ const CRON_PRESETS = {
19
+ "every-5-min": "*/5 * * * *",
20
+ "every-hour": "0 * * * *",
21
+ "every-day-9am": "0 9 * * *",
22
+ "every-weekday-9am": "0 9 * * 1-5",
23
+ "every-monday": "0 9 * * 1",
24
+ "every-month": "0 9 1 * *",
25
+ };
26
+ function cronToHuman(expr) {
27
+ const presetName = Object.entries(CRON_PRESETS).find(([, v]) => v === expr)?.[0];
28
+ if (presetName) {
29
+ return presetName.replace(/-/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
30
+ }
31
+ return expr;
32
+ }
33
+ function formatTimeAgo(dateStr) {
34
+ const diff = Date.now() - new Date(dateStr).getTime();
35
+ const mins = Math.floor(diff / 60000);
36
+ if (mins < 1)
37
+ return "just now";
38
+ if (mins < 60)
39
+ return `${mins}m ago`;
40
+ const hours = Math.floor(mins / 60);
41
+ if (hours < 24)
42
+ return `${hours}h ago`;
43
+ const days = Math.floor(hours / 24);
44
+ return `${days}d ago`;
45
+ }
46
+ function statusBadge(status) {
47
+ switch (status) {
48
+ case "active": return chalk_1.default.green("● active");
49
+ case "paused": return chalk_1.default.yellow("● paused");
50
+ case "succeeded": return chalk_1.default.green("✓ succeeded");
51
+ case "failed": return chalk_1.default.red("✗ failed");
52
+ case "running": return chalk_1.default.blue("◌ running");
53
+ case "pending": return chalk_1.default.gray("○ pending");
54
+ default: return chalk_1.default.gray(status);
55
+ }
56
+ }
57
+ async function tasksListCommand() {
58
+ const spinner = (0, ora_1.default)("Fetching tasks...").start();
59
+ try {
60
+ const data = await (0, api_js_1.apiRequest)("/tasks");
61
+ spinner.stop();
62
+ if (!data.tasks || data.tasks.length === 0) {
63
+ console.log(chalk_1.default.gray("\n No tasks yet. Create one with: orth tasks create\n"));
64
+ return;
65
+ }
66
+ console.log(chalk_1.default.bold("\nTasks\n"));
67
+ for (const task of data.tasks) {
68
+ console.log(` ${chalk_1.default.white.bold(task.name)} ${statusBadge(task.status)} ${chalk_1.default.gray(cronToHuman(task.cron_expression))}`);
69
+ console.log(` Skill: ${chalk_1.default.cyan(task.skill_slug)} Runs: ${task.run_count}${task.last_run_at ? ` Last: ${formatTimeAgo(task.last_run_at)}` : ""}`);
70
+ console.log(` ID: ${chalk_1.default.gray(task.id)}`);
71
+ console.log();
72
+ }
73
+ }
74
+ catch (err) {
75
+ spinner.fail("Failed to fetch tasks");
76
+ console.error(chalk_1.default.red(err.message));
77
+ process.exit(1);
78
+ }
79
+ }
80
+ async function tasksCreateCommand(options) {
81
+ const { skill, name, schedule } = options;
82
+ if (!skill) {
83
+ console.error(chalk_1.default.red("Skill slug is required. Usage: orth tasks create --skill <slug>"));
84
+ process.exit(1);
85
+ }
86
+ // Parse schedule
87
+ let cronExpression = schedule || "0 9 * * *"; // default: daily at 9am
88
+ if (CRON_PRESETS[cronExpression]) {
89
+ cronExpression = CRON_PRESETS[cronExpression];
90
+ }
91
+ // Parse input key=value pairs
92
+ const skillInput = {};
93
+ if (options.input) {
94
+ for (const pair of options.input) {
95
+ const [key, ...rest] = pair.split("=");
96
+ if (key && rest.length > 0) {
97
+ skillInput[key] = rest.join("=");
98
+ }
99
+ }
100
+ }
101
+ const taskName = name || `${skill} (${cronToHuman(cronExpression)})`;
102
+ const spinner = (0, ora_1.default)("Creating task...").start();
103
+ try {
104
+ const data = await (0, api_js_1.apiRequest)("/tasks", {
105
+ method: "POST",
106
+ body: {
107
+ name: taskName,
108
+ skillSlug: skill,
109
+ skillInput,
110
+ cronExpression,
111
+ },
112
+ });
113
+ spinner.succeed("Task created!");
114
+ console.log(`\n ${chalk_1.default.white.bold(data.task.name)}`);
115
+ console.log(` Skill: ${chalk_1.default.cyan(data.task.skill_slug)}`);
116
+ console.log(` Schedule: ${chalk_1.default.gray(cronToHuman(data.task.cron_expression))}`);
117
+ console.log(` Status: ${statusBadge(data.task.status)}`);
118
+ console.log(` ID: ${chalk_1.default.gray(data.task.id)}\n`);
119
+ }
120
+ catch (err) {
121
+ spinner.fail("Failed to create task");
122
+ console.error(chalk_1.default.red(err.message));
123
+ process.exit(1);
124
+ }
125
+ }
126
+ async function tasksShowCommand(taskId) {
127
+ const spinner = (0, ora_1.default)("Fetching task...").start();
128
+ try {
129
+ const data = await (0, api_js_1.apiRequest)(`/tasks/${taskId}`);
130
+ spinner.stop();
131
+ const t = data.task;
132
+ console.log(`\n ${chalk_1.default.white.bold(t.name)}`);
133
+ console.log(` Status: ${statusBadge(t.status)}`);
134
+ console.log(` Skill: ${chalk_1.default.cyan(t.skill_slug)}`);
135
+ console.log(` Schedule: ${chalk_1.default.gray(cronToHuman(t.cron_expression))} (${t.timezone})`);
136
+ console.log(` Runs: ${t.run_count}${t.last_run_at ? ` Last: ${formatTimeAgo(t.last_run_at)}` : ""}`);
137
+ if (Object.keys(t.skill_input || {}).length > 0) {
138
+ console.log(` Input: ${chalk_1.default.gray(JSON.stringify(t.skill_input))}`);
139
+ }
140
+ console.log(` ID: ${chalk_1.default.gray(t.id)}`);
141
+ console.log(` Created: ${new Date(t.created_at).toLocaleString()}\n`);
142
+ }
143
+ catch (err) {
144
+ spinner.fail("Failed to fetch task");
145
+ console.error(chalk_1.default.red(err.message));
146
+ process.exit(1);
147
+ }
148
+ }
149
+ async function tasksDeleteCommand(taskId) {
150
+ const spinner = (0, ora_1.default)("Deleting task...").start();
151
+ try {
152
+ await (0, api_js_1.apiRequest)(`/tasks/${taskId}`, { method: "DELETE" });
153
+ spinner.succeed("Task deleted");
154
+ }
155
+ catch (err) {
156
+ spinner.fail("Failed to delete task");
157
+ console.error(chalk_1.default.red(err.message));
158
+ process.exit(1);
159
+ }
160
+ }
161
+ async function tasksPauseCommand(taskId) {
162
+ const spinner = (0, ora_1.default)("Pausing task...").start();
163
+ try {
164
+ const data = await (0, api_js_1.apiRequest)(`/tasks/${taskId}/pause`, { method: "POST" });
165
+ spinner.succeed(`Task paused: ${data.task.name}`);
166
+ }
167
+ catch (err) {
168
+ spinner.fail("Failed to pause task");
169
+ console.error(chalk_1.default.red(err.message));
170
+ process.exit(1);
171
+ }
172
+ }
173
+ async function tasksResumeCommand(taskId) {
174
+ const spinner = (0, ora_1.default)("Resuming task...").start();
175
+ try {
176
+ const data = await (0, api_js_1.apiRequest)(`/tasks/${taskId}/resume`, { method: "POST" });
177
+ spinner.succeed(`Task resumed: ${data.task.name}`);
178
+ }
179
+ catch (err) {
180
+ spinner.fail("Failed to resume task");
181
+ console.error(chalk_1.default.red(err.message));
182
+ process.exit(1);
183
+ }
184
+ }
185
+ async function tasksTriggerCommand(taskId) {
186
+ const spinner = (0, ora_1.default)("Triggering task...").start();
187
+ try {
188
+ await (0, api_js_1.apiRequest)(`/tasks/${taskId}/trigger`, { method: "POST" });
189
+ spinner.succeed("Task triggered — check logs for progress");
190
+ }
191
+ catch (err) {
192
+ spinner.fail("Failed to trigger task");
193
+ console.error(chalk_1.default.red(err.message));
194
+ process.exit(1);
195
+ }
196
+ }
197
+ async function tasksLogsCommand(taskId, options) {
198
+ const limit = parseInt(options.limit || "10") || 10;
199
+ const spinner = (0, ora_1.default)("Fetching run history...").start();
200
+ try {
201
+ const data = await (0, api_js_1.apiRequest)(`/tasks/${taskId}/runs?limit=${limit}`);
202
+ spinner.stop();
203
+ if (!data.runs || data.runs.length === 0) {
204
+ console.log(chalk_1.default.gray("\n No runs yet.\n"));
205
+ return;
206
+ }
207
+ console.log(chalk_1.default.bold(`\nRun History (${data.total} total)\n`));
208
+ for (const run of data.runs) {
209
+ const duration = run.duration_ms != null ? `${(run.duration_ms / 1000).toFixed(0)}s` : "—";
210
+ const time = run.started_at ? new Date(run.started_at).toLocaleString() : "—";
211
+ console.log(` ${statusBadge(run.status)} ${chalk_1.default.gray(time)} ${chalk_1.default.gray(duration)}`);
212
+ if (run.error) {
213
+ console.log(` ${chalk_1.default.red(run.error)}`);
214
+ }
215
+ if (run.output) {
216
+ const preview = run.output.slice(0, 200);
217
+ console.log(` ${chalk_1.default.gray(preview)}${run.output.length > 200 ? "..." : ""}`);
218
+ }
219
+ console.log();
220
+ }
221
+ }
222
+ catch (err) {
223
+ spinner.fail("Failed to fetch run history");
224
+ console.error(chalk_1.default.red(err.message));
225
+ process.exit(1);
226
+ }
227
+ }
package/dist/index.js CHANGED
@@ -10,6 +10,7 @@ const account_js_1 = require("./commands/account.js");
10
10
  const code_js_1 = require("./commands/code.js");
11
11
  const skills_js_1 = require("./commands/skills.js");
12
12
  const apiRequest_js_1 = require("./commands/apiRequest.js");
13
+ const tasks_js_1 = require("./commands/tasks.js");
13
14
  const analytics_js_1 = require("./analytics.js");
14
15
  /**
15
16
  * Wraps an async action callback so that rejected promises are caught,
@@ -145,6 +146,14 @@ skillsGroup
145
146
  (0, analytics_js_1.trackEvent)("skills.list");
146
147
  await (0, skills_js_1.skillsListCommand)(options);
147
148
  }));
149
+ skillsGroup
150
+ .command("mine")
151
+ .description("List your own skills")
152
+ .option("-l, --limit <number>", "Max results", "50")
153
+ .action(asyncAction(async (options) => {
154
+ (0, analytics_js_1.trackEvent)("skills.mine");
155
+ await (0, skills_js_1.skillsMineCommand)(options);
156
+ }));
148
157
  skillsGroup
149
158
  .command("search <query>")
150
159
  .description("Search for agent skills")
@@ -238,6 +247,73 @@ skillsGroup
238
247
  await (0, skills_js_1.skillsRequestCommand)(input);
239
248
  }));
240
249
  // ─────────────────────────────────────────────────────────────────────────────
250
+ // orth tasks <subcommand> — Scheduled task commands
251
+ // ─────────────────────────────────────────────────────────────────────────────
252
+ const tasksGroup = program
253
+ .command("tasks")
254
+ .description("Scheduled task commands");
255
+ tasksGroup
256
+ .command("list")
257
+ .description("List your scheduled tasks")
258
+ .action(asyncAction(async () => {
259
+ (0, analytics_js_1.trackEvent)("tasks.list");
260
+ await (0, tasks_js_1.tasksListCommand)();
261
+ }));
262
+ tasksGroup
263
+ .command("create")
264
+ .description("Create a new scheduled task")
265
+ .requiredOption("-s, --skill <slug>", "Skill to run")
266
+ .option("-n, --name <name>", "Task name")
267
+ .option("--schedule <cron>", "Cron expression or preset (every-5-min, every-hour, every-day-9am, every-weekday-9am, every-monday, every-month)")
268
+ .option("-i, --input <pairs...>", "Skill input as key=value pairs")
269
+ .action(asyncAction(async (options) => {
270
+ (0, analytics_js_1.trackEvent)("tasks.create", { skill: options.skill });
271
+ await (0, tasks_js_1.tasksCreateCommand)(options);
272
+ }));
273
+ tasksGroup
274
+ .command("show <id>")
275
+ .description("Show task details")
276
+ .action(asyncAction(async (id) => {
277
+ (0, analytics_js_1.trackEvent)("tasks.show", { id });
278
+ await (0, tasks_js_1.tasksShowCommand)(id);
279
+ }));
280
+ tasksGroup
281
+ .command("delete <id>")
282
+ .description("Delete a scheduled task")
283
+ .action(asyncAction(async (id) => {
284
+ (0, analytics_js_1.trackEvent)("tasks.delete", { id });
285
+ await (0, tasks_js_1.tasksDeleteCommand)(id);
286
+ }));
287
+ tasksGroup
288
+ .command("pause <id>")
289
+ .description("Pause a scheduled task")
290
+ .action(asyncAction(async (id) => {
291
+ (0, analytics_js_1.trackEvent)("tasks.pause", { id });
292
+ await (0, tasks_js_1.tasksPauseCommand)(id);
293
+ }));
294
+ tasksGroup
295
+ .command("resume <id>")
296
+ .description("Resume a paused task")
297
+ .action(asyncAction(async (id) => {
298
+ (0, analytics_js_1.trackEvent)("tasks.resume", { id });
299
+ await (0, tasks_js_1.tasksResumeCommand)(id);
300
+ }));
301
+ tasksGroup
302
+ .command("trigger <id>")
303
+ .description("Manually trigger a task run")
304
+ .action(asyncAction(async (id) => {
305
+ (0, analytics_js_1.trackEvent)("tasks.trigger", { id });
306
+ await (0, tasks_js_1.tasksTriggerCommand)(id);
307
+ }));
308
+ tasksGroup
309
+ .command("logs <id>")
310
+ .description("View run history for a task")
311
+ .option("-l, --limit <number>", "Max results", "10")
312
+ .action(asyncAction(async (id, options) => {
313
+ (0, analytics_js_1.trackEvent)("tasks.logs", { id });
314
+ await (0, tasks_js_1.tasksLogsCommand)(id, options);
315
+ }));
316
+ // ─────────────────────────────────────────────────────────────────────────────
241
317
  // Backward-compatible aliases (flat commands)
242
318
  // ─────────────────────────────────────────────────────────────────────────────
243
319
  program
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orth/cli",
3
- "version": "0.2.20",
3
+ "version": "0.2.22",
4
4
  "description": "CLI to access all APIs and skills on the Orthogonal platform",
5
5
  "main": "dist/index.js",
6
6
  "bin": {