@brainbase-labs/cli 0.16.0 → 0.16.2
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/README.md +6 -0
- package/dist/index.js +432 -166
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,6 +22,12 @@ brainbase template onboard <creator/slug> # install or refresh a template
|
|
|
22
22
|
|
|
23
23
|
Run `brainbase help` to see every command.
|
|
24
24
|
|
|
25
|
+
## Development
|
|
26
|
+
|
|
27
|
+
Use Bun 1.3.10 when building this repository. The generated
|
|
28
|
+
`dist/index.js` is committed and byte-checked in CI, and Bun patch releases
|
|
29
|
+
can produce different bundle output.
|
|
30
|
+
|
|
25
31
|
## Agent runtime configuration
|
|
26
32
|
|
|
27
33
|
`brainbase.agent.yaml` can declare the provider and default model used by
|
package/dist/index.js
CHANGED
|
@@ -16651,7 +16651,7 @@ Learn more about this warning here: https://reactjs.org/link/legacy-context`, so
|
|
|
16651
16651
|
|
|
16652
16652
|
` + ("" + errorBoundaryMessage);
|
|
16653
16653
|
console["error"](combinedMessage);
|
|
16654
|
-
}
|
|
16654
|
+
} else {}
|
|
16655
16655
|
} catch (e2) {
|
|
16656
16656
|
setTimeout(function() {
|
|
16657
16657
|
throw e2;
|
|
@@ -36008,7 +36008,7 @@ function padStart(s, n) {
|
|
|
36008
36008
|
// package.json
|
|
36009
36009
|
var package_default = {
|
|
36010
36010
|
name: "@brainbase-labs/cli",
|
|
36011
|
-
version: "0.16.
|
|
36011
|
+
version: "0.16.2",
|
|
36012
36012
|
description: "Pack, share, and install agent templates across harnesses (Claude Code, Codex, ...).",
|
|
36013
36013
|
type: "module",
|
|
36014
36014
|
bin: {
|
|
@@ -36407,6 +36407,17 @@ function writeJson(p, data) {
|
|
|
36407
36407
|
fs2.writeFileSync(p, JSON.stringify(data, null, 2) + `
|
|
36408
36408
|
`);
|
|
36409
36409
|
}
|
|
36410
|
+
function writeJsonAtomic(p, data) {
|
|
36411
|
+
ensureDir(path2.dirname(p));
|
|
36412
|
+
const temporaryPath = `${p}.${process.pid}.${Math.random().toString(16).slice(2)}.tmp`;
|
|
36413
|
+
try {
|
|
36414
|
+
fs2.writeFileSync(temporaryPath, JSON.stringify(data, null, 2) + `
|
|
36415
|
+
`, { flag: "wx", mode: 384 });
|
|
36416
|
+
fs2.renameSync(temporaryPath, p);
|
|
36417
|
+
} finally {
|
|
36418
|
+
fs2.rmSync(temporaryPath, { force: true });
|
|
36419
|
+
}
|
|
36420
|
+
}
|
|
36410
36421
|
function listDirs(dir) {
|
|
36411
36422
|
if (!exists(dir))
|
|
36412
36423
|
return [];
|
|
@@ -40874,7 +40885,14 @@ import fs7 from "node:fs";
|
|
|
40874
40885
|
// src/core/auth.ts
|
|
40875
40886
|
import path8 from "node:path";
|
|
40876
40887
|
import fs6 from "node:fs";
|
|
40888
|
+
import { randomUUID } from "node:crypto";
|
|
40877
40889
|
var AUTH_FILE = path8.join(BRAINBASE_HOME, "auth.json");
|
|
40890
|
+
var AUTH_LOCK_FILE = `${AUTH_FILE}.lock`;
|
|
40891
|
+
var AUTH_LOCK_TIMEOUT_MS = 5000;
|
|
40892
|
+
var REFRESH_LOCK_FILE = `${AUTH_FILE}.refresh.lock`;
|
|
40893
|
+
var REFRESH_LOCK_TIMEOUT_MS = 1e4;
|
|
40894
|
+
var REFRESH_REQUEST_TIMEOUT_MS = 5000;
|
|
40895
|
+
var lockWaiter = new Int32Array(new SharedArrayBuffer(4));
|
|
40878
40896
|
var AuthSessionSchema = exports_external.object({
|
|
40879
40897
|
schemaVersion: exports_external.literal(1),
|
|
40880
40898
|
access_token: exports_external.string(),
|
|
@@ -40883,6 +40901,7 @@ var AuthSessionSchema = exports_external.object({
|
|
|
40883
40901
|
user_id: exports_external.string(),
|
|
40884
40902
|
email: exports_external.string().optional(),
|
|
40885
40903
|
server: exports_external.string().optional(),
|
|
40904
|
+
control_plane_url: exports_external.string().optional(),
|
|
40886
40905
|
supabase_url: exports_external.string().optional(),
|
|
40887
40906
|
supabase_anon_key: exports_external.string().optional(),
|
|
40888
40907
|
authedAt: exports_external.string()
|
|
@@ -40896,22 +40915,99 @@ function readAuth() {
|
|
|
40896
40915
|
return null;
|
|
40897
40916
|
}
|
|
40898
40917
|
}
|
|
40899
|
-
function
|
|
40918
|
+
function acquireLock(lockFile, timeoutMs) {
|
|
40900
40919
|
ensureDir(BRAINBASE_HOME);
|
|
40901
|
-
|
|
40920
|
+
const deadline = Date.now() + timeoutMs;
|
|
40921
|
+
const lockId = randomUUID();
|
|
40922
|
+
const owner = `${process.pid}:${lockId}`;
|
|
40923
|
+
const candidate = `${lockFile}.${lockId}.tmp`;
|
|
40924
|
+
while (true) {
|
|
40925
|
+
try {
|
|
40926
|
+
fs6.writeFileSync(candidate, owner, {
|
|
40927
|
+
encoding: "utf8",
|
|
40928
|
+
mode: 384,
|
|
40929
|
+
flag: "wx"
|
|
40930
|
+
});
|
|
40931
|
+
fs6.linkSync(candidate, lockFile);
|
|
40932
|
+
fs6.rmSync(candidate, { force: true });
|
|
40933
|
+
return () => {
|
|
40934
|
+
try {
|
|
40935
|
+
if (fs6.readFileSync(lockFile, "utf8") === owner) {
|
|
40936
|
+
fs6.rmSync(lockFile, { force: true });
|
|
40937
|
+
}
|
|
40938
|
+
} catch {}
|
|
40939
|
+
};
|
|
40940
|
+
} catch (error) {
|
|
40941
|
+
fs6.rmSync(candidate, { force: true });
|
|
40942
|
+
if (error.code !== "EEXIST")
|
|
40943
|
+
throw error;
|
|
40944
|
+
if (Date.now() >= deadline)
|
|
40945
|
+
return null;
|
|
40946
|
+
Atomics.wait(lockWaiter, 0, 0, 10);
|
|
40947
|
+
}
|
|
40948
|
+
}
|
|
40949
|
+
}
|
|
40950
|
+
function acquireAuthLock() {
|
|
40951
|
+
const release = acquireLock(AUTH_LOCK_FILE, AUTH_LOCK_TIMEOUT_MS);
|
|
40952
|
+
if (!release) {
|
|
40953
|
+
throw new Error(`Timed out waiting to update CLI authentication; if no other brainbase process is running, remove ${AUTH_LOCK_FILE}`);
|
|
40954
|
+
}
|
|
40955
|
+
return release;
|
|
40956
|
+
}
|
|
40957
|
+
function withAuthLock(operation) {
|
|
40958
|
+
const release = acquireAuthLock();
|
|
40959
|
+
try {
|
|
40960
|
+
return operation();
|
|
40961
|
+
} finally {
|
|
40962
|
+
release();
|
|
40963
|
+
}
|
|
40964
|
+
}
|
|
40965
|
+
function writeAuthUnlocked(s) {
|
|
40966
|
+
writeJsonAtomic(AUTH_FILE, s);
|
|
40902
40967
|
try {
|
|
40903
40968
|
fs6.chmodSync(AUTH_FILE, 384);
|
|
40904
40969
|
} catch {}
|
|
40905
40970
|
}
|
|
40971
|
+
function writeAuth(s) {
|
|
40972
|
+
withAuthLock(() => writeAuthUnlocked(s));
|
|
40973
|
+
}
|
|
40906
40974
|
function clearAuth() {
|
|
40907
|
-
|
|
40908
|
-
|
|
40975
|
+
withAuthLock(() => {
|
|
40976
|
+
if (exists(AUTH_FILE))
|
|
40977
|
+
fs6.rmSync(AUTH_FILE);
|
|
40978
|
+
});
|
|
40909
40979
|
}
|
|
40910
40980
|
function isExpired(session) {
|
|
40911
40981
|
if (!session.expires_at)
|
|
40912
40982
|
return false;
|
|
40913
40983
|
const now = Math.floor(Date.now() / 1000);
|
|
40914
|
-
return session.expires_at <= now
|
|
40984
|
+
return session.expires_at <= now + 5;
|
|
40985
|
+
}
|
|
40986
|
+
function isNearExpiry(session, marginSeconds = 60) {
|
|
40987
|
+
if (!session.expires_at)
|
|
40988
|
+
return false;
|
|
40989
|
+
const now = Math.floor(Date.now() / 1000);
|
|
40990
|
+
return session.expires_at <= now + marginSeconds;
|
|
40991
|
+
}
|
|
40992
|
+
function isAuthValid(session) {
|
|
40993
|
+
return !!session && !isExpired(session);
|
|
40994
|
+
}
|
|
40995
|
+
function isSameAuthIdentity(a3, b3) {
|
|
40996
|
+
return a3.user_id === b3.user_id && (a3.server ?? null) === (b3.server ?? null) && (a3.control_plane_url ?? null) === (b3.control_plane_url ?? null) && (a3.supabase_url ?? null) === (b3.supabase_url ?? null);
|
|
40997
|
+
}
|
|
40998
|
+
|
|
40999
|
+
class AuthSessionChangedError extends Error {
|
|
41000
|
+
constructor() {
|
|
41001
|
+
super("CLI authentication changed while this command was running; retry it");
|
|
41002
|
+
this.name = "AuthSessionChangedError";
|
|
41003
|
+
}
|
|
41004
|
+
}
|
|
41005
|
+
|
|
41006
|
+
class AuthRefreshLockTimeoutError extends Error {
|
|
41007
|
+
constructor() {
|
|
41008
|
+
super(`Timed out waiting to refresh CLI authentication; retry, or if no other brainbase process is running, remove ${REFRESH_LOCK_FILE}`);
|
|
41009
|
+
this.name = "AuthRefreshLockTimeoutError";
|
|
41010
|
+
}
|
|
40915
41011
|
}
|
|
40916
41012
|
function authStatus() {
|
|
40917
41013
|
const s = readAuth();
|
|
@@ -40921,52 +41017,157 @@ function authStatus() {
|
|
|
40921
41017
|
return { ok: false, session: s, reason: "session expired" };
|
|
40922
41018
|
return { ok: true, session: s };
|
|
40923
41019
|
}
|
|
40924
|
-
|
|
40925
|
-
|
|
40926
|
-
|
|
40927
|
-
|
|
41020
|
+
var refreshInFlight = null;
|
|
41021
|
+
function validatedRefreshResult(expectedSession, result) {
|
|
41022
|
+
const current = readAuth();
|
|
41023
|
+
if (!current || !isSameAuthIdentity(current, expectedSession) || result && !isSameAuthIdentity(result, expectedSession)) {
|
|
41024
|
+
throw new AuthSessionChangedError;
|
|
41025
|
+
}
|
|
41026
|
+
if (result)
|
|
41027
|
+
return result;
|
|
41028
|
+
return isAuthValid(current) ? current : null;
|
|
41029
|
+
}
|
|
41030
|
+
function adoptRefreshedLineage(session) {
|
|
41031
|
+
const current = readAuth();
|
|
41032
|
+
if (!current || !isSameAuthIdentity(current, session)) {
|
|
41033
|
+
throw new AuthSessionChangedError;
|
|
41034
|
+
}
|
|
41035
|
+
const sameRefreshLineage = current.access_token === session.access_token && current.refresh_token === session.refresh_token;
|
|
41036
|
+
if (sameRefreshLineage)
|
|
41037
|
+
return;
|
|
41038
|
+
return isAuthValid(current) ? current : null;
|
|
41039
|
+
}
|
|
41040
|
+
async function refreshSession(session) {
|
|
40928
41041
|
if (!session.refresh_token)
|
|
40929
41042
|
return null;
|
|
40930
41043
|
if (!session.supabase_url || !session.supabase_anon_key)
|
|
40931
41044
|
return null;
|
|
40932
|
-
const
|
|
40933
|
-
|
|
41045
|
+
const releaseRefreshLock = acquireLock(REFRESH_LOCK_FILE, REFRESH_LOCK_TIMEOUT_MS);
|
|
41046
|
+
if (!releaseRefreshLock) {
|
|
41047
|
+
const adopted = adoptRefreshedLineage(session);
|
|
41048
|
+
if (adopted !== undefined)
|
|
41049
|
+
return adopted;
|
|
41050
|
+
if (isAuthValid(session))
|
|
41051
|
+
return session;
|
|
41052
|
+
throw new AuthRefreshLockTimeoutError;
|
|
41053
|
+
}
|
|
40934
41054
|
try {
|
|
40935
|
-
|
|
40936
|
-
|
|
40937
|
-
|
|
40938
|
-
|
|
40939
|
-
|
|
40940
|
-
|
|
40941
|
-
|
|
40942
|
-
|
|
41055
|
+
const adopted = adoptRefreshedLineage(session);
|
|
41056
|
+
if (adopted !== undefined)
|
|
41057
|
+
return adopted;
|
|
41058
|
+
const url = `${session.supabase_url.replace(/\/+$/, "")}/auth/v1/token?grant_type=refresh_token`;
|
|
41059
|
+
let res;
|
|
41060
|
+
try {
|
|
41061
|
+
res = await fetch(url, {
|
|
41062
|
+
method: "POST",
|
|
41063
|
+
signal: AbortSignal.timeout(REFRESH_REQUEST_TIMEOUT_MS),
|
|
41064
|
+
headers: {
|
|
41065
|
+
"Content-Type": "application/json",
|
|
41066
|
+
apikey: session.supabase_anon_key,
|
|
41067
|
+
Authorization: `Bearer ${session.supabase_anon_key}`
|
|
41068
|
+
},
|
|
41069
|
+
body: JSON.stringify({ refresh_token: session.refresh_token })
|
|
41070
|
+
});
|
|
41071
|
+
} catch {
|
|
41072
|
+
return null;
|
|
41073
|
+
}
|
|
41074
|
+
if (!res.ok)
|
|
41075
|
+
return null;
|
|
41076
|
+
let data;
|
|
41077
|
+
try {
|
|
41078
|
+
data = await res.json();
|
|
41079
|
+
} catch {
|
|
41080
|
+
return null;
|
|
41081
|
+
}
|
|
41082
|
+
if (!data.access_token)
|
|
41083
|
+
return null;
|
|
41084
|
+
const now = Math.floor(Date.now() / 1000);
|
|
41085
|
+
const expires_at = data.expires_at ?? (data.expires_in ? now + data.expires_in : undefined);
|
|
41086
|
+
const updated = {
|
|
41087
|
+
...session,
|
|
41088
|
+
access_token: data.access_token,
|
|
41089
|
+
refresh_token: data.refresh_token ?? session.refresh_token,
|
|
41090
|
+
expires_at,
|
|
41091
|
+
user_id: data.user?.id ?? session.user_id,
|
|
41092
|
+
email: data.user?.email ?? session.email,
|
|
41093
|
+
authedAt: new Date().toISOString()
|
|
41094
|
+
};
|
|
41095
|
+
if (!isSameAuthIdentity(updated, session)) {
|
|
41096
|
+
throw new AuthSessionChangedError;
|
|
41097
|
+
}
|
|
41098
|
+
return withAuthLock(() => {
|
|
41099
|
+
const adopted2 = adoptRefreshedLineage(session);
|
|
41100
|
+
if (adopted2 !== undefined)
|
|
41101
|
+
return adopted2;
|
|
41102
|
+
writeAuthUnlocked(updated);
|
|
41103
|
+
return updated;
|
|
40943
41104
|
});
|
|
40944
|
-
}
|
|
40945
|
-
|
|
41105
|
+
} finally {
|
|
41106
|
+
releaseRefreshLock();
|
|
40946
41107
|
}
|
|
40947
|
-
|
|
41108
|
+
}
|
|
41109
|
+
async function tryRefreshSession(expectedSession = readAuth()) {
|
|
41110
|
+
if (!expectedSession)
|
|
40948
41111
|
return null;
|
|
40949
|
-
|
|
41112
|
+
if (refreshInFlight) {
|
|
41113
|
+
if (!isSameAuthIdentity(refreshInFlight.session, expectedSession)) {
|
|
41114
|
+
throw new AuthSessionChangedError;
|
|
41115
|
+
}
|
|
41116
|
+
const result = await refreshInFlight.promise;
|
|
41117
|
+
return validatedRefreshResult(expectedSession, result);
|
|
41118
|
+
}
|
|
41119
|
+
const current = readAuth();
|
|
41120
|
+
if (!current || !isSameAuthIdentity(current, expectedSession)) {
|
|
41121
|
+
throw new AuthSessionChangedError;
|
|
41122
|
+
}
|
|
41123
|
+
const refresh = refreshSession(current);
|
|
41124
|
+
refreshInFlight = { session: current, promise: refresh };
|
|
40950
41125
|
try {
|
|
40951
|
-
|
|
40952
|
-
|
|
40953
|
-
|
|
41126
|
+
const result = await refresh;
|
|
41127
|
+
return validatedRefreshResult(expectedSession, result);
|
|
41128
|
+
} finally {
|
|
41129
|
+
if (refreshInFlight?.promise === refresh)
|
|
41130
|
+
refreshInFlight = null;
|
|
41131
|
+
}
|
|
41132
|
+
}
|
|
41133
|
+
async function refreshSessionAfterUnauthorized(rejectedSession) {
|
|
41134
|
+
const current = readAuth();
|
|
41135
|
+
if (!current || !isSameAuthIdentity(current, rejectedSession)) {
|
|
41136
|
+
throw new AuthSessionChangedError;
|
|
41137
|
+
}
|
|
41138
|
+
if (current.access_token !== rejectedSession.access_token && isAuthValid(current)) {
|
|
41139
|
+
return current;
|
|
40954
41140
|
}
|
|
40955
|
-
|
|
41141
|
+
const refreshed = await tryRefreshSession(rejectedSession);
|
|
41142
|
+
if (refreshed) {
|
|
41143
|
+
if (!isSameAuthIdentity(refreshed, rejectedSession)) {
|
|
41144
|
+
throw new AuthSessionChangedError;
|
|
41145
|
+
}
|
|
41146
|
+
return refreshed;
|
|
41147
|
+
}
|
|
41148
|
+
const latest = readAuth();
|
|
41149
|
+
if (!latest || !isSameAuthIdentity(latest, rejectedSession)) {
|
|
41150
|
+
throw new AuthSessionChangedError;
|
|
41151
|
+
}
|
|
41152
|
+
if (latest.access_token !== rejectedSession.access_token && isAuthValid(latest)) {
|
|
41153
|
+
return latest;
|
|
41154
|
+
}
|
|
41155
|
+
return null;
|
|
41156
|
+
}
|
|
41157
|
+
async function ensureFreshSession() {
|
|
41158
|
+
const s = readAuth();
|
|
41159
|
+
if (!s)
|
|
40956
41160
|
return null;
|
|
40957
|
-
|
|
40958
|
-
|
|
40959
|
-
const
|
|
40960
|
-
|
|
40961
|
-
|
|
40962
|
-
|
|
40963
|
-
|
|
40964
|
-
|
|
40965
|
-
|
|
40966
|
-
|
|
40967
|
-
};
|
|
40968
|
-
writeAuth(updated);
|
|
40969
|
-
return updated;
|
|
41161
|
+
if (!isExpired(s) && !isNearExpiry(s))
|
|
41162
|
+
return s;
|
|
41163
|
+
const refreshed = await tryRefreshSession(s);
|
|
41164
|
+
if (refreshed)
|
|
41165
|
+
return refreshed;
|
|
41166
|
+
const current = readAuth();
|
|
41167
|
+
if (current && isSameAuthIdentity(current, s) && isAuthValid(current)) {
|
|
41168
|
+
return current;
|
|
41169
|
+
}
|
|
41170
|
+
return null;
|
|
40970
41171
|
}
|
|
40971
41172
|
|
|
40972
41173
|
// src/core/skill-marker-write.ts
|
|
@@ -47245,6 +47446,7 @@ var HARNESS_ALIASES = {
|
|
|
47245
47446
|
"claude-code-cloud": "claude-code",
|
|
47246
47447
|
codex_cloud: "codex",
|
|
47247
47448
|
"codex-cloud": "codex",
|
|
47449
|
+
qwen: "qwen-code",
|
|
47248
47450
|
qwen_acp: "qwen-code",
|
|
47249
47451
|
"qwen-acp": "qwen-code",
|
|
47250
47452
|
qwen_cloud: "qwen-code",
|
|
@@ -53363,19 +53565,27 @@ class ApiError extends Error {
|
|
|
53363
53565
|
this.name = "ApiError";
|
|
53364
53566
|
}
|
|
53365
53567
|
}
|
|
53366
|
-
function
|
|
53367
|
-
const
|
|
53568
|
+
function normalizeControlPlaneUrl(url) {
|
|
53569
|
+
const normalized = url?.trim().replace(/\/+$/, "");
|
|
53570
|
+
return normalized || DEFAULT_CONTROL_PLANE_BASE;
|
|
53571
|
+
}
|
|
53572
|
+
function controlPlaneBaseUrl(session) {
|
|
53573
|
+
const controlPlane = process.env.BRAINBASE_CONTROL_PLANE_URL?.trim();
|
|
53368
53574
|
if (controlPlane) {
|
|
53369
|
-
return
|
|
53575
|
+
return normalizeControlPlaneUrl(controlPlane);
|
|
53370
53576
|
}
|
|
53371
|
-
const legacyApi = process.env.BRAINBASE_API_URL;
|
|
53577
|
+
const legacyApi = process.env.BRAINBASE_API_URL?.trim();
|
|
53372
53578
|
if (legacyApi) {
|
|
53373
|
-
return
|
|
53579
|
+
return legacyApi.replace(/\/+$/, "");
|
|
53374
53580
|
}
|
|
53375
|
-
return
|
|
53581
|
+
return normalizeControlPlaneUrl(session?.control_plane_url);
|
|
53582
|
+
}
|
|
53583
|
+
function apiBase(session) {
|
|
53584
|
+
const suffix = usesLegacyControlPlane() ? "/api/cli" : "/v2/cli";
|
|
53585
|
+
return `${controlPlaneBaseUrl(session)}${suffix}`;
|
|
53376
53586
|
}
|
|
53377
53587
|
function usesLegacyControlPlane() {
|
|
53378
|
-
return !process.env.BRAINBASE_CONTROL_PLANE_URL && !!process.env.BRAINBASE_API_URL;
|
|
53588
|
+
return !process.env.BRAINBASE_CONTROL_PLANE_URL?.trim() && !!process.env.BRAINBASE_API_URL?.trim();
|
|
53379
53589
|
}
|
|
53380
53590
|
function legacyScheduleError() {
|
|
53381
53591
|
return new ApiError("Schedule-trigger writes require the MAS control plane. Set BRAINBASE_CONTROL_PLANE_URL or unset the legacy BRAINBASE_API_URL override.", 400);
|
|
@@ -53383,38 +53593,58 @@ function legacyScheduleError() {
|
|
|
53383
53593
|
function legacyAgentConfigError() {
|
|
53384
53594
|
return new ApiError("Declarative machine/model config requires the MAS control plane. Set BRAINBASE_CONTROL_PLANE_URL or unset the legacy BRAINBASE_API_URL override.", 400);
|
|
53385
53595
|
}
|
|
53386
|
-
function
|
|
53387
|
-
const status = authStatus();
|
|
53388
|
-
if (!status.ok || !status.session) {
|
|
53389
|
-
throw new ApiError(status.reason ?? "not logged in", 401);
|
|
53390
|
-
}
|
|
53391
|
-
return status.session;
|
|
53392
|
-
}
|
|
53393
|
-
function resolveCredential() {
|
|
53596
|
+
async function resolveCredential() {
|
|
53394
53597
|
const envToken = process.env.BRAINBASE_TOKEN;
|
|
53395
53598
|
if (envToken && envToken.trim()) {
|
|
53396
|
-
return {
|
|
53599
|
+
return {
|
|
53600
|
+
bearer: envToken.trim(),
|
|
53601
|
+
session: null,
|
|
53602
|
+
source: "env_pat"
|
|
53603
|
+
};
|
|
53604
|
+
}
|
|
53605
|
+
const session = await ensureFreshSession();
|
|
53606
|
+
if (session) {
|
|
53607
|
+
return {
|
|
53608
|
+
bearer: session.access_token,
|
|
53609
|
+
session,
|
|
53610
|
+
source: "session"
|
|
53611
|
+
};
|
|
53397
53612
|
}
|
|
53398
|
-
const
|
|
53399
|
-
|
|
53613
|
+
const status = authStatus();
|
|
53614
|
+
throw new ApiError(status.ok ? "CLI authentication changed while this command was starting; retry it" : status.reason ?? "not logged in", 401);
|
|
53400
53615
|
}
|
|
53401
|
-
async function
|
|
53402
|
-
const
|
|
53403
|
-
|
|
53404
|
-
|
|
53405
|
-
|
|
53406
|
-
|
|
53407
|
-
|
|
53408
|
-
|
|
53409
|
-
|
|
53410
|
-
headers["Content-Type"] = "application/json";
|
|
53616
|
+
async function sendRequest(url, init, bearer) {
|
|
53617
|
+
const headers = new Headers(init.headers);
|
|
53618
|
+
if (!headers.has("Authorization")) {
|
|
53619
|
+
headers.set("Authorization", `Bearer ${bearer}`);
|
|
53620
|
+
}
|
|
53621
|
+
if (!headers.has("Accept"))
|
|
53622
|
+
headers.set("Accept", "application/json");
|
|
53623
|
+
if (init.body && !headers.has("Content-Type")) {
|
|
53624
|
+
headers.set("Content-Type", "application/json");
|
|
53411
53625
|
}
|
|
53412
|
-
let res;
|
|
53413
53626
|
try {
|
|
53414
|
-
|
|
53627
|
+
return await fetch(url, { ...init, headers });
|
|
53415
53628
|
} catch (err) {
|
|
53416
53629
|
throw new ApiError(`Network error: ${err.message}`);
|
|
53417
53630
|
}
|
|
53631
|
+
}
|
|
53632
|
+
async function sendWithAuthRetry(session, send) {
|
|
53633
|
+
const res = await send();
|
|
53634
|
+
if (res.status !== 401 || !session)
|
|
53635
|
+
return res;
|
|
53636
|
+
const refreshed = await refreshSessionAfterUnauthorized(session);
|
|
53637
|
+
if (!refreshed || refreshed.access_token === session.access_token) {
|
|
53638
|
+
return res;
|
|
53639
|
+
}
|
|
53640
|
+
if (res.body)
|
|
53641
|
+
res.body.cancel().catch(() => {});
|
|
53642
|
+
return await send(refreshed);
|
|
53643
|
+
}
|
|
53644
|
+
async function request(pathname, init = {}) {
|
|
53645
|
+
const credential = await resolveCredential();
|
|
53646
|
+
const retrySession = credential.source === "session" && !new Headers(init.headers).has("Authorization") ? credential.session : null;
|
|
53647
|
+
const res = await sendWithAuthRetry(retrySession, (refreshed) => sendRequest(`${apiBase(refreshed ?? credential.session)}${pathname}`, init, refreshed?.access_token ?? credential.bearer));
|
|
53418
53648
|
const text2 = await res.text();
|
|
53419
53649
|
let body = text2;
|
|
53420
53650
|
try {
|
|
@@ -53531,6 +53761,9 @@ function proxyBaseUrl(session) {
|
|
|
53531
53761
|
const envOverride = process.env.BRAINBASE_PROXY_URL || process.env.BRAINBASE_API_URL;
|
|
53532
53762
|
if (envOverride)
|
|
53533
53763
|
return envOverride.replace(/\/+$/, "");
|
|
53764
|
+
if (process.env.BRAINBASE_TOKEN?.trim()) {
|
|
53765
|
+
return DEFAULT_PROXY_BASE.replace(/\/+$/, "");
|
|
53766
|
+
}
|
|
53534
53767
|
if (session?.server)
|
|
53535
53768
|
return session.server.replace(/\/+$/, "");
|
|
53536
53769
|
return DEFAULT_PROXY_BASE.replace(/\/+$/, "");
|
|
@@ -53608,61 +53841,89 @@ function registryHost() {
|
|
|
53608
53841
|
const env3 = process.env.BRAINBASE_REGISTRY_URL || process.env.BRAINBASE_API_URL;
|
|
53609
53842
|
if (env3)
|
|
53610
53843
|
return env3.replace(/\/+$/, "");
|
|
53844
|
+
if (process.env.BRAINBASE_TOKEN?.trim())
|
|
53845
|
+
return DEFAULT_BASE;
|
|
53611
53846
|
const s = readAuth();
|
|
53612
53847
|
if (s?.server)
|
|
53613
53848
|
return s.server.replace(/\/+$/, "");
|
|
53614
53849
|
return DEFAULT_BASE.replace(/\/+$/, "");
|
|
53615
53850
|
}
|
|
53616
|
-
function
|
|
53617
|
-
|
|
53618
|
-
|
|
53619
|
-
|
|
53620
|
-
|
|
53621
|
-
|
|
53622
|
-
|
|
53623
|
-
|
|
53624
|
-
|
|
53625
|
-
|
|
53851
|
+
function patAuth(token) {
|
|
53852
|
+
return {
|
|
53853
|
+
headers: {
|
|
53854
|
+
Authorization: `Bearer ${token}`,
|
|
53855
|
+
"X-Auth-Source": "pat"
|
|
53856
|
+
},
|
|
53857
|
+
session: null
|
|
53858
|
+
};
|
|
53859
|
+
}
|
|
53860
|
+
function jwtAuth(session) {
|
|
53861
|
+
return {
|
|
53862
|
+
headers: {
|
|
53863
|
+
Authorization: `Bearer ${session.access_token}`,
|
|
53864
|
+
"X-Auth-Source": "jwt"
|
|
53865
|
+
},
|
|
53866
|
+
session
|
|
53867
|
+
};
|
|
53868
|
+
}
|
|
53869
|
+
async function resolveAuth() {
|
|
53870
|
+
const envToken = process.env.BRAINBASE_TOKEN?.trim();
|
|
53871
|
+
if (envToken)
|
|
53872
|
+
return patAuth(envToken);
|
|
53873
|
+
let freshSession;
|
|
53874
|
+
try {
|
|
53875
|
+
freshSession = await ensureFreshSession();
|
|
53876
|
+
} catch (error) {
|
|
53877
|
+
if (!(error instanceof AuthRefreshLockTimeoutError))
|
|
53878
|
+
throw error;
|
|
53879
|
+
const pat2 = readToken();
|
|
53880
|
+
if (pat2)
|
|
53881
|
+
return patAuth(pat2.token);
|
|
53882
|
+
throw error;
|
|
53626
53883
|
}
|
|
53884
|
+
if (freshSession)
|
|
53885
|
+
return jwtAuth(freshSession);
|
|
53627
53886
|
const status = authStatus();
|
|
53628
|
-
if (status.ok && status.session) {
|
|
53629
|
-
return {
|
|
53630
|
-
headers: {
|
|
53631
|
-
Authorization: `Bearer ${status.session.access_token}`,
|
|
53632
|
-
"X-Auth-Source": "jwt"
|
|
53633
|
-
},
|
|
53634
|
-
session: status.session
|
|
53635
|
-
};
|
|
53636
|
-
}
|
|
53637
53887
|
const pat = readToken();
|
|
53638
|
-
if (pat)
|
|
53639
|
-
return
|
|
53640
|
-
|
|
53641
|
-
Authorization: `Bearer ${pat.token}`,
|
|
53642
|
-
"X-Auth-Source": "pat"
|
|
53643
|
-
},
|
|
53644
|
-
session: null
|
|
53645
|
-
};
|
|
53646
|
-
}
|
|
53647
|
-
throw new ApiError(status.reason ?? "not logged in", 401);
|
|
53888
|
+
if (pat)
|
|
53889
|
+
return patAuth(pat.token);
|
|
53890
|
+
throw new ApiError(status.ok ? "CLI authentication changed while this command was starting; retry it" : status.reason ?? "not logged in", 401);
|
|
53648
53891
|
}
|
|
53649
|
-
|
|
53650
|
-
const
|
|
53892
|
+
function mergeHeaders(auth, overrides) {
|
|
53893
|
+
const headers = new Headers(auth);
|
|
53894
|
+
new Headers(overrides).forEach((value, key2) => headers.set(key2, value));
|
|
53895
|
+
return headers;
|
|
53896
|
+
}
|
|
53897
|
+
async function sendRequest2(pathname, init, session) {
|
|
53651
53898
|
const url = `${baseUrl(session)}${pathname}`;
|
|
53652
|
-
const merged = {
|
|
53653
|
-
...headers,
|
|
53654
|
-
Accept: "application/json",
|
|
53655
|
-
...init.headers ?? {}
|
|
53656
|
-
};
|
|
53657
|
-
if (init.body && !merged["Content-Type"] && typeof init.body === "string") {
|
|
53658
|
-
merged["Content-Type"] = "application/json";
|
|
53659
|
-
}
|
|
53660
|
-
let res;
|
|
53661
53899
|
try {
|
|
53662
|
-
|
|
53900
|
+
return await fetch(url, init);
|
|
53663
53901
|
} catch (err) {
|
|
53664
53902
|
throw new ApiError(`Network error: ${err.message}`);
|
|
53665
53903
|
}
|
|
53904
|
+
}
|
|
53905
|
+
async function sendAuthenticatedRequest(pathname, init, auth) {
|
|
53906
|
+
return await sendRequest2(pathname, {
|
|
53907
|
+
...init,
|
|
53908
|
+
headers: mergeHeaders(auth.headers, init.headers)
|
|
53909
|
+
}, auth.session);
|
|
53910
|
+
}
|
|
53911
|
+
async function registryFetch(pathname, init = {}) {
|
|
53912
|
+
if (new Headers(init.headers).has("Authorization")) {
|
|
53913
|
+
return await sendRequest2(pathname, init, readAuth());
|
|
53914
|
+
}
|
|
53915
|
+
const auth = await resolveAuth();
|
|
53916
|
+
const retrySession = auth.headers["X-Auth-Source"] === "jwt" ? auth.session : null;
|
|
53917
|
+
return await sendWithAuthRetry(retrySession, (refreshed) => sendAuthenticatedRequest(pathname, init, refreshed ? jwtAuth(refreshed) : auth));
|
|
53918
|
+
}
|
|
53919
|
+
async function jsonRequest(pathname, init = {}) {
|
|
53920
|
+
const headers = new Headers(init.headers);
|
|
53921
|
+
if (!headers.has("Accept"))
|
|
53922
|
+
headers.set("Accept", "application/json");
|
|
53923
|
+
if (init.body && !headers.has("Content-Type") && typeof init.body === "string") {
|
|
53924
|
+
headers.set("Content-Type", "application/json");
|
|
53925
|
+
}
|
|
53926
|
+
const res = await registryFetch(pathname, { ...init, headers });
|
|
53666
53927
|
const text2 = await res.text();
|
|
53667
53928
|
let body = text2;
|
|
53668
53929
|
try {
|
|
@@ -53720,9 +53981,8 @@ var registryApi = {
|
|
|
53720
53981
|
return jsonRequest(`/v1/registry/templates/${encodeURIComponent(creator)}/${encodeURIComponent(slug)}/versions/${encodeURIComponent(version)}`);
|
|
53721
53982
|
},
|
|
53722
53983
|
async getFile(creator, slug, version, relPath) {
|
|
53723
|
-
const
|
|
53724
|
-
const
|
|
53725
|
-
const res = await fetch(url, { headers });
|
|
53984
|
+
const pathname = `/v1/registry/templates/${encodeURIComponent(creator)}/${encodeURIComponent(slug)}/versions/${encodeURIComponent(version)}/files/${relPath}`;
|
|
53985
|
+
const res = await registryFetch(pathname);
|
|
53726
53986
|
if (!res.ok) {
|
|
53727
53987
|
throw new ApiError(`HTTP ${res.status} reading file ${relPath}`, res.status);
|
|
53728
53988
|
}
|
|
@@ -53730,9 +53990,8 @@ var registryApi = {
|
|
|
53730
53990
|
return Buffer.from(ab);
|
|
53731
53991
|
},
|
|
53732
53992
|
async downloadTarball(creator, slug, version, destPath) {
|
|
53733
|
-
const
|
|
53734
|
-
const
|
|
53735
|
-
const res = await fetch(url, { headers });
|
|
53993
|
+
const pathname = `/v1/registry/templates/${encodeURIComponent(creator)}/${encodeURIComponent(slug)}/versions/${encodeURIComponent(version)}/tarball`;
|
|
53994
|
+
const res = await registryFetch(pathname);
|
|
53736
53995
|
if (!res.ok || !res.body) {
|
|
53737
53996
|
throw new ApiError(`HTTP ${res.status} downloading tarball`, res.status);
|
|
53738
53997
|
}
|
|
@@ -53758,8 +54017,7 @@ var registryApi = {
|
|
|
53758
54017
|
});
|
|
53759
54018
|
},
|
|
53760
54019
|
async publishVersion(creator, slug, input) {
|
|
53761
|
-
const
|
|
53762
|
-
const url = `${baseUrl(session)}/v1/registry/templates/${encodeURIComponent(creator)}/${encodeURIComponent(slug)}/versions`;
|
|
54020
|
+
const pathname = `/v1/registry/templates/${encodeURIComponent(creator)}/${encodeURIComponent(slug)}/versions`;
|
|
53763
54021
|
const form = new FormData;
|
|
53764
54022
|
form.set("version", input.version);
|
|
53765
54023
|
form.set("source_harness", input.sourceHarness);
|
|
@@ -53767,16 +54025,11 @@ var registryApi = {
|
|
|
53767
54025
|
form.set("manifest", new Blob([input.manifestJson], { type: "application/json" }), "manifest.json");
|
|
53768
54026
|
const bytes = fs45.readFileSync(input.bundlePath);
|
|
53769
54027
|
form.set("bundle", new Blob([bytes], { type: "application/gzip" }), "bundle.tgz");
|
|
53770
|
-
|
|
53771
|
-
|
|
53772
|
-
|
|
53773
|
-
|
|
53774
|
-
|
|
53775
|
-
body: form
|
|
53776
|
-
});
|
|
53777
|
-
} catch (err) {
|
|
53778
|
-
throw new ApiError(`Network error: ${err.message}`);
|
|
53779
|
-
}
|
|
54028
|
+
const res = await registryFetch(pathname, {
|
|
54029
|
+
method: "POST",
|
|
54030
|
+
headers: { Accept: "application/json" },
|
|
54031
|
+
body: form
|
|
54032
|
+
});
|
|
53780
54033
|
const text2 = await res.text();
|
|
53781
54034
|
let body = text2;
|
|
53782
54035
|
try {
|
|
@@ -58375,9 +58628,8 @@ var skillsApi = {
|
|
|
58375
58628
|
return jsonRequest(`/v1/skill-registry/skills/${encodeURIComponent(creator)}/${encodeURIComponent(slug)}/versions/${encodeURIComponent(version)}`);
|
|
58376
58629
|
},
|
|
58377
58630
|
async getFile(creator, slug, version, relPath) {
|
|
58378
|
-
const
|
|
58379
|
-
const
|
|
58380
|
-
const res = await fetch(url, { headers });
|
|
58631
|
+
const pathname = `/v1/skill-registry/skills/${encodeURIComponent(creator)}/${encodeURIComponent(slug)}/versions/${encodeURIComponent(version)}/files/${relPath}`;
|
|
58632
|
+
const res = await registryFetch(pathname);
|
|
58381
58633
|
if (!res.ok) {
|
|
58382
58634
|
throw new ApiError(`HTTP ${res.status} reading file ${relPath}`, res.status);
|
|
58383
58635
|
}
|
|
@@ -58385,9 +58637,8 @@ var skillsApi = {
|
|
|
58385
58637
|
return Buffer.from(ab);
|
|
58386
58638
|
},
|
|
58387
58639
|
async downloadTarball(creator, slug, version, destPath) {
|
|
58388
|
-
const
|
|
58389
|
-
const
|
|
58390
|
-
const res = await fetch(url, { headers });
|
|
58640
|
+
const pathname = `/v1/skill-registry/skills/${encodeURIComponent(creator)}/${encodeURIComponent(slug)}/versions/${encodeURIComponent(version)}/tarball`;
|
|
58641
|
+
const res = await registryFetch(pathname);
|
|
58391
58642
|
if (!res.ok || !res.body) {
|
|
58392
58643
|
throw new ApiError(`HTTP ${res.status} downloading tarball`, res.status);
|
|
58393
58644
|
}
|
|
@@ -58413,8 +58664,7 @@ var skillsApi = {
|
|
|
58413
58664
|
});
|
|
58414
58665
|
},
|
|
58415
58666
|
async publishVersion(creator, slug, input) {
|
|
58416
|
-
const
|
|
58417
|
-
const url = `${baseUrl(session)}/v1/skill-registry/skills/${encodeURIComponent(creator)}/${encodeURIComponent(slug)}/versions`;
|
|
58667
|
+
const pathname = `/v1/skill-registry/skills/${encodeURIComponent(creator)}/${encodeURIComponent(slug)}/versions`;
|
|
58418
58668
|
const form = new FormData;
|
|
58419
58669
|
form.set("version", input.version);
|
|
58420
58670
|
form.set("source_harness", input.sourceHarness);
|
|
@@ -58422,16 +58672,11 @@ var skillsApi = {
|
|
|
58422
58672
|
form.set("manifest", new Blob([input.manifestJson], { type: "application/json" }), "manifest.json");
|
|
58423
58673
|
const bytes = fs52.readFileSync(input.bundlePath);
|
|
58424
58674
|
form.set("bundle", new Blob([bytes], { type: "application/gzip" }), "bundle.tgz");
|
|
58425
|
-
|
|
58426
|
-
|
|
58427
|
-
|
|
58428
|
-
|
|
58429
|
-
|
|
58430
|
-
body: form
|
|
58431
|
-
});
|
|
58432
|
-
} catch (err) {
|
|
58433
|
-
throw new ApiError(`Network error: ${err.message}`);
|
|
58434
|
-
}
|
|
58675
|
+
const res = await registryFetch(pathname, {
|
|
58676
|
+
method: "POST",
|
|
58677
|
+
headers: { Accept: "application/json" },
|
|
58678
|
+
body: form
|
|
58679
|
+
});
|
|
58435
58680
|
const text2 = await res.text();
|
|
58436
58681
|
let body = text2;
|
|
58437
58682
|
try {
|
|
@@ -60434,24 +60679,24 @@ function WelcomeCard(props) {
|
|
|
60434
60679
|
/* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Box_default, {
|
|
60435
60680
|
flexDirection: "column",
|
|
60436
60681
|
children: [
|
|
60437
|
-
props.
|
|
60682
|
+
props.controlPlaneUrl && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Box_default, {
|
|
60438
60683
|
children: [
|
|
60439
60684
|
/* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Box_default, {
|
|
60440
|
-
width:
|
|
60685
|
+
width: 15,
|
|
60441
60686
|
children: /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text, {
|
|
60442
60687
|
dimColor: true,
|
|
60443
|
-
children: "
|
|
60688
|
+
children: "control plane"
|
|
60444
60689
|
}, undefined, false, undefined, this)
|
|
60445
60690
|
}, undefined, false, undefined, this),
|
|
60446
60691
|
/* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text, {
|
|
60447
|
-
children: props.
|
|
60692
|
+
children: props.controlPlaneUrl
|
|
60448
60693
|
}, undefined, false, undefined, this)
|
|
60449
60694
|
]
|
|
60450
60695
|
}, undefined, true, undefined, this),
|
|
60451
60696
|
expiresText && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Box_default, {
|
|
60452
60697
|
children: [
|
|
60453
60698
|
/* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Box_default, {
|
|
60454
|
-
width:
|
|
60699
|
+
width: 15,
|
|
60455
60700
|
children: /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text, {
|
|
60456
60701
|
dimColor: true,
|
|
60457
60702
|
children: "expires"
|
|
@@ -60484,8 +60729,12 @@ async function showWelcomeCard(props) {
|
|
|
60484
60729
|
}
|
|
60485
60730
|
|
|
60486
60731
|
// src/cli/login.ts
|
|
60487
|
-
var DEFAULT_WEB_URL = "https://
|
|
60732
|
+
var DEFAULT_WEB_URL = "https://app.brainbaselabs.com";
|
|
60488
60733
|
var LOGIN_TIMEOUT_MS = 5 * 60 * 1000;
|
|
60734
|
+
function resolveLoginWebBase(web, envWeb = process.env.BRAINBASE_WEB_URL) {
|
|
60735
|
+
const override = web?.trim() || envWeb?.trim() || DEFAULT_WEB_URL;
|
|
60736
|
+
return override.replace(/\/+$/, "");
|
|
60737
|
+
}
|
|
60489
60738
|
function openInBrowser(url) {
|
|
60490
60739
|
const platform2 = process.platform;
|
|
60491
60740
|
const cmd = platform2 === "darwin" ? "open" : platform2 === "win32" ? "cmd" : "xdg-open";
|
|
@@ -60519,7 +60768,7 @@ async function readBody(req) {
|
|
|
60519
60768
|
}
|
|
60520
60769
|
async function runLogin(_cwd, args) {
|
|
60521
60770
|
banner("login — connect this device to brainbase");
|
|
60522
|
-
const webBase = (args.web
|
|
60771
|
+
const webBase = resolveLoginWebBase(args.web);
|
|
60523
60772
|
const expectedState = randomBytes(16).toString("hex");
|
|
60524
60773
|
const port = await getFreePort();
|
|
60525
60774
|
const callback = `http://127.0.0.1:${port}/cb`;
|
|
@@ -60568,6 +60817,7 @@ async function runLogin(_cwd, args) {
|
|
|
60568
60817
|
user_id: payload.user_id,
|
|
60569
60818
|
email: payload.email,
|
|
60570
60819
|
server: payload.server,
|
|
60820
|
+
control_plane_url: normalizeControlPlaneUrl(payload.control_plane_url),
|
|
60571
60821
|
supabase_url: payload.supabase_url,
|
|
60572
60822
|
supabase_anon_key: payload.supabase_anon_key,
|
|
60573
60823
|
authedAt: new Date().toISOString()
|
|
@@ -60609,7 +60859,7 @@ async function runLogin(_cwd, args) {
|
|
|
60609
60859
|
if (session) {
|
|
60610
60860
|
await showWelcomeCard({
|
|
60611
60861
|
email: session.email ?? session.user_id,
|
|
60612
|
-
|
|
60862
|
+
controlPlaneUrl: controlPlaneBaseUrl(session),
|
|
60613
60863
|
expiresAt: session.expires_at,
|
|
60614
60864
|
hint: "brainbase template pack — bundle your first agent"
|
|
60615
60865
|
});
|
|
@@ -60630,7 +60880,7 @@ function IdentityCard(props) {
|
|
|
60630
60880
|
tone: props.tone ?? "info",
|
|
60631
60881
|
children: [
|
|
60632
60882
|
props.email && /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Box_default, {
|
|
60633
|
-
marginBottom: props.
|
|
60883
|
+
marginBottom: props.controlPlaneUrl || props.expiresAt ? 1 : 0,
|
|
60634
60884
|
children: /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Text, {
|
|
60635
60885
|
bold: true,
|
|
60636
60886
|
children: props.email
|
|
@@ -60639,24 +60889,24 @@ function IdentityCard(props) {
|
|
|
60639
60889
|
/* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Box_default, {
|
|
60640
60890
|
flexDirection: "column",
|
|
60641
60891
|
children: [
|
|
60642
|
-
props.
|
|
60892
|
+
props.controlPlaneUrl && /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Box_default, {
|
|
60643
60893
|
children: [
|
|
60644
60894
|
/* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Box_default, {
|
|
60645
|
-
width:
|
|
60895
|
+
width: 15,
|
|
60646
60896
|
children: /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Text, {
|
|
60647
60897
|
dimColor: true,
|
|
60648
|
-
children: "
|
|
60898
|
+
children: "control plane"
|
|
60649
60899
|
}, undefined, false, undefined, this)
|
|
60650
60900
|
}, undefined, false, undefined, this),
|
|
60651
60901
|
/* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Text, {
|
|
60652
|
-
children: props.
|
|
60902
|
+
children: props.controlPlaneUrl
|
|
60653
60903
|
}, undefined, false, undefined, this)
|
|
60654
60904
|
]
|
|
60655
60905
|
}, undefined, true, undefined, this),
|
|
60656
60906
|
props.expiresAt && /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Box_default, {
|
|
60657
60907
|
children: [
|
|
60658
60908
|
/* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Box_default, {
|
|
60659
|
-
width:
|
|
60909
|
+
width: 15,
|
|
60660
60910
|
children: /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(Text, {
|
|
60661
60911
|
dimColor: true,
|
|
60662
60912
|
children: "expires"
|
|
@@ -60720,7 +60970,7 @@ async function runWhoami() {
|
|
|
60720
60970
|
title: "WHOAMI",
|
|
60721
60971
|
tone: "ok",
|
|
60722
60972
|
email: session.email ?? session.user_id,
|
|
60723
|
-
|
|
60973
|
+
controlPlaneUrl: controlPlaneBaseUrl(session),
|
|
60724
60974
|
expiresAt: session.expires_at
|
|
60725
60975
|
});
|
|
60726
60976
|
}
|
|
@@ -75796,6 +76046,12 @@ var PROTECTED = new Set([
|
|
|
75796
76046
|
"status",
|
|
75797
76047
|
"token"
|
|
75798
76048
|
]);
|
|
76049
|
+
var STORED_PAT_COMMANDS = new Set([
|
|
76050
|
+
"template",
|
|
76051
|
+
"skill",
|
|
76052
|
+
"publish",
|
|
76053
|
+
"token"
|
|
76054
|
+
]);
|
|
75799
76055
|
function help() {
|
|
75800
76056
|
const out = [];
|
|
75801
76057
|
out.push("");
|
|
@@ -75873,7 +76129,7 @@ function help() {
|
|
|
75873
76129
|
out.push(` ${import_picocolors43.default.dim("--track")} for agent create: enable tracking non-interactively (off without a TTY)`);
|
|
75874
76130
|
out.push(` ${import_picocolors43.default.dim("--shell <sh|fish>")} for agent env: pick output format (auto-detected from $SHELL)`);
|
|
75875
76131
|
out.push(` ${import_picocolors43.default.dim("--all")} for template list: include installs from other folders`);
|
|
75876
|
-
out.push(` ${import_picocolors43.default.dim("--web <url>")} for login: web app URL (default https://
|
|
76132
|
+
out.push(` ${import_picocolors43.default.dim("--web <url>")} for login: web app URL (default https://app.brainbaselabs.com)`);
|
|
75877
76133
|
out.push("");
|
|
75878
76134
|
out.push(divider("ENV"));
|
|
75879
76135
|
out.push("");
|
|
@@ -75938,13 +76194,23 @@ async function requireAuth(cmd) {
|
|
|
75938
76194
|
return;
|
|
75939
76195
|
let status = authStatus();
|
|
75940
76196
|
if (!status.ok && status.session?.refresh_token) {
|
|
75941
|
-
|
|
76197
|
+
let refreshed;
|
|
76198
|
+
try {
|
|
76199
|
+
refreshed = await tryRefreshSession(status.session);
|
|
76200
|
+
} catch (error2) {
|
|
76201
|
+
if (error2 instanceof AuthRefreshLockTimeoutError && STORED_PAT_COMMANDS.has(cmd) && readToken()) {
|
|
76202
|
+
return;
|
|
76203
|
+
}
|
|
76204
|
+
throw error2;
|
|
76205
|
+
}
|
|
75942
76206
|
if (refreshed) {
|
|
75943
76207
|
status = { ok: true, session: refreshed };
|
|
75944
76208
|
}
|
|
75945
76209
|
}
|
|
75946
76210
|
if (status.ok)
|
|
75947
76211
|
return;
|
|
76212
|
+
if (STORED_PAT_COMMANDS.has(cmd) && readToken())
|
|
76213
|
+
return;
|
|
75948
76214
|
console.error("");
|
|
75949
76215
|
console.error(` ${brandTint("◆")} ${import_picocolors43.default.bold("brainbase")}`);
|
|
75950
76216
|
console.error("");
|