@orth/cli 0.2.2 → 0.2.3
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/commands/api.js +4 -4
- package/dist/commands/skills.d.ts +4 -0
- package/dist/commands/skills.js +101 -19
- package/dist/index.js +9 -0
- package/package.json +1 -1
package/dist/commands/api.js
CHANGED
|
@@ -36,7 +36,7 @@ async function apiCommand(slug, path, options) {
|
|
|
36
36
|
chalk_1.default.white(api.name || "") +
|
|
37
37
|
chalk_1.default.gray(` (${api.endpoints?.length || 0} endpoints)`));
|
|
38
38
|
}
|
|
39
|
-
console.log(chalk_1.default.gray("\nRun '
|
|
39
|
+
console.log(chalk_1.default.gray("\nRun 'orth api <slug>' to see endpoints for an API"));
|
|
40
40
|
return;
|
|
41
41
|
}
|
|
42
42
|
if (path) {
|
|
@@ -127,7 +127,7 @@ async function apiCommand(slug, path, options) {
|
|
|
127
127
|
const api = data.results.find((a) => a.slug === slug);
|
|
128
128
|
if (!api) {
|
|
129
129
|
console.log(chalk_1.default.yellow(`API '${slug}' not found.`));
|
|
130
|
-
console.log(chalk_1.default.gray("Run '
|
|
130
|
+
console.log(chalk_1.default.gray("Run 'orth api' to see available APIs"));
|
|
131
131
|
return;
|
|
132
132
|
}
|
|
133
133
|
console.log(chalk_1.default.bold(`\n${chalk_1.default.cyan(api.name)} (${api.slug})\n`));
|
|
@@ -139,8 +139,8 @@ async function apiCommand(slug, path, options) {
|
|
|
139
139
|
console.log(chalk_1.default.gray(` ${endpoint.description.slice(0, 80)}${endpoint.description.length > 80 ? "..." : ""}`));
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
|
-
console.log(chalk_1.default.gray("\nRun '
|
|
143
|
-
console.log(chalk_1.default.gray("Run '
|
|
142
|
+
console.log(chalk_1.default.gray("\nRun 'orth api " + slug + " <path>' for endpoint details"));
|
|
143
|
+
console.log(chalk_1.default.gray("Run 'orth run " + slug + " <path>' to call an endpoint"));
|
|
144
144
|
}
|
|
145
145
|
catch (error) {
|
|
146
146
|
spinner.stop();
|
|
@@ -21,6 +21,10 @@ export declare function skillsSubmitCommand(inputPath: string | undefined, optio
|
|
|
21
21
|
name?: string;
|
|
22
22
|
tags?: string;
|
|
23
23
|
}): Promise<void>;
|
|
24
|
+
export declare function skillsUpdateCommand(slug: string, inputPath: string | undefined, options: {
|
|
25
|
+
name?: string;
|
|
26
|
+
tags?: string;
|
|
27
|
+
}): Promise<void>;
|
|
24
28
|
export declare function skillsRequestVerificationCommand(slug: string): Promise<void>;
|
|
25
29
|
export declare function skillsPublishCommand(slug: string, options: {
|
|
26
30
|
unpublish?: boolean;
|
package/dist/commands/skills.js
CHANGED
|
@@ -43,6 +43,7 @@ exports.skillsCreateCommand = skillsCreateCommand;
|
|
|
43
43
|
exports.skillsInstallCommand = skillsInstallCommand;
|
|
44
44
|
exports.skillsInitCommand = skillsInitCommand;
|
|
45
45
|
exports.skillsSubmitCommand = skillsSubmitCommand;
|
|
46
|
+
exports.skillsUpdateCommand = skillsUpdateCommand;
|
|
46
47
|
exports.skillsRequestVerificationCommand = skillsRequestVerificationCommand;
|
|
47
48
|
exports.skillsPublishCommand = skillsPublishCommand;
|
|
48
49
|
exports.skillsRequestCommand = skillsRequestCommand;
|
|
@@ -63,7 +64,7 @@ const AGENT_DIRS = {
|
|
|
63
64
|
openclaw: path.join(os.homedir(), ".openclaw", "skills"),
|
|
64
65
|
};
|
|
65
66
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
66
|
-
//
|
|
67
|
+
// orth skills list
|
|
67
68
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
68
69
|
async function skillsListCommand(options) {
|
|
69
70
|
const spinner = (0, ora_1.default)("Loading skills...").start();
|
|
@@ -93,8 +94,8 @@ async function skillsListCommand(options) {
|
|
|
93
94
|
console.log(chalk_1.default.gray(` Slug: ${skill.slug}`));
|
|
94
95
|
console.log();
|
|
95
96
|
}
|
|
96
|
-
console.log(chalk_1.default.gray("Run '
|
|
97
|
-
console.log(chalk_1.default.gray("Run '
|
|
97
|
+
console.log(chalk_1.default.gray("Run 'orth skills show <slug>' to see skill details"));
|
|
98
|
+
console.log(chalk_1.default.gray("Run 'orth skills add <slug>' to add a skill locally"));
|
|
98
99
|
}
|
|
99
100
|
catch (error) {
|
|
100
101
|
spinner.stop();
|
|
@@ -103,7 +104,7 @@ async function skillsListCommand(options) {
|
|
|
103
104
|
}
|
|
104
105
|
}
|
|
105
106
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
106
|
-
//
|
|
107
|
+
// orth skills search <query>
|
|
107
108
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
108
109
|
async function skillsSearchCommand(query, options) {
|
|
109
110
|
const spinner = (0, ora_1.default)("Searching skills...").start();
|
|
@@ -128,7 +129,7 @@ async function skillsSearchCommand(query, options) {
|
|
|
128
129
|
console.log(chalk_1.default.gray(` Slug: ${skill.slug}`));
|
|
129
130
|
console.log();
|
|
130
131
|
}
|
|
131
|
-
console.log(chalk_1.default.gray("Run '
|
|
132
|
+
console.log(chalk_1.default.gray("Run 'orth skills show <slug>' for full details"));
|
|
132
133
|
}
|
|
133
134
|
catch (error) {
|
|
134
135
|
spinner.stop();
|
|
@@ -137,7 +138,7 @@ async function skillsSearchCommand(query, options) {
|
|
|
137
138
|
}
|
|
138
139
|
}
|
|
139
140
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
140
|
-
//
|
|
141
|
+
// orth skills show <slug>
|
|
141
142
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
142
143
|
async function skillsShowCommand(slug) {
|
|
143
144
|
const spinner = (0, ora_1.default)("Loading skill...").start();
|
|
@@ -191,7 +192,7 @@ async function skillsShowCommand(slug) {
|
|
|
191
192
|
console.log(chalk_1.default.bold("Install:"));
|
|
192
193
|
console.log(chalk_1.default.white(` ${skill.installCommand}`));
|
|
193
194
|
}
|
|
194
|
-
console.log(chalk_1.default.gray(`\nRun '
|
|
195
|
+
console.log(chalk_1.default.gray(`\nRun 'orth skills add ${skill.slug}' to add locally`));
|
|
195
196
|
}
|
|
196
197
|
catch (error) {
|
|
197
198
|
spinner.stop();
|
|
@@ -200,7 +201,7 @@ async function skillsShowCommand(slug) {
|
|
|
200
201
|
}
|
|
201
202
|
}
|
|
202
203
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
203
|
-
//
|
|
204
|
+
// orth skills create <githubRepo>
|
|
204
205
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
205
206
|
async function skillsCreateCommand(githubRepo, options) {
|
|
206
207
|
const spinner = (0, ora_1.default)("Creating skill from GitHub...").start();
|
|
@@ -242,7 +243,7 @@ async function skillsCreateCommand(githubRepo, options) {
|
|
|
242
243
|
console.log(chalk_1.default.gray(` ${data.skill.description}`));
|
|
243
244
|
}
|
|
244
245
|
console.log(chalk_1.default.bold("\nYour skill is on the platform but not yet verified."));
|
|
245
|
-
console.log(chalk_1.default.white(`To request verification: ${chalk_1.default.cyan(`
|
|
246
|
+
console.log(chalk_1.default.white(`To request verification: ${chalk_1.default.cyan(`orth skills request-verification ${data.skill.slug}`)}`));
|
|
246
247
|
console.log(chalk_1.default.gray("Once verified, you can toggle discoverability anytime."));
|
|
247
248
|
}
|
|
248
249
|
catch (error) {
|
|
@@ -252,7 +253,7 @@ async function skillsCreateCommand(githubRepo, options) {
|
|
|
252
253
|
}
|
|
253
254
|
}
|
|
254
255
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
255
|
-
//
|
|
256
|
+
// orth skills add <slug>
|
|
256
257
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
257
258
|
async function skillsInstallCommand(slug, options) {
|
|
258
259
|
const spinner = (0, ora_1.default)("Fetching skill...").start();
|
|
@@ -333,7 +334,7 @@ async function skillsInstallCommand(slug, options) {
|
|
|
333
334
|
}
|
|
334
335
|
}
|
|
335
336
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
336
|
-
//
|
|
337
|
+
// orth skills init [name]
|
|
337
338
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
338
339
|
// Known binary/large file extensions to skip when reading local files
|
|
339
340
|
const SKIP_EXTENSIONS = new Set([
|
|
@@ -419,7 +420,7 @@ Describe the next step.
|
|
|
419
420
|
console.log(chalk_1.default.bold("\nNext steps:"));
|
|
420
421
|
console.log(chalk_1.default.white(" 1. Edit SKILL.md with your skill's instructions"));
|
|
421
422
|
console.log(chalk_1.default.white(" 2. Add any supporting files to scripts/, references/, or assets/"));
|
|
422
|
-
console.log(chalk_1.default.white(` 3. Submit to Orthogonal: ${chalk_1.default.cyan(`
|
|
423
|
+
console.log(chalk_1.default.white(` 3. Submit to Orthogonal: ${chalk_1.default.cyan(`orth skills submit ${dirPath}`)}`));
|
|
423
424
|
}
|
|
424
425
|
catch (error) {
|
|
425
426
|
console.error(chalk_1.default.red(`Error: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
@@ -427,7 +428,7 @@ Describe the next step.
|
|
|
427
428
|
}
|
|
428
429
|
}
|
|
429
430
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
430
|
-
//
|
|
431
|
+
// orth skills submit [path]
|
|
431
432
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
432
433
|
function readFilesRecursive(dirPath, basePath = "") {
|
|
433
434
|
const files = [];
|
|
@@ -508,7 +509,7 @@ async function skillsSubmitCommand(inputPath, options) {
|
|
|
508
509
|
if (!primaryFile) {
|
|
509
510
|
spinner.stop();
|
|
510
511
|
console.error(chalk_1.default.red("Error: No SKILL.md found in the root of the directory"));
|
|
511
|
-
console.log(chalk_1.default.gray("Run '
|
|
512
|
+
console.log(chalk_1.default.gray("Run 'orth skills init' to create a skill template"));
|
|
512
513
|
process.exit(1);
|
|
513
514
|
}
|
|
514
515
|
// Parse frontmatter
|
|
@@ -565,7 +566,7 @@ async function skillsSubmitCommand(inputPath, options) {
|
|
|
565
566
|
console.log(chalk_1.default.gray(` ${data.skill.description.slice(0, 100)}`));
|
|
566
567
|
}
|
|
567
568
|
console.log(chalk_1.default.bold("\nYour skill is on the platform but not yet verified."));
|
|
568
|
-
console.log(chalk_1.default.white(`To request verification: ${chalk_1.default.cyan(`
|
|
569
|
+
console.log(chalk_1.default.white(`To request verification: ${chalk_1.default.cyan(`orth skills request-verification ${data.skill.slug}`)}`));
|
|
569
570
|
console.log(chalk_1.default.gray("Once verified, you can toggle discoverability anytime."));
|
|
570
571
|
console.log(chalk_1.default.gray(`Dashboard: https://orthogonal.com/dashboard/skills`));
|
|
571
572
|
}
|
|
@@ -576,7 +577,88 @@ async function skillsSubmitCommand(inputPath, options) {
|
|
|
576
577
|
}
|
|
577
578
|
}
|
|
578
579
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
579
|
-
//
|
|
580
|
+
// orth skills update <slug> [path]
|
|
581
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
582
|
+
async function skillsUpdateCommand(slug, inputPath, options) {
|
|
583
|
+
const dirPath = inputPath ? path.resolve(inputPath) : process.cwd();
|
|
584
|
+
const spinner = (0, ora_1.default)("Reading skill files...").start();
|
|
585
|
+
try {
|
|
586
|
+
// Validate directory exists
|
|
587
|
+
if (!fs.existsSync(dirPath) || !fs.statSync(dirPath).isDirectory()) {
|
|
588
|
+
spinner.stop();
|
|
589
|
+
console.error(chalk_1.default.red(`Error: ${dirPath} is not a directory`));
|
|
590
|
+
process.exit(1);
|
|
591
|
+
}
|
|
592
|
+
// Read all files
|
|
593
|
+
const files = readFilesRecursive(dirPath);
|
|
594
|
+
if (files.length === 0) {
|
|
595
|
+
spinner.stop();
|
|
596
|
+
console.error(chalk_1.default.red("Error: No files found in the directory"));
|
|
597
|
+
process.exit(1);
|
|
598
|
+
}
|
|
599
|
+
// Validate SKILL.md exists
|
|
600
|
+
const primaryFile = files.find((f) => f.isPrimary);
|
|
601
|
+
if (!primaryFile) {
|
|
602
|
+
spinner.stop();
|
|
603
|
+
console.error(chalk_1.default.red("Error: No SKILL.md found in the root of the directory"));
|
|
604
|
+
process.exit(1);
|
|
605
|
+
}
|
|
606
|
+
// Parse frontmatter
|
|
607
|
+
// Note: Unlike submit, name/description are optional for updates
|
|
608
|
+
// We only send them if provided (to allow partial updates)
|
|
609
|
+
const frontmatter = parseFrontmatter(primaryFile.content);
|
|
610
|
+
const skillName = options.name || frontmatter.name;
|
|
611
|
+
const skillDescription = frontmatter.description;
|
|
612
|
+
// Check size limits
|
|
613
|
+
const totalSize = files.reduce((acc, f) => acc + f.content.length, 0);
|
|
614
|
+
if (files.length > 50) {
|
|
615
|
+
spinner.stop();
|
|
616
|
+
console.error(chalk_1.default.red("Error: Too many files (max 50)"));
|
|
617
|
+
process.exit(1);
|
|
618
|
+
}
|
|
619
|
+
if (totalSize > 1024 * 1024) {
|
|
620
|
+
spinner.stop();
|
|
621
|
+
console.error(chalk_1.default.red("Error: Total content too large (max 1MB)"));
|
|
622
|
+
process.exit(1);
|
|
623
|
+
}
|
|
624
|
+
spinner.text = "Updating skill...";
|
|
625
|
+
const tags = options.tags
|
|
626
|
+
? options.tags.split(",").map((t) => t.trim())
|
|
627
|
+
: undefined;
|
|
628
|
+
const updatePayload = {
|
|
629
|
+
files: files.map((f) => ({
|
|
630
|
+
filePath: f.filePath,
|
|
631
|
+
content: f.content,
|
|
632
|
+
isPrimary: f.isPrimary,
|
|
633
|
+
})),
|
|
634
|
+
};
|
|
635
|
+
if (skillName)
|
|
636
|
+
updatePayload.name = skillName;
|
|
637
|
+
if (skillDescription)
|
|
638
|
+
updatePayload.description = skillDescription;
|
|
639
|
+
if (tags)
|
|
640
|
+
updatePayload.tags = tags;
|
|
641
|
+
const data = await (0, api_js_1.apiRequest)(`/skills/${slug}`, {
|
|
642
|
+
method: "PUT",
|
|
643
|
+
body: updatePayload,
|
|
644
|
+
});
|
|
645
|
+
spinner.stop();
|
|
646
|
+
console.log(chalk_1.default.green(`\n✓ Skill updated successfully`));
|
|
647
|
+
console.log(chalk_1.default.bold(`\n${data.skill.name}`));
|
|
648
|
+
console.log(chalk_1.default.gray(` Slug: ${data.skill.slug}`));
|
|
649
|
+
console.log(chalk_1.default.gray(` Files: ${files.length}`));
|
|
650
|
+
if (data.skill.description) {
|
|
651
|
+
console.log(chalk_1.default.gray(` ${data.skill.description.slice(0, 100)}`));
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
catch (error) {
|
|
655
|
+
spinner.stop();
|
|
656
|
+
console.error(chalk_1.default.red(`Error: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
657
|
+
process.exit(1);
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
661
|
+
// orth skills request-verification <slug>
|
|
580
662
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
581
663
|
async function skillsRequestVerificationCommand(slug) {
|
|
582
664
|
const spinner = (0, ora_1.default)("Submitting verification request...").start();
|
|
@@ -604,16 +686,16 @@ async function skillsRequestVerificationCommand(slug) {
|
|
|
604
686
|
}
|
|
605
687
|
}
|
|
606
688
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
607
|
-
//
|
|
689
|
+
// orth skills publish <slug> (deprecated - redirects to request-verification)
|
|
608
690
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
609
691
|
async function skillsPublishCommand(slug, options) {
|
|
610
692
|
console.log(chalk_1.default.yellow("Note: Direct publishing has been replaced with a verification workflow."));
|
|
611
|
-
console.log(chalk_1.default.white(`\nTo request your skill to be verified, run:\n ${chalk_1.default.cyan(`
|
|
693
|
+
console.log(chalk_1.default.white(`\nTo request your skill to be verified, run:\n ${chalk_1.default.cyan(`orth skills request-verification ${slug}`)}`));
|
|
612
694
|
console.log(chalk_1.default.white("Once verified, you can toggle discoverability from your dashboard."));
|
|
613
695
|
console.log(chalk_1.default.gray("\nOr manage from the dashboard: https://orthogonal.com/dashboard/skills"));
|
|
614
696
|
}
|
|
615
697
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
616
|
-
//
|
|
698
|
+
// orth skills request <input>
|
|
617
699
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
618
700
|
async function skillsRequestCommand(input) {
|
|
619
701
|
const spinner = (0, ora_1.default)("Submitting skill request...").start();
|
package/dist/index.js
CHANGED
|
@@ -175,6 +175,15 @@ skillsGroup
|
|
|
175
175
|
(0, analytics_js_1.trackEvent)("skills.submit", { path: inputPath });
|
|
176
176
|
await (0, skills_js_1.skillsSubmitCommand)(inputPath, options);
|
|
177
177
|
}));
|
|
178
|
+
skillsGroup
|
|
179
|
+
.command("update <slug> [path]")
|
|
180
|
+
.description("Update an existing skill with local files")
|
|
181
|
+
.option("-n, --name <name>", "Override skill name from frontmatter")
|
|
182
|
+
.option("-t, --tags <tags>", "Comma-separated tags")
|
|
183
|
+
.action(asyncAction(async (slug, inputPath, options) => {
|
|
184
|
+
(0, analytics_js_1.trackEvent)("skills.update", { slug, path: inputPath });
|
|
185
|
+
await (0, skills_js_1.skillsUpdateCommand)(slug, inputPath, options);
|
|
186
|
+
}));
|
|
178
187
|
skillsGroup
|
|
179
188
|
.command("request-verification <slug>")
|
|
180
189
|
.description("Request verification for your skill (required before discoverability)")
|