@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.
Files changed (3) hide show
  1. package/README.md +2 -0
  2. package/dist/index.js +856 -596
  3. 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 http2 = {
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: http2.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: http2,
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 import_picocolors44 = __toESM(require_picocolors(), 1);
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.17.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 platform2 = process.platform;
61234
- const cmd = platform2 === "darwin" ? "open" : platform2 === "win32" ? "cmd" : "xdg-open";
61235
- const args = platform2 === "win32" ? ["/c", "start", '""', url] : [url];
61236
- spawn(cmd, args, { stdio: "ignore", detached: true }).unref();
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
- async function readBody(req) {
61256
- return new Promise((resolve, reject2) => {
61257
- const chunks = [];
61258
- req.on("data", (c2) => chunks.push(c2));
61259
- req.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")));
61260
- req.on("error", reject2);
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
- spinner.start("Waiting for browser sign-in (Ctrl-C to cancel)");
61342
- const timeout = setTimeout(() => {
61343
- spinner.stop("Timed out.");
61344
- server.close();
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 session = await result2;
61349
- clearTimeout(timeout);
61350
- server.close();
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
- if (session) {
61354
- await showWelcomeCard({
61355
- email: session.email ?? session.user_id,
61356
- controlPlaneUrl: controlPlaneBaseUrl(session),
61357
- expiresAt: session.expires_at,
61358
- hint: "brainbase template pack — bundle your first agent"
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
- clearTimeout(timeout);
61363
- server.close();
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 import_picocolors32 = __toESM(require_picocolors(), 1);
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 import_picocolors31 = __toESM(require_picocolors(), 1);
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/cli/agent-create.ts
65366
- async function runAgentCreate(cwd2, args) {
65367
- banner("agent create claim a brainbase.agent.yaml and link this folder");
65368
- let manifest = await loadOrScaffoldManifest(cwd2, args);
65369
- if (!manifest)
65370
- return;
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
- const orgsSpinner = de();
65377
- orgsSpinner.start("Loading your organizations…");
65378
- let orgs;
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
- orgs = await api.listOrgs();
65552
+ const value = await fetch2();
65553
+ sp.stop(done(value));
65554
+ return value;
65381
65555
  } catch (err) {
65382
- orgsSpinner.stop("Failed.");
65383
- handleApiError4(err);
65384
- return;
65556
+ sp.stop("Failed.");
65557
+ throw err;
65385
65558
  }
65386
- orgsSpinner.stop(`Found ${orgs.length} organization${orgs.length === 1 ? "" : "s"}.`);
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
- f2.warn("You are not in any organizations yet.");
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
- let org;
65393
- if (args.orgId) {
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
- f2.error(`Org ${args.orgId} not found or you're not a member.`);
65397
- return;
65581
+ throw new OrgTeamError(`Org ${orgRef} not found, or you're not a member of it.`);
65398
65582
  }
65399
- org = found;
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
- const teamsSpinner = de();
65412
- teamsSpinner.start(`Loading teams in ${org.name}…`);
65413
- let teams;
65414
- try {
65415
- teams = await api.listTeams(org.id);
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
- teamsSpinner.stop(`Found ${teams.length} team${teams.length === 1 ? "" : "s"}.`);
65422
- let team;
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
- f2.error(`Team ${args.teamId} not found in this org.`);
65427
- return;
65623
+ throw new OrgTeamError(`Team ${args.teamId} not found in ${org.name}.`);
65428
65624
  }
65429
- team = found;
65430
- } else if (!isInteractive()) {
65431
- if (teams.length === 1) {
65432
- team = teams[0];
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
- } else if (teams.length === 0) {
65435
- throw new NonInteractiveError(`No teams in ${org.name} yet — create one in the web app, then re-run.`);
65436
- } else {
65437
- throw new NonInteractiveError(`Multiple teams in ${org.name}. Pass --team <id> to choose non-interactively.`);
65438
- }
65439
- } else {
65440
- const teamOptions = [
65441
- ...teams.map((t) => ({ value: t.id, label: t.name, hint: t.role })),
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
- const picked = ensureNotCancelled(teamChoice);
65449
- if (picked === "__new__") {
65450
- const name = await te({
65451
- message: "New team name",
65452
- validate: (v3) => !v3?.trim() ? "Required" : undefined
65453
- });
65454
- const teamName = ensureNotCancelled(name);
65455
- const createSpinner2 = de();
65456
- createSpinner2.start("Creating team…");
65457
- try {
65458
- team = await api.createTeam(org.id, teamName.trim());
65459
- createSpinner2.stop(`Created team ${import_picocolors31.default.bold(team.name)}.`);
65460
- } catch (err) {
65461
- createSpinner2.stop("Failed.");
65462
- handleApiError4(err);
65463
- return;
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
- team = teams.find((t) => t.id === picked);
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
- `${import_picocolors31.default.dim("org")} ${import_picocolors31.default.bold(org.name)}`,
65492
- `${import_picocolors31.default.dim("team")} ${import_picocolors31.default.bold(team.name)}`,
65493
- `${import_picocolors31.default.dim("harness")} ${import_picocolors31.default.bold(harness)}`,
65494
- `${import_picocolors31.default.dim("agent")} ${import_picocolors31.default.bold(agentName)}`,
65495
- ...tagline ? [`${import_picocolors31.default.dim("tagline")} ${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 ${import_picocolors31.default.bold(manifest.entrypoint.file)} not found.`);
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 ${import_picocolors31.default.bold(agent.name)}.`);
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 ${import_picocolors31.default.bold(agent.id)} was created, but this control plane did not apply ${fields.join(" / ")}.`);
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 ${import_picocolors31.default.cyan("brainbase agent pull --force")} to accept ${agent.machine_kind}, or delete this agent and recreate it after upgrading the control plane.`);
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 ${import_picocolors31.default.cyan("brainbase agent push")} to apply default_model.`);
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 ${import_picocolors31.default.cyan("--track")} to route ${harness} LLM traffic through brainbase.`);
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? ${import_picocolors31.default.dim("(routes LLM calls through brainbase so they appear under this agent)")}`,
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 ${import_picocolors31.default.cyan("brainbase agent push")}.`);
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 ${import_picocolors31.default.cyan("brainbase agent push")} to retry.`);
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 ${import_picocolors31.default.cyan("brainbase agent push")} to retry.`);
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 ${import_picocolors31.default.bold(agent.name)} and linked this folder.`);
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 ${import_picocolors31.default.cyan("codex")} once in this folder and approve trust ${import_picocolors31.default.dim("— Codex only loads project-scope config in trusted projects.")}`));
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 ${import_picocolors31.default.dim("— install harness files (skills/mcps) under .claude/, .codex/, …")}`));
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 ${import_picocolors31.default.bold(AGENT_MANIFEST_FILE)} here.`);
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 ${import_picocolors31.default.bold(AGENT_MANIFEST_FILE)} and continue?`,
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 ${import_picocolors31.default.bold(AGENT_MANIFEST_FILE)}.`);
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: ${import_picocolors31.default.bold(detected[0].adapter.displayName)}.`);
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(` ${import_picocolors32.default.bold("brainbase agent")} ${import_picocolors32.default.dim("<sub> [options]")}`);
66141
+ out.push(` ${import_picocolors34.default.bold("brainbase agent")} ${import_picocolors34.default.dim("<sub> [options]")}`);
65842
66142
  out.push("");
65843
- out.push(` ${import_picocolors32.default.cyan("create")} ${import_picocolors32.default.dim("claim an unclaimed brainbase.agent.yaml and create the cloud agent")}`);
65844
- out.push(` ${import_picocolors32.default.cyan("pull")} ${import_picocolors32.default.dim("[<id>]")} ${import_picocolors32.default.dim("apply cloud changes into this folder pass <id> to switch (--force to override); --run-entrypoint to also execute the agent entrypoint")}`);
65845
- out.push(` ${import_picocolors32.default.cyan("push")} ${import_picocolors32.default.dim("send local changes to the cloudinstructions, playbooks, skills, MCPs, entrypoint (--force to overwrite cloud-side conflicts with local)")}`);
65846
- out.push(` ${import_picocolors32.default.cyan("unpack")} ${import_picocolors32.default.dim("install the claimed agent into a harness layout (--harness to override)")}`);
65847
- out.push(` ${import_picocolors32.default.cyan("status")} ${import_picocolors32.default.dim("show what would push and what would pull")}`);
65848
- out.push(` ${import_picocolors32.default.cyan("env")} ${import_picocolors32.default.dim('print export statements use with `eval "$(brainbase agent env)"`')}`);
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 folderpass <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 import_picocolors39 = __toESM(require_picocolors(), 1);
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 import_picocolors33 = __toESM(require_picocolors(), 1);
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 ${import_picocolors33.default.cyan("brainbase orchestration pull <id>")} with an orchestration id,
66364
- or ${import_picocolors33.default.cyan("brainbase orchestration list")} to find one.`);
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(` ${import_picocolors33.default.bold(cloud.name)} ${import_picocolors33.default.dim(`(${cloud.id})`)}`);
66768
+ planLines.push(` ${import_picocolors37.default.bold(cloud.name)} ${import_picocolors37.default.dim(`(${cloud.id})`)}`);
66384
66769
  if (cloud.description)
66385
- planLines.push(` ${import_picocolors33.default.dim(cloud.description)}`);
66770
+ planLines.push(` ${import_picocolors37.default.dim(cloud.description)}`);
66386
66771
  planLines.push("");
66387
- planLines.push(` ${import_picocolors33.default.dim("members:")}`);
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 ? import_picocolors33.default.red(" (manifest unavailable — skipped)") : "";
66391
- planLines.push(` ${import_picocolors33.default.cyan("•")} ${import_picocolors33.default.bold(slugFor(m3.agent_id))} ${import_picocolors33.default.dim(`(${m3.name})`)}${tail2}`);
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(` ${import_picocolors33.default.dim("edges:")}`);
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 ? ` ${import_picocolors33.default.dim("— " + e2.description)}` : "";
66400
- planLines.push(` ${import_picocolors33.default.cyan(from)} ${import_picocolors33.default.dim("→")} ${import_picocolors33.default.cyan(to2)}${desc}`);
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 ${import_picocolors33.default.bold(cwd2)}?`,
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 ${import_picocolors33.default.bold(slug)} ${import_picocolors33.default.dim(`(${m3.manifest.components.length} components)`)}.`);
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)}/ ${import_picocolors33.default.dim(`(${installedMembers.length}/${cloud.members.length} members)`)}.`);
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 import_picocolors34 = __toESM(require_picocolors(), 1);
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 ${import_picocolors34.default.cyan("brainbase orchestration pull <id>")} first.`);
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 ${import_picocolors34.default.bold(ORCH_MANIFEST_FILE)} here.`);
66606
- f2.info(`Run ${import_picocolors34.default.cyan("brainbase orchestration pull")} to materialise the manifest before pushing.`);
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 ${import_picocolors34.default.cyan("brainbase orchestration pull")} to materialise the missing folders.`);
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(` ${import_picocolors34.default.bold(link2.name)} ${import_picocolors34.default.dim(`(${link2.orchestration_id})`)}`);
66643
- plan.push(` ${import_picocolors34.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"}`)}`);
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(` ${import_picocolors34.default.dim("per-member agent push:")}`);
67031
+ plan.push(` ${import_picocolors38.default.dim("per-member agent push:")}`);
66647
67032
  for (const m3 of manifest.members) {
66648
- plan.push(` ${import_picocolors34.default.cyan("•")} ${import_picocolors34.default.bold(m3.slug)}`);
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(`${import_picocolors34.default.dim("───")} ${import_picocolors34.default.bold(m3.slug)} ${import_picocolors34.default.dim("───")}`);
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 ${import_picocolors34.default.cyan("brainbase orchestration pull")} to reconcile, then push again.`);
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 import_picocolors35 = __toESM(require_picocolors(), 1);
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 ${import_picocolors35.default.cyan("brainbase orchestration pull <id>")} first.`);
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(` ${import_picocolors35.default.bold(link2.name)} ${import_picocolors35.default.dim(`(${link2.orchestration_id})`)}`);
66766
- lines.push(` ${import_picocolors35.default.dim("revision")} cloud ${cloud.revision}${lock ? ` · lock ${lock.revision}` : " · never pulled"}`);
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(` ${import_picocolors35.default.bold("members")}`);
67165
+ lines.push(` ${import_picocolors39.default.bold("members")}`);
66781
67166
  for (const slug of membersAdded) {
66782
- lines.push(` ${import_picocolors35.default.yellow("→ push")} added in yaml: ${import_picocolors35.default.bold(slug)}`);
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(` ${import_picocolors35.default.cyan("← pull")} added on cloud: ${import_picocolors35.default.bold(slug)}`);
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(` ${import_picocolors35.default.bold("edges")}`);
67185
+ lines.push(` ${import_picocolors39.default.bold("edges")}`);
66801
67186
  for (const k3 of edgesAdded)
66802
- lines.push(` ${import_picocolors35.default.yellow("→ push")} added in yaml: ${k3}`);
67187
+ lines.push(` ${import_picocolors39.default.yellow("→ push")} added in yaml: ${k3}`);
66803
67188
  for (const k3 of edgesRemoved)
66804
- lines.push(` ${import_picocolors35.default.cyan("← pull")} added on cloud: ${k3}`);
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(` ${import_picocolors35.default.bold("schedule triggers")}`);
67227
+ lines.push(` ${import_picocolors39.default.bold("schedule triggers")}`);
66843
67228
  for (const k3 of triggersAdded)
66844
- lines.push(` ${import_picocolors35.default.yellow("→ push")} added/changed in yaml: ${localTriggers.get(k3) ?? k3}`);
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(` ${import_picocolors35.default.cyan("← pull")} added/changed on cloud: ${cloudTriggers.get(k3) ?? k3}`);
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(` ${import_picocolors35.default.bold("member content drift")}`);
67254
+ lines.push(` ${import_picocolors39.default.bold("member content drift")}`);
66870
67255
  for (const d3 of memberDrift) {
66871
- lines.push(` ${import_picocolors35.default.cyan("?")} ${import_picocolors35.default.bold(d3.slug)} ${import_picocolors35.default.dim("— " + d3.reason)}`);
67256
+ lines.push(` ${import_picocolors39.default.cyan("?")} ${import_picocolors39.default.bold(d3.slug)} ${import_picocolors39.default.dim("— " + d3.reason)}`);
66872
67257
  }
66873
- lines.push(` ${import_picocolors35.default.dim("cd into each member folder and run")} ${import_picocolors35.default.cyan("brainbase agent status")}`);
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(` ${import_picocolors35.default.bold("cloud revision")}`);
66879
- lines.push(` ${import_picocolors35.default.cyan("← pull")} cloud changed since last pull: ${import_picocolors35.default.dim(`lock ${lock.revision} → cloud ${cloud.revision}`)}`);
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(` ${import_picocolors35.default.green("✓")} everything is in sync`);
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(` ${import_picocolors35.default.dim("run")} ${import_picocolors35.default.cyan("brainbase orchestration pull")} ${import_picocolors35.default.dim("to apply cloud changes,")} ${import_picocolors35.default.cyan("brainbase orchestration push")} ${import_picocolors35.default.dim("to send yours")}`);
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 import_picocolors36 = __toESM(require_picocolors(), 1);
67289
+ var import_picocolors40 = __toESM(require_picocolors(), 1);
66905
67290
  async function runOrchestrationList(args) {
66906
67291
  banner("orchestration list — orchestrations under a team");
66907
- let orgId = args.orgId;
66908
- let teamId = args.teamId;
66909
- if (!orgId || !isUuid(orgId)) {
66910
- let orgs;
66911
- try {
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(orgId, teamId);
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
- handleApiError7(err);
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(` ${import_picocolors36.default.bold(o2.name)} ${import_picocolors36.default.dim(o2.id)}`);
67313
+ lines.push(` ${import_picocolors40.default.bold(o2.name)} ${import_picocolors40.default.dim(o2.id)}`);
66978
67314
  if (o2.description)
66979
- lines.push(` ${import_picocolors36.default.dim(o2.description)}`);
66980
- lines.push(` ${import_picocolors36.default.dim(`${o2.member_count} member${o2.member_count === 1 ? "" : "s"} · ${o2.edge_count} edge${o2.edge_count === 1 ? "" : "s"}`)}`);
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(` ${import_picocolors36.default.dim("pull one with")} ${import_picocolors36.default.cyan("brainbase orchestration pull <id>")}`);
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 import_picocolors37 = __toESM(require_picocolors(), 1);
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 ${import_picocolors37.default.cyan("brainbase orchestration pull <id>")} first.`);
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 ${import_picocolors37.default.bold(slug)} is taken — using ${import_picocolors37.default.bold(candidate)}.`);
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 ${import_picocolors37.default.bold(link2.group_id)}. ` + `Pass ${import_picocolors37.default.cyan("--org <id>")} explicitly.`);
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 ${import_picocolors37.default.bold(slug)} FROM which member(s)? — edges INTO ${slug} (space to select, enter to skip)`,
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 ${import_picocolors37.default.bold(slug)} TO which member(s)? — edges OUT of ${slug} (space to select, enter to skip)`,
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 ${import_picocolors37.default.cyan("brainbase orchestration push")} to apply.`);
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 import_picocolors38 = __toESM(require_picocolors(), 1);
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 ${import_picocolors38.default.cyan("brainbase orchestration push")} to update it.`);
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 ${import_picocolors38.default.bold(ORCH_MANIFEST_FILE)} here.`);
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(args);
67226
- if (!target)
67227
- return;
67547
+ const target = await resolveOrgAndTeam({
67548
+ orgId: args.orgId,
67549
+ teamId: args.teamId,
67550
+ announce: true
67551
+ });
67228
67552
  const plan = [
67229
67553
  "",
67230
- ` ${import_picocolors38.default.bold(manifest.orchestration.name)}`,
67231
- ` ${import_picocolors38.default.dim("org")} ${import_picocolors38.default.bold(target.org.name)}`,
67232
- ` ${import_picocolors38.default.dim("team")} ${import_picocolors38.default.bold(target.team.name)}`,
67233
- ` ${import_picocolors38.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"}`,
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 ${import_picocolors38.default.bold(created.name)}.`);
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
- handleApiError8(err);
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 handleApiError8(err) {
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
- printHelp2();
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
- printHelp2();
67688
+ printHelp3();
67446
67689
  return;
67447
67690
  default:
67448
67691
  console.error(`Unknown orchestration subcommand: ${sub}
67449
67692
  `);
67450
- printHelp2();
67693
+ printHelp3();
67451
67694
  process.exit(1);
67452
67695
  }
67453
67696
  }
67454
- function printHelp2() {
67697
+ function printHelp3() {
67455
67698
  const out = [];
67456
67699
  out.push("");
67457
- out.push(` ${import_picocolors39.default.bold("brainbase orchestration")} ${import_picocolors39.default.dim("<sub> [options]")}`);
67700
+ out.push(` ${import_picocolors43.default.bold("brainbase orchestration")} ${import_picocolors43.default.dim("<sub> [options]")}`);
67458
67701
  out.push("");
67459
- out.push(` ${import_picocolors39.default.cyan("create")} ${import_picocolors39.default.dim("claim a local orchestration manifest and create it in the cloud")}`);
67460
- out.push(` ${import_picocolors39.default.cyan("pull")} ${import_picocolors39.default.dim("<id>")} ${import_picocolors39.default.dim("fetch orchestration + every member agent into this folder")}`);
67461
- out.push(` ${import_picocolors39.default.cyan("push")} ${import_picocolors39.default.dim("push each member, then update the orchestration graph")}`);
67462
- out.push(` ${import_picocolors39.default.cyan("add-agent")} ${import_picocolors39.default.dim("<name>")} ${import_picocolors39.default.dim("create a member agent, wire edges (--from/--to), and push")}`);
67463
- out.push(` ${import_picocolors39.default.cyan("status")} ${import_picocolors39.default.dim("show what would push and what would pull")}`);
67464
- out.push(` ${import_picocolors39.default.cyan("list")} ${import_picocolors39.default.dim("list orchestrations under a team")}`);
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(` ${import_picocolors39.default.bold("Flags")}`);
67467
- out.push(` ${import_picocolors39.default.dim("--yes, -y")} skip confirmations`);
67468
- out.push(` ${import_picocolors39.default.dim("--harness <id>")} harness for newly-created member folders (default claude-code)`);
67469
- out.push(` ${import_picocolors39.default.dim("--graph-only")} for push: only update members + edges, skip per-member push`);
67470
- out.push(` ${import_picocolors39.default.dim("--org <id>")} for create/list: org id or slug (CLI vocab — DB teams.id)`);
67471
- out.push(` ${import_picocolors39.default.dim("--team <id>")} for create/list: team id (CLI vocab — DB groups.id)`);
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 import_picocolors40 = __toESM(require_picocolors(), 1);
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 ${import_picocolors40.default.cyan("brainbase link")} first.`);
67765
+ f2.info(`Run ${import_picocolors44.default.cyan("brainbase link")} first.`);
67523
67766
  return;
67524
67767
  }
67525
- f2.info(`${import_picocolors40.default.bold("publish")} is coming soon — for now, edit the agent on the web app and run ${import_picocolors40.default.cyan("brainbase sync")} to bring changes here.`);
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 import_picocolors41 = __toESM(require_picocolors(), 1);
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 ${import_picocolors41.default.bold(args.id)}? CIs and machines using it will stop working.`,
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(import_picocolors41.default.dim("No local token stored."));
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(` ${import_picocolors41.default.bold("brainbase token")} ${import_picocolors41.default.dim("<command>")}`);
68426
+ out.push(` ${import_picocolors45.default.bold("brainbase token")} ${import_picocolors45.default.dim("<command>")}`);
68184
68427
  out.push("");
68185
- out.push(` ${import_picocolors41.default.cyan("create")} ${import_picocolors41.default.dim("issue a new long-lived CLI key (PAT)")}`);
68186
- out.push(` ${import_picocolors41.default.cyan("list")} ${import_picocolors41.default.dim("show your active tokens")}`);
68187
- out.push(` ${import_picocolors41.default.cyan("revoke")} ${import_picocolors41.default.dim("<id>")} ${import_picocolors41.default.dim("revoke a token by id")}`);
68188
- out.push(` ${import_picocolors41.default.cyan("clear")} ${import_picocolors41.default.dim("forget the local token (does not revoke)")}`);
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(` ${import_picocolors41.default.bold("create flags")}`);
68191
- out.push(` ${import_picocolors41.default.cyan("--name, -n")} ${import_picocolors41.default.dim("<label>")} ${import_picocolors41.default.dim("token label (prompted if omitted)")}`);
68192
- out.push(` ${import_picocolors41.default.cyan("--scopes")} ${import_picocolors41.default.dim("<list>")} ${import_picocolors41.default.dim("comma-separated; allowed: read, publish, admin")}`);
68193
- out.push(` ${import_picocolors41.default.dim("default: read,publish")}`);
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 import_picocolors42 = __toESM(require_picocolors(), 1);
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 randomBytes2 = await getRandomValues(size2 - result2.length);
74664
- for (const randomByte of randomBytes2) {
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(import_picocolors42.default.dim("No MCP servers configured — nothing to check."));
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" ? import_picocolors42.default.green("✓") : s3.status === "auth_failed" ? import_picocolors42.default.red("✗") : import_picocolors42.default.yellow("⚠");
76555
- const detail = s3.status === "ok" ? import_picocolors42.default.dim(`${s3.tool_count} tool${s3.tool_count === 1 ? "" : "s"}`) : import_picocolors42.default.dim(s3.status + (s3.error ? ` — ${s3.error}` : ""));
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" ? import_picocolors42.default.green("All MCP servers connected.") : import_picocolors42.default.yellow("Some MCP servers are unhealthy.");
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 import_picocolors43 = __toESM(require_picocolors(), 1);
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
- printHelp3();
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
- printHelp3();
76998
+ printHelp4();
76756
76999
  return;
76757
77000
  default:
76758
77001
  console.error(`Unknown task subcommand: ${sub}
76759
77002
  `);
76760
- printHelp3();
77003
+ printHelp4();
76761
77004
  process.exit(1);
76762
77005
  }
76763
77006
  }
76764
- function printHelp3() {
77007
+ function printHelp4() {
76765
77008
  const out = [];
76766
77009
  out.push("");
76767
- out.push(` ${import_picocolors43.default.bold("brainbase task")} ${import_picocolors43.default.dim("<sub> [options]")}`);
77010
+ out.push(` ${import_picocolors47.default.bold("brainbase task")} ${import_picocolors47.default.dim("<sub> [options]")}`);
76768
77011
  out.push("");
76769
- out.push(` ${import_picocolors43.default.cyan("create")} ${import_picocolors43.default.dim("--message <text>")} ${import_picocolors43.default.dim("create a task and start its first run")}`);
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(` ${import_picocolors43.default.bold("create flags")}`);
76772
- out.push(` ${import_picocolors43.default.dim("--message <text>")} required first user message`);
76773
- out.push(` ${import_picocolors43.default.dim("--agent <id>")} override the claimed agent in brainbase.agent.yaml`);
76774
- out.push(` ${import_picocolors43.default.dim("--title <text>")} optional task title`);
76775
- out.push(` ${import_picocolors43.default.dim("--model <id>")} optional model override`);
76776
- out.push(` ${import_picocolors43.default.dim("--json")} print task_id, agent_id, and status as JSON`);
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(` ${import_picocolors43.default.dim("Flag-like values:")} use ${import_picocolors43.default.cyan("--flag=value")} or ${import_picocolors43.default.cyan("--flag -- <value>")}`);
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("◆")} ${import_picocolors44.default.bold("brainbase")} ${import_picocolors44.default.dim(`v${VERSION}`)}`);
76805
- out.push(` ${import_picocolors44.default.dim("connect your local agent to the brainbase platform")}`);
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(` ${import_picocolors44.default.bold("brainbase")} ${import_picocolors44.default.dim("<command> [options]")}`);
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(` ${import_picocolors44.default.cyan("login")} ${import_picocolors44.default.dim(" open the web app and connect this device")}`);
76814
- out.push(` ${import_picocolors44.default.cyan("logout")} ${import_picocolors44.default.dim(" clear the local session")}`);
76815
- out.push(` ${import_picocolors44.default.cyan("whoami")} ${import_picocolors44.default.dim(" show the current user")}`);
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(` ${import_picocolors44.default.cyan("agent create")} ${import_picocolors44.default.dim("claim an unclaimed brainbase.agent.yaml and create the cloud agent")}`);
76820
- out.push(` ${import_picocolors44.default.cyan("agent pull")} ${import_picocolors44.default.dim("[<id>]")} ${import_picocolors44.default.dim("bring cloud changes into this folder (--force to override; --run-entrypoint to also execute the agent entrypoint)")}`);
76821
- out.push(` ${import_picocolors44.default.cyan("agent push")} ${import_picocolors44.default.dim("send local changes to the cloud (--force to overwrite cloud-side conflicts with local)")}`);
76822
- out.push(` ${import_picocolors44.default.cyan("agent unpack")} ${import_picocolors44.default.dim("install the claimed agent into a harness layout")}`);
76823
- out.push(` ${import_picocolors44.default.cyan("link")} ${import_picocolors44.default.dim("attach this folder to an existing agent")}`);
76824
- out.push(` ${import_picocolors44.default.cyan("agent status")} ${import_picocolors44.default.dim("show what would pull and what would push")}`);
76825
- out.push(` ${import_picocolors44.default.cyan("agent env")} ${import_picocolors44.default.dim("print export lines for `eval $(brainbase agent env)`")}`);
76826
- out.push(` ${import_picocolors44.default.cyan("run")} ${import_picocolors44.default.dim("<cmd> [args...]")} ${import_picocolors44.default.dim("run <cmd> with secrets.env loaded into env")}`);
76827
- out.push(` ${import_picocolors44.default.cyan("status")} ${import_picocolors44.default.dim("show what this folder is linked to")}`);
76828
- out.push(` ${import_picocolors44.default.cyan("unlink")} ${import_picocolors44.default.dim("disconnect this folder")}`);
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(` ${import_picocolors44.default.cyan("task create")} ${import_picocolors44.default.dim("--message <text>")} ${import_picocolors44.default.dim("create a managed task and start its first run")}`);
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(` ${import_picocolors44.default.cyan("orchestration create")} ${import_picocolors44.default.dim("claim a local orchestration manifest and create it in the cloud")}`);
76837
- out.push(` ${import_picocolors44.default.cyan("orchestration list")} ${import_picocolors44.default.dim("list orchestrations under a team")}`);
76838
- out.push(` ${import_picocolors44.default.cyan("orchestration pull")} ${import_picocolors44.default.dim("<id>")} ${import_picocolors44.default.dim("recursively fetch an orchestration + every member agent")}`);
76839
- out.push(` ${import_picocolors44.default.cyan("orchestration push")} ${import_picocolors44.default.dim("recursively push each member, then update the graph")}`);
76840
- out.push(` ${import_picocolors44.default.cyan("orchestration status")} ${import_picocolors44.default.dim("show what would push and what would pull")}`);
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(` ${import_picocolors44.default.cyan("template pack")} ${import_picocolors44.default.dim("bundle the current agent into a template")}`);
76845
- out.push(` ${import_picocolors44.default.cyan("template publish")} ${import_picocolors44.default.dim("upload a template to the registry")}`);
76846
- out.push(` ${import_picocolors44.default.cyan("template search")} ${import_picocolors44.default.dim("[query]")} ${import_picocolors44.default.dim("search the registry")}`);
76847
- out.push(` ${import_picocolors44.default.cyan("template info")} ${import_picocolors44.default.dim("<creator/slug>")} ${import_picocolors44.default.dim("show registry details for a template")}`);
76848
- out.push(` ${import_picocolors44.default.cyan("template onboard")} ${import_picocolors44.default.dim("<creator/slug>")} ${import_picocolors44.default.dim("install (or refresh) a template")}`);
76849
- out.push(` ${import_picocolors44.default.cyan("template list")} ${import_picocolors44.default.dim("show installed templates")}`);
76850
- out.push(` ${import_picocolors44.default.cyan("template remove")} ${import_picocolors44.default.dim("<creator/slug>")} ${import_picocolors44.default.dim("uninstall a template")}`);
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(` ${import_picocolors44.default.cyan("skill add")} ${import_picocolors44.default.dim("<source>")} ${import_picocolors44.default.dim("install a skill (github / git / brainbase)")}`);
76855
- out.push(` ${import_picocolors44.default.cyan("skill list")} ${import_picocolors44.default.dim("show locally installed skills + their source")}`);
76856
- out.push(` ${import_picocolors44.default.cyan("skill update")} ${import_picocolors44.default.dim("<slug>")} ${import_picocolors44.default.dim("re-fetch a skill from its recorded source")}`);
76857
- out.push(` ${import_picocolors44.default.cyan("skill remove")} ${import_picocolors44.default.dim("<slug>")} ${import_picocolors44.default.dim("uninstall a skill")}`);
76858
- out.push(` ${import_picocolors44.default.cyan("skill search")} ${import_picocolors44.default.dim("[query]")} ${import_picocolors44.default.dim("search the brainbase skill registry")}`);
76859
- out.push(` ${import_picocolors44.default.cyan("skill info")} ${import_picocolors44.default.dim("<creator/slug>")} ${import_picocolors44.default.dim("show registry details for a skill")}`);
76860
- out.push(` ${import_picocolors44.default.cyan("skill publish")} ${import_picocolors44.default.dim("[dir]")} ${import_picocolors44.default.dim("publish a SKILL.md folder (defaults to .)")}`);
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(` ${import_picocolors44.default.cyan("token create")} ${import_picocolors44.default.dim("issue a long-lived CLI key for CI / scripts")}`);
76865
- out.push(` ${import_picocolors44.default.cyan("token list")} ${import_picocolors44.default.dim("show your active tokens")}`);
76866
- out.push(` ${import_picocolors44.default.cyan("token revoke")} ${import_picocolors44.default.dim("<id>")} ${import_picocolors44.default.dim("revoke a token")}`);
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(` ${import_picocolors44.default.cyan("mcp check")} ${import_picocolors44.default.dim("[--json]")} ${import_picocolors44.default.dim("verify MCP server connectivity through the brainbase proxy (runs at sandbox bootstrap)")}`);
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(` ${import_picocolors44.default.dim("--harness <id>")} force harness for onboard / sync (e.g. claude-code)`);
76875
- out.push(` ${import_picocolors44.default.dim("--scope <s>")} force scope: global | project`);
76876
- out.push(` ${import_picocolors44.default.dim("--yes, -y")} skip confirmations / auto-overwrite`);
76877
- out.push(` ${import_picocolors44.default.dim("--agent <id>")} for link/task create: use this agent id explicitly`);
76878
- out.push(` ${import_picocolors44.default.dim("--message <text>")} for task create: required first user message`);
76879
- out.push(` ${import_picocolors44.default.dim("--title <text>")} for task create: optional task title`);
76880
- out.push(` ${import_picocolors44.default.dim("--model <id>")} for task create: optional model override`);
76881
- out.push(` ${import_picocolors44.default.dim("--json")} for task create/mcp check: machine-readable output`);
76882
- out.push(` ${import_picocolors44.default.dim("--no-tracking")} for link: skip routing LLM traffic through brainbase`);
76883
- out.push(` ${import_picocolors44.default.dim("--track")} for agent create: enable tracking non-interactively (off without a TTY)`);
76884
- out.push(` ${import_picocolors44.default.dim("--shell <sh|fish>")} for agent env: pick output format (auto-detected from $SHELL)`);
76885
- out.push(` ${import_picocolors44.default.dim("--all")} for template list: include installs from other folders`);
76886
- out.push(` ${import_picocolors44.default.dim("--web <url>")} for login: web app URL (default https://app.brainbaselabs.com)`);
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(` ${import_picocolors44.default.dim("BRAINBASE_HOME")} override the local config dir (default ~/.brainbase)`);
76891
- out.push(` ${import_picocolors44.default.dim("BRAINBASE_WEB_URL")} override the web app URL used by login`);
76892
- out.push(` ${import_picocolors44.default.dim("BRAINBASE_CONTROL_PLANE_URL")} override the MAS host (/v2/cli; task create uses /v2/tasks)`);
76893
- out.push(` ${import_picocolors44.default.dim("BRAINBASE_API_URL")} legacy KLS host override (uses /api/cli; proxy/registry fallback)`);
76894
- out.push(` ${import_picocolors44.default.dim("BRAINBASE_PROXY_URL")} override the model-proxy URL used by harness traffic (default https://api.v1.brainbaselabs.com)`);
76895
- out.push(` ${import_picocolors44.default.dim("BRAINBASE_REGISTRY_URL")} override the registry API URL (default https://api.v1.brainbaselabs.com)`);
76896
- out.push(` ${import_picocolors44.default.dim("BRAINBASE_TOKEN")} long-lived CLI PAT (overrides token.json)`);
76897
- out.push(` ${import_picocolors44.default.dim("BRAINBASE_SKIP_AUTH")} bypass the auth gate for development`);
76898
- out.push(` ${import_picocolors44.default.dim("BRAINBASE_NON_INTERACTIVE")} force non-interactive mode — skip/auto-default prompts (CI & agents)`);
76899
- out.push(` ${import_picocolors44.default.dim("BRAINBASE_RUN_ENTRYPOINT")} =1 → agent pull executes the agent entrypoint (sandbox boots; or pass --run-entrypoint)`);
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(` ${import_picocolors44.default.dim("•")} ${import_picocolors44.default.bold("claude-code")} ${import_picocolors44.default.dim("skills, mcps, agents, commands, playbooks, instructions, files")}`);
76904
- out.push(` ${import_picocolors44.default.dim("•")} ${import_picocolors44.default.bold("codex")} ${import_picocolors44.default.dim("skills, mcps, commands, playbooks, instructions, files")}`);
76905
- out.push(` ${import_picocolors44.default.dim("•")} ${import_picocolors44.default.bold("kafka")} ${import_picocolors44.default.dim("skills, mcps, agents, commands, playbooks, instructions, files")}`);
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("◆")} ${import_picocolors44.default.bold("brainbase")}`);
77219
+ console.error(` ${brandTint("◆")} ${import_picocolors48.default.bold("brainbase")}`);
76970
77220
  console.error("");
76971
- console.error(` ${import_picocolors44.default.red("✗")} You need to sign in to use ${import_picocolors44.default.bold("brainbase " + cmd)}.`);
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(` ${import_picocolors44.default.dim(status.reason)}`);
77223
+ console.error(` ${import_picocolors48.default.dim(status.reason)}`);
76974
77224
  console.error("");
76975
- console.error(` Run ${import_picocolors44.default.cyan("brainbase login")} to connect this device.`);
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(import_picocolors44.default.red(`
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);