@orth/cli 0.2.0

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/config.js ADDED
@@ -0,0 +1,36 @@
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.config = void 0;
7
+ exports.getApiKey = getApiKey;
8
+ exports.setApiKey = setApiKey;
9
+ exports.clearApiKey = clearApiKey;
10
+ exports.requireApiKey = requireApiKey;
11
+ const conf_1 = __importDefault(require("conf"));
12
+ exports.config = new conf_1.default({
13
+ projectName: "orthogonal-cli",
14
+ schema: {
15
+ apiKey: {
16
+ type: "string",
17
+ },
18
+ },
19
+ });
20
+ function getApiKey() {
21
+ return process.env.ORTHOGONAL_API_KEY || exports.config.get("apiKey");
22
+ }
23
+ function setApiKey(key) {
24
+ exports.config.set("apiKey", key);
25
+ }
26
+ function clearApiKey() {
27
+ exports.config.delete("apiKey");
28
+ }
29
+ function requireApiKey() {
30
+ const key = getApiKey();
31
+ if (!key) {
32
+ console.error("Error: Not authenticated. Run 'orth login' first or set ORTHOGONAL_API_KEY.");
33
+ process.exit(1);
34
+ }
35
+ return key;
36
+ }
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,249 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const commander_1 = require("commander");
5
+ const search_js_1 = require("./commands/search.js");
6
+ const run_js_1 = require("./commands/run.js");
7
+ const api_js_1 = require("./commands/api.js");
8
+ const auth_js_1 = require("./commands/auth.js");
9
+ const account_js_1 = require("./commands/account.js");
10
+ const code_js_1 = require("./commands/code.js");
11
+ const skills_js_1 = require("./commands/skills.js");
12
+ const apiRequest_js_1 = require("./commands/apiRequest.js");
13
+ const analytics_js_1 = require("./analytics.js");
14
+ /**
15
+ * Wraps an async action callback so that rejected promises are caught,
16
+ * logged, and cause the process to exit with code 1. Without this,
17
+ * Commander.js silently swallows unhandled rejections from async actions.
18
+ */
19
+ function asyncAction(fn) {
20
+ return (...args) => {
21
+ fn(...args).catch((err) => {
22
+ console.error(err instanceof Error ? err.message : "Unknown error");
23
+ process.exit(1);
24
+ });
25
+ };
26
+ }
27
+ const program = new commander_1.Command();
28
+ program
29
+ .name("orth")
30
+ .description("CLI to access all APIs and skills on the Orthogonal platform")
31
+ .version("0.2.0");
32
+ // ─────────────────────────────────────────────────────────────────────────────
33
+ // Auth commands (top-level)
34
+ // ─────────────────────────────────────────────────────────────────────────────
35
+ program
36
+ .command("login")
37
+ .description("Authenticate with your Orthogonal API key")
38
+ .option("-k, --key <key>", "API key (or set ORTHOGONAL_API_KEY env var)")
39
+ .action(asyncAction(async (options) => {
40
+ (0, analytics_js_1.trackEvent)("login");
41
+ await (0, auth_js_1.loginCommand)(options);
42
+ }));
43
+ program
44
+ .command("logout")
45
+ .description("Remove stored API key")
46
+ .action(asyncAction(async () => {
47
+ (0, analytics_js_1.trackEvent)("logout");
48
+ await (0, auth_js_1.logoutCommand)();
49
+ }));
50
+ program
51
+ .command("whoami")
52
+ .description("Show current authentication status")
53
+ .action(asyncAction(async () => {
54
+ (0, analytics_js_1.trackEvent)("whoami");
55
+ await (0, auth_js_1.whoamiCommand)();
56
+ }));
57
+ // ─────────────────────────────────────────────────────────────────────────────
58
+ // Account commands (top-level)
59
+ // ─────────────────────────────────────────────────────────────────────────────
60
+ program
61
+ .command("balance")
62
+ .description("Check your credit balance")
63
+ .action(asyncAction(async () => {
64
+ (0, analytics_js_1.trackEvent)("balance");
65
+ await (0, account_js_1.balanceCommand)();
66
+ }));
67
+ program
68
+ .command("usage")
69
+ .description("Show recent API usage")
70
+ .option("-l, --limit <number>", "Number of recent calls", "10")
71
+ .action(asyncAction(async (options) => {
72
+ (0, analytics_js_1.trackEvent)("usage");
73
+ await (0, account_js_1.usageCommand)(options);
74
+ }));
75
+ // ─────────────────────────────────────────────────────────────────────────────
76
+ // orth api <subcommand> — API commands group
77
+ // ─────────────────────────────────────────────────────────────────────────────
78
+ const apiGroup = program.command("api").description("API marketplace commands");
79
+ apiGroup
80
+ .command("list")
81
+ .description("List available APIs")
82
+ .action(asyncAction(async () => {
83
+ (0, analytics_js_1.trackEvent)("api.list");
84
+ await (0, api_js_1.apiCommand)(undefined, undefined, {});
85
+ }));
86
+ apiGroup
87
+ .command("show <slug> [path]")
88
+ .description("Show API endpoints or endpoint details")
89
+ .option("--x402", "Output x402 payment URL only")
90
+ .option("--x402-full", "Output full x402 payment details")
91
+ .action(asyncAction(async (slug, path, options) => {
92
+ (0, analytics_js_1.trackEvent)("api.show", { slug, path });
93
+ await (0, api_js_1.apiCommand)(slug, path, options);
94
+ }));
95
+ apiGroup
96
+ .command("search <query>")
97
+ .description("Search for APIs using natural language")
98
+ .option("-l, --limit <number>", "Max results", "10")
99
+ .action(asyncAction(async (query, options) => {
100
+ (0, analytics_js_1.trackEvent)("api.search", { query });
101
+ await (0, search_js_1.searchCommand)(query, options);
102
+ }));
103
+ apiGroup
104
+ .command("run <slug> <path>")
105
+ .description("Call an API endpoint")
106
+ .option("-X, --method <method>", "HTTP method", "GET")
107
+ .option("-q, --query <params...>", "Query params (key=value)")
108
+ .option("-b, --body <json>", "Request body JSON")
109
+ .option("-d, --data <json>", "Alias for --body")
110
+ .option("--raw", "Output raw JSON without formatting")
111
+ .action(asyncAction(async (slug, path, options) => {
112
+ (0, analytics_js_1.trackEvent)("api.run", { slug, path });
113
+ await (0, run_js_1.runCommand)(slug, path, options);
114
+ }));
115
+ apiGroup
116
+ .command("code <slug> <path>")
117
+ .description("Generate integration code for an endpoint")
118
+ .option("-l, --lang <language>", "Language: typescript, python, curl", "typescript")
119
+ .action(asyncAction(async (slug, path, options) => {
120
+ (0, analytics_js_1.trackEvent)("api.code", { slug, path });
121
+ await (0, code_js_1.codeCommand)(slug, path, options);
122
+ }));
123
+ apiGroup
124
+ .command("request <docsUrl>")
125
+ .description("Request an API to be added to the platform")
126
+ .option("-d, --description <text>", "Additional notes about the API")
127
+ .action(asyncAction(async (docsUrl, options) => {
128
+ (0, analytics_js_1.trackEvent)("api.request", { docsUrl });
129
+ await (0, apiRequest_js_1.apiRequestCommand)(docsUrl, options);
130
+ }));
131
+ // ─────────────────────────────────────────────────────────────────────────────
132
+ // orth skills <subcommand> — Skills commands group
133
+ // ─────────────────────────────────────────────────────────────────────────────
134
+ const skillsGroup = program
135
+ .command("skills")
136
+ .description("Agent skills library commands");
137
+ skillsGroup
138
+ .command("list")
139
+ .description("List discoverable skills")
140
+ .option("-l, --limit <number>", "Max results", "20")
141
+ .action(asyncAction(async (options) => {
142
+ (0, analytics_js_1.trackEvent)("skills.list");
143
+ await (0, skills_js_1.skillsListCommand)(options);
144
+ }));
145
+ skillsGroup
146
+ .command("search <query>")
147
+ .description("Search for agent skills")
148
+ .option("-l, --limit <number>", "Max results", "20")
149
+ .action(asyncAction(async (query, options) => {
150
+ (0, analytics_js_1.trackEvent)("skills.search", { query });
151
+ await (0, skills_js_1.skillsSearchCommand)(query, options);
152
+ }));
153
+ skillsGroup
154
+ .command("show <slug>")
155
+ .description("Show skill details and files")
156
+ .action(asyncAction(async (slug) => {
157
+ (0, analytics_js_1.trackEvent)("skills.show", { slug });
158
+ await (0, skills_js_1.skillsShowCommand)(slug);
159
+ }));
160
+ skillsGroup
161
+ .command("init [name]")
162
+ .description("Initialize a new skill directory with SKILL.md template")
163
+ .option("--bare", "Only create SKILL.md, skip subdirectories")
164
+ .option("--path <dir>", "Output directory")
165
+ .action(asyncAction(async (name, options) => {
166
+ (0, analytics_js_1.trackEvent)("skills.init", { name });
167
+ await (0, skills_js_1.skillsInitCommand)(name, options);
168
+ }));
169
+ skillsGroup
170
+ .command("submit [path]")
171
+ .description("Submit a local skill to the Orthogonal platform")
172
+ .option("-n, --name <name>", "Override skill name from frontmatter")
173
+ .option("-t, --tags <tags>", "Comma-separated tags")
174
+ .action(asyncAction(async (inputPath, options) => {
175
+ (0, analytics_js_1.trackEvent)("skills.submit", { path: inputPath });
176
+ await (0, skills_js_1.skillsSubmitCommand)(inputPath, options);
177
+ }));
178
+ skillsGroup
179
+ .command("request-verification <slug>")
180
+ .description("Request verification for your skill (required before discoverability)")
181
+ .action(asyncAction(async (slug) => {
182
+ (0, analytics_js_1.trackEvent)("skills.request-verification", { slug });
183
+ await (0, skills_js_1.skillsRequestVerificationCommand)(slug);
184
+ }));
185
+ skillsGroup
186
+ .command("create <githubRepo>")
187
+ .description("Create a skill from a GitHub URL or owner/repo")
188
+ .option("-p, --path <path>", "Path to skill within repo")
189
+ .option("-r, --ref <ref>", "Git ref (branch/tag)", "main")
190
+ .option("-n, --name <name>", "Skill name (auto-detected from SKILL.md)")
191
+ .action(asyncAction(async (githubRepo, options) => {
192
+ (0, analytics_js_1.trackEvent)("skills.create", { githubRepo });
193
+ await (0, skills_js_1.skillsCreateCommand)(githubRepo, options);
194
+ }));
195
+ skillsGroup
196
+ .command("add <slug>")
197
+ .description("Add a skill to your local agent skills directories")
198
+ .option("--agent <agent>", "Install for specific agent only (cursor, claude, copilot)")
199
+ .action(asyncAction(async (slug, options) => {
200
+ (0, analytics_js_1.trackEvent)("skills.add", { slug });
201
+ await (0, skills_js_1.skillsInstallCommand)(slug, options);
202
+ }));
203
+ skillsGroup
204
+ .command("publish <slug>")
205
+ .description("Toggle skill discoverability")
206
+ .option("--unpublish", "Make skill private")
207
+ .action(asyncAction(async (slug, options) => {
208
+ (0, analytics_js_1.trackEvent)("skills.publish", { slug });
209
+ await (0, skills_js_1.skillsPublishCommand)(slug, options);
210
+ }));
211
+ skillsGroup
212
+ .command("request <input>")
213
+ .description("Request a skill to be added (GitHub URL or description)")
214
+ .action(asyncAction(async (input) => {
215
+ (0, analytics_js_1.trackEvent)("skills.request", { input });
216
+ await (0, skills_js_1.skillsRequestCommand)(input);
217
+ }));
218
+ // ─────────────────────────────────────────────────────────────────────────────
219
+ // Backward-compatible aliases (flat commands)
220
+ // ─────────────────────────────────────────────────────────────────────────────
221
+ program
222
+ .command("search <query>")
223
+ .description("Search for APIs (alias for 'orth api search')")
224
+ .option("-l, --limit <number>", "Max results", "10")
225
+ .action(asyncAction(async (query, options) => {
226
+ (0, analytics_js_1.trackEvent)("search", { query });
227
+ await (0, search_js_1.searchCommand)(query, options);
228
+ }));
229
+ program
230
+ .command("run <api> <path>")
231
+ .description("Call an API endpoint (alias for 'orth api run')")
232
+ .option("-X, --method <method>", "HTTP method", "GET")
233
+ .option("-q, --query <params...>", "Query params (key=value)")
234
+ .option("-b, --body <json>", "Request body JSON")
235
+ .option("-d, --data <json>", "Alias for --body")
236
+ .option("--raw", "Output raw JSON without formatting")
237
+ .action(asyncAction(async (api, path, options) => {
238
+ (0, analytics_js_1.trackEvent)("run", { api, path });
239
+ await (0, run_js_1.runCommand)(api, path, options);
240
+ }));
241
+ program
242
+ .command("code <api> <path>")
243
+ .description("Generate integration code (alias for 'orth api code')")
244
+ .option("-l, --lang <language>", "Language: typescript, python, curl", "typescript")
245
+ .action(asyncAction(async (api, path, options) => {
246
+ (0, analytics_js_1.trackEvent)("code", { api, path });
247
+ await (0, code_js_1.codeCommand)(api, path, options);
248
+ }));
249
+ program.parse();
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@orth/cli",
3
+ "version": "0.2.0",
4
+ "description": "CLI to access all APIs and skills on the Orthogonal platform",
5
+ "main": "dist/index.js",
6
+ "bin": {
7
+ "orth": "dist/index.js"
8
+ },
9
+ "files": [
10
+ "dist",
11
+ "README.md"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc",
15
+ "dev": "tsc -w",
16
+ "start": "node dist/index.js",
17
+ "test": "vitest run",
18
+ "test:watch": "vitest",
19
+ "prepublishOnly": "npm run build"
20
+ },
21
+ "keywords": [
22
+ "orthogonal",
23
+ "api",
24
+ "cli",
25
+ "ai-agents",
26
+ "skills",
27
+ "mcp"
28
+ ],
29
+ "author": "Orthogonal <founders@orthogonal.sh> (https://orthogonal.sh)",
30
+ "license": "MIT",
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "git+https://github.com/orthogonal-sh/cli.git"
34
+ },
35
+ "homepage": "https://orthogonal.sh",
36
+ "bugs": {
37
+ "url": "https://github.com/orthogonal-sh/cli/issues"
38
+ },
39
+ "publishConfig": {
40
+ "access": "public"
41
+ },
42
+ "dependencies": {
43
+ "chalk": "^5.3.0",
44
+ "commander": "^12.0.0",
45
+ "conf": "^12.0.0",
46
+ "node-fetch": "^3.3.2",
47
+ "ora": "^8.0.1"
48
+ },
49
+ "devDependencies": {
50
+ "@types/node": "^20.0.0",
51
+ "typescript": "^5.0.0",
52
+ "vitest": "^3.2.4"
53
+ },
54
+ "engines": {
55
+ "node": ">=18"
56
+ }
57
+ }