@vendian/cli 0.0.39 → 0.0.41
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/cli-wrapper.mjs +77 -30
- package/package.json +1 -1
package/cli-wrapper.mjs
CHANGED
|
@@ -43,7 +43,9 @@ __export(auth_exports, {
|
|
|
43
43
|
buildWindowsOpenCommand: () => buildWindowsOpenCommand,
|
|
44
44
|
cloudAuthStatus: () => cloudAuthStatus,
|
|
45
45
|
cloudConfigPath: () => cloudConfigPath,
|
|
46
|
+
defaultOAuthRedirectUri: () => defaultOAuthRedirectUri,
|
|
46
47
|
fetchPackageCredentials: () => fetchPackageCredentials,
|
|
48
|
+
formatOAuthError: () => formatOAuthError,
|
|
47
49
|
loadCloudConfig: () => loadCloudConfig,
|
|
48
50
|
loginWithVendianOAuth: () => loginWithVendianOAuth,
|
|
49
51
|
resolveApiUrl: () => resolveApiUrl,
|
|
@@ -91,6 +93,11 @@ async function loginWithVendianOAuth({ backend, apiUrl, noBrowser = false, env =
|
|
|
91
93
|
clerkToken
|
|
92
94
|
});
|
|
93
95
|
return { apiUrl: resolvedApiUrl, ...exchange };
|
|
96
|
+
} catch (error) {
|
|
97
|
+
throw new Error(formatOAuthError(error, {
|
|
98
|
+
apiUrl: resolvedApiUrl,
|
|
99
|
+
redirectUri: callback.redirectUri
|
|
100
|
+
}), { cause: error });
|
|
94
101
|
} finally {
|
|
95
102
|
await callback.close();
|
|
96
103
|
}
|
|
@@ -175,6 +182,16 @@ function activateCloudProfile({ backend, apiUrl, env = process.env, platform = p
|
|
|
175
182
|
profiles
|
|
176
183
|
};
|
|
177
184
|
}
|
|
185
|
+
function defaultOAuthRedirectUri(env = process.env) {
|
|
186
|
+
const port = Number(env.VENDIAN_CLI_OAUTH_REDIRECT_PORT || DEFAULT_OAUTH_REDIRECT_PORT);
|
|
187
|
+
return `http://127.0.0.1:${port}/callback`;
|
|
188
|
+
}
|
|
189
|
+
function formatOAuthError(error, { apiUrl, redirectUri } = {}) {
|
|
190
|
+
const message = error && typeof error.message === "string" ? error.message : String(error || "OAuth login failed");
|
|
191
|
+
const hint = oauthRedirectHint(message, { apiUrl, redirectUri });
|
|
192
|
+
return hint ? `${message}
|
|
193
|
+
${hint}` : message;
|
|
194
|
+
}
|
|
178
195
|
async function getOAuthConfig(apiUrl, redirectUri) {
|
|
179
196
|
const url = new URL(`${apiUrl}/api/v1/cli/auth/oauth/config`);
|
|
180
197
|
url.searchParams.set("redirectUri", redirectUri);
|
|
@@ -256,6 +273,7 @@ async function createCallbackServer(env) {
|
|
|
256
273
|
const code = url.searchParams.get("code");
|
|
257
274
|
const state = url.searchParams.get("state");
|
|
258
275
|
const error = url.searchParams.get("error");
|
|
276
|
+
const errorDescription = url.searchParams.get("error_description");
|
|
259
277
|
const body = code ? "Vendian CLI authentication complete. You can close this window." : "Vendian CLI authentication failed. Return to the terminal.";
|
|
260
278
|
res.writeHead(code ? 200 : 400, {
|
|
261
279
|
"Content-Type": "text/plain; charset=utf-8",
|
|
@@ -268,7 +286,8 @@ async function createCallbackServer(env) {
|
|
|
268
286
|
}
|
|
269
287
|
settled = true;
|
|
270
288
|
if (error) {
|
|
271
|
-
|
|
289
|
+
const details = errorDescription ? `${error} (${errorDescription})` : error;
|
|
290
|
+
reject(new Error(`OAuth login failed: ${details}`));
|
|
272
291
|
return;
|
|
273
292
|
}
|
|
274
293
|
if (!code) {
|
|
@@ -290,6 +309,18 @@ async function createCallbackServer(env) {
|
|
|
290
309
|
close: () => new Promise((resolve) => server.close(resolve))
|
|
291
310
|
};
|
|
292
311
|
}
|
|
312
|
+
function oauthRedirectHint(message, { apiUrl, redirectUri } = {}) {
|
|
313
|
+
if (!redirectUri) {
|
|
314
|
+
return "";
|
|
315
|
+
}
|
|
316
|
+
const lower = String(message || "").toLowerCase();
|
|
317
|
+
const looksLikeRedirectMismatch = lower.includes("redirect_uri") || lower.includes("pre-registered redirect") || lower.includes("oauth login timed out before callback completed") || lower.includes("oauth callback did not include an authorization code");
|
|
318
|
+
if (!looksLikeRedirectMismatch) {
|
|
319
|
+
return "";
|
|
320
|
+
}
|
|
321
|
+
const target = apiUrl || "this backend";
|
|
322
|
+
return `If Clerk rejected the CLI callback for ${target}, add this redirect URL in Clerk: ${redirectUri}`;
|
|
323
|
+
}
|
|
293
324
|
function openBrowser(url) {
|
|
294
325
|
const platform = process.platform;
|
|
295
326
|
if (platform === "win32") {
|
|
@@ -491,6 +522,29 @@ function spawnForward(command, args, options = {}) {
|
|
|
491
522
|
});
|
|
492
523
|
});
|
|
493
524
|
}
|
|
525
|
+
function childProcessIsRunning(child) {
|
|
526
|
+
return Boolean(child) && child.exitCode == null && child.signalCode == null;
|
|
527
|
+
}
|
|
528
|
+
function killProcessTree(child, {
|
|
529
|
+
platform = process.platform,
|
|
530
|
+
signal = "SIGTERM",
|
|
531
|
+
spawnSyncFn = spawnSync
|
|
532
|
+
} = {}) {
|
|
533
|
+
if (!childProcessIsRunning(child)) return false;
|
|
534
|
+
if (platform === "win32") {
|
|
535
|
+
try {
|
|
536
|
+
spawnSyncFn("taskkill", ["/F", "/T", "/PID", String(child.pid)], { stdio: "ignore" });
|
|
537
|
+
} catch {
|
|
538
|
+
}
|
|
539
|
+
return true;
|
|
540
|
+
}
|
|
541
|
+
try {
|
|
542
|
+
child.kill(signal);
|
|
543
|
+
return true;
|
|
544
|
+
} catch {
|
|
545
|
+
return false;
|
|
546
|
+
}
|
|
547
|
+
}
|
|
494
548
|
|
|
495
549
|
// src/python.js
|
|
496
550
|
import fs2 from "node:fs";
|
|
@@ -2381,7 +2435,7 @@ function buildLocalServeEventStreamArgs({ agentsDir: agentsDir2 = "./agents", co
|
|
|
2381
2435
|
}
|
|
2382
2436
|
|
|
2383
2437
|
// src/version.js
|
|
2384
|
-
var CLI_VERSION = true ? "0.0.
|
|
2438
|
+
var CLI_VERSION = true ? "0.0.41" : process.env.npm_package_version || "0.0.0-dev";
|
|
2385
2439
|
|
|
2386
2440
|
// src/dev-server.js
|
|
2387
2441
|
var __dirname = path8.dirname(fileURLToPath(import.meta.url));
|
|
@@ -2440,8 +2494,8 @@ async function startDevServer({
|
|
|
2440
2494
|
}
|
|
2441
2495
|
function shutdown(server) {
|
|
2442
2496
|
console.log("\n \x1B[90mShutting down...\x1B[0m");
|
|
2443
|
-
if (serveChild
|
|
2444
|
-
serveChild
|
|
2497
|
+
if (childProcessIsRunning(serveChild)) {
|
|
2498
|
+
killProcessTree(serveChild, { signal: "SIGTERM" });
|
|
2445
2499
|
}
|
|
2446
2500
|
server.close();
|
|
2447
2501
|
process.exit(0);
|
|
@@ -2530,7 +2584,7 @@ async function handleApi(req, res, pathname, parsed) {
|
|
|
2530
2584
|
}
|
|
2531
2585
|
}
|
|
2532
2586
|
function apiStatus(req, res) {
|
|
2533
|
-
const serving = serveChild
|
|
2587
|
+
const serving = childProcessIsRunning(serveChild);
|
|
2534
2588
|
jsonResponse(res, {
|
|
2535
2589
|
serving,
|
|
2536
2590
|
agentsDir,
|
|
@@ -2544,7 +2598,7 @@ function apiStatus(req, res) {
|
|
|
2544
2598
|
});
|
|
2545
2599
|
}
|
|
2546
2600
|
function apiServeState(req, res) {
|
|
2547
|
-
const serving = serveChild
|
|
2601
|
+
const serving = childProcessIsRunning(serveChild);
|
|
2548
2602
|
const agentStatuses = serveState.agents.map((agent) => {
|
|
2549
2603
|
const relPath = agent.relativePath || ".";
|
|
2550
2604
|
const runtime = agentRuntimeStatus(agent, serveState.agentRunState);
|
|
@@ -2718,7 +2772,7 @@ function devServerStateAfterServeStart(current = {}, target = {}) {
|
|
|
2718
2772
|
};
|
|
2719
2773
|
}
|
|
2720
2774
|
async function apiServeStart(req, res, body) {
|
|
2721
|
-
if (serveChild
|
|
2775
|
+
if (childProcessIsRunning(serveChild)) {
|
|
2722
2776
|
return jsonResponse(res, { ok: false, error: "Already serving" });
|
|
2723
2777
|
}
|
|
2724
2778
|
const target = resolveServeStartTarget(body, { agentsDir, collectionId });
|
|
@@ -2790,14 +2844,15 @@ async function apiServeStart(req, res, body) {
|
|
|
2790
2844
|
}
|
|
2791
2845
|
}
|
|
2792
2846
|
function apiServeStop(req, res) {
|
|
2793
|
-
if (!serveChild
|
|
2847
|
+
if (!childProcessIsRunning(serveChild)) {
|
|
2794
2848
|
activeServeAgentsDir = "";
|
|
2795
2849
|
return jsonResponse(res, { ok: true, wasRunning: false });
|
|
2796
2850
|
}
|
|
2797
|
-
serveChild
|
|
2851
|
+
const stoppingChild = serveChild;
|
|
2852
|
+
killProcessTree(stoppingChild, { signal: "SIGTERM" });
|
|
2798
2853
|
setTimeout(() => {
|
|
2799
|
-
if (
|
|
2800
|
-
|
|
2854
|
+
if (childProcessIsRunning(stoppingChild)) {
|
|
2855
|
+
killProcessTree(stoppingChild, { signal: "SIGKILL" });
|
|
2801
2856
|
}
|
|
2802
2857
|
}, 3e3);
|
|
2803
2858
|
jsonResponse(res, { ok: true, wasRunning: true });
|
|
@@ -2974,7 +3029,6 @@ function openUrl(url) {
|
|
|
2974
3029
|
// src/tui.js
|
|
2975
3030
|
init_constants();
|
|
2976
3031
|
init_auth();
|
|
2977
|
-
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
2978
3032
|
import fs12 from "node:fs";
|
|
2979
3033
|
import path9 from "node:path";
|
|
2980
3034
|
import readline from "node:readline";
|
|
@@ -3685,7 +3739,7 @@ async function runServeDashboard({ env, platform, agentsDir: agentsDir2, collect
|
|
|
3685
3739
|
stopSignalAttempt += 1;
|
|
3686
3740
|
const signal = stopSignalForAttempt(stopSignalAttempt);
|
|
3687
3741
|
if (process.platform === "win32") {
|
|
3688
|
-
|
|
3742
|
+
killProcessTree2(child);
|
|
3689
3743
|
} else {
|
|
3690
3744
|
try {
|
|
3691
3745
|
child.kill(signal);
|
|
@@ -3707,7 +3761,7 @@ async function runServeDashboard({ env, platform, agentsDir: agentsDir2, collect
|
|
|
3707
3761
|
clearTimeout(ctrlCArmTimer);
|
|
3708
3762
|
ctrlCArmed = false;
|
|
3709
3763
|
if (process.platform === "win32") {
|
|
3710
|
-
|
|
3764
|
+
killProcessTree2(child);
|
|
3711
3765
|
} else {
|
|
3712
3766
|
try {
|
|
3713
3767
|
child.kill(stopSignalForAttempt(stopSignalAttempt));
|
|
@@ -3721,9 +3775,13 @@ async function runServeDashboard({ env, platform, agentsDir: agentsDir2, collect
|
|
|
3721
3775
|
if (!key) return;
|
|
3722
3776
|
if (key.ctrl && key.name === "c") {
|
|
3723
3777
|
if (ctrlCArmed) {
|
|
3724
|
-
|
|
3725
|
-
child
|
|
3726
|
-
}
|
|
3778
|
+
if (process.platform === "win32") {
|
|
3779
|
+
killProcessTree2(child);
|
|
3780
|
+
} else {
|
|
3781
|
+
try {
|
|
3782
|
+
child?.kill("SIGINT");
|
|
3783
|
+
} catch (error) {
|
|
3784
|
+
}
|
|
3727
3785
|
}
|
|
3728
3786
|
finish("exit");
|
|
3729
3787
|
return;
|
|
@@ -3962,19 +4020,8 @@ function stopSignalForAttempt(attempt = 0) {
|
|
|
3962
4020
|
if (attempt === 1) return "SIGTERM";
|
|
3963
4021
|
return "SIGKILL";
|
|
3964
4022
|
}
|
|
3965
|
-
function
|
|
3966
|
-
|
|
3967
|
-
if (process.platform === "win32") {
|
|
3968
|
-
try {
|
|
3969
|
-
spawnSync4("taskkill", ["/F", "/T", "/PID", String(child.pid)], { stdio: "ignore" });
|
|
3970
|
-
} catch {
|
|
3971
|
-
}
|
|
3972
|
-
} else {
|
|
3973
|
-
try {
|
|
3974
|
-
child.kill("SIGTERM");
|
|
3975
|
-
} catch {
|
|
3976
|
-
}
|
|
3977
|
-
}
|
|
4023
|
+
function killProcessTree2(child) {
|
|
4024
|
+
killProcessTree(child, { signal: "SIGTERM" });
|
|
3978
4025
|
}
|
|
3979
4026
|
function helpText() {
|
|
3980
4027
|
return [
|