@brainbase-labs/cli 0.17.0 → 0.19.0
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 +2 -0
- package/dist/index.js +856 -596
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -32012,7 +32012,7 @@ var require_schemes = __commonJS((exports, module) => {
|
|
|
32012
32012
|
urnComponent.nss = (uuidComponent.uuid || "").toLowerCase();
|
|
32013
32013
|
return urnComponent;
|
|
32014
32014
|
}
|
|
32015
|
-
var
|
|
32015
|
+
var http = {
|
|
32016
32016
|
scheme: "http",
|
|
32017
32017
|
domainHost: true,
|
|
32018
32018
|
parse: httpParse,
|
|
@@ -32020,7 +32020,7 @@ var require_schemes = __commonJS((exports, module) => {
|
|
|
32020
32020
|
};
|
|
32021
32021
|
var https = {
|
|
32022
32022
|
scheme: "https",
|
|
32023
|
-
domainHost:
|
|
32023
|
+
domainHost: http.domainHost,
|
|
32024
32024
|
parse: httpParse,
|
|
32025
32025
|
serialize: httpSerialize
|
|
32026
32026
|
};
|
|
@@ -32049,7 +32049,7 @@ var require_schemes = __commonJS((exports, module) => {
|
|
|
32049
32049
|
skipNormalize: true
|
|
32050
32050
|
};
|
|
32051
32051
|
var SCHEMES = {
|
|
32052
|
-
http
|
|
32052
|
+
http,
|
|
32053
32053
|
https,
|
|
32054
32054
|
ws: ws2,
|
|
32055
32055
|
wss,
|
|
@@ -35141,7 +35141,7 @@ var require_dist2 = __commonJS((exports, module) => {
|
|
|
35141
35141
|
});
|
|
35142
35142
|
|
|
35143
35143
|
// src/index.ts
|
|
35144
|
-
var
|
|
35144
|
+
var import_picocolors48 = __toESM(require_picocolors(), 1);
|
|
35145
35145
|
import process14 from "node:process";
|
|
35146
35146
|
import fs79 from "node:fs";
|
|
35147
35147
|
|
|
@@ -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.
|
|
36011
|
+
version: "0.19.0",
|
|
36012
36012
|
description: "Pack, share, and install agent templates across harnesses (Claude Code, Codex, ...).",
|
|
36013
36013
|
type: "module",
|
|
36014
36014
|
bin: {
|
|
@@ -40969,9 +40969,6 @@ function writeAuthUnlocked(s) {
|
|
|
40969
40969
|
fs6.chmodSync(AUTH_FILE, 384);
|
|
40970
40970
|
} catch {}
|
|
40971
40971
|
}
|
|
40972
|
-
function writeAuth(s) {
|
|
40973
|
-
withAuthLock(() => writeAuthUnlocked(s));
|
|
40974
|
-
}
|
|
40975
40972
|
function clearAuth() {
|
|
40976
40973
|
withAuthLock(() => {
|
|
40977
40974
|
if (exists(AUTH_FILE))
|
|
@@ -54248,6 +54245,22 @@ var api = {
|
|
|
54248
54245
|
body: JSON.stringify({ name })
|
|
54249
54246
|
});
|
|
54250
54247
|
},
|
|
54248
|
+
async listAgents(orgId, teamId) {
|
|
54249
|
+
const path58 = `/orgs/${encodeURIComponent(orgId)}/teams/${encodeURIComponent(teamId)}/agents`;
|
|
54250
|
+
let body;
|
|
54251
|
+
try {
|
|
54252
|
+
body = await request(path58);
|
|
54253
|
+
} catch (err) {
|
|
54254
|
+
if (err instanceof ApiError && err.status === 404) {
|
|
54255
|
+
throw new ApiError("This control plane does not support listing agents yet. Update the server, or use the web app to find the agent id.", 404, err.body);
|
|
54256
|
+
}
|
|
54257
|
+
throw err;
|
|
54258
|
+
}
|
|
54259
|
+
if (!Array.isArray(body)) {
|
|
54260
|
+
throw new ApiError(`Unexpected response listing agents: expected an array from ${path58}.`, undefined, body);
|
|
54261
|
+
}
|
|
54262
|
+
return body;
|
|
54263
|
+
},
|
|
54251
54264
|
createAgent(input) {
|
|
54252
54265
|
if (usesLegacyControlPlane() && (input.machine_kind !== undefined || input.default_model !== undefined)) {
|
|
54253
54266
|
return Promise.reject(legacyAgentConfigError());
|
|
@@ -61140,12 +61153,183 @@ function printSkillHelp() {
|
|
|
61140
61153
|
}
|
|
61141
61154
|
|
|
61142
61155
|
// src/cli/login.ts
|
|
61143
|
-
import http from "node:http";
|
|
61144
|
-
import net from "node:net";
|
|
61145
|
-
import { randomBytes } from "node:crypto";
|
|
61146
61156
|
import { spawn } from "node:child_process";
|
|
61147
61157
|
var import_picocolors21 = __toESM(require_picocolors(), 1);
|
|
61148
61158
|
|
|
61159
|
+
// src/core/login-poll.ts
|
|
61160
|
+
var DEFAULT_LOGIN_TIMEOUT_MS = 10 * 60 * 1000;
|
|
61161
|
+
var MIN_LOGIN_TIMEOUT_MS = 30000;
|
|
61162
|
+
var DEFAULT_POLL_INTERVAL_MS = 2000;
|
|
61163
|
+
var MIN_POLL_INTERVAL_MS = 500;
|
|
61164
|
+
var REQUEST_TIMEOUT_MS = 1e4;
|
|
61165
|
+
var MAX_CONSECUTIVE_FAILURES = 20;
|
|
61166
|
+
|
|
61167
|
+
class LoginTimeoutError extends Error {
|
|
61168
|
+
constructor(timeoutMs, lastError) {
|
|
61169
|
+
super(`Login timed out after ${Math.round(timeoutMs / 1000)}s` + (lastError ? ` (last error: ${lastError})` : ""));
|
|
61170
|
+
this.name = "LoginTimeoutError";
|
|
61171
|
+
}
|
|
61172
|
+
}
|
|
61173
|
+
function sleep(ms2) {
|
|
61174
|
+
return new Promise((resolve) => setTimeout(resolve, ms2));
|
|
61175
|
+
}
|
|
61176
|
+
var MAX_POLL_INTERVAL_MS = 60000;
|
|
61177
|
+
function backoffInterval(res, current) {
|
|
61178
|
+
const header = Number(res.headers.get("Retry-After"));
|
|
61179
|
+
const suggested = Number.isFinite(header) && header > 0 ? header * 1000 : current * 2;
|
|
61180
|
+
return Math.min(Math.max(suggested, current), MAX_POLL_INTERVAL_MS);
|
|
61181
|
+
}
|
|
61182
|
+
function clamp2(value, min2, max2) {
|
|
61183
|
+
if (!Number.isFinite(value))
|
|
61184
|
+
return min2;
|
|
61185
|
+
return Math.min(Math.max(value, min2), max2);
|
|
61186
|
+
}
|
|
61187
|
+
function unsupportedDeployment(webBase) {
|
|
61188
|
+
return new Error(`${webBase} does not support device login. Update the Brainbase console, or point at another deployment with \`brainbase login --web <url>\`.`);
|
|
61189
|
+
}
|
|
61190
|
+
var UNSAFE_URI_CHARS = /[\s"'`$&|;<>^(){}\\!*]/;
|
|
61191
|
+
function resolveVerificationUri(webBase, uri) {
|
|
61192
|
+
const fallback = `${webBase}/cli/auth`;
|
|
61193
|
+
let base2;
|
|
61194
|
+
try {
|
|
61195
|
+
base2 = new URL(`${webBase}/`);
|
|
61196
|
+
} catch {
|
|
61197
|
+
return fallback;
|
|
61198
|
+
}
|
|
61199
|
+
let resolved;
|
|
61200
|
+
try {
|
|
61201
|
+
resolved = new URL(uri, base2);
|
|
61202
|
+
} catch {
|
|
61203
|
+
return fallback;
|
|
61204
|
+
}
|
|
61205
|
+
if (resolved.origin !== base2.origin)
|
|
61206
|
+
return fallback;
|
|
61207
|
+
if (resolved.protocol !== "http:" && resolved.protocol !== "https:") {
|
|
61208
|
+
return fallback;
|
|
61209
|
+
}
|
|
61210
|
+
const path73 = `${resolved.pathname}${resolved.search}${resolved.hash}`;
|
|
61211
|
+
if (UNSAFE_URI_CHARS.test(path73))
|
|
61212
|
+
return fallback;
|
|
61213
|
+
return resolved.toString();
|
|
61214
|
+
}
|
|
61215
|
+
async function readJson2(res) {
|
|
61216
|
+
try {
|
|
61217
|
+
const body = await res.json();
|
|
61218
|
+
return body && typeof body === "object" ? body : null;
|
|
61219
|
+
} catch {
|
|
61220
|
+
return null;
|
|
61221
|
+
}
|
|
61222
|
+
}
|
|
61223
|
+
var JSON_HEADERS = {
|
|
61224
|
+
"Content-Type": "application/json",
|
|
61225
|
+
Accept: "application/json"
|
|
61226
|
+
};
|
|
61227
|
+
async function startDeviceAuthorization(options) {
|
|
61228
|
+
const { webBase, fetchImpl = fetch } = options;
|
|
61229
|
+
const url = `${webBase}/api/cli/auth/device`;
|
|
61230
|
+
let res;
|
|
61231
|
+
try {
|
|
61232
|
+
res = await fetchImpl(url, {
|
|
61233
|
+
method: "POST",
|
|
61234
|
+
headers: JSON_HEADERS,
|
|
61235
|
+
body: "{}",
|
|
61236
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
|
|
61237
|
+
});
|
|
61238
|
+
} catch (err) {
|
|
61239
|
+
throw new Error(`Could not reach ${url}: ${err.message}`);
|
|
61240
|
+
}
|
|
61241
|
+
if (res.status === 404)
|
|
61242
|
+
throw unsupportedDeployment(webBase);
|
|
61243
|
+
if (!res.ok) {
|
|
61244
|
+
throw new Error(`Could not start login (${webBase} returned ${res.status}).`);
|
|
61245
|
+
}
|
|
61246
|
+
const body = await readJson2(res);
|
|
61247
|
+
if (!body?.device_code || !body.user_code) {
|
|
61248
|
+
throw unsupportedDeployment(webBase);
|
|
61249
|
+
}
|
|
61250
|
+
return {
|
|
61251
|
+
deviceCode: body.device_code,
|
|
61252
|
+
userCode: body.user_code,
|
|
61253
|
+
verificationUri: resolveVerificationUri(webBase, body.verification_uri ?? "/cli/auth"),
|
|
61254
|
+
intervalMs: clamp2(body.interval ? body.interval * 1000 : DEFAULT_POLL_INTERVAL_MS, MIN_POLL_INTERVAL_MS, MAX_POLL_INTERVAL_MS),
|
|
61255
|
+
expiresInMs: clamp2(body.expires_in ? body.expires_in * 1000 : DEFAULT_LOGIN_TIMEOUT_MS, MIN_LOGIN_TIMEOUT_MS, DEFAULT_LOGIN_TIMEOUT_MS)
|
|
61256
|
+
};
|
|
61257
|
+
}
|
|
61258
|
+
async function awaitDeviceSession(options) {
|
|
61259
|
+
const {
|
|
61260
|
+
webBase,
|
|
61261
|
+
authorization,
|
|
61262
|
+
timeoutMs = Math.min(authorization.expiresInMs, DEFAULT_LOGIN_TIMEOUT_MS),
|
|
61263
|
+
now: now2 = Date.now,
|
|
61264
|
+
wait = sleep,
|
|
61265
|
+
fetchImpl = fetch
|
|
61266
|
+
} = options;
|
|
61267
|
+
const url = `${webBase}/api/cli/auth/device/token`;
|
|
61268
|
+
const deadline = now2() + timeoutMs;
|
|
61269
|
+
let consecutiveFailures = 0;
|
|
61270
|
+
let intervalMs = authorization.intervalMs;
|
|
61271
|
+
let lastError;
|
|
61272
|
+
while (now2() < deadline) {
|
|
61273
|
+
let res;
|
|
61274
|
+
try {
|
|
61275
|
+
res = await fetchImpl(url, {
|
|
61276
|
+
method: "POST",
|
|
61277
|
+
headers: JSON_HEADERS,
|
|
61278
|
+
body: JSON.stringify({ device_code: authorization.deviceCode }),
|
|
61279
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
|
|
61280
|
+
});
|
|
61281
|
+
} catch (err) {
|
|
61282
|
+
lastError = err.message;
|
|
61283
|
+
if (++consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) {
|
|
61284
|
+
throw new Error(`Could not reach ${url}: ${lastError}`);
|
|
61285
|
+
}
|
|
61286
|
+
await wait(intervalMs);
|
|
61287
|
+
continue;
|
|
61288
|
+
}
|
|
61289
|
+
if (res.status === 410) {
|
|
61290
|
+
throw new Error("This login expired. Run `brainbase login` again.");
|
|
61291
|
+
}
|
|
61292
|
+
if (res.status === 409) {
|
|
61293
|
+
throw new Error("This login was already completed on another device. Run `brainbase login` again.");
|
|
61294
|
+
}
|
|
61295
|
+
if (res.status === 404)
|
|
61296
|
+
throw unsupportedDeployment(webBase);
|
|
61297
|
+
if (res.status === 429) {
|
|
61298
|
+
consecutiveFailures = 0;
|
|
61299
|
+
intervalMs = backoffInterval(res, intervalMs);
|
|
61300
|
+
lastError = "the server asked us to slow down";
|
|
61301
|
+
await wait(intervalMs);
|
|
61302
|
+
continue;
|
|
61303
|
+
}
|
|
61304
|
+
if (!res.ok) {
|
|
61305
|
+
lastError = `poll returned ${res.status}`;
|
|
61306
|
+
if (res.status >= 400 && res.status < 500) {
|
|
61307
|
+
const detail = (await readJson2(res))?.error;
|
|
61308
|
+
throw new Error(typeof detail === "string" ? detail : `The server rejected this login (${res.status}). Run \`brainbase login\` again.`);
|
|
61309
|
+
}
|
|
61310
|
+
if (++consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) {
|
|
61311
|
+
throw new Error(`Could not reach ${url}: ${lastError}`);
|
|
61312
|
+
}
|
|
61313
|
+
await wait(intervalMs);
|
|
61314
|
+
continue;
|
|
61315
|
+
}
|
|
61316
|
+
consecutiveFailures = 0;
|
|
61317
|
+
const body = await readJson2(res);
|
|
61318
|
+
if (!body) {
|
|
61319
|
+
throw unsupportedDeployment(webBase);
|
|
61320
|
+
}
|
|
61321
|
+
if (body.status === "ready") {
|
|
61322
|
+
const session = body.session;
|
|
61323
|
+
if (!session) {
|
|
61324
|
+
throw new Error("The server said the login was ready but sent no session. Run `brainbase login` again.");
|
|
61325
|
+
}
|
|
61326
|
+
return session;
|
|
61327
|
+
}
|
|
61328
|
+
await wait(intervalMs);
|
|
61329
|
+
}
|
|
61330
|
+
throw new LoginTimeoutError(timeoutMs, lastError);
|
|
61331
|
+
}
|
|
61332
|
+
|
|
61149
61333
|
// src/ui/ink/WelcomeCard.tsx
|
|
61150
61334
|
var jsx_dev_runtime14 = __toESM(require_jsx_dev_runtime(), 1);
|
|
61151
61335
|
function WelcomeCard(props) {
|
|
@@ -61224,143 +61408,132 @@ async function showWelcomeCard(props) {
|
|
|
61224
61408
|
|
|
61225
61409
|
// src/cli/login.ts
|
|
61226
61410
|
var DEFAULT_WEB_URL = "https://app.brainbaselabs.com";
|
|
61227
|
-
var LOGIN_TIMEOUT_MS = 5 * 60 * 1000;
|
|
61228
61411
|
function resolveLoginWebBase(web, envWeb = process.env.BRAINBASE_WEB_URL) {
|
|
61229
61412
|
const override = web?.trim() || envWeb?.trim() || DEFAULT_WEB_URL;
|
|
61230
61413
|
return override.replace(/\/+$/, "");
|
|
61231
61414
|
}
|
|
61415
|
+
function isInsecureWebBase(webBase) {
|
|
61416
|
+
let url;
|
|
61417
|
+
try {
|
|
61418
|
+
url = new URL(webBase);
|
|
61419
|
+
} catch {
|
|
61420
|
+
return false;
|
|
61421
|
+
}
|
|
61422
|
+
if (url.protocol !== "http:")
|
|
61423
|
+
return false;
|
|
61424
|
+
return !["127.0.0.1", "localhost", "[::1]", "::1"].includes(url.hostname);
|
|
61425
|
+
}
|
|
61232
61426
|
function openInBrowser(url) {
|
|
61233
|
-
const
|
|
61234
|
-
|
|
61235
|
-
|
|
61236
|
-
|
|
61237
|
-
|
|
61238
|
-
function getFreePort() {
|
|
61239
|
-
return new Promise((resolve, reject2) => {
|
|
61240
|
-
const srv = net.createServer();
|
|
61241
|
-
srv.unref();
|
|
61242
|
-
srv.on("error", reject2);
|
|
61243
|
-
srv.listen(0, "127.0.0.1", () => {
|
|
61244
|
-
const addr = srv.address();
|
|
61245
|
-
if (typeof addr === "object" && addr) {
|
|
61246
|
-
const port = addr.port;
|
|
61247
|
-
srv.close(() => resolve(port));
|
|
61248
|
-
} else {
|
|
61249
|
-
srv.close();
|
|
61250
|
-
reject2(new Error("no port"));
|
|
61251
|
-
}
|
|
61427
|
+
const [cmd, args] = process.platform === "darwin" ? ["open", [url]] : process.platform === "win32" ? ["rundll32.exe", ["url.dll,FileProtocolHandler", url]] : ["xdg-open", [url]];
|
|
61428
|
+
try {
|
|
61429
|
+
const child = spawn(cmd, args, {
|
|
61430
|
+
stdio: "ignore",
|
|
61431
|
+
detached: true
|
|
61252
61432
|
});
|
|
61253
|
-
|
|
61433
|
+
child.on("error", () => {});
|
|
61434
|
+
child.unref();
|
|
61435
|
+
} catch {}
|
|
61254
61436
|
}
|
|
61255
|
-
|
|
61256
|
-
return
|
|
61257
|
-
|
|
61258
|
-
|
|
61259
|
-
|
|
61260
|
-
|
|
61261
|
-
|
|
61437
|
+
function displayUserCode(code) {
|
|
61438
|
+
return code.replace(/[^A-Za-z0-9-]/g, "");
|
|
61439
|
+
}
|
|
61440
|
+
function isLoopbackUrl(url) {
|
|
61441
|
+
return ["127.0.0.1", "localhost", "[::1]", "::1"].includes(url.hostname);
|
|
61442
|
+
}
|
|
61443
|
+
function assertNoTransportDowngrade(session, webBase) {
|
|
61444
|
+
let base2;
|
|
61445
|
+
try {
|
|
61446
|
+
base2 = new URL(webBase);
|
|
61447
|
+
} catch {
|
|
61448
|
+
return;
|
|
61449
|
+
}
|
|
61450
|
+
if (base2.protocol !== "https:")
|
|
61451
|
+
return;
|
|
61452
|
+
for (const [field, value] of [
|
|
61453
|
+
["server", session.server],
|
|
61454
|
+
["control_plane_url", session.control_plane_url],
|
|
61455
|
+
["supabase_url", session.supabase_url]
|
|
61456
|
+
]) {
|
|
61457
|
+
if (!value)
|
|
61458
|
+
continue;
|
|
61459
|
+
let url;
|
|
61460
|
+
try {
|
|
61461
|
+
url = new URL(value);
|
|
61462
|
+
} catch {
|
|
61463
|
+
throw new Error(`The server returned an unusable ${field} (${value}).`);
|
|
61464
|
+
}
|
|
61465
|
+
if (url.protocol !== "https:" && !isLoopbackUrl(url)) {
|
|
61466
|
+
throw new Error(`${webBase} returned a plaintext ${field} (${value}). Refusing to store it — every later command would send your token over an unencrypted connection.`);
|
|
61467
|
+
}
|
|
61468
|
+
}
|
|
61469
|
+
}
|
|
61470
|
+
function toAuthSession(session, webBase) {
|
|
61471
|
+
if (!session.access_token || !session.user_id) {
|
|
61472
|
+
throw new Error("The server returned an incomplete session.");
|
|
61473
|
+
}
|
|
61474
|
+
assertNoTransportDowngrade(session, webBase);
|
|
61475
|
+
const optional = (value) => value ?? undefined;
|
|
61476
|
+
const stored = {
|
|
61477
|
+
schemaVersion: 1,
|
|
61478
|
+
access_token: session.access_token,
|
|
61479
|
+
refresh_token: optional(session.refresh_token),
|
|
61480
|
+
expires_at: optional(session.expires_at),
|
|
61481
|
+
user_id: session.user_id,
|
|
61482
|
+
email: optional(session.email),
|
|
61483
|
+
server: optional(session.server),
|
|
61484
|
+
control_plane_url: normalizeControlPlaneUrl(optional(session.control_plane_url)),
|
|
61485
|
+
supabase_url: optional(session.supabase_url),
|
|
61486
|
+
supabase_anon_key: optional(session.supabase_anon_key),
|
|
61487
|
+
authedAt: new Date().toISOString()
|
|
61488
|
+
};
|
|
61489
|
+
const parsed = AuthSessionSchema.safeParse(stored);
|
|
61490
|
+
if (!parsed.success) {
|
|
61491
|
+
throw new Error(`The server returned a session this CLI cannot store (${parsed.error.issues[0]?.path.join(".") || "unknown field"}).`);
|
|
61492
|
+
}
|
|
61493
|
+
return parsed.data;
|
|
61494
|
+
}
|
|
61495
|
+
async function withCancelOnInterrupt(body) {
|
|
61496
|
+
const onInterrupt = () => {
|
|
61497
|
+
f2.warn("Cancelled. Nothing was saved.");
|
|
61498
|
+
process.exit(130);
|
|
61499
|
+
};
|
|
61500
|
+
process.prependListener("SIGINT", onInterrupt);
|
|
61501
|
+
try {
|
|
61502
|
+
return await body();
|
|
61503
|
+
} finally {
|
|
61504
|
+
process.removeListener("SIGINT", onInterrupt);
|
|
61505
|
+
}
|
|
61262
61506
|
}
|
|
61263
61507
|
async function runLogin(_cwd, args) {
|
|
61264
61508
|
banner("login — connect this device to brainbase");
|
|
61265
61509
|
const webBase = resolveLoginWebBase(args.web);
|
|
61266
|
-
const expectedState = randomBytes(16).toString("hex");
|
|
61267
|
-
const port = await getFreePort();
|
|
61268
|
-
const callback = `http://127.0.0.1:${port}/cb`;
|
|
61269
|
-
const url = `${webBase}/cli/auth?callback=${encodeURIComponent(callback)}&state=${expectedState}`;
|
|
61270
|
-
let resolveResult;
|
|
61271
|
-
let rejectResult;
|
|
61272
|
-
const result2 = new Promise((res, rej) => {
|
|
61273
|
-
resolveResult = res;
|
|
61274
|
-
rejectResult = rej;
|
|
61275
|
-
});
|
|
61276
|
-
const corsOrigin = webBase;
|
|
61277
|
-
const server = http.createServer(async (req, res) => {
|
|
61278
|
-
const reqOrigin = req.headers.origin ?? corsOrigin;
|
|
61279
|
-
res.setHeader("Access-Control-Allow-Origin", reqOrigin);
|
|
61280
|
-
res.setHeader("Access-Control-Allow-Methods", "POST, OPTIONS");
|
|
61281
|
-
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
|
61282
|
-
res.setHeader("Vary", "Origin");
|
|
61283
|
-
if (req.method === "OPTIONS") {
|
|
61284
|
-
res.writeHead(204).end();
|
|
61285
|
-
return;
|
|
61286
|
-
}
|
|
61287
|
-
if (req.method === "GET" && (req.url === "/" || req.url === "/cb")) {
|
|
61288
|
-
res.writeHead(200, { "Content-Type": "text/plain" });
|
|
61289
|
-
res.end("brainbase login server is alive. Complete sign-in in your browser.");
|
|
61290
|
-
return;
|
|
61291
|
-
}
|
|
61292
|
-
if (req.method === "POST" && req.url === "/cb") {
|
|
61293
|
-
try {
|
|
61294
|
-
const body = await readBody(req);
|
|
61295
|
-
const payload = JSON.parse(body);
|
|
61296
|
-
if (payload.state !== expectedState) {
|
|
61297
|
-
res.writeHead(400, { "Content-Type": "application/json" });
|
|
61298
|
-
res.end(JSON.stringify({ error: "state mismatch" }));
|
|
61299
|
-
return;
|
|
61300
|
-
}
|
|
61301
|
-
if (!payload.access_token || !payload.user_id) {
|
|
61302
|
-
res.writeHead(400, { "Content-Type": "application/json" });
|
|
61303
|
-
res.end(JSON.stringify({ error: "missing fields" }));
|
|
61304
|
-
return;
|
|
61305
|
-
}
|
|
61306
|
-
const session = {
|
|
61307
|
-
schemaVersion: 1,
|
|
61308
|
-
access_token: payload.access_token,
|
|
61309
|
-
refresh_token: payload.refresh_token,
|
|
61310
|
-
expires_at: payload.expires_at,
|
|
61311
|
-
user_id: payload.user_id,
|
|
61312
|
-
email: payload.email,
|
|
61313
|
-
server: payload.server,
|
|
61314
|
-
control_plane_url: normalizeControlPlaneUrl(payload.control_plane_url),
|
|
61315
|
-
supabase_url: payload.supabase_url,
|
|
61316
|
-
supabase_anon_key: payload.supabase_anon_key,
|
|
61317
|
-
authedAt: new Date().toISOString()
|
|
61318
|
-
};
|
|
61319
|
-
writeAuth(session);
|
|
61320
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
61321
|
-
res.end(JSON.stringify({ ok: true }));
|
|
61322
|
-
resolveResult(session);
|
|
61323
|
-
} catch (err) {
|
|
61324
|
-
res.writeHead(500, { "Content-Type": "application/json" });
|
|
61325
|
-
res.end(JSON.stringify({ error: err.message }));
|
|
61326
|
-
rejectResult(err);
|
|
61327
|
-
}
|
|
61328
|
-
return;
|
|
61329
|
-
}
|
|
61330
|
-
res.writeHead(404).end();
|
|
61331
|
-
});
|
|
61332
|
-
await new Promise((resolve, reject2) => {
|
|
61333
|
-
server.once("error", reject2);
|
|
61334
|
-
server.listen(port, "127.0.0.1", () => resolve());
|
|
61335
|
-
});
|
|
61336
|
-
f2.info(`Opening ${import_picocolors21.default.cyan(`${webBase}/cli/auth`)} in your browser…`);
|
|
61337
|
-
f2.info(import_picocolors21.default.dim(`If it doesn't open, visit:`));
|
|
61338
|
-
console.log(import_picocolors21.default.dim(" ") + url);
|
|
61339
|
-
openInBrowser(url);
|
|
61340
61510
|
const spinner = de();
|
|
61341
|
-
|
|
61342
|
-
|
|
61343
|
-
|
|
61344
|
-
|
|
61345
|
-
rejectResult(new Error(`Login timed out after ${LOGIN_TIMEOUT_MS / 1000}s`));
|
|
61346
|
-
}, LOGIN_TIMEOUT_MS);
|
|
61511
|
+
let spinning = false;
|
|
61512
|
+
if (isInsecureWebBase(webBase)) {
|
|
61513
|
+
f2.warn(import_picocolors21.default.yellow(`${webBase} is not HTTPS — your session would cross the network in the clear.`));
|
|
61514
|
+
}
|
|
61347
61515
|
try {
|
|
61348
|
-
const
|
|
61349
|
-
|
|
61350
|
-
|
|
61516
|
+
const authorization = await startDeviceAuthorization({ webBase });
|
|
61517
|
+
f2.step(`Your code: ${import_picocolors21.default.bold(import_picocolors21.default.cyan(displayUserCode(authorization.userCode)))}`);
|
|
61518
|
+
f2.info(`Enter it at ${import_picocolors21.default.cyan(authorization.verificationUri)}`);
|
|
61519
|
+
f2.info(import_picocolors21.default.dim("Opening your browser…"));
|
|
61520
|
+
openInBrowser(authorization.verificationUri);
|
|
61521
|
+
spinner.start("Waiting for you to approve in the browser (Ctrl-C to cancel)");
|
|
61522
|
+
spinning = true;
|
|
61523
|
+
const session = await withCancelOnInterrupt(() => awaitDeviceSession({ webBase, authorization }));
|
|
61524
|
+
const stored = toAuthSession(session, webBase);
|
|
61351
61525
|
spinner.stop("Authorized.");
|
|
61526
|
+
spinning = false;
|
|
61352
61527
|
$e("Welcome to brainbase.");
|
|
61353
|
-
|
|
61354
|
-
|
|
61355
|
-
|
|
61356
|
-
|
|
61357
|
-
|
|
61358
|
-
|
|
61359
|
-
});
|
|
61360
|
-
}
|
|
61528
|
+
await showWelcomeCard({
|
|
61529
|
+
email: stored.email ?? stored.user_id,
|
|
61530
|
+
controlPlaneUrl: controlPlaneBaseUrl(stored),
|
|
61531
|
+
expiresAt: stored.expires_at,
|
|
61532
|
+
hint: "brainbase template pack — bundle your first agent"
|
|
61533
|
+
});
|
|
61361
61534
|
} catch (err) {
|
|
61362
|
-
|
|
61363
|
-
|
|
61535
|
+
if (spinning)
|
|
61536
|
+
spinner.stop("Login failed.");
|
|
61364
61537
|
f2.error(err.message);
|
|
61365
61538
|
process.exit(1);
|
|
61366
61539
|
}
|
|
@@ -63027,7 +63200,7 @@ function runHarnessInstall(harnessId, components, opts, agentName) {
|
|
|
63027
63200
|
}
|
|
63028
63201
|
|
|
63029
63202
|
// src/cli/agent.ts
|
|
63030
|
-
var
|
|
63203
|
+
var import_picocolors34 = __toESM(require_picocolors(), 1);
|
|
63031
63204
|
|
|
63032
63205
|
// src/cli/agent-pull.ts
|
|
63033
63206
|
import { spawn as spawn2 } from "node:child_process";
|
|
@@ -65336,7 +65509,7 @@ function formatExport(shell, key2, value) {
|
|
|
65336
65509
|
|
|
65337
65510
|
// src/cli/agent-create.ts
|
|
65338
65511
|
import path81 from "node:path";
|
|
65339
|
-
var
|
|
65512
|
+
var import_picocolors32 = __toESM(require_picocolors(), 1);
|
|
65340
65513
|
|
|
65341
65514
|
// src/ui/box.ts
|
|
65342
65515
|
var import_picocolors30 = __toESM(require_picocolors(), 1);
|
|
@@ -65362,110 +65535,189 @@ function tip(text2, indent = 2) {
|
|
|
65362
65535
|
return " ".repeat(indent) + import_picocolors30.default.dim("›") + " " + import_picocolors30.default.dim(text2);
|
|
65363
65536
|
}
|
|
65364
65537
|
|
|
65365
|
-
// src/
|
|
65366
|
-
|
|
65367
|
-
|
|
65368
|
-
|
|
65369
|
-
|
|
65370
|
-
|
|
65371
|
-
if (manifest.id) {
|
|
65372
|
-
f2.warn(`This folder already belongs to an agent — ${import_picocolors31.default.bold(manifest.agent.name)} (${import_picocolors31.default.dim(manifest.id)}).`);
|
|
65373
|
-
f2.info(`If you want to detach it, run ${import_picocolors31.default.cyan("brainbase unlink")} first; or move to a different directory.`);
|
|
65374
|
-
return;
|
|
65538
|
+
// src/core/org-team.ts
|
|
65539
|
+
var import_picocolors31 = __toESM(require_picocolors(), 1);
|
|
65540
|
+
class OrgTeamError extends Error {
|
|
65541
|
+
constructor(message) {
|
|
65542
|
+
super(message);
|
|
65543
|
+
this.name = "OrgTeamError";
|
|
65375
65544
|
}
|
|
65376
|
-
|
|
65377
|
-
|
|
65378
|
-
|
|
65545
|
+
}
|
|
65546
|
+
async function loading(announce, message, done, fetch2) {
|
|
65547
|
+
if (!announce)
|
|
65548
|
+
return await fetch2();
|
|
65549
|
+
const sp = de();
|
|
65550
|
+
sp.start(message);
|
|
65379
65551
|
try {
|
|
65380
|
-
|
|
65552
|
+
const value = await fetch2();
|
|
65553
|
+
sp.stop(done(value));
|
|
65554
|
+
return value;
|
|
65381
65555
|
} catch (err) {
|
|
65382
|
-
|
|
65383
|
-
|
|
65384
|
-
return;
|
|
65556
|
+
sp.stop("Failed.");
|
|
65557
|
+
throw err;
|
|
65385
65558
|
}
|
|
65386
|
-
|
|
65559
|
+
}
|
|
65560
|
+
async function chooseOne(opts) {
|
|
65561
|
+
if (!opts.allowPrompt) {
|
|
65562
|
+
throw new NonInteractiveError(`${opts.message} cannot be answered while emitting JSON. ${opts.flagHint}`);
|
|
65563
|
+
}
|
|
65564
|
+
return await select({
|
|
65565
|
+
message: opts.message,
|
|
65566
|
+
options: opts.options,
|
|
65567
|
+
flagHint: opts.flagHint
|
|
65568
|
+
});
|
|
65569
|
+
}
|
|
65570
|
+
async function resolveOrg(orgRef, opts = {}) {
|
|
65571
|
+
if (orgRef === "") {
|
|
65572
|
+
throw new OrgTeamError("--org needs a value: an organization id or slug.");
|
|
65573
|
+
}
|
|
65574
|
+
const orgs = await loading(opts.announce, "Loading your organizations…", (found) => `Found ${found.length} organization${found.length === 1 ? "" : "s"}.`, () => api.listOrgs());
|
|
65387
65575
|
if (orgs.length === 0) {
|
|
65388
|
-
|
|
65389
|
-
$e("Create one on the web app first, then come back.");
|
|
65390
|
-
return;
|
|
65576
|
+
throw new OrgTeamError("You are not a member of any organization. Create one in the web app first.");
|
|
65391
65577
|
}
|
|
65392
|
-
|
|
65393
|
-
|
|
65394
|
-
const found = orgs.find((o2) => o2.id === args.orgId || o2.slug === args.orgId);
|
|
65578
|
+
if (orgRef) {
|
|
65579
|
+
const found = orgs.find((o2) => o2.id === orgRef || o2.slug === orgRef);
|
|
65395
65580
|
if (!found) {
|
|
65396
|
-
|
|
65397
|
-
return;
|
|
65581
|
+
throw new OrgTeamError(`Org ${orgRef} not found, or you're not a member of it.`);
|
|
65398
65582
|
}
|
|
65399
|
-
|
|
65400
|
-
} else if (orgs.length === 1) {
|
|
65401
|
-
org = orgs[0];
|
|
65402
|
-
f2.info(`Using organization ${import_picocolors31.default.bold(org.name)}.`);
|
|
65403
|
-
} else {
|
|
65404
|
-
const orgId = await select({
|
|
65405
|
-
message: "Pick an organization",
|
|
65406
|
-
options: orgs.map((o2) => ({ value: o2.id, label: o2.name, hint: o2.role })),
|
|
65407
|
-
flagHint: "Pass --org <id-or-slug> to choose non-interactively."
|
|
65408
|
-
});
|
|
65409
|
-
org = orgs.find((o2) => o2.id === orgId);
|
|
65583
|
+
return found;
|
|
65410
65584
|
}
|
|
65411
|
-
|
|
65412
|
-
|
|
65413
|
-
|
|
65414
|
-
|
|
65415
|
-
|
|
65416
|
-
} catch (err) {
|
|
65417
|
-
teamsSpinner.stop("Failed.");
|
|
65418
|
-
handleApiError4(err);
|
|
65419
|
-
return;
|
|
65585
|
+
if (orgs.length === 1) {
|
|
65586
|
+
const org = orgs[0];
|
|
65587
|
+
if (opts.announce)
|
|
65588
|
+
f2.info(`Using organization ${import_picocolors31.default.bold(org.name)}.`);
|
|
65589
|
+
return org;
|
|
65420
65590
|
}
|
|
65421
|
-
|
|
65422
|
-
|
|
65591
|
+
const orgId = await chooseOne({
|
|
65592
|
+
message: "Which organization?",
|
|
65593
|
+
options: orgs.map((o2) => ({ value: o2.id, label: o2.name, hint: o2.role })),
|
|
65594
|
+
flagHint: "Pass --org <id-or-slug>.",
|
|
65595
|
+
allowPrompt: opts.allowPrompt !== false
|
|
65596
|
+
});
|
|
65597
|
+
return orgs.find((o2) => o2.id === orgId);
|
|
65598
|
+
}
|
|
65599
|
+
function canOfferTeamCreation(opts) {
|
|
65600
|
+
return !!opts.offerCreateTeam && opts.allowPrompt !== false && opts.interactive;
|
|
65601
|
+
}
|
|
65602
|
+
function shouldAutoPickLoneTeam(opts) {
|
|
65603
|
+
return opts.teamCount === 1 && !opts.canCreate;
|
|
65604
|
+
}
|
|
65605
|
+
async function resolveOrgAndTeam(args) {
|
|
65606
|
+
if (args.orgId === "") {
|
|
65607
|
+
throw new OrgTeamError("--org needs a value: an organization id or slug.");
|
|
65608
|
+
}
|
|
65609
|
+
if (args.teamId === "") {
|
|
65610
|
+
throw new OrgTeamError("--team needs a value: a team id.");
|
|
65611
|
+
}
|
|
65612
|
+
if (args.teamId && !args.orgId) {
|
|
65613
|
+
return await findTeamAcrossOrgs(args.teamId);
|
|
65614
|
+
}
|
|
65615
|
+
const org = await resolveOrg(args.orgId, {
|
|
65616
|
+
allowPrompt: args.allowPrompt,
|
|
65617
|
+
announce: args.announce
|
|
65618
|
+
});
|
|
65619
|
+
const teams = await loading(args.announce, `Loading teams in ${org.name}…`, (found) => `Found ${found.length} team${found.length === 1 ? "" : "s"}.`, () => api.listTeams(org.id));
|
|
65423
65620
|
if (args.teamId) {
|
|
65424
65621
|
const found = teams.find((t) => t.id === args.teamId);
|
|
65425
65622
|
if (!found) {
|
|
65426
|
-
|
|
65427
|
-
return;
|
|
65623
|
+
throw new OrgTeamError(`Team ${args.teamId} not found in ${org.name}.`);
|
|
65428
65624
|
}
|
|
65429
|
-
team
|
|
65430
|
-
}
|
|
65431
|
-
|
|
65432
|
-
|
|
65625
|
+
return { org, team: found };
|
|
65626
|
+
}
|
|
65627
|
+
const canCreate = canOfferTeamCreation({
|
|
65628
|
+
offerCreateTeam: args.offerCreateTeam,
|
|
65629
|
+
allowPrompt: args.allowPrompt,
|
|
65630
|
+
interactive: isInteractive()
|
|
65631
|
+
});
|
|
65632
|
+
if (teams.length === 0 && !canCreate) {
|
|
65633
|
+
throw new OrgTeamError(`${org.name} has no teams yet. Create one in the web app first.`);
|
|
65634
|
+
}
|
|
65635
|
+
if (shouldAutoPickLoneTeam({ teamCount: teams.length, canCreate })) {
|
|
65636
|
+
const team = teams[0];
|
|
65637
|
+
if (args.announce)
|
|
65433
65638
|
f2.info(`Using team ${import_picocolors31.default.bold(team.name)}.`);
|
|
65434
|
-
|
|
65435
|
-
|
|
65436
|
-
|
|
65437
|
-
|
|
65438
|
-
|
|
65439
|
-
|
|
65440
|
-
|
|
65441
|
-
|
|
65442
|
-
{ value: "__new__", label: "+ Create a new team" }
|
|
65443
|
-
];
|
|
65444
|
-
const teamChoice = await ie({
|
|
65445
|
-
message: "Pick a team (or create one)",
|
|
65446
|
-
options: teamOptions
|
|
65639
|
+
return { org, team };
|
|
65640
|
+
}
|
|
65641
|
+
if (!canCreate) {
|
|
65642
|
+
const teamId = await chooseOne({
|
|
65643
|
+
message: "Which team?",
|
|
65644
|
+
options: teams.map((t) => ({ value: t.id, label: t.name, hint: t.role })),
|
|
65645
|
+
flagHint: "Pass --team <id>.",
|
|
65646
|
+
allowPrompt: args.allowPrompt !== false
|
|
65447
65647
|
});
|
|
65448
|
-
|
|
65449
|
-
|
|
65450
|
-
|
|
65451
|
-
|
|
65452
|
-
|
|
65453
|
-
|
|
65454
|
-
|
|
65455
|
-
|
|
65456
|
-
|
|
65457
|
-
|
|
65458
|
-
|
|
65459
|
-
|
|
65460
|
-
|
|
65461
|
-
|
|
65462
|
-
|
|
65463
|
-
|
|
65464
|
-
|
|
65648
|
+
return { org, team: teams.find((t) => t.id === teamId) };
|
|
65649
|
+
}
|
|
65650
|
+
return { org, team: await pickOrCreateTeam(org, teams) };
|
|
65651
|
+
}
|
|
65652
|
+
var CREATE_TEAM = "__new__";
|
|
65653
|
+
async function pickOrCreateTeam(org, teams) {
|
|
65654
|
+
const picked = ensureNotCancelled(await ie({
|
|
65655
|
+
message: "Pick a team (or create one)",
|
|
65656
|
+
options: [
|
|
65657
|
+
...teams.map((t) => ({ value: t.id, label: t.name, hint: t.role })),
|
|
65658
|
+
{ value: CREATE_TEAM, label: "+ Create a new team" }
|
|
65659
|
+
]
|
|
65660
|
+
}));
|
|
65661
|
+
if (picked !== CREATE_TEAM)
|
|
65662
|
+
return teams.find((t) => t.id === picked);
|
|
65663
|
+
const name = ensureNotCancelled(await te({
|
|
65664
|
+
message: "New team name",
|
|
65665
|
+
validate: (v3) => !v3?.trim() ? "Required" : undefined
|
|
65666
|
+
}));
|
|
65667
|
+
return await loading(true, "Creating team…", (created) => `Created team ${import_picocolors31.default.bold(created.name)}.`, () => api.createTeam(org.id, name.trim()));
|
|
65668
|
+
}
|
|
65669
|
+
async function findTeamAcrossOrgs(teamId) {
|
|
65670
|
+
const orgs = await api.listOrgs();
|
|
65671
|
+
if (orgs.length === 0) {
|
|
65672
|
+
throw new OrgTeamError("You are not a member of any organization.");
|
|
65673
|
+
}
|
|
65674
|
+
const { resolved, failures } = await listTeamsPerOrg(orgs);
|
|
65675
|
+
for (const { org, teams } of resolved) {
|
|
65676
|
+
const team = teams.find((t) => t.id === teamId);
|
|
65677
|
+
if (team)
|
|
65678
|
+
return { org, team };
|
|
65679
|
+
}
|
|
65680
|
+
if (failures.length > 0)
|
|
65681
|
+
throw failures[0].error;
|
|
65682
|
+
throw new OrgTeamError(`Team ${teamId} not found in any of your organizations. Run \`brainbase team list\` to see the ids you can use.`);
|
|
65683
|
+
}
|
|
65684
|
+
async function listTeamsPerOrg(orgs) {
|
|
65685
|
+
const settled = await Promise.allSettled(orgs.map((org) => api.listTeams(org.id)));
|
|
65686
|
+
const entries = [];
|
|
65687
|
+
const resolved = [];
|
|
65688
|
+
const failures = [];
|
|
65689
|
+
settled.forEach((outcome, index) => {
|
|
65690
|
+
const org = orgs[index];
|
|
65691
|
+
if (outcome.status === "fulfilled") {
|
|
65692
|
+
const entry = { org, teams: outcome.value };
|
|
65693
|
+
entries.push(entry);
|
|
65694
|
+
resolved.push(entry);
|
|
65465
65695
|
} else {
|
|
65466
|
-
|
|
65696
|
+
const error = outcome.reason;
|
|
65697
|
+
entries.push({ org, teams: [], error: error.message });
|
|
65698
|
+
failures.push({ org, error });
|
|
65467
65699
|
}
|
|
65700
|
+
});
|
|
65701
|
+
return { entries, resolved, failures };
|
|
65702
|
+
}
|
|
65703
|
+
|
|
65704
|
+
// src/cli/agent-create.ts
|
|
65705
|
+
async function runAgentCreate(cwd2, args) {
|
|
65706
|
+
banner("agent create — claim a brainbase.agent.yaml and link this folder");
|
|
65707
|
+
let manifest = await loadOrScaffoldManifest(cwd2, args);
|
|
65708
|
+
if (!manifest)
|
|
65709
|
+
return;
|
|
65710
|
+
if (manifest.id) {
|
|
65711
|
+
f2.warn(`This folder already belongs to an agent — ${import_picocolors32.default.bold(manifest.agent.name)} (${import_picocolors32.default.dim(manifest.id)}).`);
|
|
65712
|
+
f2.info(`If you want to detach it, run ${import_picocolors32.default.cyan("brainbase unlink")} first; or move to a different directory.`);
|
|
65713
|
+
return;
|
|
65468
65714
|
}
|
|
65715
|
+
const { org, team } = await resolveOrgAndTeam({
|
|
65716
|
+
orgId: args.orgId,
|
|
65717
|
+
teamId: args.teamId,
|
|
65718
|
+
announce: true,
|
|
65719
|
+
offerCreateTeam: true
|
|
65720
|
+
});
|
|
65469
65721
|
const harness = normalizeHarnessId(args.harness ?? manifest.harness ?? await pickHarness2(cwd2));
|
|
65470
65722
|
let agentName = args.name?.trim() || manifest.agent.name.trim();
|
|
65471
65723
|
if (!agentName) {
|
|
@@ -65488,11 +65740,11 @@ async function runAgentCreate(cwd2, args) {
|
|
|
65488
65740
|
}
|
|
65489
65741
|
if (!autoProceed(args.yes)) {
|
|
65490
65742
|
le([
|
|
65491
|
-
`${
|
|
65492
|
-
`${
|
|
65493
|
-
`${
|
|
65494
|
-
`${
|
|
65495
|
-
...tagline ? [`${
|
|
65743
|
+
`${import_picocolors32.default.dim("org")} ${import_picocolors32.default.bold(org.name)}`,
|
|
65744
|
+
`${import_picocolors32.default.dim("team")} ${import_picocolors32.default.bold(team.name)}`,
|
|
65745
|
+
`${import_picocolors32.default.dim("harness")} ${import_picocolors32.default.bold(harness)}`,
|
|
65746
|
+
`${import_picocolors32.default.dim("agent")} ${import_picocolors32.default.bold(agentName)}`,
|
|
65747
|
+
...tagline ? [`${import_picocolors32.default.dim("tagline")} ${tagline}`] : []
|
|
65496
65748
|
].join(`
|
|
65497
65749
|
`), "Will create");
|
|
65498
65750
|
const confirmed = await se({ message: "Create this agent?", initialValue: true });
|
|
@@ -65506,7 +65758,7 @@ async function runAgentCreate(cwd2, args) {
|
|
|
65506
65758
|
const body = resolveEntrypoint(cwd2, manifest);
|
|
65507
65759
|
if (body === null) {
|
|
65508
65760
|
if (manifest.entrypoint.file) {
|
|
65509
|
-
f2.error(`Entrypoint file ${
|
|
65761
|
+
f2.error(`Entrypoint file ${import_picocolors32.default.bold(manifest.entrypoint.file)} not found.`);
|
|
65510
65762
|
} else {
|
|
65511
65763
|
f2.error("Entrypoint block is empty.");
|
|
65512
65764
|
}
|
|
@@ -65528,10 +65780,11 @@ async function runAgentCreate(cwd2, args) {
|
|
|
65528
65780
|
...manifest.machine_kind !== undefined ? { machine_kind: manifest.machine_kind } : {},
|
|
65529
65781
|
...manifest.default_model !== undefined ? { default_model: manifest.default_model } : {}
|
|
65530
65782
|
});
|
|
65531
|
-
createSpinner.stop(`Created ${
|
|
65783
|
+
createSpinner.stop(`Created ${import_picocolors32.default.bold(agent.name)}.`);
|
|
65532
65784
|
} catch (err) {
|
|
65533
65785
|
createSpinner.stop("Failed.");
|
|
65534
65786
|
handleApiError4(err);
|
|
65787
|
+
process.exitCode = 1;
|
|
65535
65788
|
return;
|
|
65536
65789
|
}
|
|
65537
65790
|
const machineConfigMissing = manifest.machine_kind !== undefined && agent.machine_kind !== manifest.machine_kind;
|
|
@@ -65544,15 +65797,15 @@ async function runAgentCreate(cwd2, args) {
|
|
|
65544
65797
|
...machineConfigMissing ? ["machine_kind"] : [],
|
|
65545
65798
|
...modelConfigMissing ? ["default_model"] : []
|
|
65546
65799
|
];
|
|
65547
|
-
f2.error(`Agent ${
|
|
65800
|
+
f2.error(`Agent ${import_picocolors32.default.bold(agent.id)} was created, but this control plane did not apply ${fields.join(" / ")}.`);
|
|
65548
65801
|
if (machineConfigMissing) {
|
|
65549
65802
|
if (agent.machine_kind) {
|
|
65550
|
-
f2.info(`machine_kind is immutable. Run ${
|
|
65803
|
+
f2.info(`machine_kind is immutable. Run ${import_picocolors32.default.cyan("brainbase agent pull --force")} to accept ${agent.machine_kind}, or delete this agent and recreate it after upgrading the control plane.`);
|
|
65551
65804
|
} else {
|
|
65552
65805
|
f2.info("machine_kind is immutable and this server did not report the provider it created. Upgrade the control plane, delete this agent, and recreate it.");
|
|
65553
65806
|
}
|
|
65554
65807
|
} else {
|
|
65555
|
-
f2.info(`Upgrade the control plane, then run ${
|
|
65808
|
+
f2.info(`Upgrade the control plane, then run ${import_picocolors32.default.cyan("brainbase agent push")} to apply default_model.`);
|
|
65556
65809
|
}
|
|
65557
65810
|
process.exitCode = 1;
|
|
65558
65811
|
return;
|
|
@@ -65566,12 +65819,12 @@ async function runAgentCreate(cwd2, args) {
|
|
|
65566
65819
|
wantsTracking = true;
|
|
65567
65820
|
} else if (!isInteractive()) {
|
|
65568
65821
|
wantsTracking = false;
|
|
65569
|
-
f2.info(`Tracking left off (non-interactive). Re-run with ${
|
|
65822
|
+
f2.info(`Tracking left off (non-interactive). Re-run with ${import_picocolors32.default.cyan("--track")} to route ${harness} LLM traffic through brainbase.`);
|
|
65570
65823
|
} else if (args.yes) {
|
|
65571
65824
|
wantsTracking = true;
|
|
65572
65825
|
} else {
|
|
65573
65826
|
const ans = await se({
|
|
65574
|
-
message: `Track ${harness} conversations on the brainbase platform? ${
|
|
65827
|
+
message: `Track ${harness} conversations on the brainbase platform? ${import_picocolors32.default.dim("(routes LLM calls through brainbase so they appear under this agent)")}`,
|
|
65575
65828
|
initialValue: true
|
|
65576
65829
|
});
|
|
65577
65830
|
wantsTracking = ensureNotCancelled(ans);
|
|
@@ -65631,7 +65884,7 @@ async function runAgentCreate(cwd2, args) {
|
|
|
65631
65884
|
if (hasContent) {
|
|
65632
65885
|
const outgoing = await buildOutgoingComponents(cwd2, manifest, null);
|
|
65633
65886
|
if (outgoing === null) {
|
|
65634
|
-
f2.warn(`Agent created, but local content wasn't uploaded. Fix the issue above and run ${
|
|
65887
|
+
f2.warn(`Agent created, but local content wasn't uploaded. Fix the issue above and run ${import_picocolors32.default.cyan("brainbase agent push")}.`);
|
|
65635
65888
|
} else if (outgoing.length > 0) {
|
|
65636
65889
|
const pushSpinner = de();
|
|
65637
65890
|
pushSpinner.start("Pushing local content…");
|
|
@@ -65645,9 +65898,9 @@ async function runAgentCreate(cwd2, args) {
|
|
|
65645
65898
|
} catch (err) {
|
|
65646
65899
|
pushSpinner.stop("Failed.");
|
|
65647
65900
|
if (err instanceof ApiError) {
|
|
65648
|
-
f2.warn(`Content upload failed: ${err.message}. Run ${
|
|
65901
|
+
f2.warn(`Content upload failed: ${err.message}. Run ${import_picocolors32.default.cyan("brainbase agent push")} to retry.`);
|
|
65649
65902
|
} else {
|
|
65650
|
-
f2.warn(`Content upload failed: ${err.message}. Run ${
|
|
65903
|
+
f2.warn(`Content upload failed: ${err.message}. Run ${import_picocolors32.default.cyan("brainbase agent push")} to retry.`);
|
|
65651
65904
|
}
|
|
65652
65905
|
}
|
|
65653
65906
|
}
|
|
@@ -65685,7 +65938,7 @@ async function runAgentCreate(cwd2, args) {
|
|
|
65685
65938
|
}
|
|
65686
65939
|
};
|
|
65687
65940
|
writeSyncState(cwd2, state);
|
|
65688
|
-
$e(`Created ${
|
|
65941
|
+
$e(`Created ${import_picocolors32.default.bold(agent.name)} and linked this folder.`);
|
|
65689
65942
|
await showResultCard({
|
|
65690
65943
|
title: "CREATED",
|
|
65691
65944
|
tone: "ok",
|
|
@@ -65698,9 +65951,9 @@ async function runAgentCreate(cwd2, args) {
|
|
|
65698
65951
|
});
|
|
65699
65952
|
console.log();
|
|
65700
65953
|
if (tracking && harness === "codex") {
|
|
65701
|
-
console.log(tip(`Run ${
|
|
65954
|
+
console.log(tip(`Run ${import_picocolors32.default.cyan("codex")} once in this folder and approve trust ${import_picocolors32.default.dim("— Codex only loads project-scope config in trusted projects.")}`));
|
|
65702
65955
|
}
|
|
65703
|
-
console.log(tip(`brainbase agent unpack ${
|
|
65956
|
+
console.log(tip(`brainbase agent unpack ${import_picocolors32.default.dim("— install harness files (skills/mcps) under .claude/, .codex/, …")}`));
|
|
65704
65957
|
console.log();
|
|
65705
65958
|
}
|
|
65706
65959
|
async function loadOrScaffoldManifest(cwd2, args) {
|
|
@@ -65712,13 +65965,13 @@ async function loadOrScaffoldManifest(cwd2, args) {
|
|
|
65712
65965
|
return null;
|
|
65713
65966
|
}
|
|
65714
65967
|
}
|
|
65715
|
-
f2.warn(`No ${
|
|
65968
|
+
f2.warn(`No ${import_picocolors32.default.bold(AGENT_MANIFEST_FILE)} here.`);
|
|
65716
65969
|
if (!args.yes) {
|
|
65717
65970
|
if (!isInteractive()) {
|
|
65718
65971
|
throw new NonInteractiveError(`No ${AGENT_MANIFEST_FILE} here. Create one first, or re-run with --yes to scaffold a minimal one.`);
|
|
65719
65972
|
}
|
|
65720
65973
|
const ans = await se({
|
|
65721
|
-
message: `Scaffold a minimal ${
|
|
65974
|
+
message: `Scaffold a minimal ${import_picocolors32.default.bold(AGENT_MANIFEST_FILE)} and continue?`,
|
|
65722
65975
|
initialValue: true
|
|
65723
65976
|
});
|
|
65724
65977
|
if (!ensureNotCancelled(ans)) {
|
|
@@ -65739,7 +65992,7 @@ async function loadOrScaffoldManifest(cwd2, args) {
|
|
|
65739
65992
|
};
|
|
65740
65993
|
try {
|
|
65741
65994
|
writeManifest(cwd2, scaffold);
|
|
65742
|
-
f2.info(`Wrote ${
|
|
65995
|
+
f2.info(`Wrote ${import_picocolors32.default.bold(AGENT_MANIFEST_FILE)}.`);
|
|
65743
65996
|
} catch (err) {
|
|
65744
65997
|
f2.error(`Failed to write manifest: ${err.message}`);
|
|
65745
65998
|
return null;
|
|
@@ -65750,7 +66003,7 @@ async function pickHarness2(cwd2) {
|
|
|
65750
66003
|
const detections = await detectHarnesses(cwd2);
|
|
65751
66004
|
const detected = detections.filter((d3) => d3.detection.detected);
|
|
65752
66005
|
if (detected.length === 1) {
|
|
65753
|
-
f2.info(`Detected harness: ${
|
|
66006
|
+
f2.info(`Detected harness: ${import_picocolors32.default.bold(detected[0].adapter.displayName)}.`);
|
|
65754
66007
|
return detected[0].adapter.id;
|
|
65755
66008
|
}
|
|
65756
66009
|
return await select({
|
|
@@ -65776,6 +66029,46 @@ function handleApiError4(err) {
|
|
|
65776
66029
|
$e("Aborted.");
|
|
65777
66030
|
}
|
|
65778
66031
|
|
|
66032
|
+
// src/cli/agent-list.ts
|
|
66033
|
+
var import_picocolors33 = __toESM(require_picocolors(), 1);
|
|
66034
|
+
async function runAgentList(args) {
|
|
66035
|
+
if (!args.json)
|
|
66036
|
+
banner("agent list — agents in this team");
|
|
66037
|
+
const { org, team } = await resolveOrgAndTeam({
|
|
66038
|
+
orgId: args.orgId,
|
|
66039
|
+
teamId: args.teamId,
|
|
66040
|
+
allowPrompt: !args.json,
|
|
66041
|
+
announce: !args.json
|
|
66042
|
+
});
|
|
66043
|
+
const agents = await api.listAgents(org.id, team.id);
|
|
66044
|
+
if (args.json) {
|
|
66045
|
+
console.log(JSON.stringify(agents, null, 2));
|
|
66046
|
+
return;
|
|
66047
|
+
}
|
|
66048
|
+
console.log(formatAgentList(agents, { orgName: org.name, teamName: team.name }));
|
|
66049
|
+
}
|
|
66050
|
+
function formatAgentList(agents, labels) {
|
|
66051
|
+
const lines = [""];
|
|
66052
|
+
if (agents.length === 0) {
|
|
66053
|
+
lines.push(` ${import_picocolors33.default.dim(`No agents in ${labels.orgName} → ${labels.teamName} yet.`)}`, "", ` ${import_picocolors33.default.dim("create one with")} ${import_picocolors33.default.cyan("brainbase agent create")}`, "");
|
|
66054
|
+
return lines.join(`
|
|
66055
|
+
`);
|
|
66056
|
+
}
|
|
66057
|
+
for (const agent of agents) {
|
|
66058
|
+
lines.push(` ${import_picocolors33.default.bold(agent.name)} ${import_picocolors33.default.dim(agent.slug)}`);
|
|
66059
|
+
if (agent.tagline)
|
|
66060
|
+
lines.push(` ${import_picocolors33.default.dim(agent.tagline)}`);
|
|
66061
|
+
const meta = [agent.harness, agent.machine_kind, agent.default_model].filter((value) => !!value).join(" · ");
|
|
66062
|
+
if (meta)
|
|
66063
|
+
lines.push(` ${import_picocolors33.default.dim(meta)}`);
|
|
66064
|
+
lines.push(` ${import_picocolors33.default.dim(agent.id)}`);
|
|
66065
|
+
lines.push("");
|
|
66066
|
+
}
|
|
66067
|
+
lines.push(` ${import_picocolors33.default.dim("link this folder to one with")} ${import_picocolors33.default.cyan("brainbase link --agent <id>")}`, "");
|
|
66068
|
+
return lines.join(`
|
|
66069
|
+
`);
|
|
66070
|
+
}
|
|
66071
|
+
|
|
65779
66072
|
// src/cli/agent.ts
|
|
65780
66073
|
async function runAgent(cwd2, sub, args, opts) {
|
|
65781
66074
|
if (args.some((arg) => arg === "--help" || arg === "-h")) {
|
|
@@ -65795,6 +66088,13 @@ async function runAgent(cwd2, sub, args, opts) {
|
|
|
65795
66088
|
track: opts.track
|
|
65796
66089
|
});
|
|
65797
66090
|
return;
|
|
66091
|
+
case "list":
|
|
66092
|
+
await runAgentList({
|
|
66093
|
+
orgId: opts.orgId,
|
|
66094
|
+
teamId: opts.teamId,
|
|
66095
|
+
json: opts.json
|
|
66096
|
+
});
|
|
66097
|
+
return;
|
|
65798
66098
|
case "pull":
|
|
65799
66099
|
await runAgentPull(cwd2, {
|
|
65800
66100
|
yes: opts.yes,
|
|
@@ -65838,26 +66138,111 @@ async function runAgent(cwd2, sub, args, opts) {
|
|
|
65838
66138
|
function printHelp() {
|
|
65839
66139
|
const out = [];
|
|
65840
66140
|
out.push("");
|
|
65841
|
-
out.push(` ${
|
|
66141
|
+
out.push(` ${import_picocolors34.default.bold("brainbase agent")} ${import_picocolors34.default.dim("<sub> [options]")}`);
|
|
65842
66142
|
out.push("");
|
|
65843
|
-
out.push(` ${
|
|
65844
|
-
out.push(` ${
|
|
65845
|
-
out.push(` ${
|
|
65846
|
-
out.push(` ${
|
|
65847
|
-
out.push(` ${
|
|
65848
|
-
out.push(` ${
|
|
66143
|
+
out.push(` ${import_picocolors34.default.cyan("list")} ${import_picocolors34.default.dim("show the agents in a team, with the ids `brainbase link` takes (--json for scripts)")}`);
|
|
66144
|
+
out.push(` ${import_picocolors34.default.cyan("create")} ${import_picocolors34.default.dim("claim an unclaimed brainbase.agent.yaml and create the cloud agent")}`);
|
|
66145
|
+
out.push(` ${import_picocolors34.default.cyan("pull")} ${import_picocolors34.default.dim("[<id>]")} ${import_picocolors34.default.dim("apply cloud changes into this folder — pass <id> to switch (--force to override); --run-entrypoint to also execute the agent entrypoint")}`);
|
|
66146
|
+
out.push(` ${import_picocolors34.default.cyan("push")} ${import_picocolors34.default.dim("send local changes to the cloud — instructions, playbooks, skills, MCPs, entrypoint (--force to overwrite cloud-side conflicts with local)")}`);
|
|
66147
|
+
out.push(` ${import_picocolors34.default.cyan("unpack")} ${import_picocolors34.default.dim("install the claimed agent into a harness layout (--harness to override)")}`);
|
|
66148
|
+
out.push(` ${import_picocolors34.default.cyan("status")} ${import_picocolors34.default.dim("show what would push and what would pull")}`);
|
|
66149
|
+
out.push(` ${import_picocolors34.default.cyan("env")} ${import_picocolors34.default.dim('print export statements — use with `eval "$(brainbase agent env)"`')}`);
|
|
66150
|
+
out.push("");
|
|
66151
|
+
console.log(out.join(`
|
|
66152
|
+
`));
|
|
66153
|
+
}
|
|
66154
|
+
|
|
66155
|
+
// src/cli/team.ts
|
|
66156
|
+
var import_picocolors36 = __toESM(require_picocolors(), 1);
|
|
66157
|
+
|
|
66158
|
+
// src/cli/team-list.ts
|
|
66159
|
+
var import_picocolors35 = __toESM(require_picocolors(), 1);
|
|
66160
|
+
async function runTeamList(args) {
|
|
66161
|
+
if (!args.json)
|
|
66162
|
+
banner("team list — teams you can put agents in");
|
|
66163
|
+
const orgs = args.orgId !== undefined ? [await resolveOrg(args.orgId)] : await api.listOrgs();
|
|
66164
|
+
const { entries, resolved, failures } = await listTeamsPerOrg(orgs);
|
|
66165
|
+
if (resolved.length === 0 && failures.length > 0)
|
|
66166
|
+
throw failures[0].error;
|
|
66167
|
+
if (args.json) {
|
|
66168
|
+
for (const { org, error } of failures) {
|
|
66169
|
+
console.error(`Could not load teams in ${org.name}: ${error.message}`);
|
|
66170
|
+
}
|
|
66171
|
+
console.log(JSON.stringify(entries, null, 2));
|
|
66172
|
+
return;
|
|
66173
|
+
}
|
|
66174
|
+
console.log(formatTeamList(entries));
|
|
66175
|
+
}
|
|
66176
|
+
function formatTeamList(grouped) {
|
|
66177
|
+
const lines = [""];
|
|
66178
|
+
if (grouped.length === 0) {
|
|
66179
|
+
lines.push(` ${import_picocolors35.default.dim("You are not a member of any organization.")}`, "");
|
|
66180
|
+
return lines.join(`
|
|
66181
|
+
`);
|
|
66182
|
+
}
|
|
66183
|
+
const nameWidth = Math.max(...grouped.flatMap(({ teams }) => teams.map((t) => t.name.length)), 0);
|
|
66184
|
+
for (const { org, teams, error } of grouped) {
|
|
66185
|
+
const slug = org.slug ? ` ${import_picocolors35.default.dim(org.slug)}` : "";
|
|
66186
|
+
lines.push(` ${import_picocolors35.default.bold(org.name)}${slug}`);
|
|
66187
|
+
if (error) {
|
|
66188
|
+
lines.push(` ${import_picocolors35.default.red(`could not load teams: ${error}`)}`);
|
|
66189
|
+
} else if (teams.length === 0) {
|
|
66190
|
+
lines.push(` ${import_picocolors35.default.dim("no teams yet — create one in the web app")}`);
|
|
66191
|
+
}
|
|
66192
|
+
for (const team of teams) {
|
|
66193
|
+
lines.push(` ${team.name.padEnd(nameWidth)} ${import_picocolors35.default.dim(team.id)}`);
|
|
66194
|
+
}
|
|
66195
|
+
lines.push("");
|
|
66196
|
+
}
|
|
66197
|
+
lines.push(` ${import_picocolors35.default.dim("list a team’s agents with")} ${import_picocolors35.default.cyan("brainbase agent list --team <id>")}`, "");
|
|
66198
|
+
return lines.join(`
|
|
66199
|
+
`);
|
|
66200
|
+
}
|
|
66201
|
+
|
|
66202
|
+
// src/cli/team.ts
|
|
66203
|
+
async function runTeam(sub, args, opts) {
|
|
66204
|
+
if (args.some((arg) => arg === "--help" || arg === "-h")) {
|
|
66205
|
+
printHelp2();
|
|
66206
|
+
return;
|
|
66207
|
+
}
|
|
66208
|
+
switch (sub) {
|
|
66209
|
+
case "list":
|
|
66210
|
+
await runTeamList({ orgId: opts.orgId, json: opts.json });
|
|
66211
|
+
return;
|
|
66212
|
+
case undefined:
|
|
66213
|
+
case "help":
|
|
66214
|
+
case "-h":
|
|
66215
|
+
case "--help":
|
|
66216
|
+
printHelp2();
|
|
66217
|
+
return;
|
|
66218
|
+
default:
|
|
66219
|
+
console.error(`Unknown team subcommand: ${sub}
|
|
66220
|
+
`);
|
|
66221
|
+
printHelp2();
|
|
66222
|
+
process.exit(1);
|
|
66223
|
+
}
|
|
66224
|
+
}
|
|
66225
|
+
function printHelp2() {
|
|
66226
|
+
const out = [];
|
|
66227
|
+
out.push("");
|
|
66228
|
+
out.push(` ${import_picocolors36.default.bold("brainbase team")} ${import_picocolors36.default.dim("<sub> [options]")}`);
|
|
66229
|
+
out.push("");
|
|
66230
|
+
out.push(` ${import_picocolors36.default.cyan("list")} ${import_picocolors36.default.dim("show the teams you can create agents in, grouped by organization")}`);
|
|
66231
|
+
out.push("");
|
|
66232
|
+
out.push(` ${import_picocolors36.default.dim("--org <id-or-slug>")} ${import_picocolors36.default.dim("limit to one organization")}`);
|
|
66233
|
+
out.push(` ${import_picocolors36.default.dim("--json")} ${import_picocolors36.default.dim("machine-readable output")}`);
|
|
65849
66234
|
out.push("");
|
|
65850
66235
|
console.log(out.join(`
|
|
65851
66236
|
`));
|
|
65852
66237
|
}
|
|
65853
66238
|
|
|
65854
66239
|
// src/cli/orchestration.ts
|
|
65855
|
-
var
|
|
66240
|
+
var import_picocolors43 = __toESM(require_picocolors(), 1);
|
|
65856
66241
|
|
|
65857
66242
|
// src/cli/orchestration-pull.ts
|
|
65858
66243
|
import path85 from "node:path";
|
|
65859
66244
|
import fs76 from "node:fs";
|
|
65860
|
-
var
|
|
66245
|
+
var import_picocolors37 = __toESM(require_picocolors(), 1);
|
|
65861
66246
|
|
|
65862
66247
|
// src/core/orchestration-manifest.ts
|
|
65863
66248
|
import path82 from "node:path";
|
|
@@ -66360,8 +66745,8 @@ async function runOrchestrationPull(cwd2, args) {
|
|
|
66360
66745
|
orchId = args.orchestrationId;
|
|
66361
66746
|
} else {
|
|
66362
66747
|
f2.warn("This folder is not linked to any orchestration.");
|
|
66363
|
-
f2.info(`Run ${
|
|
66364
|
-
or ${
|
|
66748
|
+
f2.info(`Run ${import_picocolors37.default.cyan("brainbase orchestration pull <id>")} with an orchestration id,
|
|
66749
|
+
or ${import_picocolors37.default.cyan("brainbase orchestration list")} to find one.`);
|
|
66365
66750
|
return;
|
|
66366
66751
|
}
|
|
66367
66752
|
const sp = de();
|
|
@@ -66380,24 +66765,24 @@ async function runOrchestrationPull(cwd2, args) {
|
|
|
66380
66765
|
const slugFor = (agentId) => slugByAgent.get(agentId) ?? agentId;
|
|
66381
66766
|
const planLines = [];
|
|
66382
66767
|
planLines.push("");
|
|
66383
|
-
planLines.push(` ${
|
|
66768
|
+
planLines.push(` ${import_picocolors37.default.bold(cloud.name)} ${import_picocolors37.default.dim(`(${cloud.id})`)}`);
|
|
66384
66769
|
if (cloud.description)
|
|
66385
|
-
planLines.push(` ${
|
|
66770
|
+
planLines.push(` ${import_picocolors37.default.dim(cloud.description)}`);
|
|
66386
66771
|
planLines.push("");
|
|
66387
|
-
planLines.push(` ${
|
|
66772
|
+
planLines.push(` ${import_picocolors37.default.dim("members:")}`);
|
|
66388
66773
|
for (const m3 of cloud.members) {
|
|
66389
66774
|
const skipped = !m3.manifest;
|
|
66390
|
-
const tail2 = skipped ?
|
|
66391
|
-
planLines.push(` ${
|
|
66775
|
+
const tail2 = skipped ? import_picocolors37.default.red(" (manifest unavailable — skipped)") : "";
|
|
66776
|
+
planLines.push(` ${import_picocolors37.default.cyan("•")} ${import_picocolors37.default.bold(slugFor(m3.agent_id))} ${import_picocolors37.default.dim(`(${m3.name})`)}${tail2}`);
|
|
66392
66777
|
}
|
|
66393
66778
|
if (cloud.edges.length) {
|
|
66394
66779
|
planLines.push("");
|
|
66395
|
-
planLines.push(` ${
|
|
66780
|
+
planLines.push(` ${import_picocolors37.default.dim("edges:")}`);
|
|
66396
66781
|
for (const e2 of cloud.edges) {
|
|
66397
66782
|
const from = slugFor(e2.from_agent_id);
|
|
66398
66783
|
const to2 = slugFor(e2.to_agent_id);
|
|
66399
|
-
const desc = e2.description ? ` ${
|
|
66400
|
-
planLines.push(` ${
|
|
66784
|
+
const desc = e2.description ? ` ${import_picocolors37.default.dim("— " + e2.description)}` : "";
|
|
66785
|
+
planLines.push(` ${import_picocolors37.default.cyan(from)} ${import_picocolors37.default.dim("→")} ${import_picocolors37.default.cyan(to2)}${desc}`);
|
|
66401
66786
|
}
|
|
66402
66787
|
}
|
|
66403
66788
|
planLines.push("");
|
|
@@ -66406,7 +66791,7 @@ async function runOrchestrationPull(cwd2, args) {
|
|
|
66406
66791
|
const isRefresh = !!existingLink;
|
|
66407
66792
|
if (!autoProceed(args.yes) && !isRefresh) {
|
|
66408
66793
|
const ok = await se({
|
|
66409
|
-
message: `Pull into ${
|
|
66794
|
+
message: `Pull into ${import_picocolors37.default.bold(cwd2)}?`,
|
|
66410
66795
|
initialValue: true
|
|
66411
66796
|
});
|
|
66412
66797
|
if (!ensureNotCancelled(ok)) {
|
|
@@ -66450,7 +66835,7 @@ async function runOrchestrationPull(cwd2, args) {
|
|
|
66450
66835
|
scope: "project",
|
|
66451
66836
|
pullSecrets: true
|
|
66452
66837
|
});
|
|
66453
|
-
memberSp.stop(`Installed ${
|
|
66838
|
+
memberSp.stop(`Installed ${import_picocolors37.default.bold(slug)} ${import_picocolors37.default.dim(`(${m3.manifest.components.length} components)`)}.`);
|
|
66454
66839
|
installedMembers.push({
|
|
66455
66840
|
agent_id: m3.agent_id,
|
|
66456
66841
|
slug,
|
|
@@ -66511,7 +66896,7 @@ async function runOrchestrationPull(cwd2, args) {
|
|
|
66511
66896
|
payload_schema: e2.payload_schema ?? {}
|
|
66512
66897
|
}))
|
|
66513
66898
|
});
|
|
66514
|
-
$e(`Pulled ${cloud.name} at revision ${cloud.revision} into ${path85.basename(cwd2)}/ ${
|
|
66899
|
+
$e(`Pulled ${cloud.name} at revision ${cloud.revision} into ${path85.basename(cwd2)}/ ${import_picocolors37.default.dim(`(${installedMembers.length}/${cloud.members.length} members)`)}.`);
|
|
66515
66900
|
}
|
|
66516
66901
|
function handleApiError5(err) {
|
|
66517
66902
|
if (err instanceof ApiError) {
|
|
@@ -66528,7 +66913,7 @@ function handleApiError5(err) {
|
|
|
66528
66913
|
}
|
|
66529
66914
|
|
|
66530
66915
|
// src/cli/orchestration-push.ts
|
|
66531
|
-
var
|
|
66916
|
+
var import_picocolors38 = __toESM(require_picocolors(), 1);
|
|
66532
66917
|
|
|
66533
66918
|
// src/core/orchestration-outgoing.ts
|
|
66534
66919
|
function buildOrchestrationGraphPayload(manifest, slugToAgentId) {
|
|
@@ -66598,12 +66983,12 @@ async function runOrchestrationPush(cwd2, args) {
|
|
|
66598
66983
|
const link2 = readOrchLink(cwd2);
|
|
66599
66984
|
if (!link2) {
|
|
66600
66985
|
f2.warn("This folder is not linked to any orchestration.");
|
|
66601
|
-
f2.info(`Run ${
|
|
66986
|
+
f2.info(`Run ${import_picocolors38.default.cyan("brainbase orchestration pull <id>")} first.`);
|
|
66602
66987
|
return;
|
|
66603
66988
|
}
|
|
66604
66989
|
if (!hasOrchManifest(cwd2)) {
|
|
66605
|
-
f2.warn(`No ${
|
|
66606
|
-
f2.info(`Run ${
|
|
66990
|
+
f2.warn(`No ${import_picocolors38.default.bold(ORCH_MANIFEST_FILE)} here.`);
|
|
66991
|
+
f2.info(`Run ${import_picocolors38.default.cyan("brainbase orchestration pull")} to materialise the manifest before pushing.`);
|
|
66607
66992
|
return;
|
|
66608
66993
|
}
|
|
66609
66994
|
let manifest;
|
|
@@ -66627,7 +67012,7 @@ async function runOrchestrationPush(cwd2, args) {
|
|
|
66627
67012
|
}
|
|
66628
67013
|
if (missing.length) {
|
|
66629
67014
|
f2.error(`Missing local checkouts for: ${missing.join(", ")}.`);
|
|
66630
|
-
f2.info(`Run ${
|
|
67015
|
+
f2.info(`Run ${import_picocolors38.default.cyan("brainbase orchestration pull")} to materialise the missing folders.`);
|
|
66631
67016
|
return;
|
|
66632
67017
|
}
|
|
66633
67018
|
let graph;
|
|
@@ -66639,13 +67024,13 @@ async function runOrchestrationPush(cwd2, args) {
|
|
|
66639
67024
|
return;
|
|
66640
67025
|
}
|
|
66641
67026
|
const plan = [""];
|
|
66642
|
-
plan.push(` ${
|
|
66643
|
-
plan.push(` ${
|
|
67027
|
+
plan.push(` ${import_picocolors38.default.bold(link2.name)} ${import_picocolors38.default.dim(`(${link2.orchestration_id})`)}`);
|
|
67028
|
+
plan.push(` ${import_picocolors38.default.dim(`${manifest.members.length} member${manifest.members.length === 1 ? "" : "s"}, ${manifest.edges.length} edge${manifest.edges.length === 1 ? "" : "s"}, ${graph.triggers.length} trigger${graph.triggers.length === 1 ? "" : "s"}`)}`);
|
|
66644
67029
|
plan.push("");
|
|
66645
67030
|
if (!args.graphOnly) {
|
|
66646
|
-
plan.push(` ${
|
|
67031
|
+
plan.push(` ${import_picocolors38.default.dim("per-member agent push:")}`);
|
|
66647
67032
|
for (const m3 of manifest.members) {
|
|
66648
|
-
plan.push(` ${
|
|
67033
|
+
plan.push(` ${import_picocolors38.default.cyan("•")} ${import_picocolors38.default.bold(m3.slug)}`);
|
|
66649
67034
|
}
|
|
66650
67035
|
plan.push("");
|
|
66651
67036
|
}
|
|
@@ -66665,7 +67050,7 @@ async function runOrchestrationPush(cwd2, args) {
|
|
|
66665
67050
|
for (const m3 of manifest.members) {
|
|
66666
67051
|
const dir = memberDir(cwd2, m3.slug);
|
|
66667
67052
|
console.log("");
|
|
66668
|
-
console.log(`${
|
|
67053
|
+
console.log(`${import_picocolors38.default.dim("───")} ${import_picocolors38.default.bold(m3.slug)} ${import_picocolors38.default.dim("───")}`);
|
|
66669
67054
|
try {
|
|
66670
67055
|
await runAgentPush(dir, { yes: true });
|
|
66671
67056
|
} catch (err) {
|
|
@@ -66723,7 +67108,7 @@ function handleApiError6(err) {
|
|
|
66723
67108
|
f2.error("You do not have access to this orchestration.");
|
|
66724
67109
|
} else if (err.status === 409) {
|
|
66725
67110
|
f2.error(err.message);
|
|
66726
|
-
f2.info(`Run ${
|
|
67111
|
+
f2.info(`Run ${import_picocolors38.default.cyan("brainbase orchestration pull")} to reconcile, then push again.`);
|
|
66727
67112
|
} else {
|
|
66728
67113
|
f2.error(err.message);
|
|
66729
67114
|
}
|
|
@@ -66733,13 +67118,13 @@ function handleApiError6(err) {
|
|
|
66733
67118
|
}
|
|
66734
67119
|
|
|
66735
67120
|
// src/cli/orchestration-status.ts
|
|
66736
|
-
var
|
|
67121
|
+
var import_picocolors39 = __toESM(require_picocolors(), 1);
|
|
66737
67122
|
async function runOrchestrationStatus(cwd2) {
|
|
66738
67123
|
banner("orchestration status — what changed locally, remotely, both");
|
|
66739
67124
|
const link2 = readOrchLink(cwd2);
|
|
66740
67125
|
if (!link2) {
|
|
66741
67126
|
f2.warn("This folder is not linked to any orchestration.");
|
|
66742
|
-
f2.info(`Run ${
|
|
67127
|
+
f2.info(`Run ${import_picocolors39.default.cyan("brainbase orchestration pull <id>")} first.`);
|
|
66743
67128
|
return;
|
|
66744
67129
|
}
|
|
66745
67130
|
const localManifest = hasOrchManifest(cwd2) ? readOrchManifest(cwd2) : null;
|
|
@@ -66762,8 +67147,8 @@ async function runOrchestrationStatus(cwd2) {
|
|
|
66762
67147
|
}
|
|
66763
67148
|
const lines = [];
|
|
66764
67149
|
lines.push("");
|
|
66765
|
-
lines.push(` ${
|
|
66766
|
-
lines.push(` ${
|
|
67150
|
+
lines.push(` ${import_picocolors39.default.bold(link2.name)} ${import_picocolors39.default.dim(`(${link2.orchestration_id})`)}`);
|
|
67151
|
+
lines.push(` ${import_picocolors39.default.dim("revision")} cloud ${cloud.revision}${lock ? ` · lock ${lock.revision}` : " · never pulled"}`);
|
|
66767
67152
|
lines.push("");
|
|
66768
67153
|
const localSlugByAgentId = new Map;
|
|
66769
67154
|
for (const m3 of localManifest?.members ?? []) {
|
|
@@ -66777,12 +67162,12 @@ async function runOrchestrationStatus(cwd2) {
|
|
|
66777
67162
|
const membersAdded = [...localMemberSet].filter((s3) => !cloudMemberSet.has(s3));
|
|
66778
67163
|
const membersRemoved = [...cloudMemberSet].filter((s3) => !localMemberSet.has(s3));
|
|
66779
67164
|
if (membersAdded.length || membersRemoved.length) {
|
|
66780
|
-
lines.push(` ${
|
|
67165
|
+
lines.push(` ${import_picocolors39.default.bold("members")}`);
|
|
66781
67166
|
for (const slug of membersAdded) {
|
|
66782
|
-
lines.push(` ${
|
|
67167
|
+
lines.push(` ${import_picocolors39.default.yellow("→ push")} added in yaml: ${import_picocolors39.default.bold(slug)}`);
|
|
66783
67168
|
}
|
|
66784
67169
|
for (const slug of membersRemoved) {
|
|
66785
|
-
lines.push(` ${
|
|
67170
|
+
lines.push(` ${import_picocolors39.default.cyan("← pull")} added on cloud: ${import_picocolors39.default.bold(slug)}`);
|
|
66786
67171
|
}
|
|
66787
67172
|
lines.push("");
|
|
66788
67173
|
}
|
|
@@ -66797,11 +67182,11 @@ async function runOrchestrationStatus(cwd2) {
|
|
|
66797
67182
|
const edgesAdded = [...localEdges.keys()].filter((k3) => !cloudEdges.has(k3));
|
|
66798
67183
|
const edgesRemoved = [...cloudEdges.keys()].filter((k3) => !localEdges.has(k3));
|
|
66799
67184
|
if (edgesAdded.length || edgesRemoved.length) {
|
|
66800
|
-
lines.push(` ${
|
|
67185
|
+
lines.push(` ${import_picocolors39.default.bold("edges")}`);
|
|
66801
67186
|
for (const k3 of edgesAdded)
|
|
66802
|
-
lines.push(` ${
|
|
67187
|
+
lines.push(` ${import_picocolors39.default.yellow("→ push")} added in yaml: ${k3}`);
|
|
66803
67188
|
for (const k3 of edgesRemoved)
|
|
66804
|
-
lines.push(` ${
|
|
67189
|
+
lines.push(` ${import_picocolors39.default.cyan("← pull")} added on cloud: ${k3}`);
|
|
66805
67190
|
lines.push("");
|
|
66806
67191
|
}
|
|
66807
67192
|
const cloudTriggerKey = (t) => {
|
|
@@ -66839,11 +67224,11 @@ async function runOrchestrationStatus(cwd2) {
|
|
|
66839
67224
|
const triggersAdded = [...localTriggers.keys()].filter((k3) => !cloudTriggers.has(k3));
|
|
66840
67225
|
const triggersRemoved = [...cloudTriggers.keys()].filter((k3) => !localTriggers.has(k3));
|
|
66841
67226
|
if (triggersAdded.length || triggersRemoved.length) {
|
|
66842
|
-
lines.push(` ${
|
|
67227
|
+
lines.push(` ${import_picocolors39.default.bold("schedule triggers")}`);
|
|
66843
67228
|
for (const k3 of triggersAdded)
|
|
66844
|
-
lines.push(` ${
|
|
67229
|
+
lines.push(` ${import_picocolors39.default.yellow("→ push")} added/changed in yaml: ${localTriggers.get(k3) ?? k3}`);
|
|
66845
67230
|
for (const k3 of triggersRemoved)
|
|
66846
|
-
lines.push(` ${
|
|
67231
|
+
lines.push(` ${import_picocolors39.default.cyan("← pull")} added/changed on cloud: ${cloudTriggers.get(k3) ?? k3}`);
|
|
66847
67232
|
lines.push("");
|
|
66848
67233
|
}
|
|
66849
67234
|
const lockByAgentId = new Map((lock?.members ?? []).map((m3) => [m3.agent_id, m3]));
|
|
@@ -66866,27 +67251,27 @@ async function runOrchestrationStatus(cwd2) {
|
|
|
66866
67251
|
}
|
|
66867
67252
|
}
|
|
66868
67253
|
if (memberDrift.length) {
|
|
66869
|
-
lines.push(` ${
|
|
67254
|
+
lines.push(` ${import_picocolors39.default.bold("member content drift")}`);
|
|
66870
67255
|
for (const d3 of memberDrift) {
|
|
66871
|
-
lines.push(` ${
|
|
67256
|
+
lines.push(` ${import_picocolors39.default.cyan("?")} ${import_picocolors39.default.bold(d3.slug)} ${import_picocolors39.default.dim("— " + d3.reason)}`);
|
|
66872
67257
|
}
|
|
66873
|
-
lines.push(` ${
|
|
67258
|
+
lines.push(` ${import_picocolors39.default.dim("cd into each member folder and run")} ${import_picocolors39.default.cyan("brainbase agent status")}`);
|
|
66874
67259
|
lines.push("");
|
|
66875
67260
|
}
|
|
66876
67261
|
const revisionDrift = lock?.revision != null && cloud.revision !== lock.revision;
|
|
66877
67262
|
if (revisionDrift) {
|
|
66878
|
-
lines.push(` ${
|
|
66879
|
-
lines.push(` ${
|
|
67263
|
+
lines.push(` ${import_picocolors39.default.bold("cloud revision")}`);
|
|
67264
|
+
lines.push(` ${import_picocolors39.default.cyan("← pull")} cloud changed since last pull: ${import_picocolors39.default.dim(`lock ${lock.revision} → cloud ${cloud.revision}`)}`);
|
|
66880
67265
|
lines.push("");
|
|
66881
67266
|
}
|
|
66882
67267
|
if (!membersAdded.length && !membersRemoved.length && !edgesAdded.length && !edgesRemoved.length && !triggersAdded.length && !triggersRemoved.length && !memberDrift.length && !revisionDrift) {
|
|
66883
|
-
lines.push(` ${
|
|
67268
|
+
lines.push(` ${import_picocolors39.default.green("✓")} everything is in sync`);
|
|
66884
67269
|
lines.push("");
|
|
66885
67270
|
console.log(lines.join(`
|
|
66886
67271
|
`));
|
|
66887
67272
|
return;
|
|
66888
67273
|
}
|
|
66889
|
-
lines.push(` ${
|
|
67274
|
+
lines.push(` ${import_picocolors39.default.dim("run")} ${import_picocolors39.default.cyan("brainbase orchestration pull")} ${import_picocolors39.default.dim("to apply cloud changes,")} ${import_picocolors39.default.cyan("brainbase orchestration push")} ${import_picocolors39.default.dim("to send yours")}`);
|
|
66890
67275
|
lines.push("");
|
|
66891
67276
|
console.log(lines.join(`
|
|
66892
67277
|
`));
|
|
@@ -66901,108 +67286,45 @@ function stableJson(value) {
|
|
|
66901
67286
|
}
|
|
66902
67287
|
|
|
66903
67288
|
// src/cli/orchestration-list.ts
|
|
66904
|
-
var
|
|
67289
|
+
var import_picocolors40 = __toESM(require_picocolors(), 1);
|
|
66905
67290
|
async function runOrchestrationList(args) {
|
|
66906
67291
|
banner("orchestration list — orchestrations under a team");
|
|
66907
|
-
|
|
66908
|
-
|
|
66909
|
-
|
|
66910
|
-
|
|
66911
|
-
|
|
66912
|
-
orgs = await api.listOrgs();
|
|
66913
|
-
} catch (err) {
|
|
66914
|
-
handleApiError7(err);
|
|
66915
|
-
return;
|
|
66916
|
-
}
|
|
66917
|
-
if (orgs.length === 0) {
|
|
66918
|
-
f2.warn("You are not a member of any organization.");
|
|
66919
|
-
return;
|
|
66920
|
-
}
|
|
66921
|
-
if (orgId) {
|
|
66922
|
-
const found = orgs.find((o2) => o2.id === orgId || o2.slug === orgId);
|
|
66923
|
-
if (!found) {
|
|
66924
|
-
f2.error(`Org ${orgId} not found or you're not a member.`);
|
|
66925
|
-
return;
|
|
66926
|
-
}
|
|
66927
|
-
orgId = found.id;
|
|
66928
|
-
} else if (orgs.length === 1) {
|
|
66929
|
-
orgId = orgs[0].id;
|
|
66930
|
-
} else {
|
|
66931
|
-
orgId = await select({
|
|
66932
|
-
message: "Which organization?",
|
|
66933
|
-
options: orgs.map((o2) => ({ value: o2.id, label: o2.name, hint: o2.role })),
|
|
66934
|
-
flagHint: "Pass --org <id-or-slug>."
|
|
66935
|
-
});
|
|
66936
|
-
}
|
|
66937
|
-
}
|
|
66938
|
-
if (!teamId) {
|
|
66939
|
-
let teams;
|
|
66940
|
-
try {
|
|
66941
|
-
teams = await api.listTeams(orgId);
|
|
66942
|
-
} catch (err) {
|
|
66943
|
-
handleApiError7(err);
|
|
66944
|
-
return;
|
|
66945
|
-
}
|
|
66946
|
-
if (teams.length === 0) {
|
|
66947
|
-
f2.warn("No teams under this organization. Create one in the web app first.");
|
|
66948
|
-
return;
|
|
66949
|
-
}
|
|
66950
|
-
if (teams.length === 1) {
|
|
66951
|
-
teamId = teams[0].id;
|
|
66952
|
-
} else {
|
|
66953
|
-
teamId = await select({
|
|
66954
|
-
message: "Which team?",
|
|
66955
|
-
options: teams.map((t) => ({ value: t.id, label: t.name })),
|
|
66956
|
-
flagHint: "Pass --team <id>."
|
|
66957
|
-
});
|
|
66958
|
-
}
|
|
66959
|
-
}
|
|
66960
|
-
let items;
|
|
67292
|
+
const { org, team } = await resolveOrgAndTeam({
|
|
67293
|
+
orgId: args.orgId,
|
|
67294
|
+
teamId: args.teamId,
|
|
67295
|
+
announce: true
|
|
67296
|
+
});
|
|
66961
67297
|
const sp = de();
|
|
66962
67298
|
sp.start("Fetching orchestrations…");
|
|
67299
|
+
let items;
|
|
66963
67300
|
try {
|
|
66964
|
-
items = await api.listOrchestrations(
|
|
66965
|
-
sp.stop(`${items.length} orchestration${items.length === 1 ? "" : "s"}.`);
|
|
67301
|
+
items = await api.listOrchestrations(org.id, team.id);
|
|
66966
67302
|
} catch (err) {
|
|
66967
67303
|
sp.stop("Failed.");
|
|
66968
|
-
|
|
66969
|
-
return;
|
|
67304
|
+
throw err;
|
|
66970
67305
|
}
|
|
67306
|
+
sp.stop(`${items.length} orchestration${items.length === 1 ? "" : "s"}.`);
|
|
66971
67307
|
if (items.length === 0) {
|
|
66972
67308
|
f2.info("This team has no orchestrations yet.");
|
|
66973
67309
|
return;
|
|
66974
67310
|
}
|
|
66975
67311
|
const lines = [""];
|
|
66976
67312
|
for (const o2 of items) {
|
|
66977
|
-
lines.push(` ${
|
|
67313
|
+
lines.push(` ${import_picocolors40.default.bold(o2.name)} ${import_picocolors40.default.dim(o2.id)}`);
|
|
66978
67314
|
if (o2.description)
|
|
66979
|
-
lines.push(` ${
|
|
66980
|
-
lines.push(` ${
|
|
67315
|
+
lines.push(` ${import_picocolors40.default.dim(o2.description)}`);
|
|
67316
|
+
lines.push(` ${import_picocolors40.default.dim(`${o2.member_count} member${o2.member_count === 1 ? "" : "s"} · ${o2.edge_count} edge${o2.edge_count === 1 ? "" : "s"}`)}`);
|
|
66981
67317
|
lines.push("");
|
|
66982
67318
|
}
|
|
66983
|
-
lines.push(` ${
|
|
67319
|
+
lines.push(` ${import_picocolors40.default.dim("pull one with")} ${import_picocolors40.default.cyan("brainbase orchestration pull <id>")}`);
|
|
66984
67320
|
lines.push("");
|
|
66985
67321
|
console.log(lines.join(`
|
|
66986
67322
|
`));
|
|
66987
67323
|
}
|
|
66988
|
-
function isUuid(value) {
|
|
66989
|
-
return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-9a-f][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);
|
|
66990
|
-
}
|
|
66991
|
-
function handleApiError7(err) {
|
|
66992
|
-
if (err instanceof ApiError) {
|
|
66993
|
-
if (err.status === 401) {
|
|
66994
|
-
f2.error("Your session is invalid. Run `brainbase login` and try again.");
|
|
66995
|
-
} else {
|
|
66996
|
-
f2.error(err.message);
|
|
66997
|
-
}
|
|
66998
|
-
} else {
|
|
66999
|
-
f2.error(err.message);
|
|
67000
|
-
}
|
|
67001
|
-
}
|
|
67002
67324
|
|
|
67003
67325
|
// src/cli/orchestration-add-agent.ts
|
|
67004
67326
|
import fs77 from "node:fs";
|
|
67005
|
-
var
|
|
67327
|
+
var import_picocolors41 = __toESM(require_picocolors(), 1);
|
|
67006
67328
|
|
|
67007
67329
|
// src/core/orchestration-add.ts
|
|
67008
67330
|
function resolveOrgIdForGroup(groupId, orgsWithTeams) {
|
|
@@ -67067,7 +67389,7 @@ async function runOrchestrationAddAgent(cwd2, args) {
|
|
|
67067
67389
|
const link2 = readOrchLink(cwd2);
|
|
67068
67390
|
if (!link2 || !hasOrchManifest(cwd2)) {
|
|
67069
67391
|
f2.warn("This folder is not a linked orchestration.");
|
|
67070
|
-
f2.info(`Run ${
|
|
67392
|
+
f2.info(`Run ${import_picocolors41.default.cyan("brainbase orchestration pull <id>")} first.`);
|
|
67071
67393
|
return;
|
|
67072
67394
|
}
|
|
67073
67395
|
let manifest;
|
|
@@ -67093,7 +67415,7 @@ async function runOrchestrationAddAgent(cwd2, args) {
|
|
|
67093
67415
|
while (manifest.members.some((m3) => m3.slug === candidate) || fs77.existsSync(memberDir(cwd2, candidate))) {
|
|
67094
67416
|
candidate = `${slug}-${++n}`;
|
|
67095
67417
|
}
|
|
67096
|
-
f2.info(`Slug ${
|
|
67418
|
+
f2.info(`Slug ${import_picocolors41.default.bold(slug)} is taken — using ${import_picocolors41.default.bold(candidate)}.`);
|
|
67097
67419
|
slug = candidate;
|
|
67098
67420
|
}
|
|
67099
67421
|
let payloadSchema;
|
|
@@ -67117,7 +67439,7 @@ async function runOrchestrationAddAgent(cwd2, args) {
|
|
|
67117
67439
|
const resolved = resolveOrgIdForGroup(link2.group_id, orgsWithTeams);
|
|
67118
67440
|
if (!resolved) {
|
|
67119
67441
|
sp.stop("Failed.");
|
|
67120
|
-
f2.error(`Could not find an org that owns group ${
|
|
67442
|
+
f2.error(`Could not find an org that owns group ${import_picocolors41.default.bold(link2.group_id)}. ` + `Pass ${import_picocolors41.default.cyan("--org <id>")} explicitly.`);
|
|
67121
67443
|
return;
|
|
67122
67444
|
}
|
|
67123
67445
|
orgId = resolved;
|
|
@@ -67134,14 +67456,14 @@ async function runOrchestrationAddAgent(cwd2, args) {
|
|
|
67134
67456
|
if (from.length === 0 && to2.length === 0 && isInteractive() && manifest.members.length > 0) {
|
|
67135
67457
|
const memberOptions = manifest.members.map((m3) => ({ value: m3.slug, label: m3.slug }));
|
|
67136
67458
|
const pickedFrom = await ae({
|
|
67137
|
-
message: `Connect ${
|
|
67459
|
+
message: `Connect ${import_picocolors41.default.bold(slug)} FROM which member(s)? — edges INTO ${slug} (space to select, enter to skip)`,
|
|
67138
67460
|
options: memberOptions,
|
|
67139
67461
|
required: false
|
|
67140
67462
|
});
|
|
67141
67463
|
if (Array.isArray(pickedFrom))
|
|
67142
67464
|
from = pickedFrom;
|
|
67143
67465
|
const pickedTo = await ae({
|
|
67144
|
-
message: `Connect ${
|
|
67466
|
+
message: `Connect ${import_picocolors41.default.bold(slug)} TO which member(s)? — edges OUT of ${slug} (space to select, enter to skip)`,
|
|
67145
67467
|
options: memberOptions,
|
|
67146
67468
|
required: false
|
|
67147
67469
|
});
|
|
@@ -67180,23 +67502,23 @@ async function runOrchestrationAddAgent(cwd2, args) {
|
|
|
67180
67502
|
}
|
|
67181
67503
|
writeOrchManifest(cwd2, updated);
|
|
67182
67504
|
if (args.noPush) {
|
|
67183
|
-
f2.info(`Manifest updated. Run ${
|
|
67505
|
+
f2.info(`Manifest updated. Run ${import_picocolors41.default.cyan("brainbase orchestration push")} to apply.`);
|
|
67184
67506
|
return;
|
|
67185
67507
|
}
|
|
67186
67508
|
await runOrchestrationPush(cwd2, { yes: true, graphOnly: true });
|
|
67187
67509
|
}
|
|
67188
67510
|
|
|
67189
67511
|
// src/cli/orchestration-create.ts
|
|
67190
|
-
var
|
|
67512
|
+
var import_picocolors42 = __toESM(require_picocolors(), 1);
|
|
67191
67513
|
async function runOrchestrationCreate(cwd2, args) {
|
|
67192
67514
|
banner("orchestration create — claim a brainbase-orchestration.yaml");
|
|
67193
67515
|
if (readOrchLink(cwd2)) {
|
|
67194
67516
|
f2.warn("This folder is already linked to an orchestration.");
|
|
67195
|
-
f2.info(`Run ${
|
|
67517
|
+
f2.info(`Run ${import_picocolors42.default.cyan("brainbase orchestration push")} to update it.`);
|
|
67196
67518
|
return;
|
|
67197
67519
|
}
|
|
67198
67520
|
if (!hasOrchManifest(cwd2)) {
|
|
67199
|
-
f2.warn(`No ${
|
|
67521
|
+
f2.warn(`No ${import_picocolors42.default.bold(ORCH_MANIFEST_FILE)} here.`);
|
|
67200
67522
|
f2.info(`Create one, or pull an existing orchestration first.`);
|
|
67201
67523
|
return;
|
|
67202
67524
|
}
|
|
@@ -67222,15 +67544,17 @@ async function runOrchestrationCreate(cwd2, args) {
|
|
|
67222
67544
|
process.exitCode = 1;
|
|
67223
67545
|
return;
|
|
67224
67546
|
}
|
|
67225
|
-
const target = await resolveOrgAndTeam(
|
|
67226
|
-
|
|
67227
|
-
|
|
67547
|
+
const target = await resolveOrgAndTeam({
|
|
67548
|
+
orgId: args.orgId,
|
|
67549
|
+
teamId: args.teamId,
|
|
67550
|
+
announce: true
|
|
67551
|
+
});
|
|
67228
67552
|
const plan = [
|
|
67229
67553
|
"",
|
|
67230
|
-
` ${
|
|
67231
|
-
` ${
|
|
67232
|
-
` ${
|
|
67233
|
-
` ${
|
|
67554
|
+
` ${import_picocolors42.default.bold(manifest.orchestration.name)}`,
|
|
67555
|
+
` ${import_picocolors42.default.dim("org")} ${import_picocolors42.default.bold(target.org.name)}`,
|
|
67556
|
+
` ${import_picocolors42.default.dim("team")} ${import_picocolors42.default.bold(target.team.name)}`,
|
|
67557
|
+
` ${import_picocolors42.default.dim("graph")} ${manifest.members.length} member${manifest.members.length === 1 ? "" : "s"}, ${manifest.edges.length} edge${manifest.edges.length === 1 ? "" : "s"}, ${graph.triggers.length} trigger${graph.triggers.length === 1 ? "" : "s"}`,
|
|
67234
67558
|
""
|
|
67235
67559
|
];
|
|
67236
67560
|
console.log(plan.join(`
|
|
@@ -67260,7 +67584,7 @@ async function runOrchestrationCreate(cwd2, args) {
|
|
|
67260
67584
|
edges: graph.edges,
|
|
67261
67585
|
triggers: graph.triggers
|
|
67262
67586
|
});
|
|
67263
|
-
sp.stop(`Created ${
|
|
67587
|
+
sp.stop(`Created ${import_picocolors42.default.bold(created.name)}.`);
|
|
67264
67588
|
writeOrchLink(cwd2, {
|
|
67265
67589
|
schemaVersion: 1,
|
|
67266
67590
|
orchestration_id: created.id,
|
|
@@ -67291,92 +67615,11 @@ async function runOrchestrationCreate(cwd2, args) {
|
|
|
67291
67615
|
$e(`Created ${created.name} at revision ${created.revision}.`);
|
|
67292
67616
|
} catch (err) {
|
|
67293
67617
|
sp.stop("Failed.");
|
|
67294
|
-
|
|
67295
|
-
process.exitCode = 1;
|
|
67296
|
-
}
|
|
67297
|
-
}
|
|
67298
|
-
async function resolveOrgAndTeam(args) {
|
|
67299
|
-
const orgsSpinner = de();
|
|
67300
|
-
orgsSpinner.start("Loading your organizations…");
|
|
67301
|
-
let orgs;
|
|
67302
|
-
try {
|
|
67303
|
-
orgs = await api.listOrgs();
|
|
67304
|
-
} catch (err) {
|
|
67305
|
-
orgsSpinner.stop("Failed.");
|
|
67306
|
-
handleApiError8(err);
|
|
67307
|
-
process.exitCode = 1;
|
|
67308
|
-
return null;
|
|
67309
|
-
}
|
|
67310
|
-
orgsSpinner.stop(`Found ${orgs.length} organization${orgs.length === 1 ? "" : "s"}.`);
|
|
67311
|
-
if (orgs.length === 0) {
|
|
67312
|
-
f2.warn("You are not in any organizations yet.");
|
|
67313
|
-
process.exitCode = 1;
|
|
67314
|
-
return null;
|
|
67315
|
-
}
|
|
67316
|
-
let org;
|
|
67317
|
-
if (args.orgId) {
|
|
67318
|
-
const found = orgs.find((o2) => o2.id === args.orgId || o2.slug === args.orgId);
|
|
67319
|
-
if (!found) {
|
|
67320
|
-
f2.error(`Org ${args.orgId} not found or you're not a member.`);
|
|
67321
|
-
process.exitCode = 1;
|
|
67322
|
-
return null;
|
|
67323
|
-
}
|
|
67324
|
-
org = found;
|
|
67325
|
-
} else if (orgs.length === 1) {
|
|
67326
|
-
org = orgs[0];
|
|
67327
|
-
f2.info(`Using organization ${import_picocolors38.default.bold(org.name)}.`);
|
|
67328
|
-
} else if (!isInteractive()) {
|
|
67329
|
-
throw new NonInteractiveError("Multiple organizations. Pass --org <id-or-slug> to choose non-interactively.");
|
|
67330
|
-
} else {
|
|
67331
|
-
const orgId = await select({
|
|
67332
|
-
message: "Pick an organization",
|
|
67333
|
-
options: orgs.map((o2) => ({ value: o2.id, label: o2.name, hint: o2.role })),
|
|
67334
|
-
flagHint: "Pass --org <id-or-slug> to choose non-interactively."
|
|
67335
|
-
});
|
|
67336
|
-
org = orgs.find((o2) => o2.id === orgId);
|
|
67337
|
-
}
|
|
67338
|
-
const teamsSpinner = de();
|
|
67339
|
-
teamsSpinner.start(`Loading teams in ${org.name}…`);
|
|
67340
|
-
let teams;
|
|
67341
|
-
try {
|
|
67342
|
-
teams = await api.listTeams(org.id);
|
|
67343
|
-
} catch (err) {
|
|
67344
|
-
teamsSpinner.stop("Failed.");
|
|
67345
|
-
handleApiError8(err);
|
|
67618
|
+
handleApiError7(err);
|
|
67346
67619
|
process.exitCode = 1;
|
|
67347
|
-
return null;
|
|
67348
67620
|
}
|
|
67349
|
-
teamsSpinner.stop(`Found ${teams.length} team${teams.length === 1 ? "" : "s"}.`);
|
|
67350
|
-
if (teams.length === 0) {
|
|
67351
|
-
f2.warn(`No teams in ${org.name} yet.`);
|
|
67352
|
-
process.exitCode = 1;
|
|
67353
|
-
return null;
|
|
67354
|
-
}
|
|
67355
|
-
let team;
|
|
67356
|
-
if (args.teamId) {
|
|
67357
|
-
const found = teams.find((t) => t.id === args.teamId);
|
|
67358
|
-
if (!found) {
|
|
67359
|
-
f2.error(`Team ${args.teamId} not found in this org.`);
|
|
67360
|
-
process.exitCode = 1;
|
|
67361
|
-
return null;
|
|
67362
|
-
}
|
|
67363
|
-
team = found;
|
|
67364
|
-
} else if (teams.length === 1) {
|
|
67365
|
-
team = teams[0];
|
|
67366
|
-
f2.info(`Using team ${import_picocolors38.default.bold(team.name)}.`);
|
|
67367
|
-
} else if (!isInteractive()) {
|
|
67368
|
-
throw new NonInteractiveError("Multiple teams. Pass --team <id> to choose non-interactively.");
|
|
67369
|
-
} else {
|
|
67370
|
-
const teamId = await select({
|
|
67371
|
-
message: "Pick a team",
|
|
67372
|
-
options: teams.map((t) => ({ value: t.id, label: t.name, hint: t.role })),
|
|
67373
|
-
flagHint: "Pass --team <id> to choose non-interactively."
|
|
67374
|
-
});
|
|
67375
|
-
team = teams.find((t) => t.id === teamId);
|
|
67376
|
-
}
|
|
67377
|
-
return { org, team };
|
|
67378
67621
|
}
|
|
67379
|
-
function
|
|
67622
|
+
function handleApiError7(err) {
|
|
67380
67623
|
if (err instanceof ApiError) {
|
|
67381
67624
|
if (err.status === 401) {
|
|
67382
67625
|
f2.error("Your session is invalid. Run `brainbase login` and try again.");
|
|
@@ -67393,7 +67636,7 @@ function handleApiError8(err) {
|
|
|
67393
67636
|
// src/cli/orchestration.ts
|
|
67394
67637
|
async function runOrchestration(cwd2, sub, args, opts) {
|
|
67395
67638
|
if (args.some((arg) => arg === "--help" || arg === "-h")) {
|
|
67396
|
-
|
|
67639
|
+
printHelp3();
|
|
67397
67640
|
return;
|
|
67398
67641
|
}
|
|
67399
67642
|
switch (sub) {
|
|
@@ -67442,33 +67685,33 @@ async function runOrchestration(cwd2, sub, args, opts) {
|
|
|
67442
67685
|
case "help":
|
|
67443
67686
|
case "-h":
|
|
67444
67687
|
case "--help":
|
|
67445
|
-
|
|
67688
|
+
printHelp3();
|
|
67446
67689
|
return;
|
|
67447
67690
|
default:
|
|
67448
67691
|
console.error(`Unknown orchestration subcommand: ${sub}
|
|
67449
67692
|
`);
|
|
67450
|
-
|
|
67693
|
+
printHelp3();
|
|
67451
67694
|
process.exit(1);
|
|
67452
67695
|
}
|
|
67453
67696
|
}
|
|
67454
|
-
function
|
|
67697
|
+
function printHelp3() {
|
|
67455
67698
|
const out = [];
|
|
67456
67699
|
out.push("");
|
|
67457
|
-
out.push(` ${
|
|
67700
|
+
out.push(` ${import_picocolors43.default.bold("brainbase orchestration")} ${import_picocolors43.default.dim("<sub> [options]")}`);
|
|
67458
67701
|
out.push("");
|
|
67459
|
-
out.push(` ${
|
|
67460
|
-
out.push(` ${
|
|
67461
|
-
out.push(` ${
|
|
67462
|
-
out.push(` ${
|
|
67463
|
-
out.push(` ${
|
|
67464
|
-
out.push(` ${
|
|
67702
|
+
out.push(` ${import_picocolors43.default.cyan("create")} ${import_picocolors43.default.dim("claim a local orchestration manifest and create it in the cloud")}`);
|
|
67703
|
+
out.push(` ${import_picocolors43.default.cyan("pull")} ${import_picocolors43.default.dim("<id>")} ${import_picocolors43.default.dim("fetch orchestration + every member agent into this folder")}`);
|
|
67704
|
+
out.push(` ${import_picocolors43.default.cyan("push")} ${import_picocolors43.default.dim("push each member, then update the orchestration graph")}`);
|
|
67705
|
+
out.push(` ${import_picocolors43.default.cyan("add-agent")} ${import_picocolors43.default.dim("<name>")} ${import_picocolors43.default.dim("create a member agent, wire edges (--from/--to), and push")}`);
|
|
67706
|
+
out.push(` ${import_picocolors43.default.cyan("status")} ${import_picocolors43.default.dim("show what would push and what would pull")}`);
|
|
67707
|
+
out.push(` ${import_picocolors43.default.cyan("list")} ${import_picocolors43.default.dim("list orchestrations under a team")}`);
|
|
67465
67708
|
out.push("");
|
|
67466
|
-
out.push(` ${
|
|
67467
|
-
out.push(` ${
|
|
67468
|
-
out.push(` ${
|
|
67469
|
-
out.push(` ${
|
|
67470
|
-
out.push(` ${
|
|
67471
|
-
out.push(` ${
|
|
67709
|
+
out.push(` ${import_picocolors43.default.bold("Flags")}`);
|
|
67710
|
+
out.push(` ${import_picocolors43.default.dim("--yes, -y")} skip confirmations`);
|
|
67711
|
+
out.push(` ${import_picocolors43.default.dim("--harness <id>")} harness for newly-created member folders (default claude-code)`);
|
|
67712
|
+
out.push(` ${import_picocolors43.default.dim("--graph-only")} for push: only update members + edges, skip per-member push`);
|
|
67713
|
+
out.push(` ${import_picocolors43.default.dim("--org <id>")} for create/list: org id or slug (CLI vocab — DB teams.id)`);
|
|
67714
|
+
out.push(` ${import_picocolors43.default.dim("--team <id>")} for create/list: team id (CLI vocab — DB groups.id)`);
|
|
67472
67715
|
out.push("");
|
|
67473
67716
|
console.log(out.join(`
|
|
67474
67717
|
`));
|
|
@@ -67513,16 +67756,16 @@ async function runRun(cwd2, args) {
|
|
|
67513
67756
|
}
|
|
67514
67757
|
|
|
67515
67758
|
// src/cli/publish.ts
|
|
67516
|
-
var
|
|
67759
|
+
var import_picocolors44 = __toESM(require_picocolors(), 1);
|
|
67517
67760
|
async function runPublish(cwd2, _args) {
|
|
67518
67761
|
banner("publish — send your changes to the team");
|
|
67519
67762
|
const link2 = readLink(cwd2);
|
|
67520
67763
|
if (!link2) {
|
|
67521
67764
|
f2.warn("This folder is not linked to any agent.");
|
|
67522
|
-
f2.info(`Run ${
|
|
67765
|
+
f2.info(`Run ${import_picocolors44.default.cyan("brainbase link")} first.`);
|
|
67523
67766
|
return;
|
|
67524
67767
|
}
|
|
67525
|
-
f2.info(`${
|
|
67768
|
+
f2.info(`${import_picocolors44.default.bold("publish")} is coming soon — for now, edit the agent on the web app and run ${import_picocolors44.default.cyan("brainbase sync")} to bring changes here.`);
|
|
67526
67769
|
}
|
|
67527
67770
|
|
|
67528
67771
|
// src/ui/ink/StatusCard.tsx
|
|
@@ -67820,7 +68063,7 @@ async function runStatus(cwd2) {
|
|
|
67820
68063
|
}
|
|
67821
68064
|
|
|
67822
68065
|
// src/cli/token.ts
|
|
67823
|
-
var
|
|
68066
|
+
var import_picocolors45 = __toESM(require_picocolors(), 1);
|
|
67824
68067
|
|
|
67825
68068
|
// src/ui/ink/TokenCards.tsx
|
|
67826
68069
|
var jsx_dev_runtime17 = __toESM(require_jsx_dev_runtime(), 1);
|
|
@@ -68114,7 +68357,7 @@ async function runTokenRevoke(args) {
|
|
|
68114
68357
|
}
|
|
68115
68358
|
if (!autoProceed(args.yes)) {
|
|
68116
68359
|
const ok = await se({
|
|
68117
|
-
message: `Revoke token ${
|
|
68360
|
+
message: `Revoke token ${import_picocolors45.default.bold(args.id)}? CIs and machines using it will stop working.`,
|
|
68118
68361
|
initialValue: false
|
|
68119
68362
|
});
|
|
68120
68363
|
if (!ensureNotCancelled(ok))
|
|
@@ -68129,7 +68372,7 @@ async function runTokenRevoke(args) {
|
|
|
68129
68372
|
}
|
|
68130
68373
|
async function runTokenClear() {
|
|
68131
68374
|
if (!readToken()) {
|
|
68132
|
-
console.log(
|
|
68375
|
+
console.log(import_picocolors45.default.dim("No local token stored."));
|
|
68133
68376
|
return;
|
|
68134
68377
|
}
|
|
68135
68378
|
clearToken();
|
|
@@ -68180,24 +68423,24 @@ async function runToken(sub, rest2, args) {
|
|
|
68180
68423
|
function printTokenHelp() {
|
|
68181
68424
|
const out = [];
|
|
68182
68425
|
out.push("");
|
|
68183
|
-
out.push(` ${
|
|
68426
|
+
out.push(` ${import_picocolors45.default.bold("brainbase token")} ${import_picocolors45.default.dim("<command>")}`);
|
|
68184
68427
|
out.push("");
|
|
68185
|
-
out.push(` ${
|
|
68186
|
-
out.push(` ${
|
|
68187
|
-
out.push(` ${
|
|
68188
|
-
out.push(` ${
|
|
68428
|
+
out.push(` ${import_picocolors45.default.cyan("create")} ${import_picocolors45.default.dim("issue a new long-lived CLI key (PAT)")}`);
|
|
68429
|
+
out.push(` ${import_picocolors45.default.cyan("list")} ${import_picocolors45.default.dim("show your active tokens")}`);
|
|
68430
|
+
out.push(` ${import_picocolors45.default.cyan("revoke")} ${import_picocolors45.default.dim("<id>")} ${import_picocolors45.default.dim("revoke a token by id")}`);
|
|
68431
|
+
out.push(` ${import_picocolors45.default.cyan("clear")} ${import_picocolors45.default.dim("forget the local token (does not revoke)")}`);
|
|
68189
68432
|
out.push("");
|
|
68190
|
-
out.push(` ${
|
|
68191
|
-
out.push(` ${
|
|
68192
|
-
out.push(` ${
|
|
68193
|
-
out.push(` ${
|
|
68433
|
+
out.push(` ${import_picocolors45.default.bold("create flags")}`);
|
|
68434
|
+
out.push(` ${import_picocolors45.default.cyan("--name, -n")} ${import_picocolors45.default.dim("<label>")} ${import_picocolors45.default.dim("token label (prompted if omitted)")}`);
|
|
68435
|
+
out.push(` ${import_picocolors45.default.cyan("--scopes")} ${import_picocolors45.default.dim("<list>")} ${import_picocolors45.default.dim("comma-separated; allowed: read, publish, admin")}`);
|
|
68436
|
+
out.push(` ${import_picocolors45.default.dim("default: read,publish")}`);
|
|
68194
68437
|
out.push("");
|
|
68195
68438
|
console.log(out.join(`
|
|
68196
68439
|
`));
|
|
68197
68440
|
}
|
|
68198
68441
|
|
|
68199
68442
|
// src/cli/mcp.ts
|
|
68200
|
-
var
|
|
68443
|
+
var import_picocolors46 = __toESM(require_picocolors(), 1);
|
|
68201
68444
|
|
|
68202
68445
|
// src/core/mcp-check/collect-servers.ts
|
|
68203
68446
|
import path86 from "node:path";
|
|
@@ -74660,8 +74903,8 @@ async function random2(size2) {
|
|
|
74660
74903
|
const evenDistCutoff = Math.pow(2, 8) - Math.pow(2, 8) % mask.length;
|
|
74661
74904
|
let result2 = "";
|
|
74662
74905
|
while (result2.length < size2) {
|
|
74663
|
-
const
|
|
74664
|
-
for (const randomByte of
|
|
74906
|
+
const randomBytes = await getRandomValues(size2 - result2.length);
|
|
74907
|
+
for (const randomByte of randomBytes) {
|
|
74665
74908
|
if (randomByte < evenDistCutoff) {
|
|
74666
74909
|
result2 += mask[randomByte % mask.length];
|
|
74667
74910
|
}
|
|
@@ -76545,17 +76788,17 @@ async function runMcpCheck(cwd2, options) {
|
|
|
76545
76788
|
function renderHuman(report) {
|
|
76546
76789
|
const lines = [];
|
|
76547
76790
|
if (report.check_status === "skipped") {
|
|
76548
|
-
lines.push(
|
|
76791
|
+
lines.push(import_picocolors46.default.dim("No MCP servers configured — nothing to check."));
|
|
76549
76792
|
return lines.join(`
|
|
76550
76793
|
`) + `
|
|
76551
76794
|
`;
|
|
76552
76795
|
}
|
|
76553
76796
|
for (const s3 of report.servers) {
|
|
76554
|
-
const mark = s3.status === "ok" ?
|
|
76555
|
-
const detail = s3.status === "ok" ?
|
|
76797
|
+
const mark = s3.status === "ok" ? import_picocolors46.default.green("✓") : s3.status === "auth_failed" ? import_picocolors46.default.red("✗") : import_picocolors46.default.yellow("⚠");
|
|
76798
|
+
const detail = s3.status === "ok" ? import_picocolors46.default.dim(`${s3.tool_count} tool${s3.tool_count === 1 ? "" : "s"}`) : import_picocolors46.default.dim(s3.status + (s3.error ? ` — ${s3.error}` : ""));
|
|
76556
76799
|
lines.push(` ${mark} ${s3.name} ${detail}`);
|
|
76557
76800
|
}
|
|
76558
|
-
const summary = report.check_status === "ok" ?
|
|
76801
|
+
const summary = report.check_status === "ok" ? import_picocolors46.default.green("All MCP servers connected.") : import_picocolors46.default.yellow("Some MCP servers are unhealthy.");
|
|
76559
76802
|
lines.push("", summary);
|
|
76560
76803
|
return lines.join(`
|
|
76561
76804
|
`) + `
|
|
@@ -76578,7 +76821,7 @@ async function runMcp(cwd2, sub, _argv, options) {
|
|
|
76578
76821
|
}
|
|
76579
76822
|
|
|
76580
76823
|
// src/cli/task.ts
|
|
76581
|
-
var
|
|
76824
|
+
var import_picocolors47 = __toESM(require_picocolors(), 1);
|
|
76582
76825
|
|
|
76583
76826
|
// src/cli/task-create.ts
|
|
76584
76827
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
@@ -76742,7 +76985,7 @@ async function runTask(cwd2, sub, args) {
|
|
|
76742
76985
|
case "create": {
|
|
76743
76986
|
const parsed = parseCreateArgs(args);
|
|
76744
76987
|
if (parsed.help) {
|
|
76745
|
-
|
|
76988
|
+
printHelp4();
|
|
76746
76989
|
return;
|
|
76747
76990
|
}
|
|
76748
76991
|
await runTaskCreate(cwd2, parsed.options);
|
|
@@ -76752,30 +76995,30 @@ async function runTask(cwd2, sub, args) {
|
|
|
76752
76995
|
case "help":
|
|
76753
76996
|
case "-h":
|
|
76754
76997
|
case "--help":
|
|
76755
|
-
|
|
76998
|
+
printHelp4();
|
|
76756
76999
|
return;
|
|
76757
77000
|
default:
|
|
76758
77001
|
console.error(`Unknown task subcommand: ${sub}
|
|
76759
77002
|
`);
|
|
76760
|
-
|
|
77003
|
+
printHelp4();
|
|
76761
77004
|
process.exit(1);
|
|
76762
77005
|
}
|
|
76763
77006
|
}
|
|
76764
|
-
function
|
|
77007
|
+
function printHelp4() {
|
|
76765
77008
|
const out = [];
|
|
76766
77009
|
out.push("");
|
|
76767
|
-
out.push(` ${
|
|
77010
|
+
out.push(` ${import_picocolors47.default.bold("brainbase task")} ${import_picocolors47.default.dim("<sub> [options]")}`);
|
|
76768
77011
|
out.push("");
|
|
76769
|
-
out.push(` ${
|
|
77012
|
+
out.push(` ${import_picocolors47.default.cyan("create")} ${import_picocolors47.default.dim("--message <text>")} ${import_picocolors47.default.dim("create a task and start its first run")}`);
|
|
76770
77013
|
out.push("");
|
|
76771
|
-
out.push(` ${
|
|
76772
|
-
out.push(` ${
|
|
76773
|
-
out.push(` ${
|
|
76774
|
-
out.push(` ${
|
|
76775
|
-
out.push(` ${
|
|
76776
|
-
out.push(` ${
|
|
77014
|
+
out.push(` ${import_picocolors47.default.bold("create flags")}`);
|
|
77015
|
+
out.push(` ${import_picocolors47.default.dim("--message <text>")} required first user message`);
|
|
77016
|
+
out.push(` ${import_picocolors47.default.dim("--agent <id>")} override the claimed agent in brainbase.agent.yaml`);
|
|
77017
|
+
out.push(` ${import_picocolors47.default.dim("--title <text>")} optional task title`);
|
|
77018
|
+
out.push(` ${import_picocolors47.default.dim("--model <id>")} optional model override`);
|
|
77019
|
+
out.push(` ${import_picocolors47.default.dim("--json")} print task_id, agent_id, and status as JSON`);
|
|
76777
77020
|
out.push("");
|
|
76778
|
-
out.push(` ${
|
|
77021
|
+
out.push(` ${import_picocolors47.default.dim("Flag-like values:")} use ${import_picocolors47.default.cyan("--flag=value")} or ${import_picocolors47.default.cyan("--flag -- <value>")}`);
|
|
76779
77022
|
out.push("");
|
|
76780
77023
|
console.log(out.join(`
|
|
76781
77024
|
`));
|
|
@@ -76801,108 +77044,115 @@ var STORED_PAT_COMMANDS = new Set([
|
|
|
76801
77044
|
function help() {
|
|
76802
77045
|
const out = [];
|
|
76803
77046
|
out.push("");
|
|
76804
|
-
out.push(` ${brandTint("◆")} ${
|
|
76805
|
-
out.push(` ${
|
|
77047
|
+
out.push(` ${brandTint("◆")} ${import_picocolors48.default.bold("brainbase")} ${import_picocolors48.default.dim(`v${VERSION}`)}`);
|
|
77048
|
+
out.push(` ${import_picocolors48.default.dim("connect your local agent to the brainbase platform")}`);
|
|
76806
77049
|
out.push("");
|
|
76807
77050
|
out.push(divider("USAGE"));
|
|
76808
77051
|
out.push("");
|
|
76809
|
-
out.push(` ${
|
|
77052
|
+
out.push(` ${import_picocolors48.default.bold("brainbase")} ${import_picocolors48.default.dim("<command> [options]")}`);
|
|
76810
77053
|
out.push("");
|
|
76811
77054
|
out.push(divider("AUTH"));
|
|
76812
77055
|
out.push("");
|
|
76813
|
-
out.push(` ${
|
|
76814
|
-
out.push(` ${
|
|
76815
|
-
out.push(` ${
|
|
77056
|
+
out.push(` ${import_picocolors48.default.cyan("login")} ${import_picocolors48.default.dim(" open the web app and connect this device")}`);
|
|
77057
|
+
out.push(` ${import_picocolors48.default.cyan("logout")} ${import_picocolors48.default.dim(" clear the local session")}`);
|
|
77058
|
+
out.push(` ${import_picocolors48.default.cyan("whoami")} ${import_picocolors48.default.dim(" show the current user")}`);
|
|
77059
|
+
out.push("");
|
|
77060
|
+
out.push(divider("DISCOVERY"));
|
|
77061
|
+
out.push("");
|
|
77062
|
+
out.push(` ${import_picocolors48.default.cyan("team list")} ${import_picocolors48.default.dim("show the teams you can create agents in")}`);
|
|
77063
|
+
out.push(` ${import_picocolors48.default.cyan("agent list")} ${import_picocolors48.default.dim("show a team's agents and their ids")}`);
|
|
76816
77064
|
out.push("");
|
|
76817
77065
|
out.push(divider("LINKED AGENT"));
|
|
76818
77066
|
out.push("");
|
|
76819
|
-
out.push(` ${
|
|
76820
|
-
out.push(` ${
|
|
76821
|
-
out.push(` ${
|
|
76822
|
-
out.push(` ${
|
|
76823
|
-
out.push(` ${
|
|
76824
|
-
out.push(` ${
|
|
76825
|
-
out.push(` ${
|
|
76826
|
-
out.push(` ${
|
|
76827
|
-
out.push(` ${
|
|
76828
|
-
out.push(` ${
|
|
77067
|
+
out.push(` ${import_picocolors48.default.cyan("agent create")} ${import_picocolors48.default.dim("claim an unclaimed brainbase.agent.yaml and create the cloud agent")}`);
|
|
77068
|
+
out.push(` ${import_picocolors48.default.cyan("agent pull")} ${import_picocolors48.default.dim("[<id>]")} ${import_picocolors48.default.dim("bring cloud changes into this folder (--force to override; --run-entrypoint to also execute the agent entrypoint)")}`);
|
|
77069
|
+
out.push(` ${import_picocolors48.default.cyan("agent push")} ${import_picocolors48.default.dim("send local changes to the cloud (--force to overwrite cloud-side conflicts with local)")}`);
|
|
77070
|
+
out.push(` ${import_picocolors48.default.cyan("agent unpack")} ${import_picocolors48.default.dim("install the claimed agent into a harness layout")}`);
|
|
77071
|
+
out.push(` ${import_picocolors48.default.cyan("link")} ${import_picocolors48.default.dim("attach this folder to an existing agent")}`);
|
|
77072
|
+
out.push(` ${import_picocolors48.default.cyan("agent status")} ${import_picocolors48.default.dim("show what would pull and what would push")}`);
|
|
77073
|
+
out.push(` ${import_picocolors48.default.cyan("agent env")} ${import_picocolors48.default.dim("print export lines for `eval $(brainbase agent env)`")}`);
|
|
77074
|
+
out.push(` ${import_picocolors48.default.cyan("run")} ${import_picocolors48.default.dim("<cmd> [args...]")} ${import_picocolors48.default.dim("run <cmd> with secrets.env loaded into env")}`);
|
|
77075
|
+
out.push(` ${import_picocolors48.default.cyan("status")} ${import_picocolors48.default.dim("show what this folder is linked to")}`);
|
|
77076
|
+
out.push(` ${import_picocolors48.default.cyan("unlink")} ${import_picocolors48.default.dim("disconnect this folder")}`);
|
|
76829
77077
|
out.push("");
|
|
76830
77078
|
out.push(divider("TASKS"));
|
|
76831
77079
|
out.push("");
|
|
76832
|
-
out.push(` ${
|
|
77080
|
+
out.push(` ${import_picocolors48.default.cyan("task create")} ${import_picocolors48.default.dim("--message <text>")} ${import_picocolors48.default.dim("create a managed task and start its first run")}`);
|
|
76833
77081
|
out.push("");
|
|
76834
77082
|
out.push(divider("ORCHESTRATIONS"));
|
|
76835
77083
|
out.push("");
|
|
76836
|
-
out.push(` ${
|
|
76837
|
-
out.push(` ${
|
|
76838
|
-
out.push(` ${
|
|
76839
|
-
out.push(` ${
|
|
76840
|
-
out.push(` ${
|
|
77084
|
+
out.push(` ${import_picocolors48.default.cyan("orchestration create")} ${import_picocolors48.default.dim("claim a local orchestration manifest and create it in the cloud")}`);
|
|
77085
|
+
out.push(` ${import_picocolors48.default.cyan("orchestration list")} ${import_picocolors48.default.dim("list orchestrations under a team")}`);
|
|
77086
|
+
out.push(` ${import_picocolors48.default.cyan("orchestration pull")} ${import_picocolors48.default.dim("<id>")} ${import_picocolors48.default.dim("recursively fetch an orchestration + every member agent")}`);
|
|
77087
|
+
out.push(` ${import_picocolors48.default.cyan("orchestration push")} ${import_picocolors48.default.dim("recursively push each member, then update the graph")}`);
|
|
77088
|
+
out.push(` ${import_picocolors48.default.cyan("orchestration status")} ${import_picocolors48.default.dim("show what would push and what would pull")}`);
|
|
76841
77089
|
out.push("");
|
|
76842
77090
|
out.push(divider("TEMPLATES"));
|
|
76843
77091
|
out.push("");
|
|
76844
|
-
out.push(` ${
|
|
76845
|
-
out.push(` ${
|
|
76846
|
-
out.push(` ${
|
|
76847
|
-
out.push(` ${
|
|
76848
|
-
out.push(` ${
|
|
76849
|
-
out.push(` ${
|
|
76850
|
-
out.push(` ${
|
|
77092
|
+
out.push(` ${import_picocolors48.default.cyan("template pack")} ${import_picocolors48.default.dim("bundle the current agent into a template")}`);
|
|
77093
|
+
out.push(` ${import_picocolors48.default.cyan("template publish")} ${import_picocolors48.default.dim("upload a template to the registry")}`);
|
|
77094
|
+
out.push(` ${import_picocolors48.default.cyan("template search")} ${import_picocolors48.default.dim("[query]")} ${import_picocolors48.default.dim("search the registry")}`);
|
|
77095
|
+
out.push(` ${import_picocolors48.default.cyan("template info")} ${import_picocolors48.default.dim("<creator/slug>")} ${import_picocolors48.default.dim("show registry details for a template")}`);
|
|
77096
|
+
out.push(` ${import_picocolors48.default.cyan("template onboard")} ${import_picocolors48.default.dim("<creator/slug>")} ${import_picocolors48.default.dim("install (or refresh) a template")}`);
|
|
77097
|
+
out.push(` ${import_picocolors48.default.cyan("template list")} ${import_picocolors48.default.dim("show installed templates")}`);
|
|
77098
|
+
out.push(` ${import_picocolors48.default.cyan("template remove")} ${import_picocolors48.default.dim("<creator/slug>")} ${import_picocolors48.default.dim("uninstall a template")}`);
|
|
76851
77099
|
out.push("");
|
|
76852
77100
|
out.push(divider("SKILLS"));
|
|
76853
77101
|
out.push("");
|
|
76854
|
-
out.push(` ${
|
|
76855
|
-
out.push(` ${
|
|
76856
|
-
out.push(` ${
|
|
76857
|
-
out.push(` ${
|
|
76858
|
-
out.push(` ${
|
|
76859
|
-
out.push(` ${
|
|
76860
|
-
out.push(` ${
|
|
77102
|
+
out.push(` ${import_picocolors48.default.cyan("skill add")} ${import_picocolors48.default.dim("<source>")} ${import_picocolors48.default.dim("install a skill (github / git / brainbase)")}`);
|
|
77103
|
+
out.push(` ${import_picocolors48.default.cyan("skill list")} ${import_picocolors48.default.dim("show locally installed skills + their source")}`);
|
|
77104
|
+
out.push(` ${import_picocolors48.default.cyan("skill update")} ${import_picocolors48.default.dim("<slug>")} ${import_picocolors48.default.dim("re-fetch a skill from its recorded source")}`);
|
|
77105
|
+
out.push(` ${import_picocolors48.default.cyan("skill remove")} ${import_picocolors48.default.dim("<slug>")} ${import_picocolors48.default.dim("uninstall a skill")}`);
|
|
77106
|
+
out.push(` ${import_picocolors48.default.cyan("skill search")} ${import_picocolors48.default.dim("[query]")} ${import_picocolors48.default.dim("search the brainbase skill registry")}`);
|
|
77107
|
+
out.push(` ${import_picocolors48.default.cyan("skill info")} ${import_picocolors48.default.dim("<creator/slug>")} ${import_picocolors48.default.dim("show registry details for a skill")}`);
|
|
77108
|
+
out.push(` ${import_picocolors48.default.cyan("skill publish")} ${import_picocolors48.default.dim("[dir]")} ${import_picocolors48.default.dim("publish a SKILL.md folder (defaults to .)")}`);
|
|
76861
77109
|
out.push("");
|
|
76862
77110
|
out.push(divider("CLI TOKENS"));
|
|
76863
77111
|
out.push("");
|
|
76864
|
-
out.push(` ${
|
|
76865
|
-
out.push(` ${
|
|
76866
|
-
out.push(` ${
|
|
77112
|
+
out.push(` ${import_picocolors48.default.cyan("token create")} ${import_picocolors48.default.dim("issue a long-lived CLI key for CI / scripts")}`);
|
|
77113
|
+
out.push(` ${import_picocolors48.default.cyan("token list")} ${import_picocolors48.default.dim("show your active tokens")}`);
|
|
77114
|
+
out.push(` ${import_picocolors48.default.cyan("token revoke")} ${import_picocolors48.default.dim("<id>")} ${import_picocolors48.default.dim("revoke a token")}`);
|
|
76867
77115
|
out.push("");
|
|
76868
77116
|
out.push(divider("MCP"));
|
|
76869
77117
|
out.push("");
|
|
76870
|
-
out.push(` ${
|
|
77118
|
+
out.push(` ${import_picocolors48.default.cyan("mcp check")} ${import_picocolors48.default.dim("[--json]")} ${import_picocolors48.default.dim("verify MCP server connectivity through the brainbase proxy (runs at sandbox bootstrap)")}`);
|
|
76871
77119
|
out.push("");
|
|
76872
77120
|
out.push(divider("FLAGS"));
|
|
76873
77121
|
out.push("");
|
|
76874
|
-
out.push(` ${
|
|
76875
|
-
out.push(` ${
|
|
76876
|
-
out.push(` ${
|
|
76877
|
-
out.push(` ${
|
|
76878
|
-
out.push(` ${
|
|
76879
|
-
out.push(` ${
|
|
76880
|
-
out.push(` ${
|
|
76881
|
-
out.push(` ${
|
|
76882
|
-
out.push(` ${
|
|
76883
|
-
out.push(` ${
|
|
76884
|
-
out.push(` ${
|
|
76885
|
-
out.push(` ${
|
|
76886
|
-
out.push(` ${
|
|
77122
|
+
out.push(` ${import_picocolors48.default.dim("--harness <id>")} force harness for onboard / sync (e.g. claude-code)`);
|
|
77123
|
+
out.push(` ${import_picocolors48.default.dim("--scope <s>")} force scope: global | project`);
|
|
77124
|
+
out.push(` ${import_picocolors48.default.dim("--yes, -y")} skip confirmations / auto-overwrite`);
|
|
77125
|
+
out.push(` ${import_picocolors48.default.dim("--agent <id>")} for link/task create: use this agent id explicitly`);
|
|
77126
|
+
out.push(` ${import_picocolors48.default.dim("--message <text>")} for task create: required first user message`);
|
|
77127
|
+
out.push(` ${import_picocolors48.default.dim("--title <text>")} for task create: optional task title`);
|
|
77128
|
+
out.push(` ${import_picocolors48.default.dim("--model <id>")} for task create: optional model override`);
|
|
77129
|
+
out.push(` ${import_picocolors48.default.dim("--org <id-or-slug>")} pick the organization (team/agent list, agent create, orchestration create/list)`);
|
|
77130
|
+
out.push(` ${import_picocolors48.default.dim("--team <id>")} pick the team, same commands (works without --org)`);
|
|
77131
|
+
out.push(` ${import_picocolors48.default.dim("--json")} for team/agent list, task create, mcp check: machine-readable output`);
|
|
77132
|
+
out.push(` ${import_picocolors48.default.dim("--no-tracking")} for link: skip routing LLM traffic through brainbase`);
|
|
77133
|
+
out.push(` ${import_picocolors48.default.dim("--track")} for agent create: enable tracking non-interactively (off without a TTY)`);
|
|
77134
|
+
out.push(` ${import_picocolors48.default.dim("--shell <sh|fish>")} for agent env: pick output format (auto-detected from $SHELL)`);
|
|
77135
|
+
out.push(` ${import_picocolors48.default.dim("--all")} for template list: include installs from other folders`);
|
|
77136
|
+
out.push(` ${import_picocolors48.default.dim("--web <url>")} for login: web app URL (default https://app.brainbaselabs.com)`);
|
|
76887
77137
|
out.push("");
|
|
76888
77138
|
out.push(divider("ENV"));
|
|
76889
77139
|
out.push("");
|
|
76890
|
-
out.push(` ${
|
|
76891
|
-
out.push(` ${
|
|
76892
|
-
out.push(` ${
|
|
76893
|
-
out.push(` ${
|
|
76894
|
-
out.push(` ${
|
|
76895
|
-
out.push(` ${
|
|
76896
|
-
out.push(` ${
|
|
76897
|
-
out.push(` ${
|
|
76898
|
-
out.push(` ${
|
|
76899
|
-
out.push(` ${
|
|
77140
|
+
out.push(` ${import_picocolors48.default.dim("BRAINBASE_HOME")} override the local config dir (default ~/.brainbase)`);
|
|
77141
|
+
out.push(` ${import_picocolors48.default.dim("BRAINBASE_WEB_URL")} override the web app URL used by login`);
|
|
77142
|
+
out.push(` ${import_picocolors48.default.dim("BRAINBASE_CONTROL_PLANE_URL")} override the MAS host (/v2/cli; task create uses /v2/tasks)`);
|
|
77143
|
+
out.push(` ${import_picocolors48.default.dim("BRAINBASE_API_URL")} legacy KLS host override (uses /api/cli; proxy/registry fallback)`);
|
|
77144
|
+
out.push(` ${import_picocolors48.default.dim("BRAINBASE_PROXY_URL")} override the model-proxy URL used by harness traffic (default https://api.v1.brainbaselabs.com)`);
|
|
77145
|
+
out.push(` ${import_picocolors48.default.dim("BRAINBASE_REGISTRY_URL")} override the registry API URL (default https://api.v1.brainbaselabs.com)`);
|
|
77146
|
+
out.push(` ${import_picocolors48.default.dim("BRAINBASE_TOKEN")} long-lived CLI PAT (overrides token.json)`);
|
|
77147
|
+
out.push(` ${import_picocolors48.default.dim("BRAINBASE_SKIP_AUTH")} bypass the auth gate for development`);
|
|
77148
|
+
out.push(` ${import_picocolors48.default.dim("BRAINBASE_NON_INTERACTIVE")} force non-interactive mode — skip/auto-default prompts (CI & agents)`);
|
|
77149
|
+
out.push(` ${import_picocolors48.default.dim("BRAINBASE_RUN_ENTRYPOINT")} =1 → agent pull executes the agent entrypoint (sandbox boots; or pass --run-entrypoint)`);
|
|
76900
77150
|
out.push("");
|
|
76901
77151
|
out.push(divider("HARNESSES"));
|
|
76902
77152
|
out.push("");
|
|
76903
|
-
out.push(` ${
|
|
76904
|
-
out.push(` ${
|
|
76905
|
-
out.push(` ${
|
|
77153
|
+
out.push(` ${import_picocolors48.default.dim("•")} ${import_picocolors48.default.bold("claude-code")} ${import_picocolors48.default.dim("skills, mcps, agents, commands, playbooks, instructions, files")}`);
|
|
77154
|
+
out.push(` ${import_picocolors48.default.dim("•")} ${import_picocolors48.default.bold("codex")} ${import_picocolors48.default.dim("skills, mcps, commands, playbooks, instructions, files")}`);
|
|
77155
|
+
out.push(` ${import_picocolors48.default.dim("•")} ${import_picocolors48.default.bold("kafka")} ${import_picocolors48.default.dim("skills, mcps, agents, commands, playbooks, instructions, files")}`);
|
|
76906
77156
|
out.push("");
|
|
76907
77157
|
console.log(out.join(`
|
|
76908
77158
|
`));
|
|
@@ -76966,13 +77216,13 @@ async function requireAuth(cmd) {
|
|
|
76966
77216
|
if (STORED_PAT_COMMANDS.has(cmd) && readToken())
|
|
76967
77217
|
return;
|
|
76968
77218
|
console.error("");
|
|
76969
|
-
console.error(` ${brandTint("◆")} ${
|
|
77219
|
+
console.error(` ${brandTint("◆")} ${import_picocolors48.default.bold("brainbase")}`);
|
|
76970
77220
|
console.error("");
|
|
76971
|
-
console.error(` ${
|
|
77221
|
+
console.error(` ${import_picocolors48.default.red("✗")} You need to sign in to use ${import_picocolors48.default.bold("brainbase " + cmd)}.`);
|
|
76972
77222
|
if (status.reason)
|
|
76973
|
-
console.error(` ${
|
|
77223
|
+
console.error(` ${import_picocolors48.default.dim(status.reason)}`);
|
|
76974
77224
|
console.error("");
|
|
76975
|
-
console.error(` Run ${
|
|
77225
|
+
console.error(` Run ${import_picocolors48.default.cyan("brainbase login")} to connect this device.`);
|
|
76976
77226
|
console.error("");
|
|
76977
77227
|
process14.exit(1);
|
|
76978
77228
|
}
|
|
@@ -77097,6 +77347,7 @@ async function main() {
|
|
|
77097
77347
|
const sub = argv.shift();
|
|
77098
77348
|
await runAgent(cwd2, sub, argv, {
|
|
77099
77349
|
yes,
|
|
77350
|
+
json: jsonFlag,
|
|
77100
77351
|
scope: scopeFlag,
|
|
77101
77352
|
shell: shellFlag,
|
|
77102
77353
|
harness,
|
|
@@ -77112,6 +77363,12 @@ async function main() {
|
|
|
77112
77363
|
});
|
|
77113
77364
|
break;
|
|
77114
77365
|
}
|
|
77366
|
+
case "team":
|
|
77367
|
+
case "teams": {
|
|
77368
|
+
const sub = argv.shift();
|
|
77369
|
+
await runTeam(sub, argv, { orgId: orgIdFlag, json: jsonFlag });
|
|
77370
|
+
break;
|
|
77371
|
+
}
|
|
77115
77372
|
case "task": {
|
|
77116
77373
|
const sub = argv.shift();
|
|
77117
77374
|
await runTask(cwd2, sub, argv);
|
|
@@ -77156,8 +77413,11 @@ async function main() {
|
|
|
77156
77413
|
process14.exit(1);
|
|
77157
77414
|
}
|
|
77158
77415
|
} catch (err) {
|
|
77159
|
-
console.error(
|
|
77416
|
+
console.error(import_picocolors48.default.red(`
|
|
77160
77417
|
${err.message}`));
|
|
77418
|
+
if (err instanceof ApiError && err.status === 401) {
|
|
77419
|
+
console.error(` Run ${import_picocolors48.default.cyan("brainbase login")} to connect this device.`);
|
|
77420
|
+
}
|
|
77161
77421
|
if (process14.env.BRAINBASE_DEBUG)
|
|
77162
77422
|
console.error(err.stack);
|
|
77163
77423
|
process14.exit(1);
|