@orth/cli 0.2.5 → 0.2.7

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/api.d.ts CHANGED
@@ -72,6 +72,39 @@ export interface IntegrateResponse {
72
72
  snippets: Record<string, string>;
73
73
  }
74
74
  export declare function search(prompt: string, limit?: number): Promise<SearchResponse>;
75
+ export interface ApiBySlugResponse {
76
+ success: boolean;
77
+ api: {
78
+ name: string;
79
+ slug: string;
80
+ description?: string;
81
+ baseUrl: string;
82
+ verified: boolean;
83
+ };
84
+ endpoints: Array<{
85
+ id: string;
86
+ path: string;
87
+ method: string;
88
+ description?: string;
89
+ price?: number;
90
+ isPayable?: boolean;
91
+ docsUrl?: string;
92
+ queryParams?: Array<{
93
+ name: string;
94
+ type: string;
95
+ required: boolean;
96
+ description?: string;
97
+ }>;
98
+ bodyParams?: Array<{
99
+ name: string;
100
+ type: string;
101
+ required: boolean;
102
+ description?: string;
103
+ }>;
104
+ }>;
105
+ count: number;
106
+ }
107
+ export declare function getApiBySlug(slug: string): Promise<ApiBySlugResponse>;
75
108
  export declare function getDetails(api: string, path: string): Promise<DetailsResponse>;
76
109
  export declare function run(api: string, path: string, options?: {
77
110
  method?: string;
package/dist/api.js CHANGED
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.apiRequest = apiRequest;
4
4
  exports.search = search;
5
+ exports.getApiBySlug = getApiBySlug;
5
6
  exports.getDetails = getDetails;
6
7
  exports.run = run;
7
8
  exports.integrate = integrate;
@@ -59,6 +60,9 @@ async function search(prompt, limit = 10) {
59
60
  body: { prompt, limit },
60
61
  });
61
62
  }
63
+ async function getApiBySlug(slug) {
64
+ return apiRequest(`/api-directory/${encodeURIComponent(slug)}`);
65
+ }
62
66
  async function getDetails(api, path) {
63
67
  return apiRequest("/details", {
64
68
  method: "POST",
@@ -1,4 +1,5 @@
1
1
  export declare function balanceCommand(): Promise<void>;
2
2
  export declare function usageCommand(options: {
3
3
  limit: string;
4
+ days?: string;
4
5
  }): Promise<void>;
@@ -11,50 +11,77 @@ const api_js_1 = require("../api.js");
11
11
  async function balanceCommand() {
12
12
  const spinner = (0, ora_1.default)("Fetching balance...").start();
13
13
  try {
14
- // Note: This endpoint may not exist yet - placeholder
15
- const data = await (0, api_js_1.apiRequest)("/account/balance");
14
+ const data = await (0, api_js_1.apiRequest)("/credits/balance");
16
15
  spinner.stop();
17
- if (data && data.balance !== undefined) {
18
- console.log(chalk_1.default.bold("\nAccount Balance:"));
19
- console.log(chalk_1.default.green.bold(` $${data.balance.toFixed(2)} ${data.currency || "USD"}`));
20
- }
21
- else {
22
- console.log(chalk_1.default.gray("Balance information not available."));
23
- console.log(chalk_1.default.gray("Check your balance at: https://orthogonal.com/dashboard"));
24
- }
16
+ console.log(`\n ${chalk_1.default.green.bold(data.balance)}\n`);
25
17
  }
26
18
  catch (error) {
27
19
  spinner.stop();
28
- // Graceful fallback if endpoint doesn't exist
29
- console.log(chalk_1.default.gray("Balance information not available via API."));
30
- console.log(chalk_1.default.gray("Check your balance at: https://orthogonal.com/dashboard"));
20
+ const message = error instanceof Error ? error.message : String(error);
21
+ if (message.includes("401") || message.includes("Authentication")) {
22
+ console.error(chalk_1.default.red("\n Authentication failed. Check your API key with: orth login\n"));
23
+ }
24
+ else {
25
+ console.error(chalk_1.default.red(`\n Failed to fetch balance: ${message}\n`));
26
+ }
27
+ process.exit(1);
31
28
  }
32
29
  }
33
30
  async function usageCommand(options) {
34
31
  const spinner = (0, ora_1.default)("Fetching usage...").start();
35
32
  try {
36
- // Note: This endpoint may not exist yet - placeholder
37
- const data = await (0, api_js_1.apiRequest)(`/account/usage?limit=${options.limit}`);
33
+ const limit = parseInt(options.limit) || 20;
34
+ const days = parseInt(options.days || "30") || 30;
35
+ const data = await (0, api_js_1.apiRequest)(`/credits/usage?limit=${limit}&days=${days}`);
38
36
  spinner.stop();
39
- if (data?.usage && data.usage.length > 0) {
40
- console.log(chalk_1.default.bold("\nRecent API Usage:\n"));
41
- for (const item of data.usage) {
42
- const date = new Date(item.timestamp).toLocaleString();
43
- console.log(chalk_1.default.gray(date.padEnd(22)) +
44
- chalk_1.default.cyan(item.api.padEnd(15)) +
45
- chalk_1.default.white(item.path.padEnd(30)) +
46
- chalk_1.default.green(`$${item.cost.toFixed(4)}`));
47
- }
48
- console.log(chalk_1.default.bold(`\nTotal: $${data.total.toFixed(2)}`));
37
+ if (!data?.usage || data.usage.length === 0) {
38
+ console.log(chalk_1.default.gray("\n No API usage in the last " + days + " days.\n"));
39
+ return;
49
40
  }
50
- else {
51
- console.log(chalk_1.default.gray("No recent usage data available."));
41
+ console.log(chalk_1.default.bold(`\n API Usage (last ${days} days)\n`));
42
+ // Table header
43
+ console.log(chalk_1.default.gray(" " +
44
+ "Date".padEnd(18) +
45
+ "API".padEnd(20) +
46
+ "Endpoint".padEnd(32) +
47
+ "Cost".padStart(10)));
48
+ console.log(chalk_1.default.gray(" " + "─".repeat(80)));
49
+ for (const item of data.usage) {
50
+ const date = new Date(item.timestamp).toLocaleDateString("en-US", {
51
+ month: "short",
52
+ day: "numeric",
53
+ hour: "2-digit",
54
+ minute: "2-digit",
55
+ });
56
+ const statusIcon = item.status === "completed" ? "" : chalk_1.default.yellow(" ⚠");
57
+ const api = item.api ?? "unknown";
58
+ const method = item.method ?? "";
59
+ const path = item.path ?? "";
60
+ const cost = item.cost ?? "$0.00";
61
+ console.log(" " +
62
+ chalk_1.default.gray(date.padEnd(18)) +
63
+ chalk_1.default.cyan(api.padEnd(20)) +
64
+ chalk_1.default.white((method + " " + path).substring(0, 30).padEnd(32)) +
65
+ chalk_1.default.green(cost.padStart(10)) +
66
+ statusIcon);
67
+ }
68
+ // Summary
69
+ if (data.totalSpent) {
70
+ console.log(chalk_1.default.gray("\n " + "─".repeat(80)));
71
+ console.log(chalk_1.default.bold(` Total: ${chalk_1.default.green(data.totalSpent)}`) +
72
+ chalk_1.default.gray(` (${data.pagination.total} calls)`));
52
73
  }
74
+ console.log();
53
75
  }
54
76
  catch (error) {
55
77
  spinner.stop();
56
- // Graceful fallback if endpoint doesn't exist
57
- console.log(chalk_1.default.gray("Usage information not available via API."));
58
- console.log(chalk_1.default.gray("Check your usage at: https://orthogonal.com/dashboard/usage"));
78
+ const message = error instanceof Error ? error.message : String(error);
79
+ if (message.includes("401") || message.includes("Authentication")) {
80
+ console.error(chalk_1.default.red("\n Authentication failed. Check your API key with: orth login\n"));
81
+ }
82
+ else {
83
+ console.error(chalk_1.default.red(`\n Failed to fetch usage: ${message}\n`));
84
+ }
85
+ process.exit(1);
59
86
  }
60
87
  }
@@ -116,25 +116,49 @@ async function apiCommand(slug, path, options) {
116
116
  }
117
117
  return;
118
118
  }
119
- // Show API endpoints
120
- const data = await (0, api_js_1.search)(slug, 20);
121
- spinner.stop();
122
- const api = data.results.find((a) => a.slug === slug);
123
- if (!api) {
124
- console.log(chalk_1.default.yellow(`API '${slug}' not found.`));
125
- console.log(chalk_1.default.gray("Run 'orth api' to see available APIs"));
126
- return;
119
+ // Show API endpoints - direct lookup by slug
120
+ try {
121
+ const apiData = await (0, api_js_1.getApiBySlug)(slug);
122
+ spinner.stop();
123
+ const api = apiData.api;
124
+ console.log(chalk_1.default.bold(`\n${chalk_1.default.cyan(api.name)} (${api.slug})\n`));
125
+ for (const endpoint of apiData.endpoints) {
126
+ const method = chalk_1.default.yellow(endpoint.method.padEnd(6));
127
+ const price = endpoint.price === 0 || endpoint.price === null || endpoint.price === undefined
128
+ ? chalk_1.default.green("free")
129
+ : "";
130
+ console.log(`${method} ${chalk_1.default.white(endpoint.path)} ${price}`);
131
+ if (endpoint.description) {
132
+ console.log(chalk_1.default.gray(` ${endpoint.description.slice(0, 80)}${endpoint.description.length > 80 ? "..." : ""}`));
133
+ }
134
+ }
135
+ console.log(chalk_1.default.gray("\nRun 'orth api show " + slug + " <path>' for endpoint details"));
136
+ console.log(chalk_1.default.gray("Run 'orth run " + slug + " <path>' to call an endpoint"));
127
137
  }
128
- console.log(chalk_1.default.bold(`\n${chalk_1.default.cyan(api.name)} (${api.slug})\n`));
129
- for (const endpoint of api.endpoints) {
130
- const method = chalk_1.default.yellow(endpoint.method.padEnd(6));
131
- console.log(`${method} ${chalk_1.default.white(endpoint.path)}`);
132
- if (endpoint.description) {
133
- console.log(chalk_1.default.gray(` ${endpoint.description.slice(0, 80)}${endpoint.description.length > 80 ? "..." : ""}`));
138
+ catch {
139
+ // Fallback to search if direct lookup fails (e.g. older backend)
140
+ const data = await (0, api_js_1.search)(slug, 20);
141
+ spinner.stop();
142
+ const api = data.results.find((a) => a.slug === slug);
143
+ if (!api) {
144
+ console.log(chalk_1.default.yellow(`API '${slug}' not found.`));
145
+ console.log(chalk_1.default.gray("Run 'orth api' to see available APIs"));
146
+ return;
147
+ }
148
+ console.log(chalk_1.default.bold(`\n${chalk_1.default.cyan(api.name)} (${api.slug})\n`));
149
+ for (const endpoint of api.endpoints) {
150
+ const method = chalk_1.default.yellow(endpoint.method.padEnd(6));
151
+ const price = endpoint.price === 0 || endpoint.price === null || endpoint.price === undefined
152
+ ? chalk_1.default.green("free")
153
+ : "";
154
+ console.log(`${method} ${chalk_1.default.white(endpoint.path)} ${price}`);
155
+ if (endpoint.description) {
156
+ console.log(chalk_1.default.gray(` ${endpoint.description.slice(0, 80)}${endpoint.description.length > 80 ? "..." : ""}`));
157
+ }
134
158
  }
159
+ console.log(chalk_1.default.gray("\nRun 'orth api show " + slug + " <path>' for endpoint details"));
160
+ console.log(chalk_1.default.gray("Run 'orth run " + slug + " <path>' to call an endpoint"));
135
161
  }
136
- console.log(chalk_1.default.gray("\nRun 'orth api show " + slug + " <path>' for endpoint details"));
137
- console.log(chalk_1.default.gray("Run 'orth run " + slug + " <path>' to call an endpoint"));
138
162
  }
139
163
  catch (error) {
140
164
  spinner.stop();
package/dist/index.js CHANGED
@@ -67,7 +67,8 @@ program
67
67
  program
68
68
  .command("usage")
69
69
  .description("Show recent API usage")
70
- .option("-l, --limit <number>", "Number of recent calls", "10")
70
+ .option("-l, --limit <number>", "Number of recent calls", "20")
71
+ .option("-d, --days <number>", "Number of days to look back", "30")
71
72
  .action(asyncAction(async (options) => {
72
73
  (0, analytics_js_1.trackEvent)("usage");
73
74
  await (0, account_js_1.usageCommand)(options);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orth/cli",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "description": "CLI to access all APIs and skills on the Orthogonal platform",
5
5
  "main": "dist/index.js",
6
6
  "bin": {