orchestrating 0.1.14 → 0.1.16
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/bin/orch +64 -8
- package/package.json +1 -1
package/bin/orch
CHANGED
|
@@ -53,6 +53,39 @@ function clearAuth() {
|
|
|
53
53
|
} catch {}
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
// --- Supabase config (public anon key, same as browser dashboard) ---
|
|
57
|
+
const SUPABASE_URL = process.env.SUPABASE_URL || "https://vhyqfzdskgrmnxrdaqql.supabase.co";
|
|
58
|
+
const SUPABASE_ANON_KEY = process.env.SUPABASE_ANON_KEY || "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InZoeXFmemRza2dybW54cmRhcXFsIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzE1NjU5NTYsImV4cCI6MjA4NzE0MTk1Nn0.hWAceFshHoeTlnwThM08enNWG-ZeXICl3uyi-AmIJEk";
|
|
59
|
+
|
|
60
|
+
async function refreshAuthToken() {
|
|
61
|
+
const auth = loadStoredAuth();
|
|
62
|
+
if (!auth || !auth.refresh_token) return null;
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
const res = await fetch(`${SUPABASE_URL}/auth/v1/token?grant_type=refresh_token`, {
|
|
66
|
+
method: "POST",
|
|
67
|
+
headers: {
|
|
68
|
+
"Content-Type": "application/json",
|
|
69
|
+
"apikey": SUPABASE_ANON_KEY,
|
|
70
|
+
},
|
|
71
|
+
body: JSON.stringify({ refresh_token: auth.refresh_token }),
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
if (!res.ok) return null;
|
|
75
|
+
|
|
76
|
+
const data = await res.json();
|
|
77
|
+
if (data.access_token) {
|
|
78
|
+
saveAuth({
|
|
79
|
+
access_token: data.access_token,
|
|
80
|
+
refresh_token: data.refresh_token || auth.refresh_token,
|
|
81
|
+
expires_at: data.expires_at || 0,
|
|
82
|
+
});
|
|
83
|
+
return data.access_token;
|
|
84
|
+
}
|
|
85
|
+
} catch {}
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
|
|
56
89
|
function getAuthToken() {
|
|
57
90
|
// 1. Env var override
|
|
58
91
|
if (process.env.ORC_TOKEN || process.env.CAST_TOKEN || process.env.AUTH_TOKEN) {
|
|
@@ -61,16 +94,18 @@ function getAuthToken() {
|
|
|
61
94
|
// 2. Stored credentials
|
|
62
95
|
const auth = loadStoredAuth();
|
|
63
96
|
if (auth && auth.access_token) {
|
|
64
|
-
// Check expiry — if expired and we have a refresh token, caller should refresh
|
|
65
|
-
if (auth.expires_at && Date.now() / 1000 > auth.expires_at) {
|
|
66
|
-
// Token expired — still return it, server will reject and CLI can prompt re-login
|
|
67
|
-
return auth.access_token;
|
|
68
|
-
}
|
|
69
97
|
return auth.access_token;
|
|
70
98
|
}
|
|
71
99
|
return "";
|
|
72
100
|
}
|
|
73
101
|
|
|
102
|
+
function isTokenExpired() {
|
|
103
|
+
const auth = loadStoredAuth();
|
|
104
|
+
if (!auth || !auth.expires_at) return false;
|
|
105
|
+
// Expired or expires within 5 minutes
|
|
106
|
+
return Date.now() / 1000 > auth.expires_at - 300;
|
|
107
|
+
}
|
|
108
|
+
|
|
74
109
|
// --- Login command ---
|
|
75
110
|
async function handleLogin() {
|
|
76
111
|
const loginUrl = process.env.ORC_LOGIN_URL || "https://orchestrat.ing/cli-auth";
|
|
@@ -216,8 +251,20 @@ const spawnArgs = commandArgs.slice(1);
|
|
|
216
251
|
let sessionId;
|
|
217
252
|
const hostname = os.hostname();
|
|
218
253
|
const serverUrl = process.env.ORC_URL || process.env.CAST_URL || "wss://api.orchestrat.ing/ws";
|
|
219
|
-
|
|
220
|
-
const
|
|
254
|
+
let authToken = getAuthToken();
|
|
255
|
+
const cwdFolder = path.basename(process.cwd());
|
|
256
|
+
const effectiveLabel = label || cwdFolder || commandArgs.join(" ");
|
|
257
|
+
|
|
258
|
+
// Refresh token on startup if expired or about to expire
|
|
259
|
+
if (authToken && isTokenExpired()) {
|
|
260
|
+
const refreshed = await refreshAuthToken();
|
|
261
|
+
if (refreshed) {
|
|
262
|
+
authToken = refreshed;
|
|
263
|
+
process.stderr.write(`${DIM}[orch] Token refreshed${RESET}\n`);
|
|
264
|
+
} else {
|
|
265
|
+
process.stderr.write("\x1b[33mToken expired. Run 'orch login' to re-authenticate.\x1b[0m\n");
|
|
266
|
+
}
|
|
267
|
+
}
|
|
221
268
|
|
|
222
269
|
// Warn if no auth and connecting to remote server
|
|
223
270
|
if (!authToken && !serverUrl.includes("localhost") && !serverUrl.includes("127.0.0.1")) {
|
|
@@ -828,7 +875,16 @@ function printLocalEvent(event) {
|
|
|
828
875
|
|
|
829
876
|
// --- WebSocket connection ---
|
|
830
877
|
|
|
831
|
-
function connectWs() {
|
|
878
|
+
async function connectWs() {
|
|
879
|
+
// Refresh token if expired before (re)connecting
|
|
880
|
+
if (isTokenExpired()) {
|
|
881
|
+
const refreshed = await refreshAuthToken();
|
|
882
|
+
if (refreshed) {
|
|
883
|
+
authToken = refreshed;
|
|
884
|
+
process.stderr.write(`${DIM}[orch] Token refreshed${RESET}\n`);
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
|
|
832
888
|
if (ws) {
|
|
833
889
|
ws.removeAllListeners();
|
|
834
890
|
ws.close();
|