@dubeyvishal/orbital-cli 1.2.9 → 1.4.9
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dubeyvishal/orbital-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.9",
|
|
4
4
|
"description": "A fullstack CLI-based AI platform with chat mode, multi-tool agents, and agentic AI workflows. Includes GitHub login with device authorization, secure authentication, and modular client–server architecture for building intelligent automation tools.",
|
|
5
5
|
"author": "Vishal Dubey",
|
|
6
6
|
"license": "MIT",
|
|
@@ -3,12 +3,9 @@ import { cancel, confirm, intro, outro, isCancel } from "@clack/prompts";
|
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import { Command } from "commander";
|
|
5
5
|
import open from "open";
|
|
6
|
-
import os from "os";
|
|
7
6
|
import path from "path";
|
|
8
7
|
import yoctoSpinner from "yocto-spinner";
|
|
9
8
|
import * as z from "zod";
|
|
10
|
-
import { createAuthClient } from "better-auth/client";
|
|
11
|
-
import { deviceAuthorizationClient } from "better-auth/client/plugins";
|
|
12
9
|
|
|
13
10
|
import { fileURLToPath } from "url";
|
|
14
11
|
import { getStoredToken, isTokenExpired, storeToken ,TOKEN_FILE } from "../../../lib/token.js";
|
|
@@ -17,12 +14,66 @@ import { apiRequestSafe } from "../../utils/apiClient.js";
|
|
|
17
14
|
import { requireGeminiApiKey } from "../../../lib/orbitalConfig.js";
|
|
18
15
|
|
|
19
16
|
|
|
20
|
-
|
|
21
17
|
const __filename = fileURLToPath(import.meta.url);
|
|
22
18
|
const __dirname = path.dirname(__filename);
|
|
23
19
|
|
|
24
20
|
const URL = API_BASE;
|
|
25
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Request a device authorization code from the server via direct fetch.
|
|
24
|
+
* Replaces: authClient.device.code()
|
|
25
|
+
*/
|
|
26
|
+
const safeJson = async (res) => {
|
|
27
|
+
const text = await res.text();
|
|
28
|
+
if (!text) return null;
|
|
29
|
+
try {
|
|
30
|
+
return JSON.parse(text);
|
|
31
|
+
} catch {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const requestDeviceCode = async (serverUrl, clientId, scope) => {
|
|
37
|
+
const res = await fetch(`${serverUrl}/api/auth/device/code`, {
|
|
38
|
+
method: "POST",
|
|
39
|
+
headers: { "Content-Type": "application/json" },
|
|
40
|
+
body: JSON.stringify({ client_id: clientId, scope }),
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const body = await safeJson(res);
|
|
44
|
+
|
|
45
|
+
if (!res.ok) {
|
|
46
|
+
return { data: null, error: body || { message: `HTTP ${res.status}` } };
|
|
47
|
+
}
|
|
48
|
+
return { data: body, error: null };
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Poll for a device token from the server via direct fetch.
|
|
53
|
+
* Replaces: authClient.device.token()
|
|
54
|
+
*/
|
|
55
|
+
const requestDeviceToken = async (serverUrl, deviceCode, clientId) => {
|
|
56
|
+
const res = await fetch(`${serverUrl}/api/auth/device/token`, {
|
|
57
|
+
method: "POST",
|
|
58
|
+
headers: {
|
|
59
|
+
"Content-Type": "application/json",
|
|
60
|
+
"user-agent": "Orbital CLI",
|
|
61
|
+
},
|
|
62
|
+
body: JSON.stringify({
|
|
63
|
+
grant_type: "urn:ietf:params:oauth:grant-type:device_code",
|
|
64
|
+
device_code: deviceCode,
|
|
65
|
+
client_id: clientId,
|
|
66
|
+
}),
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
const body = await safeJson(res);
|
|
70
|
+
|
|
71
|
+
if (!res.ok) {
|
|
72
|
+
return { data: null, error: body || { message: `HTTP ${res.status}` } };
|
|
73
|
+
}
|
|
74
|
+
return { data: body, error: null };
|
|
75
|
+
};
|
|
76
|
+
|
|
26
77
|
const resolveClientId = async (cliClientId) => {
|
|
27
78
|
const resolved = (cliClientId || "").trim();
|
|
28
79
|
if (resolved.length > 0) return resolved;
|
|
@@ -85,20 +136,16 @@ export const loginAction = async (cmdOptions) => {
|
|
|
85
136
|
}
|
|
86
137
|
}
|
|
87
138
|
|
|
88
|
-
const authClient = createAuthClient({
|
|
89
|
-
baseURL: serverUrl,
|
|
90
|
-
plugins: [deviceAuthorizationClient()],
|
|
91
|
-
});
|
|
92
|
-
|
|
93
139
|
const spinner = yoctoSpinner({
|
|
94
140
|
text: "Requesting device authorization...",
|
|
95
141
|
}).start();
|
|
96
142
|
|
|
97
143
|
try {
|
|
98
|
-
const { data, error } = await
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
144
|
+
const { data, error } = await requestDeviceCode(
|
|
145
|
+
serverUrl,
|
|
146
|
+
clientId,
|
|
147
|
+
"openid profile email",
|
|
148
|
+
);
|
|
102
149
|
|
|
103
150
|
spinner.stop();
|
|
104
151
|
|
|
@@ -150,7 +197,7 @@ export const loginAction = async (cmdOptions) => {
|
|
|
150
197
|
);
|
|
151
198
|
|
|
152
199
|
const token = await pollForToken(
|
|
153
|
-
|
|
200
|
+
serverUrl,
|
|
154
201
|
device_code,
|
|
155
202
|
clientId,
|
|
156
203
|
interval,
|
|
@@ -179,7 +226,7 @@ export const loginAction = async (cmdOptions) => {
|
|
|
179
226
|
};
|
|
180
227
|
|
|
181
228
|
const pollForToken = async (
|
|
182
|
-
|
|
229
|
+
serverUrl,
|
|
183
230
|
deviceCode,
|
|
184
231
|
clientId,
|
|
185
232
|
initialInterval,
|
|
@@ -199,16 +246,11 @@ const pollForToken = async (
|
|
|
199
246
|
if (!spinner.isSpinning) spinner.start();
|
|
200
247
|
|
|
201
248
|
try {
|
|
202
|
-
const { data, error } = await
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
headers: {
|
|
208
|
-
"user-agent": `My CLI`,
|
|
209
|
-
},
|
|
210
|
-
},
|
|
211
|
-
});
|
|
249
|
+
const { data, error } = await requestDeviceToken(
|
|
250
|
+
serverUrl,
|
|
251
|
+
deviceCode,
|
|
252
|
+
clientId,
|
|
253
|
+
);
|
|
212
254
|
|
|
213
255
|
if (data?.access_token) {
|
|
214
256
|
spinner.stop();
|
|
@@ -254,7 +296,7 @@ const pollForToken = async (
|
|
|
254
296
|
};
|
|
255
297
|
|
|
256
298
|
export const login = new Command("login")
|
|
257
|
-
.description("Login to
|
|
258
|
-
.option("--server-url <url>", "The
|
|
299
|
+
.description("Login to Orbital CLI")
|
|
300
|
+
.option("--server-url <url>", "The server URL", URL)
|
|
259
301
|
.option("--client-id <id>", "The OAuth client ID")
|
|
260
302
|
.action(loginAction);
|