@brainbase-labs/cli 0.42.0 → 0.43.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 (2) hide show
  1. package/dist/index.js +532 -202
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -35182,7 +35182,7 @@ var require_dist2 = __commonJS((exports, module) => {
35182
35182
  });
35183
35183
 
35184
35184
  // src/index.ts
35185
- var import_picocolors69 = __toESM(require_picocolors(), 1);
35185
+ var import_picocolors71 = __toESM(require_picocolors(), 1);
35186
35186
  import process14 from "node:process";
35187
35187
  import fs91 from "node:fs";
35188
35188
 
@@ -36059,7 +36059,7 @@ function padStart(s, n) {
36059
36059
  // package.json
36060
36060
  var package_default = {
36061
36061
  name: "@brainbase-labs/cli",
36062
- version: "0.42.0",
36062
+ version: "0.43.0",
36063
36063
  description: "Pack, share, and install agent templates across harnesses (Claude Code, Codex, ...).",
36064
36064
  type: "module",
36065
36065
  bin: {
@@ -55614,6 +55614,12 @@ var api = {
55614
55614
  listOrgs() {
55615
55615
  return request("/orgs");
55616
55616
  },
55617
+ listOrgMembersPage(orgId, cursor2) {
55618
+ const query = new URLSearchParams({ limit: "200" });
55619
+ if (cursor2)
55620
+ query.set("cursor", cursor2);
55621
+ return request(`/orgs/${encodeURIComponent(orgId)}/members?${query.toString()}`);
55622
+ },
55617
55623
  listTeams(orgId) {
55618
55624
  return request(`/orgs/${encodeURIComponent(orgId)}/teams`);
55619
55625
  },
@@ -82128,7 +82134,7 @@ var REASON_HINTS = {
82128
82134
  build_already_live: "That build is already live.",
82129
82135
  nothing_live: "Nothing is live yet, so there is nothing to roll back from.",
82130
82136
  release_already_live: "That release is already live.",
82131
- audience_empty: "Nobody can open it yet. Set the audience with `brainbase interface access <id> --everyone` or `--people <ids>`.",
82137
+ audience_empty: "Nobody can open it yet. Set the audience with `brainbase interface access <id> --everyone` or `--people <emails>`.",
82132
82138
  slug_unavailable: "Pick another address."
82133
82139
  };
82134
82140
  function usesPat() {
@@ -82356,6 +82362,14 @@ var interfacesApi = {
82356
82362
  },
82357
82363
  getOperation(operationId, signal) {
82358
82364
  return read(`/operations/${encodeURIComponent(operationId)}`, signal);
82365
+ },
82366
+ startPreview(taskId, interfaceId) {
82367
+ return write(`/tasks/${encodeURIComponent(taskId)}/interface-preview`, "POST", {
82368
+ interface_id: interfaceId
82369
+ });
82370
+ },
82371
+ probePreview(machineId, port, signal) {
82372
+ return read(`/machines/${encodeURIComponent(machineId)}/preview/probe?port=${encodeURIComponent(String(port))}`, signal);
82359
82373
  }
82360
82374
  };
82361
82375
  function isTransientReadError(error2) {
@@ -84004,7 +84018,7 @@ function printHelp5() {
84004
84018
  }
84005
84019
 
84006
84020
  // src/cli/interface.ts
84007
- var import_picocolors67 = __toESM(require_picocolors(), 1);
84021
+ var import_picocolors68 = __toESM(require_picocolors(), 1);
84008
84022
 
84009
84023
  // src/cli/interface-build.ts
84010
84024
  var import_picocolors63 = __toESM(require_picocolors(), 1);
@@ -84449,6 +84463,57 @@ var buildCommands = { build };
84449
84463
  // src/cli/interface-lifecycle.ts
84450
84464
  var import_picocolors65 = __toESM(require_picocolors(), 1);
84451
84465
 
84466
+ // src/core/org-members.ts
84467
+ async function listAllOrgMembers(orgId) {
84468
+ const members = [];
84469
+ let cursor2;
84470
+ for (;; ) {
84471
+ let page;
84472
+ try {
84473
+ page = await api.listOrgMembersPage(orgId, cursor2);
84474
+ } catch (error2) {
84475
+ if (error2 instanceof ApiError && error2.status === 404) {
84476
+ throw new Error("This Brainbase server cannot list organization members, so people can only be named by user id.");
84477
+ }
84478
+ throw error2;
84479
+ }
84480
+ members.push(...page.members);
84481
+ if (!page.next_cursor)
84482
+ return members;
84483
+ if (page.next_cursor === cursor2) {
84484
+ throw new Error("Could not read the member list: the page cursor stopped advancing.");
84485
+ }
84486
+ cursor2 = page.next_cursor;
84487
+ }
84488
+ }
84489
+ function isEmail(entry) {
84490
+ return entry.includes("@");
84491
+ }
84492
+ function resolveEmails(entries, members, flag) {
84493
+ const ids = entries.map((entry) => {
84494
+ if (!isEmail(entry))
84495
+ return entry;
84496
+ const wanted = entry.toLowerCase();
84497
+ const matches2 = members.filter((member) => member.email?.toLowerCase() === wanted);
84498
+ if (matches2.length === 1)
84499
+ return matches2[0].id;
84500
+ if (matches2.length === 0) {
84501
+ throw new Error(`${flag}: nobody you can see in this organization has the email ${entry}. ` + "`brainbase member ls` lists the people you can share with.");
84502
+ }
84503
+ throw new Error(`${flag}: more than one member has the email ${entry} (${matches2.map((m3) => m3.id).join(", ")}). Pass the user id instead.`);
84504
+ });
84505
+ return [...new Set(ids)];
84506
+ }
84507
+ function personLabel(id, members) {
84508
+ const member = members?.get(id);
84509
+ if (!member?.email)
84510
+ return id;
84511
+ return member.name ? `${member.email} (${member.name})` : member.email;
84512
+ }
84513
+ function membersById(members) {
84514
+ return new Map(members.map((member) => [member.id, member]));
84515
+ }
84516
+
84452
84517
  // src/cli/interface-read.ts
84453
84518
  var import_picocolors64 = __toESM(require_picocolors(), 1);
84454
84519
  function interfaceState(row) {
@@ -84639,7 +84704,7 @@ function sessionUserId() {
84639
84704
  function parseIds(raw, flag) {
84640
84705
  const ids = [...new Set(raw.split(",").map((id) => id.trim()).filter(Boolean))];
84641
84706
  if (ids.length === 0)
84642
- throw new Error(`${flag} takes user ids separated by commas, or \`me\`.`);
84707
+ throw new Error(`${flag} takes emails or user ids separated by commas, or \`me\`.`);
84643
84708
  return ids;
84644
84709
  }
84645
84710
  function withMe(ids, self) {
@@ -84657,6 +84722,30 @@ function resolveMeForAccess(ids, flag) {
84657
84722
  function grantIds(access) {
84658
84723
  return access.grants.map((grant) => grant.subject_id);
84659
84724
  }
84725
+ async function resolvePeople(entries, orgId, flag) {
84726
+ if (!entries.some(isEmail))
84727
+ return { ids: entries, members: null };
84728
+ const members = await listAllOrgMembers(await orgId());
84729
+ return { ids: resolveEmails(entries, members, flag), members: membersById(members) };
84730
+ }
84731
+ async function membersForDisplay(orgId, known) {
84732
+ if (known)
84733
+ return known;
84734
+ try {
84735
+ return membersById(await listAllOrgMembers(orgId));
84736
+ } catch {
84737
+ return null;
84738
+ }
84739
+ }
84740
+ function peopleJson(access, members) {
84741
+ return grantIds(access).map((id) => {
84742
+ const member = members?.get(id);
84743
+ return { id, email: member?.email ?? null, name: member?.name ?? null };
84744
+ });
84745
+ }
84746
+ function namesOf(ids, members) {
84747
+ return ids.map((id) => safe(personLabel(id, members))).join(", ");
84748
+ }
84660
84749
  function exactlyOne(parsed, flags) {
84661
84750
  const given = flags.filter(([key2]) => parsed.options[key2] !== undefined && parsed.options[key2] !== false);
84662
84751
  if (given.length > 1) {
@@ -84664,15 +84753,15 @@ function exactlyOne(parsed, flags) {
84664
84753
  }
84665
84754
  return given[0]?.[0] ?? null;
84666
84755
  }
84667
- function peopleLine(access) {
84756
+ function peopleLine(access, members) {
84668
84757
  const ids = grantIds(access);
84669
- return ids.length ? ids.map(safe).join(", ") : import_picocolors65.default.dim("nobody named");
84758
+ return ids.length ? namesOf(ids, members) : import_picocolors65.default.dim("nobody named");
84670
84759
  }
84671
- function printAccess(row, access) {
84760
+ function printAccess(row, access, members) {
84672
84761
  console.log([
84673
84762
  "",
84674
84763
  field("audience", audienceLabel(access)),
84675
- field("people", peopleLine(access)),
84764
+ field("people", peopleLine(access, members)),
84676
84765
  field("threads", threadsLabel(row.share_agent_threads)),
84677
84766
  ""
84678
84767
  ].join(`
@@ -84706,6 +84795,12 @@ async function create3(ctx) {
84706
84795
  const self = sessionUserId();
84707
84796
  if (audience && self)
84708
84797
  audience.ids = withMe(audience.ids, self);
84798
+ let members = null;
84799
+ if (audience) {
84800
+ const resolved = await resolvePeople(audience.ids, async () => (await api.getAgent(agentId)).org_id, "--people");
84801
+ audience.ids = resolved.ids;
84802
+ members = resolved.members;
84803
+ }
84709
84804
  const replayKey = stringOption(parsed, "idempotencyKey")?.trim();
84710
84805
  const created = await interfacesApi.create({ agentId, name, slug: stringOption(parsed, "address")?.trim() || undefined }, { idempotencyKey: replayKey || newIdempotencyKey() });
84711
84806
  let access = null;
@@ -84739,10 +84834,13 @@ async function create3(ctx) {
84739
84834
  accessError = error2;
84740
84835
  }
84741
84836
  }
84837
+ if (access?.audience_mode === "users")
84838
+ members = await membersForDisplay(created.team_id, members);
84742
84839
  if (json) {
84743
84840
  printJson({
84744
84841
  interface: created,
84745
84842
  access,
84843
+ ...access ? { people: peopleJson(access, members) } : {},
84746
84844
  ...note ? { note } : {},
84747
84845
  ...accessError ? { error: errorShape(accessError) } : {}
84748
84846
  });
@@ -84763,10 +84861,10 @@ async function create3(ctx) {
84763
84861
  if (access) {
84764
84862
  out.push(field("audience", audienceLabel(access)));
84765
84863
  if (access.audience_mode === "users")
84766
- out.push(field("people", peopleLine(access)));
84864
+ out.push(field("people", peopleLine(access, members)));
84767
84865
  }
84768
84866
  if (!audience) {
84769
- out.push("", ` Nobody can open it until you choose who can: \`brainbase interface access ${id} --everyone\` or \`--people <ids>\`.`);
84867
+ out.push("", ` Nobody can open it until you choose who can: \`brainbase interface access ${id} --everyone\` or \`--people <emails>\`.`);
84770
84868
  }
84771
84869
  if (created.share_agent_threads) {
84772
84870
  out.push(` ${import_picocolors65.default.dim(`To show viewers only their own conversations: \`brainbase interface threads ${id} --private\`.`)}`);
@@ -84781,7 +84879,7 @@ async function create3(ctx) {
84781
84879
  } else if (accessError && isUnanswered(accessError)) {
84782
84880
  fail(`Created ${id}, but the answer to setting who can open it was lost, so whether it was saved could not be confirmed. ` + `Check with \`brainbase interface access ${id}\`.`);
84783
84881
  } else if (accessError) {
84784
- fail(`Created ${id}, but setting who can open it failed, so nobody can open it yet: ${safe(errorShape(accessError).message)} ` + `Set it with \`brainbase interface access ${id} --everyone\` or \`--people <ids>\`.`);
84882
+ fail(`Created ${id}, but setting who can open it failed, so nobody can open it yet: ${safe(errorShape(accessError).message)} ` + `Set it with \`brainbase interface access ${id} --everyone\` or \`--people <emails>\`.`);
84785
84883
  }
84786
84884
  });
84787
84885
  }
@@ -84800,27 +84898,36 @@ async function access(ctx) {
84800
84898
  { key: "remove", names: ["--remove"], kind: "value" }
84801
84899
  ]);
84802
84900
  json = booleanOption(parsed, "json");
84803
- const [id] = expectPositionals(parsed, ["id"], "brainbase interface access <id> [--everyone | --people <ids> | --add <ids> | --remove <ids>]");
84901
+ const [id] = expectPositionals(parsed, ["id"], "brainbase interface access <id> [--everyone | --people <emails> | --add <emails> | --remove <emails>]");
84804
84902
  const change = exactlyOne(parsed, [
84805
84903
  ["everyone", "--everyone"],
84806
84904
  ["people", "--people"],
84807
84905
  ["add", "--add"],
84808
84906
  ["remove", "--remove"]
84809
84907
  ]);
84810
- const ids = change && change !== "everyone" ? resolveMeForAccess(parseIds(stringOption(parsed, change) ?? "", `--${change}`), `--${change}`) : [];
84908
+ const entries = change && change !== "everyone" ? resolveMeForAccess(parseIds(stringOption(parsed, change) ?? "", `--${change}`), `--${change}`) : [];
84811
84909
  if (!change) {
84812
84910
  const [row2, current2] = await Promise.all([interfacesApi.get(id), interfacesApi.getAccess(id)]);
84911
+ const members2 = current2.grants.length ? await membersForDisplay(row2.team_id, null) : null;
84813
84912
  if (json) {
84814
- printJson({ id: row2.id, ...current2, share_agent_threads: row2.share_agent_threads });
84913
+ printJson({
84914
+ id: row2.id,
84915
+ ...current2,
84916
+ people: peopleJson(current2, members2),
84917
+ share_agent_threads: row2.share_agent_threads
84918
+ });
84815
84919
  return;
84816
84920
  }
84817
- printAccess(row2, current2);
84921
+ printAccess(row2, current2, members2);
84818
84922
  return;
84819
84923
  }
84820
84924
  const [row, current] = await Promise.all([
84821
84925
  interfacesApi.get(id),
84822
84926
  change === "add" || change === "remove" ? interfacesApi.getAccess(id) : null
84823
84927
  ]);
84928
+ const resolved = await resolvePeople(entries, async () => row.team_id, `--${change}`);
84929
+ const ids = resolved.ids;
84930
+ let members = resolved.members;
84824
84931
  const label = safe(row.name);
84825
84932
  let summary;
84826
84933
  switch (change) {
@@ -84828,13 +84935,13 @@ async function access(ctx) {
84828
84935
  summary = `Everyone in the organisation will be able to open ${label}.`;
84829
84936
  break;
84830
84937
  case "people":
84831
- summary = `Only these people will be able to open ${label}: ${ids.map(safe).join(", ")}.`;
84938
+ summary = `Only these people will be able to open ${label}: ${namesOf(ids, members)}.`;
84832
84939
  break;
84833
84940
  case "add":
84834
- summary = `${ids.map(safe).join(", ")} will be able to open ${label}.`;
84941
+ summary = `${namesOf(ids, members)} will be able to open ${label}.`;
84835
84942
  break;
84836
84943
  case "remove":
84837
- summary = `${ids.map(safe).join(", ")} will no longer be able to open ${label}.`;
84944
+ summary = `${namesOf(ids, members)} will no longer be able to open ${label}.`;
84838
84945
  break;
84839
84946
  default: {
84840
84947
  const unreachable = change;
@@ -84869,11 +84976,13 @@ async function access(ctx) {
84869
84976
  saved = await interfacesApi.setAccess(id, "users", fresh.filter((subject) => !ids.includes(subject)));
84870
84977
  }
84871
84978
  }
84979
+ if (saved.grants.length)
84980
+ members = await membersForDisplay(row.team_id, members);
84872
84981
  if (json) {
84873
- printJson(saved);
84982
+ printJson({ ...saved, people: peopleJson(saved, members) });
84874
84983
  return;
84875
84984
  }
84876
- printAccess(row, saved);
84985
+ printAccess(row, saved, members);
84877
84986
  });
84878
84987
  }
84879
84988
  async function threads(ctx) {
@@ -85064,14 +85173,145 @@ var lifecycleCommands = {
85064
85173
  unarchive
85065
85174
  };
85066
85175
 
85067
- // src/cli/interface-release.ts
85176
+ // src/cli/interface-preview.ts
85068
85177
  var import_picocolors66 = __toESM(require_picocolors(), 1);
85178
+ function warn(line) {
85179
+ console.error(import_picocolors66.default.yellow(line));
85180
+ }
85181
+ var PREVIEW_TIMEOUT_SECONDS = 300;
85182
+ var PROBE_INTERVAL_MS = 2000;
85183
+ async function pickConversation(row, named) {
85184
+ if (named)
85185
+ return { taskId: named, why: "the conversation you named" };
85186
+ const running = row.running_generation?.thread_id;
85187
+ if (running)
85188
+ return { taskId: running, why: "the build conversation running now" };
85189
+ const tasks = await masApi.listTasks({ metadata: { [INTERFACE_THREAD_METADATA_KEY]: row.id }, limit: 200 });
85190
+ const newest = [...tasks].sort((a3, b4) => Date.parse(b4.created_at) - Date.parse(a3.created_at))[0];
85191
+ if (!newest) {
85192
+ throw new Error(`No build conversation has been opened for ${safe(row.name)} yet, so there is nothing to preview. ` + `Start one with \`brainbase interface build ${safe(row.id)} "<what to build>"\`.`);
85193
+ }
85194
+ return { taskId: newest.id, why: "the most recent build conversation" };
85195
+ }
85196
+ function previewAddress(started, row) {
85197
+ if (started.preview_url !== undefined)
85198
+ return started.preview_url;
85199
+ const live = row.live_release?.url;
85200
+ if (!live)
85201
+ return null;
85202
+ const host = new URL(live).hostname;
85203
+ const prefix = `${started.slug}.`;
85204
+ return host.startsWith(prefix) ? `https://${started.slug}-preview.${host.slice(prefix.length)}` : null;
85205
+ }
85206
+ function missingAddress(started) {
85207
+ return started.preview_url === null ? "none: this Brainbase server has no public domain for interfaces" : "unknown: this Brainbase server does not report it, and nothing is live to work it out from";
85208
+ }
85209
+ async function waitUntilServing(started, options) {
85210
+ const now2 = options.deps.now ?? Date.now;
85211
+ const interval = options.deps.pollIntervalMs ?? PROBE_INTERVAL_MS;
85212
+ const deadline = now2() + options.timeoutMs;
85213
+ const stop = interruption(options.deps);
85214
+ try {
85215
+ for (;; ) {
85216
+ if (stop.signal.aborted)
85217
+ return "interrupted";
85218
+ const left = deadline - now2();
85219
+ if (left <= 0)
85220
+ return "timeout";
85221
+ const probeStop = new AbortController;
85222
+ const onStop = () => probeStop.abort(stop.signal.reason);
85223
+ stop.signal.addEventListener("abort", onStop, { once: true });
85224
+ const timer = setTimeout(() => probeStop.abort(), left);
85225
+ try {
85226
+ const probe = await interfacesApi.probePreview(started.machine_id, started.port, probeStop.signal);
85227
+ if (probe.serving)
85228
+ return "serving";
85229
+ } catch (error2) {
85230
+ if (stop.signal.aborted)
85231
+ return "interrupted";
85232
+ if (probeStop.signal.aborted)
85233
+ return "timeout";
85234
+ if (!isTransientReadError(error2))
85235
+ throw error2;
85236
+ } finally {
85237
+ clearTimeout(timer);
85238
+ stop.signal.removeEventListener("abort", onStop);
85239
+ }
85240
+ const remaining = deadline - now2();
85241
+ if (remaining <= 0)
85242
+ return "timeout";
85243
+ if (await pause(Math.min(interval, remaining), stop.signal))
85244
+ return "interrupted";
85245
+ }
85246
+ } finally {
85247
+ stop.dispose();
85248
+ }
85249
+ }
85250
+ function showing(started, taskId) {
85251
+ return started.source === "working_copy" ? `the working copy of conversation ${safe(taskId)}, unsaved edits included` : `the last saved version${started.commit ? ` (${safe(started.commit)})` : ""}`;
85252
+ }
85253
+ async function preview(ctx) {
85254
+ let json = wantsJson(ctx.args);
85255
+ await runReportingErrors(() => json, async () => {
85256
+ const parsed = parseArgv(ctx.args, [
85257
+ JSON_FLAG,
85258
+ TIMEOUT_FLAG,
85259
+ NO_WAIT_FLAG,
85260
+ { key: "task", names: ["--task"], kind: "value" }
85261
+ ]);
85262
+ json = booleanOption(parsed, "json");
85263
+ const [id] = expectPositionals(parsed, ["id"], "brainbase interface preview <id> [--task <task id>]");
85264
+ const waitMs = timeoutMs2(stringOption(parsed, "timeout"), PREVIEW_TIMEOUT_SECONDS);
85265
+ const noWait = booleanOption(parsed, "noWait");
85266
+ const say = progress(json);
85267
+ const row = await interfacesApi.get(id);
85268
+ const { taskId, why } = await pickConversation(row, stringOption(parsed, "task")?.trim() || undefined);
85269
+ say(import_picocolors66.default.dim(` Previewing ${why}, ${safe(taskId)}.`));
85270
+ const started = await interfacesApi.startPreview(taskId, row.id);
85271
+ const address2 = previewAddress(started, row);
85272
+ let outcome = started.state === "serving" ? "serving" : "not_waited";
85273
+ if (outcome !== "serving" && !noWait) {
85274
+ say(import_picocolors66.default.dim(" Starting the dev server in the sandbox…"));
85275
+ outcome = await waitUntilServing(started, { timeoutMs: waitMs, deps: ctx.deps });
85276
+ }
85277
+ if (json) {
85278
+ printJson({ task_id: taskId, ...started, preview_url: address2, serving: outcome === "serving" });
85279
+ } else {
85280
+ const out = [
85281
+ "",
85282
+ ` ${outcome === "serving" ? import_picocolors66.default.green("Preview ready") : import_picocolors66.default.yellow("Preview starting")} ${import_picocolors66.default.bold(safe(started.name))}`,
85283
+ "",
85284
+ field("address", address2 ? safe(address2) : import_picocolors66.default.dim(missingAddress(started))),
85285
+ field("showing", showing(started, taskId)),
85286
+ "",
85287
+ ` ${import_picocolors66.default.dim("Opens for people who can edit the agent, after signing in. Nothing is published.")}`,
85288
+ ""
85289
+ ];
85290
+ console.log(out.join(`
85291
+ `));
85292
+ if (started.restored) {
85293
+ warn("The conversation's working copy was no longer in the sandbox, so its last saved version is shown and edits that were never saved are gone.");
85294
+ }
85295
+ }
85296
+ if (outcome === "timeout") {
85297
+ if (!json)
85298
+ warn(`Still starting after ${Math.round(waitMs / 1000)}s. It may come up shortly: open the address, or run this again.`);
85299
+ process.exitCode = 1;
85300
+ } else if (outcome === "interrupted") {
85301
+ process.exitCode = SIGINT_EXIT_CODE;
85302
+ }
85303
+ });
85304
+ }
85305
+ var previewCommands = { preview };
85306
+
85307
+ // src/cli/interface-release.ts
85308
+ var import_picocolors67 = __toESM(require_picocolors(), 1);
85069
85309
  var PUBLISH_TIMEOUT_SECONDS = 300;
85070
85310
  var REBUILD_USAGE = "brainbase interface rebuild <id> [--version <version id>]";
85071
85311
  var PUBLISH_USAGE = "brainbase interface publish <id> [--build <build id>]";
85072
85312
  var ROLLBACK_USAGE = "brainbase interface rollback <id> --release <release id>";
85073
- function warn(line) {
85074
- console.error(import_picocolors66.default.yellow(line));
85313
+ function warn2(line) {
85314
+ console.error(import_picocolors67.default.yellow(line));
85075
85315
  }
85076
85316
  function text3(value) {
85077
85317
  return typeof value === "string" && value.trim() ? value : null;
@@ -85088,8 +85328,8 @@ async function follow(operationId, what, options) {
85088
85328
  intervalMs: options.deps.pollIntervalMs,
85089
85329
  signal: stop.signal,
85090
85330
  now: options.deps.now,
85091
- onStatus: (operation) => say(import_picocolors66.default.dim(` ${what} ${operation.status}`)),
85092
- onStall: () => warn(`The ${what} looks stalled: its worker stopped checking in. Still waiting, in case another worker picks it up.`)
85331
+ onStatus: (operation) => say(import_picocolors67.default.dim(` ${what} ${operation.status}`)),
85332
+ onStall: () => warn2(`The ${what} looks stalled: its worker stopped checking in. Still waiting, in case another worker picks it up.`)
85093
85333
  });
85094
85334
  if (outcome.kind === "settled") {
85095
85335
  const operation = outcome.operation;
@@ -85107,12 +85347,12 @@ function reportUnsuccessful(result2, what, options) {
85107
85347
  if (options.json) {
85108
85348
  printJson({ outcome: result2.outcome, operation_id: result2.operationId, operation: result2.operation });
85109
85349
  } else if (result2.outcome === "failed") {
85110
- console.error(import_picocolors66.default.red(`The ${what} failed (operation ${id}):`));
85350
+ console.error(import_picocolors67.default.red(`The ${what} failed (operation ${id}):`));
85111
85351
  console.error(safeBlock(result2.operation?.error ?? "Brainbase gave no reason."));
85112
85352
  } else if (result2.outcome === "timeout") {
85113
- warn(`Stopped waiting after ${Math.round(options.timeoutMs / 1000)}s. The ${what} keeps running on the server (operation ${id}).`);
85353
+ warn2(`Stopped waiting after ${Math.round(options.timeoutMs / 1000)}s. The ${what} keeps running on the server (operation ${id}).`);
85114
85354
  } else {
85115
- warn(`Stopped waiting. The ${what} keeps running on the server (operation ${id}).`);
85355
+ warn2(`Stopped waiting. The ${what} keeps running on the server (operation ${id}).`);
85116
85356
  }
85117
85357
  process.exitCode = result2.outcome === "interrupted" ? SIGINT_EXIT_CODE : 1;
85118
85358
  return true;
@@ -85166,7 +85406,7 @@ async function rebuild(ctx) {
85166
85406
  if (json)
85167
85407
  printJson({ outcome: "started", operation_id: operationId, operation });
85168
85408
  else
85169
- console.log(import_picocolors66.default.dim(` Follow it with \`brainbase interface builds ${safe(id)}\`.`));
85409
+ console.log(import_picocolors67.default.dim(` Follow it with \`brainbase interface builds ${safe(id)}\`.`));
85170
85410
  return;
85171
85411
  }
85172
85412
  const result2 = await follow(operationId, "build", { json, timeoutMs: waitMs, deps: ctx.deps });
@@ -85178,8 +85418,8 @@ async function rebuild(ctx) {
85178
85418
  }
85179
85419
  const buildId = safe(result2.operation?.build_id ?? "");
85180
85420
  const version2 = safe(result2.operation?.source_version_id ?? "");
85181
- console.log(import_picocolors66.default.green(`✓ Build ${buildId} succeeded${version2 ? ` (version ${version2})` : ""}.`));
85182
- console.log(import_picocolors66.default.dim(` Publish it with \`brainbase interface publish ${safe(id)} --build ${buildId}\`.`));
85421
+ console.log(import_picocolors67.default.green(`✓ Build ${buildId} succeeded${version2 ? ` (version ${version2})` : ""}.`));
85422
+ console.log(import_picocolors67.default.dim(` Publish it with \`brainbase interface publish ${safe(id)} --build ${buildId}\`.`));
85183
85423
  });
85184
85424
  }
85185
85425
  function liveBuildOf(row, releases) {
@@ -85237,7 +85477,7 @@ function describeBuild(buildId, builds) {
85237
85477
  const build2 = builds.find((candidate) => candidate.id === buildId);
85238
85478
  if (!build2)
85239
85479
  return `build ${safe(buildId)}`;
85240
- return `build ${safe(build2.id)} ${import_picocolors66.default.dim(`(version ${safe(build2.source_version_id)}, built ${ago(build2.created_at)})`)}`;
85480
+ return `build ${safe(build2.id)} ${import_picocolors67.default.dim(`(version ${safe(build2.source_version_id)}, built ${ago(build2.created_at)})`)}`;
85241
85481
  }
85242
85482
  function reportAlreadyLive(json, buildId, releaseId, url2) {
85243
85483
  if (json) {
@@ -85282,7 +85522,7 @@ async function publish(ctx) {
85282
85522
  } else {
85283
85523
  const picked = await pickBuild(id, row, builds, releases, liveBuildId);
85284
85524
  if (picked.warning)
85285
- warn(picked.warning);
85525
+ warn2(picked.warning);
85286
85526
  buildId = picked.build.id;
85287
85527
  }
85288
85528
  if (buildId === liveBuildId) {
@@ -85291,8 +85531,8 @@ async function publish(ctx) {
85291
85531
  }
85292
85532
  if (!json) {
85293
85533
  console.log("");
85294
- console.log(` ${import_picocolors66.default.dim("Live now".padEnd(14))}${liveBuildId ? `${describeBuild(liveBuildId, builds)} at ${safe(row.live_release?.url)}` : row.live_release ? `release ${safe(row.live_release.id)} at ${safe(row.live_release.url)}` : import_picocolors66.default.dim("nothing")}`);
85295
- console.log(` ${import_picocolors66.default.dim("Will publish".padEnd(14))}${describeBuild(buildId, builds)}`);
85534
+ console.log(` ${import_picocolors67.default.dim("Live now".padEnd(14))}${liveBuildId ? `${describeBuild(liveBuildId, builds)} at ${safe(row.live_release?.url)}` : row.live_release ? `release ${safe(row.live_release.id)} at ${safe(row.live_release.url)}` : import_picocolors67.default.dim("nothing")}`);
85535
+ console.log(` ${import_picocolors67.default.dim("Will publish".padEnd(14))}${describeBuild(buildId, builds)}`);
85296
85536
  console.log("");
85297
85537
  }
85298
85538
  const proceed = await confirmChange({
@@ -85324,7 +85564,7 @@ async function publish(ctx) {
85324
85564
  return;
85325
85565
  }
85326
85566
  if (error2.reason === "audience_empty") {
85327
- throw reword(error2, `Nobody can open this interface yet, so it was not published. Choose who can with \`brainbase interface access ${safe(id)} --everyone\` or \`--people <user ids>\`, then publish again.`);
85567
+ throw reword(error2, `Nobody can open this interface yet, so it was not published. Choose who can with \`brainbase interface access ${safe(id)} --everyone\` or \`--people <emails>\`, then publish again.`);
85328
85568
  }
85329
85569
  if (error2.reason !== "operation_in_flight")
85330
85570
  throw error2;
@@ -85335,7 +85575,7 @@ async function publish(ctx) {
85335
85575
  if (json)
85336
85576
  printJson({ outcome: "started", operation_id: operationId, operation });
85337
85577
  else
85338
- console.log(import_picocolors66.default.dim(` Check it with \`brainbase interface get ${safe(id)}\`.`));
85578
+ console.log(import_picocolors67.default.dim(` Check it with \`brainbase interface get ${safe(id)}\`.`));
85339
85579
  return;
85340
85580
  }
85341
85581
  const result2 = await follow(operationId, "publish", { json, timeoutMs: waitMs, deps: ctx.deps });
@@ -85352,11 +85592,11 @@ async function publish(ctx) {
85352
85592
  printJson({ outcome: "succeeded", operation_id: operationId, operation: result2.operation, url: url2 });
85353
85593
  return;
85354
85594
  }
85355
- console.log(import_picocolors66.default.green(`✓ Build ${safe(buildId)} is live.`));
85595
+ console.log(import_picocolors67.default.green(`✓ Build ${safe(buildId)} is live.`));
85356
85596
  if (url2)
85357
85597
  console.log(` ${safe(url2)}`);
85358
85598
  if (urlUnread) {
85359
- console.log(import_picocolors66.default.dim(` Its address could not be read just now; see it with \`brainbase interface open ${safe(id)}\`.`));
85599
+ console.log(import_picocolors67.default.dim(` Its address could not be read just now; see it with \`brainbase interface open ${safe(id)}\`.`));
85360
85600
  }
85361
85601
  });
85362
85602
  }
@@ -85392,8 +85632,8 @@ async function rollback(ctx) {
85392
85632
  }
85393
85633
  if (!json) {
85394
85634
  console.log("");
85395
- console.log(` ${import_picocolors66.default.dim("Live now".padEnd(20))}release ${safe(row.live_release.id)} at ${safe(row.live_release.url)}`);
85396
- console.log(` ${import_picocolors66.default.dim("Will be live again".padEnd(20))}release ${safe(releaseId)}`);
85635
+ console.log(` ${import_picocolors67.default.dim("Live now".padEnd(20))}release ${safe(row.live_release.id)} at ${safe(row.live_release.url)}`);
85636
+ console.log(` ${import_picocolors67.default.dim("Will be live again".padEnd(20))}release ${safe(releaseId)}`);
85397
85637
  console.log("");
85398
85638
  }
85399
85639
  const proceed = await confirmChange({
@@ -85426,7 +85666,7 @@ async function rollback(ctx) {
85426
85666
  printJson(release);
85427
85667
  return;
85428
85668
  }
85429
- console.log(import_picocolors66.default.green(`✓ Release ${safe(release.id)} is live again (build ${safe(release.build_id)}).`));
85669
+ console.log(import_picocolors67.default.green(`✓ Release ${safe(release.id)} is live again (build ${safe(release.build_id)}).`));
85430
85670
  console.log(` ${safe(release.url)}`);
85431
85671
  });
85432
85672
  }
@@ -85437,7 +85677,8 @@ var COMMANDS = {
85437
85677
  ...readCommands,
85438
85678
  ...lifecycleCommands,
85439
85679
  ...releaseCommands,
85440
- ...buildCommands
85680
+ ...buildCommands,
85681
+ ...previewCommands
85441
85682
  };
85442
85683
  var ALIASES = { list: "ls", show: "get" };
85443
85684
  async function runInterface(cwd2, sub, args, deps = {}) {
@@ -85460,22 +85701,22 @@ async function runInterface(cwd2, sub, args, deps = {}) {
85460
85701
  await command({ cwd: cwd2, args, deps });
85461
85702
  }
85462
85703
  function line(command, args, description) {
85463
- return ` ${import_picocolors67.default.cyan(command)}${args ? ` ${import_picocolors67.default.dim(args)}` : ""}
85464
- ${import_picocolors67.default.dim(description)}`;
85704
+ return ` ${import_picocolors68.default.cyan(command)}${args ? ` ${import_picocolors68.default.dim(args)}` : ""}
85705
+ ${import_picocolors68.default.dim(description)}`;
85465
85706
  }
85466
85707
  function printHelp6() {
85467
85708
  const out = [];
85468
85709
  out.push("");
85469
- out.push(` ${import_picocolors67.default.bold("brainbase interface")} ${import_picocolors67.default.dim("<sub> [options]")}`);
85470
- out.push(` ${import_picocolors67.default.dim("Dashboards for an agent: build them in a conversation, publish them, choose who can open them.")}`);
85710
+ out.push(` ${import_picocolors68.default.bold("brainbase interface")} ${import_picocolors68.default.dim("<sub> [options]")}`);
85711
+ out.push(` ${import_picocolors68.default.dim("Dashboards for an agent: build them in a conversation, publish them, choose who can open them.")}`);
85471
85712
  out.push("");
85472
85713
  out.push(line("ls", "[--agent <id>] [--archived | --only-archived]", "list interfaces you can see"));
85473
85714
  out.push(line("get", "<id>", "one interface: address, audience, live release, draft, running build conversation"));
85474
85715
  out.push(line("open", "<id>", "print the live address"));
85475
85716
  out.push(line("versions | builds | releases", "<id>", "history, newest first"));
85476
85717
  out.push("");
85477
- out.push(line("create", "[--agent <id>] --name <name> [--address <slug>] [--everyone | --people <ids>]", "create an interface on an agent"));
85478
- out.push(line("access", "<id> [--everyone | --people <ids> | --add <ids> | --remove <ids>]", "show or set who can open it"));
85718
+ out.push(line("create", "[--agent <id>] --name <name> [--address <slug>] [--everyone | --people <emails>]", "create an interface on an agent"));
85719
+ out.push(line("access", "<id> [--everyone | --people <emails> | --add <emails> | --remove <emails>]", "show or set who can open it"));
85479
85720
  out.push(line("threads", "<id> [--shared | --private]", "show or set whether viewers see every conversation on the agent"));
85480
85721
  out.push(line("rename", "<id> <name>", "change the name"));
85481
85722
  out.push(line("address", "<id> <slug>", "change the address (viewers sign in again)"));
@@ -85485,15 +85726,97 @@ function printHelp6() {
85485
85726
  out.push(line("rebuild", "<id> [--version <id>]", "build the draft version again, or a named one"));
85486
85727
  out.push(line("publish", "<id> [--build <id>]", "make a build live (default: the newest succeeded build)"));
85487
85728
  out.push(line("rollback", "<id> --release <id>", "make an earlier release live again"));
85729
+ out.push(line("preview", "<id> [--task <id>] [--no-wait]", "serve the unpublished draft from its build conversation and print the preview address"));
85730
+ out.push("");
85731
+ out.push(` ${import_picocolors68.default.dim("--json")} machine-readable output; never prompts`);
85732
+ out.push(` ${import_picocolors68.default.dim("--yes, -y")} skip confirmation (required without a terminal)`);
85733
+ out.push(` ${import_picocolors68.default.dim("--no-wait")} for rebuild and publish: return the operation at once; for preview: do not wait for the dev server`);
85734
+ out.push(` ${import_picocolors68.default.dim("--timeout <seconds>")} for build, rebuild, publish and preview: how long to wait (builds 900, publish and preview 300)`);
85735
+ out.push(` ${import_picocolors68.default.dim("--idempotency-key <key>")} replay a create, build, rebuild, publish or rollback whose answer was lost`);
85736
+ out.push("");
85737
+ out.push(` ${import_picocolors68.default.dim("People are emails (see `brainbase member ls`), user ids, or `me`. Audience members also need access to the agent.")}`);
85738
+ out.push(` ${import_picocolors68.default.dim("Exit codes: 0 done, 1 refused or failed, 130 interrupted (the server keeps working).")}`);
85739
+ out.push("");
85740
+ console.log(out.join(`
85741
+ `));
85742
+ }
85743
+
85744
+ // src/cli/member.ts
85745
+ var import_picocolors69 = __toESM(require_picocolors(), 1);
85746
+ async function runMember(sub, args, opts) {
85747
+ if (args.some((arg) => arg === "--help" || arg === "-h")) {
85748
+ printHelp7();
85749
+ return;
85750
+ }
85751
+ switch (sub) {
85752
+ case "ls":
85753
+ case "list":
85754
+ if (args.length > 0) {
85755
+ console.error(`Unexpected argument: ${args[0]}
85756
+ `);
85757
+ printHelp7();
85758
+ process.exit(1);
85759
+ }
85760
+ await runMemberList(opts);
85761
+ return;
85762
+ case undefined:
85763
+ case "help":
85764
+ case "-h":
85765
+ case "--help":
85766
+ printHelp7();
85767
+ return;
85768
+ default:
85769
+ console.error(`Unknown member subcommand: ${sub}
85770
+ `);
85771
+ printHelp7();
85772
+ process.exit(1);
85773
+ }
85774
+ }
85775
+ async function runMemberList(opts) {
85776
+ const org = await resolveOrg(opts.orgId, { allowPrompt: !opts.json, announce: !opts.json });
85777
+ const members = await listAllOrgMembers(org.id);
85778
+ if (opts.json) {
85779
+ console.log(JSON.stringify({ org, members }, null, 2));
85780
+ return;
85781
+ }
85782
+ banner(`member ls — ${sanitizeLabel(org.name)}`);
85783
+ console.log(formatMemberList(members));
85784
+ }
85785
+ function formatMemberList(members) {
85786
+ if (members.length === 0)
85787
+ return `
85788
+ ${import_picocolors69.default.dim("Nobody here you can see.")}
85789
+ `;
85790
+ const sorted = [...members].sort((a3, b4) => (a3.email ?? a3.id).localeCompare(b4.email ?? b4.id));
85791
+ const rows = sorted.map((member) => ({
85792
+ email: sanitizeLabel(member.email ?? "(no sign-in account)"),
85793
+ name: sanitizeLabel(member.name ?? ""),
85794
+ role: sanitizeLabel(member.role),
85795
+ teams: member.teams.map((team) => sanitizeLabel(team.name)).join(", ")
85796
+ }));
85797
+ const emailWidth = Math.max(...rows.map((row) => row.email.length));
85798
+ const nameWidth = Math.max(...rows.map((row) => row.name.length));
85799
+ const roleWidth = Math.max(...rows.map((row) => row.role.length));
85800
+ const lines = [""];
85801
+ for (const row of rows) {
85802
+ lines.push(` ${row.email.padEnd(emailWidth)} ${row.name.padEnd(nameWidth)} ${import_picocolors69.default.dim(row.role.padEnd(roleWidth))} ${import_picocolors69.default.dim(row.teams)}`.trimEnd());
85803
+ }
85804
+ lines.push("", ` ${import_picocolors69.default.dim("share a dashboard with one of them:")} ${import_picocolors69.default.cyan("brainbase interface access <id> --add <email>")}`, "");
85805
+ return lines.join(`
85806
+ `);
85807
+ }
85808
+ function printHelp7() {
85809
+ const out = [];
85810
+ out.push("");
85811
+ out.push(` ${import_picocolors69.default.bold("brainbase member")} ${import_picocolors69.default.dim("<sub> [options]")}`);
85812
+ out.push("");
85813
+ out.push(` ${import_picocolors69.default.cyan("ls")} ${import_picocolors69.default.dim("the people in an organization you can see, with their emails, roles and teams")}`);
85488
85814
  out.push("");
85489
- out.push(` ${import_picocolors67.default.dim("--json")} machine-readable output; never prompts`);
85490
- out.push(` ${import_picocolors67.default.dim("--yes, -y")} skip confirmation (required without a terminal)`);
85491
- out.push(` ${import_picocolors67.default.dim("--no-wait")} for rebuild and publish: return the operation at once`);
85492
- out.push(` ${import_picocolors67.default.dim("--timeout <seconds>")} for build, rebuild and publish: how long to wait (builds 900, publish 300)`);
85493
- out.push(` ${import_picocolors67.default.dim("--idempotency-key <key>")} replay a create, build, rebuild, publish or rollback whose answer was lost`);
85815
+ out.push(` ${import_picocolors69.default.dim("--org <id-or-slug>")} ${import_picocolors69.default.dim("which organization (picked automatically when you are in one)")}`);
85816
+ out.push(` ${import_picocolors69.default.dim("--json")} ${import_picocolors69.default.dim("machine-readable output")}`);
85494
85817
  out.push("");
85495
- out.push(` ${import_picocolors67.default.dim("People are user ids, or `me`. Audience members also need access to the agent.")}`);
85496
- out.push(` ${import_picocolors67.default.dim("Exit codes: 0 done, 1 refused or failed, 130 interrupted (the server keeps working).")}`);
85818
+ out.push(` ${import_picocolors69.default.dim("Owners and admins see everyone. Anyone else sees the owners, the admins, themselves")}`);
85819
+ out.push(` ${import_picocolors69.default.dim("and the people who share a team with them, as in the web app.")}`);
85497
85820
  out.push("");
85498
85821
  console.log(out.join(`
85499
85822
  `));
@@ -88586,7 +88909,7 @@ async function runBenchmarkPhase(specPathInput, resultPathInput, expectedPhase,
88586
88909
  }
88587
88910
 
88588
88911
  // src/cli/benchmark-control.ts
88589
- var import_picocolors68 = __toESM(require_picocolors(), 1);
88912
+ var import_picocolors70 = __toESM(require_picocolors(), 1);
88590
88913
  import fs89 from "node:fs";
88591
88914
  import path101 from "node:path";
88592
88915
 
@@ -91600,20 +91923,20 @@ async function emitCursorPages(output, fetchPage, options) {
91600
91923
  function commandHelp() {
91601
91924
  return [
91602
91925
  "",
91603
- ` ${import_picocolors68.default.bold("brainbase benchmark")} ${import_picocolors68.default.dim("<command> [options]")}`,
91926
+ ` ${import_picocolors70.default.bold("brainbase benchmark")} ${import_picocolors70.default.dim("<command> [options]")}`,
91604
91927
  "",
91605
- ` ${import_picocolors68.default.cyan("init | list | show | create | validate | pull | push")}`,
91606
- ` ${import_picocolors68.default.cyan("publish | revisions | import | export | archive | restore")}`,
91607
- ` ${import_picocolors68.default.cyan("run plan|start|watch|list|show|cancel|resume")}`,
91608
- ` ${import_picocolors68.default.cyan("results | diagnoses | attempt | artifacts | export-results")}`,
91609
- ` ${import_picocolors68.default.cyan("history | baseline show|set|clear")}`,
91928
+ ` ${import_picocolors70.default.cyan("init | list | show | create | validate | pull | push")}`,
91929
+ ` ${import_picocolors70.default.cyan("publish | revisions | import | export | archive | restore")}`,
91930
+ ` ${import_picocolors70.default.cyan("run plan|start|watch|list|show|cancel|resume")}`,
91931
+ ` ${import_picocolors70.default.cyan("results | diagnoses | attempt | artifacts | export-results")}`,
91932
+ ` ${import_picocolors70.default.cyan("history | baseline show|set|clear")}`,
91610
91933
  "",
91611
- ` ${import_picocolors68.default.dim("Use --agent to override brainbase.agent.yaml, and --json or --jsonl for automation.")}`,
91934
+ ` ${import_picocolors70.default.dim("Use --agent to override brainbase.agent.yaml, and --json or --jsonl for automation.")}`,
91612
91935
  "",
91613
- ` ${import_picocolors68.default.bold("benchmark runtime (machine-only)")}`,
91614
- ` ${import_picocolors68.default.cyan("hydrate")} ${import_picocolors68.default.dim("--spec <path> --result <path> --json")}`,
91615
- ` ${import_picocolors68.default.cyan("evaluate")} ${import_picocolors68.default.dim("--spec <path> --result <path> --json")}`,
91616
- ` ${import_picocolors68.default.cyan("capabilities")} ${import_picocolors68.default.dim("--json")}`,
91936
+ ` ${import_picocolors70.default.bold("benchmark runtime (machine-only)")}`,
91937
+ ` ${import_picocolors70.default.cyan("hydrate")} ${import_picocolors70.default.dim("--spec <path> --result <path> --json")}`,
91938
+ ` ${import_picocolors70.default.cyan("evaluate")} ${import_picocolors70.default.dim("--spec <path> --result <path> --json")}`,
91939
+ ` ${import_picocolors70.default.cyan("capabilities")} ${import_picocolors70.default.dim("--json")}`,
91617
91940
  ""
91618
91941
  ].join(`
91619
91942
  `);
@@ -91860,17 +92183,17 @@ async function runImport(cwd2, argv, deps) {
91860
92183
  const primary = optionalNonblank(options.parsed, "primaryEvaluator");
91861
92184
  if (primary)
91862
92185
  request2.primary_evaluator_key = primary;
91863
- const preview = await client.previewHuggingFaceImport(request2);
92186
+ const preview2 = await client.previewHuggingFaceImport(request2);
91864
92187
  if (bool(options.parsed, "preview")) {
91865
- output.result(preview);
92188
+ output.result(preview2);
91866
92189
  return;
91867
92190
  }
91868
- const provenance = requireObject(preview.provenance ?? {}, "preview provenance");
92191
+ const provenance = requireObject(preview2.provenance ?? {}, "preview provenance");
91869
92192
  const materialize = {
91870
92193
  ...request2,
91871
92194
  expected_commit: stringField(provenance, "commit"),
91872
- expected_materialization_digest: stringField(preview, "materialization_digest"),
91873
- expected_content_digest: stringField(preview, "content_digest")
92195
+ expected_materialization_digest: stringField(preview2, "materialization_digest"),
92196
+ expected_content_digest: stringField(preview2, "content_digest")
91874
92197
  };
91875
92198
  output.result(json(await client.materializeHuggingFaceImport(materialize, {
91876
92199
  idempotencyKey: idempotencyKey(options)
@@ -93032,181 +93355,182 @@ var SUBCOMMAND_OWNED_FLAGS = {
93032
93355
  function help() {
93033
93356
  const out = [];
93034
93357
  out.push("");
93035
- out.push(` ${brandTint("◆")} ${import_picocolors69.default.bold("brainbase")} ${import_picocolors69.default.dim(`v${VERSION}`)}`);
93036
- out.push(` ${import_picocolors69.default.dim("connect your local agent to the brainbase platform")}`);
93358
+ out.push(` ${brandTint("◆")} ${import_picocolors71.default.bold("brainbase")} ${import_picocolors71.default.dim(`v${VERSION}`)}`);
93359
+ out.push(` ${import_picocolors71.default.dim("connect your local agent to the brainbase platform")}`);
93037
93360
  out.push("");
93038
93361
  out.push(divider("USAGE"));
93039
93362
  out.push("");
93040
- out.push(` ${import_picocolors69.default.bold("brainbase")} ${import_picocolors69.default.dim("<command> [options]")}`);
93363
+ out.push(` ${import_picocolors71.default.bold("brainbase")} ${import_picocolors71.default.dim("<command> [options]")}`);
93041
93364
  out.push("");
93042
93365
  out.push(divider("AUTH"));
93043
93366
  out.push("");
93044
- out.push(` ${import_picocolors69.default.cyan("login")} ${import_picocolors69.default.dim(" open the web app and connect this device")}`);
93045
- out.push(` ${import_picocolors69.default.cyan("logout")} ${import_picocolors69.default.dim(" clear the local session")}`);
93046
- out.push(` ${import_picocolors69.default.cyan("whoami")} ${import_picocolors69.default.dim("[--json]")} ${import_picocolors69.default.dim(" show which credential is in use and what it covers")}`);
93367
+ out.push(` ${import_picocolors71.default.cyan("login")} ${import_picocolors71.default.dim(" open the web app and connect this device")}`);
93368
+ out.push(` ${import_picocolors71.default.cyan("logout")} ${import_picocolors71.default.dim(" clear the local session")}`);
93369
+ out.push(` ${import_picocolors71.default.cyan("whoami")} ${import_picocolors71.default.dim("[--json]")} ${import_picocolors71.default.dim(" show which credential is in use and what it covers")}`);
93047
93370
  out.push("");
93048
93371
  out.push(divider("DISCOVERY"));
93049
93372
  out.push("");
93050
- out.push(` ${import_picocolors69.default.cyan("team list")} ${import_picocolors69.default.dim("show the teams you can create agents in")}`);
93051
- out.push(` ${import_picocolors69.default.cyan("agent list")} ${import_picocolors69.default.dim("show a team's agents and their ids")}`);
93373
+ out.push(` ${import_picocolors71.default.cyan("team list")} ${import_picocolors71.default.dim("show the teams you can create agents in")}`);
93374
+ out.push(` ${import_picocolors71.default.cyan("member ls")} ${import_picocolors71.default.dim("show the people in an organization, with the emails interface access takes")}`);
93375
+ out.push(` ${import_picocolors71.default.cyan("agent list")} ${import_picocolors71.default.dim("show a team's agents and their ids")}`);
93052
93376
  out.push("");
93053
93377
  out.push(divider("LINKED AGENT"));
93054
93378
  out.push("");
93055
- out.push(` ${import_picocolors69.default.cyan("agent init")} ${import_picocolors69.default.dim("write a starter brainbase.agent.yaml here — offline, no login needed")}`);
93056
- out.push(` ${import_picocolors69.default.cyan("agent create")} ${import_picocolors69.default.dim("claim an unclaimed brainbase.agent.yaml and create the cloud agent")}`);
93057
- out.push(` ${import_picocolors69.default.cyan("agent pull")} ${import_picocolors69.default.dim("[<id>]")} ${import_picocolors69.default.dim("bring cloud changes into this folder (--force to override; --run-entrypoint to also execute the agent entrypoint; --link to link first)")}`);
93058
- out.push(` ${import_picocolors69.default.cyan("agent push")} ${import_picocolors69.default.dim("send local changes to the cloud (--force to overwrite cloud-side conflicts with local)")}`);
93059
- out.push(` ${import_picocolors69.default.cyan("agent delete")} ${import_picocolors69.default.dim("<id>")} ${import_picocolors69.default.dim("permanently delete a cloud agent and every task it has run")}`);
93060
- out.push(` ${import_picocolors69.default.cyan("agent unpack")} ${import_picocolors69.default.dim("install the claimed agent into a harness layout")}`);
93061
- out.push(` ${import_picocolors69.default.cyan("link")} ${import_picocolors69.default.dim("attach this folder to an existing agent")}`);
93062
- out.push(` ${import_picocolors69.default.cyan("agent status")} ${import_picocolors69.default.dim("show what would pull and what would push")}`);
93063
- out.push(` ${import_picocolors69.default.cyan("agent connections")} ${import_picocolors69.default.dim("show which integrations this agent is wired to (--json for CI)")}`);
93064
- out.push(` ${import_picocolors69.default.cyan("agent connect")} ${import_picocolors69.default.dim("<name>")} ${import_picocolors69.default.dim("connect slack or meeting from the terminal")}`);
93065
- out.push(` ${import_picocolors69.default.cyan("agent disconnect")} ${import_picocolors69.default.dim("<name>")} ${import_picocolors69.default.dim("revoke a slack or meeting install")}`);
93066
- out.push(` ${import_picocolors69.default.cyan("agent env")} ${import_picocolors69.default.dim("print export lines for `eval $(brainbase agent env)`")}`);
93067
- out.push(` ${import_picocolors69.default.cyan("run")} ${import_picocolors69.default.dim("<cmd> [args...]")} ${import_picocolors69.default.dim("run <cmd> with secrets.env loaded into env")}`);
93068
- out.push(` ${import_picocolors69.default.cyan("status")} ${import_picocolors69.default.dim("show what this folder is linked to")}`);
93069
- out.push(` ${import_picocolors69.default.cyan("unlink")} ${import_picocolors69.default.dim("disconnect this folder")}`);
93379
+ out.push(` ${import_picocolors71.default.cyan("agent init")} ${import_picocolors71.default.dim("write a starter brainbase.agent.yaml here — offline, no login needed")}`);
93380
+ out.push(` ${import_picocolors71.default.cyan("agent create")} ${import_picocolors71.default.dim("claim an unclaimed brainbase.agent.yaml and create the cloud agent")}`);
93381
+ out.push(` ${import_picocolors71.default.cyan("agent pull")} ${import_picocolors71.default.dim("[<id>]")} ${import_picocolors71.default.dim("bring cloud changes into this folder (--force to override; --run-entrypoint to also execute the agent entrypoint; --link to link first)")}`);
93382
+ out.push(` ${import_picocolors71.default.cyan("agent push")} ${import_picocolors71.default.dim("send local changes to the cloud (--force to overwrite cloud-side conflicts with local)")}`);
93383
+ out.push(` ${import_picocolors71.default.cyan("agent delete")} ${import_picocolors71.default.dim("<id>")} ${import_picocolors71.default.dim("permanently delete a cloud agent and every task it has run")}`);
93384
+ out.push(` ${import_picocolors71.default.cyan("agent unpack")} ${import_picocolors71.default.dim("install the claimed agent into a harness layout")}`);
93385
+ out.push(` ${import_picocolors71.default.cyan("link")} ${import_picocolors71.default.dim("attach this folder to an existing agent")}`);
93386
+ out.push(` ${import_picocolors71.default.cyan("agent status")} ${import_picocolors71.default.dim("show what would pull and what would push")}`);
93387
+ out.push(` ${import_picocolors71.default.cyan("agent connections")} ${import_picocolors71.default.dim("show which integrations this agent is wired to (--json for CI)")}`);
93388
+ out.push(` ${import_picocolors71.default.cyan("agent connect")} ${import_picocolors71.default.dim("<name>")} ${import_picocolors71.default.dim("connect slack or meeting from the terminal")}`);
93389
+ out.push(` ${import_picocolors71.default.cyan("agent disconnect")} ${import_picocolors71.default.dim("<name>")} ${import_picocolors71.default.dim("revoke a slack or meeting install")}`);
93390
+ out.push(` ${import_picocolors71.default.cyan("agent env")} ${import_picocolors71.default.dim("print export lines for `eval $(brainbase agent env)`")}`);
93391
+ out.push(` ${import_picocolors71.default.cyan("run")} ${import_picocolors71.default.dim("<cmd> [args...]")} ${import_picocolors71.default.dim("run <cmd> with secrets.env loaded into env")}`);
93392
+ out.push(` ${import_picocolors71.default.cyan("status")} ${import_picocolors71.default.dim("show what this folder is linked to")}`);
93393
+ out.push(` ${import_picocolors71.default.cyan("unlink")} ${import_picocolors71.default.dim("disconnect this folder")}`);
93070
93394
  out.push("");
93071
93395
  out.push(divider("TASKS"));
93072
93396
  out.push("");
93073
- out.push(` ${import_picocolors69.default.cyan("task create")} ${import_picocolors69.default.dim("--message <text>")} ${import_picocolors69.default.dim("create a managed task and start its first run (--wait to block on it; --interface <id> for a build conversation)")}`);
93074
- out.push(` ${import_picocolors69.default.cyan("task list")} ${import_picocolors69.default.dim("recent tasks you can reach (--interface <id> for its build conversations)")}`);
93075
- out.push(` ${import_picocolors69.default.cyan("task get")} ${import_picocolors69.default.dim("<task-id>")} ${import_picocolors69.default.dim("one task: status, agent, machine, eval verdicts")}`);
93076
- out.push(` ${import_picocolors69.default.cyan("task logs")} ${import_picocolors69.default.dim("<task-id> [--follow]")} ${import_picocolors69.default.dim("one line per event in the task's transcript, or tail it live")}`);
93077
- out.push(` ${import_picocolors69.default.cyan("task send")} ${import_picocolors69.default.dim("<task-id> <message>")} ${import_picocolors69.default.dim("send a follow-up during execution, or queue it for the next turn")}`);
93078
- out.push(` ${import_picocolors69.default.cyan("task stop")} ${import_picocolors69.default.dim("<task-id>")} ${import_picocolors69.default.dim("stop execution and cancel pending follow-ups, retaining their text")}`);
93079
- out.push(` ${import_picocolors69.default.cyan("task delete")} ${import_picocolors69.default.dim("<task-id>")} ${import_picocolors69.default.dim("permanently delete a stopped task and tear down its sandbox")}`);
93397
+ out.push(` ${import_picocolors71.default.cyan("task create")} ${import_picocolors71.default.dim("--message <text>")} ${import_picocolors71.default.dim("create a managed task and start its first run (--wait to block on it; --interface <id> for a build conversation)")}`);
93398
+ out.push(` ${import_picocolors71.default.cyan("task list")} ${import_picocolors71.default.dim("recent tasks you can reach (--interface <id> for its build conversations)")}`);
93399
+ out.push(` ${import_picocolors71.default.cyan("task get")} ${import_picocolors71.default.dim("<task-id>")} ${import_picocolors71.default.dim("one task: status, agent, machine, eval verdicts")}`);
93400
+ out.push(` ${import_picocolors71.default.cyan("task logs")} ${import_picocolors71.default.dim("<task-id> [--follow]")} ${import_picocolors71.default.dim("one line per event in the task's transcript, or tail it live")}`);
93401
+ out.push(` ${import_picocolors71.default.cyan("task send")} ${import_picocolors71.default.dim("<task-id> <message>")} ${import_picocolors71.default.dim("send a follow-up during execution, or queue it for the next turn")}`);
93402
+ out.push(` ${import_picocolors71.default.cyan("task stop")} ${import_picocolors71.default.dim("<task-id>")} ${import_picocolors71.default.dim("stop execution and cancel pending follow-ups, retaining their text")}`);
93403
+ out.push(` ${import_picocolors71.default.cyan("task delete")} ${import_picocolors71.default.dim("<task-id>")} ${import_picocolors71.default.dim("permanently delete a stopped task and tear down its sandbox")}`);
93080
93404
  out.push("");
93081
93405
  out.push(divider("INTERFACES"));
93082
93406
  out.push("");
93083
- out.push(` ${import_picocolors69.default.cyan("interface ls")} ${import_picocolors69.default.dim("dashboards you can see (--agent to narrow)")}`);
93084
- out.push(` ${import_picocolors69.default.cyan("interface create")} ${import_picocolors69.default.dim("--name <n>")} ${import_picocolors69.default.dim("create one on an agent, with who can open it")}`);
93085
- out.push(` ${import_picocolors69.default.cyan("interface build")} ${import_picocolors69.default.dim('<id> "<ask>"')} ${import_picocolors69.default.dim("describe a change; the agent builds it while you watch")}`);
93086
- out.push(` ${import_picocolors69.default.cyan("interface publish")} ${import_picocolors69.default.dim("<id>")} ${import_picocolors69.default.dim("make the newest succeeded build live")}`);
93087
- out.push(` ${import_picocolors69.default.cyan("interface rollback")} ${import_picocolors69.default.dim("<id>")} ${import_picocolors69.default.dim("make an earlier release live again (--release <id>)")}`);
93088
- out.push(` ${import_picocolors69.default.cyan("interface access")} ${import_picocolors69.default.dim("<id>")} ${import_picocolors69.default.dim("show or set who can open it")}`);
93089
- out.push(` ${import_picocolors69.default.cyan("interface --help")} ${import_picocolors69.default.dim("every interface subcommand")}`);
93407
+ out.push(` ${import_picocolors71.default.cyan("interface ls")} ${import_picocolors71.default.dim("dashboards you can see (--agent to narrow)")}`);
93408
+ out.push(` ${import_picocolors71.default.cyan("interface create")} ${import_picocolors71.default.dim("--name <n>")} ${import_picocolors71.default.dim("create one on an agent, with who can open it")}`);
93409
+ out.push(` ${import_picocolors71.default.cyan("interface build")} ${import_picocolors71.default.dim('<id> "<ask>"')} ${import_picocolors71.default.dim("describe a change; the agent builds it while you watch")}`);
93410
+ out.push(` ${import_picocolors71.default.cyan("interface publish")} ${import_picocolors71.default.dim("<id>")} ${import_picocolors71.default.dim("make the newest succeeded build live")}`);
93411
+ out.push(` ${import_picocolors71.default.cyan("interface rollback")} ${import_picocolors71.default.dim("<id>")} ${import_picocolors71.default.dim("make an earlier release live again (--release <id>)")}`);
93412
+ out.push(` ${import_picocolors71.default.cyan("interface access")} ${import_picocolors71.default.dim("<id>")} ${import_picocolors71.default.dim("show or set who can open it")}`);
93413
+ out.push(` ${import_picocolors71.default.cyan("interface --help")} ${import_picocolors71.default.dim("every interface subcommand")}`);
93090
93414
  out.push("");
93091
93415
  out.push(divider("SANDBOXES"));
93092
93416
  out.push("");
93093
- out.push(` ${import_picocolors69.default.cyan("machine ls")} ${import_picocolors69.default.dim("[--all]")} ${import_picocolors69.default.dim("list your sandboxes — live ones only unless --all")}`);
93094
- out.push(` ${import_picocolors69.default.cyan("machine rm")} ${import_picocolors69.default.dim("<id>")} ${import_picocolors69.default.dim("tear a sandbox down (it bills until you do)")}`);
93417
+ out.push(` ${import_picocolors71.default.cyan("machine ls")} ${import_picocolors71.default.dim("[--all]")} ${import_picocolors71.default.dim("list your sandboxes — live ones only unless --all")}`);
93418
+ out.push(` ${import_picocolors71.default.cyan("machine rm")} ${import_picocolors71.default.dim("<id>")} ${import_picocolors71.default.dim("tear a sandbox down (it bills until you do)")}`);
93095
93419
  out.push("");
93096
93420
  out.push(divider("BENCHMARKS"));
93097
93421
  out.push("");
93098
- out.push(` ${import_picocolors69.default.cyan("benchmark list")} ${import_picocolors69.default.dim("list benchmarks for the linked agent")}`);
93099
- out.push(` ${import_picocolors69.default.cyan("benchmark init")} ${import_picocolors69.default.dim("[directory]")} ${import_picocolors69.default.dim("scaffold a local benchmark")}`);
93100
- out.push(` ${import_picocolors69.default.cyan("benchmark create")} ${import_picocolors69.default.dim("[path|-]")} ${import_picocolors69.default.dim("create a benchmark draft")}`);
93101
- out.push(` ${import_picocolors69.default.cyan("benchmark run")} ${import_picocolors69.default.dim("<benchmark> --yes")} ${import_picocolors69.default.dim("plan and start a benchmark run")}`);
93102
- out.push(` ${import_picocolors69.default.cyan("benchmark results")} ${import_picocolors69.default.dim("<run>")} ${import_picocolors69.default.dim("inspect normalized benchmark results")}`);
93422
+ out.push(` ${import_picocolors71.default.cyan("benchmark list")} ${import_picocolors71.default.dim("list benchmarks for the linked agent")}`);
93423
+ out.push(` ${import_picocolors71.default.cyan("benchmark init")} ${import_picocolors71.default.dim("[directory]")} ${import_picocolors71.default.dim("scaffold a local benchmark")}`);
93424
+ out.push(` ${import_picocolors71.default.cyan("benchmark create")} ${import_picocolors71.default.dim("[path|-]")} ${import_picocolors71.default.dim("create a benchmark draft")}`);
93425
+ out.push(` ${import_picocolors71.default.cyan("benchmark run")} ${import_picocolors71.default.dim("<benchmark> --yes")} ${import_picocolors71.default.dim("plan and start a benchmark run")}`);
93426
+ out.push(` ${import_picocolors71.default.cyan("benchmark results")} ${import_picocolors71.default.dim("<run>")} ${import_picocolors71.default.dim("inspect normalized benchmark results")}`);
93103
93427
  out.push("");
93104
93428
  out.push(divider("BENCHMARK RUNTIME"));
93105
93429
  out.push("");
93106
- out.push(` ${import_picocolors69.default.cyan("benchmark hydrate")} ${import_picocolors69.default.dim("--spec <path> --result <path> --json")}`);
93107
- out.push(` ${import_picocolors69.default.cyan("benchmark evaluate")} ${import_picocolors69.default.dim("--spec <path> --result <path> --json")}`);
93108
- out.push(` ${import_picocolors69.default.cyan("benchmark capabilities")} ${import_picocolors69.default.dim("--json")}`);
93430
+ out.push(` ${import_picocolors71.default.cyan("benchmark hydrate")} ${import_picocolors71.default.dim("--spec <path> --result <path> --json")}`);
93431
+ out.push(` ${import_picocolors71.default.cyan("benchmark evaluate")} ${import_picocolors71.default.dim("--spec <path> --result <path> --json")}`);
93432
+ out.push(` ${import_picocolors71.default.cyan("benchmark capabilities")} ${import_picocolors71.default.dim("--json")}`);
93109
93433
  out.push("");
93110
93434
  out.push(divider("ORCHESTRATIONS"));
93111
93435
  out.push("");
93112
- out.push(` ${import_picocolors69.default.cyan("orchestration create")} ${import_picocolors69.default.dim("claim a local orchestration manifest and create it in the cloud")}`);
93113
- out.push(` ${import_picocolors69.default.cyan("orchestration list")} ${import_picocolors69.default.dim("list orchestrations under a team")}`);
93114
- out.push(` ${import_picocolors69.default.cyan("orchestration pull")} ${import_picocolors69.default.dim("<id>")} ${import_picocolors69.default.dim("recursively fetch an orchestration + every member agent")}`);
93115
- out.push(` ${import_picocolors69.default.cyan("orchestration push")} ${import_picocolors69.default.dim("recursively push each member, then update the graph")}`);
93116
- out.push(` ${import_picocolors69.default.cyan("orchestration status")} ${import_picocolors69.default.dim("show what would push and what would pull")}`);
93117
- out.push(` ${import_picocolors69.default.cyan("orchestration delete")} ${import_picocolors69.default.dim("<id>")} ${import_picocolors69.default.dim("permanently delete an orchestration graph (member agents are kept)")}`);
93436
+ out.push(` ${import_picocolors71.default.cyan("orchestration create")} ${import_picocolors71.default.dim("claim a local orchestration manifest and create it in the cloud")}`);
93437
+ out.push(` ${import_picocolors71.default.cyan("orchestration list")} ${import_picocolors71.default.dim("list orchestrations under a team")}`);
93438
+ out.push(` ${import_picocolors71.default.cyan("orchestration pull")} ${import_picocolors71.default.dim("<id>")} ${import_picocolors71.default.dim("recursively fetch an orchestration + every member agent")}`);
93439
+ out.push(` ${import_picocolors71.default.cyan("orchestration push")} ${import_picocolors71.default.dim("recursively push each member, then update the graph")}`);
93440
+ out.push(` ${import_picocolors71.default.cyan("orchestration status")} ${import_picocolors71.default.dim("show what would push and what would pull")}`);
93441
+ out.push(` ${import_picocolors71.default.cyan("orchestration delete")} ${import_picocolors71.default.dim("<id>")} ${import_picocolors71.default.dim("permanently delete an orchestration graph (member agents are kept)")}`);
93118
93442
  out.push("");
93119
93443
  out.push(divider("TEMPLATES"));
93120
93444
  out.push("");
93121
- out.push(` ${import_picocolors69.default.cyan("template pack")} ${import_picocolors69.default.dim("bundle the current agent into a template")}`);
93122
- out.push(` ${import_picocolors69.default.cyan("template publish")} ${import_picocolors69.default.dim("upload a template to the registry")}`);
93123
- out.push(` ${import_picocolors69.default.cyan("template search")} ${import_picocolors69.default.dim("[query]")} ${import_picocolors69.default.dim("search the registry")}`);
93124
- out.push(` ${import_picocolors69.default.cyan("template info")} ${import_picocolors69.default.dim("<creator/slug>")} ${import_picocolors69.default.dim("show registry details for a template")}`);
93125
- out.push(` ${import_picocolors69.default.cyan("template onboard")} ${import_picocolors69.default.dim("<creator/slug>")} ${import_picocolors69.default.dim("install (or refresh) a template")}`);
93126
- out.push(` ${import_picocolors69.default.cyan("template list")} ${import_picocolors69.default.dim("show installed templates")}`);
93127
- out.push(` ${import_picocolors69.default.cyan("template remove")} ${import_picocolors69.default.dim("<creator/slug>")} ${import_picocolors69.default.dim("uninstall a template")}`);
93445
+ out.push(` ${import_picocolors71.default.cyan("template pack")} ${import_picocolors71.default.dim("bundle the current agent into a template")}`);
93446
+ out.push(` ${import_picocolors71.default.cyan("template publish")} ${import_picocolors71.default.dim("upload a template to the registry")}`);
93447
+ out.push(` ${import_picocolors71.default.cyan("template search")} ${import_picocolors71.default.dim("[query]")} ${import_picocolors71.default.dim("search the registry")}`);
93448
+ out.push(` ${import_picocolors71.default.cyan("template info")} ${import_picocolors71.default.dim("<creator/slug>")} ${import_picocolors71.default.dim("show registry details for a template")}`);
93449
+ out.push(` ${import_picocolors71.default.cyan("template onboard")} ${import_picocolors71.default.dim("<creator/slug>")} ${import_picocolors71.default.dim("install (or refresh) a template")}`);
93450
+ out.push(` ${import_picocolors71.default.cyan("template list")} ${import_picocolors71.default.dim("show installed templates")}`);
93451
+ out.push(` ${import_picocolors71.default.cyan("template remove")} ${import_picocolors71.default.dim("<creator/slug>")} ${import_picocolors71.default.dim("uninstall a template")}`);
93128
93452
  out.push("");
93129
93453
  out.push(divider("SKILLS"));
93130
93454
  out.push("");
93131
- out.push(` ${import_picocolors69.default.cyan("skill add")} ${import_picocolors69.default.dim("<source>")} ${import_picocolors69.default.dim("install a skill (github / git / brainbase)")}`);
93132
- out.push(` ${import_picocolors69.default.cyan("skill list")} ${import_picocolors69.default.dim("show locally installed skills + their source")}`);
93133
- out.push(` ${import_picocolors69.default.cyan("skill update")} ${import_picocolors69.default.dim("<slug>")} ${import_picocolors69.default.dim("re-fetch a skill from its recorded source")}`);
93134
- out.push(` ${import_picocolors69.default.cyan("skill remove")} ${import_picocolors69.default.dim("<slug>")} ${import_picocolors69.default.dim("uninstall a skill")}`);
93135
- out.push(` ${import_picocolors69.default.cyan("skill search")} ${import_picocolors69.default.dim("[query]")} ${import_picocolors69.default.dim("search the brainbase skill registry")}`);
93136
- out.push(` ${import_picocolors69.default.cyan("skill info")} ${import_picocolors69.default.dim("<creator/slug>")} ${import_picocolors69.default.dim("show registry details for a skill")}`);
93137
- out.push(` ${import_picocolors69.default.cyan("skill publish")} ${import_picocolors69.default.dim("[dir]")} ${import_picocolors69.default.dim("publish a SKILL.md folder (defaults to .)")}`);
93455
+ out.push(` ${import_picocolors71.default.cyan("skill add")} ${import_picocolors71.default.dim("<source>")} ${import_picocolors71.default.dim("install a skill (github / git / brainbase)")}`);
93456
+ out.push(` ${import_picocolors71.default.cyan("skill list")} ${import_picocolors71.default.dim("show locally installed skills + their source")}`);
93457
+ out.push(` ${import_picocolors71.default.cyan("skill update")} ${import_picocolors71.default.dim("<slug>")} ${import_picocolors71.default.dim("re-fetch a skill from its recorded source")}`);
93458
+ out.push(` ${import_picocolors71.default.cyan("skill remove")} ${import_picocolors71.default.dim("<slug>")} ${import_picocolors71.default.dim("uninstall a skill")}`);
93459
+ out.push(` ${import_picocolors71.default.cyan("skill search")} ${import_picocolors71.default.dim("[query]")} ${import_picocolors71.default.dim("search the brainbase skill registry")}`);
93460
+ out.push(` ${import_picocolors71.default.cyan("skill info")} ${import_picocolors71.default.dim("<creator/slug>")} ${import_picocolors71.default.dim("show registry details for a skill")}`);
93461
+ out.push(` ${import_picocolors71.default.cyan("skill publish")} ${import_picocolors71.default.dim("[dir]")} ${import_picocolors71.default.dim("publish a SKILL.md folder (defaults to .)")}`);
93138
93462
  out.push("");
93139
93463
  out.push(divider("CLI TOKENS"));
93140
93464
  out.push("");
93141
- out.push(` ${import_picocolors69.default.cyan("token create")} ${import_picocolors69.default.dim("issue a long-lived CLI key for CI / scripts")}`);
93142
- out.push(` ${import_picocolors69.default.cyan("token list")} ${import_picocolors69.default.dim("show your tokens")}`);
93143
- out.push(` ${import_picocolors69.default.cyan("token rename")} ${import_picocolors69.default.dim("<id>")} ${import_picocolors69.default.dim("relabel a token")}`);
93144
- out.push(` ${import_picocolors69.default.cyan("token revoke")} ${import_picocolors69.default.dim("<id>")} ${import_picocolors69.default.dim("revoke a token")}`);
93465
+ out.push(` ${import_picocolors71.default.cyan("token create")} ${import_picocolors71.default.dim("issue a long-lived CLI key for CI / scripts")}`);
93466
+ out.push(` ${import_picocolors71.default.cyan("token list")} ${import_picocolors71.default.dim("show your tokens")}`);
93467
+ out.push(` ${import_picocolors71.default.cyan("token rename")} ${import_picocolors71.default.dim("<id>")} ${import_picocolors71.default.dim("relabel a token")}`);
93468
+ out.push(` ${import_picocolors71.default.cyan("token revoke")} ${import_picocolors71.default.dim("<id>")} ${import_picocolors71.default.dim("revoke a token")}`);
93145
93469
  out.push("");
93146
93470
  out.push(divider("MCP"));
93147
93471
  out.push("");
93148
- out.push(` ${import_picocolors69.default.cyan("mcp check")} ${import_picocolors69.default.dim("[--json]")} ${import_picocolors69.default.dim("verify MCP server connectivity through the brainbase proxy (runs at sandbox bootstrap)")}`);
93149
- out.push(` ${import_picocolors69.default.cyan("mcp list")} ${import_picocolors69.default.dim("[--json]")} ${import_picocolors69.default.dim("show configured servers with OAuth state and expiry")}`);
93150
- out.push(` ${import_picocolors69.default.cyan("mcp connect")} ${import_picocolors69.default.dim("<name>")} ${import_picocolors69.default.dim("authorize an OAuth-backed server: prints a single-use link, opens it, waits for approval")}`);
93472
+ out.push(` ${import_picocolors71.default.cyan("mcp check")} ${import_picocolors71.default.dim("[--json]")} ${import_picocolors71.default.dim("verify MCP server connectivity through the brainbase proxy (runs at sandbox bootstrap)")}`);
93473
+ out.push(` ${import_picocolors71.default.cyan("mcp list")} ${import_picocolors71.default.dim("[--json]")} ${import_picocolors71.default.dim("show configured servers with OAuth state and expiry")}`);
93474
+ out.push(` ${import_picocolors71.default.cyan("mcp connect")} ${import_picocolors71.default.dim("<name>")} ${import_picocolors71.default.dim("authorize an OAuth-backed server: prints a single-use link, opens it, waits for approval")}`);
93151
93475
  out.push("");
93152
93476
  out.push(divider("FLAGS"));
93153
93477
  out.push("");
93154
- out.push(` ${import_picocolors69.default.dim("--harness <id>")} force harness for onboard / sync (e.g. claude-code)`);
93155
- out.push(` ${import_picocolors69.default.dim("--scope <s>")} force scope: global | project`);
93156
- out.push(` ${import_picocolors69.default.dim("--yes, -y")} skip confirmations / auto-overwrite`);
93478
+ out.push(` ${import_picocolors71.default.dim("--harness <id>")} force harness for onboard / sync (e.g. claude-code)`);
93479
+ out.push(` ${import_picocolors71.default.dim("--scope <s>")} force scope: global | project`);
93480
+ out.push(` ${import_picocolors71.default.dim("--yes, -y")} skip confirmations / auto-overwrite`);
93157
93481
  out.push(` ${" ".repeat("--yes, -y".length)} required for destructive commands with no terminal (pipes, CI)`);
93158
- out.push(` ${import_picocolors69.default.dim("--agent <id>")} for link/task create: use this agent id explicitly (task list: filter to it)`);
93159
- out.push(` ${import_picocolors69.default.dim("--message <text>")} for task create: required first user message`);
93160
- out.push(` ${import_picocolors69.default.dim("--title <text>")} for task create: optional task title`);
93161
- out.push(` ${import_picocolors69.default.dim("--model <id>")} for task create: optional model override`);
93162
- out.push(` ${import_picocolors69.default.dim("--wait")} for task create: block until the task finishes; exit 1 unless it succeeded`);
93163
- out.push(` ${import_picocolors69.default.dim("--timeout <secs>")} for task create --wait: give up after <secs> and exit 1`);
93164
- out.push(` ${import_picocolors69.default.dim("--limit <n>")} for task list (1-200), task logs (events to print; with --follow, the first page size) and machine ls`);
93165
- out.push(` ${import_picocolors69.default.dim("--follow, -f")} for task logs: stay attached and print events as they land`);
93166
- out.push(` ${import_picocolors69.default.dim("--org <id-or-slug>")} pick the organization (team/agent list, agent create, orchestration create/list)`);
93167
- out.push(` ${import_picocolors69.default.dim("--team <id>")} pick the team, same commands (works without --org)`);
93168
- out.push(` ${import_picocolors69.default.dim("--json")} machine-readable output for supported commands`);
93169
- out.push(` ${import_picocolors69.default.dim("--no-tracking")} for link / agent pull --link: skip routing LLM traffic through brainbase`);
93170
- out.push(` ${import_picocolors69.default.dim("--link")} for agent pull: link this folder to the agent first, as \`brainbase link --agent <id> --yes\` would, in one process`);
93171
- out.push(` ${import_picocolors69.default.dim("--track")} for agent create: enable tracking non-interactively (off without a TTY)`);
93172
- out.push(` ${import_picocolors69.default.dim("--shell <sh|fish>")} for agent env: pick output format (auto-detected from $SHELL)`);
93173
- out.push(` ${import_picocolors69.default.dim("--bot-token <t>")} for agent connect slack (or BRAINBASE_SLACK_BOT_TOKEN, or stdin)`);
93174
- out.push(` ${import_picocolors69.default.dim("--signing-secret <s>")} for agent connect slack (or BRAINBASE_SLACK_SIGNING_SECRET, or stdin)`);
93175
- out.push(` ${import_picocolors69.default.dim("--bot-name <name>")} for agent connect meeting: the bot's display name`);
93176
- out.push(` ${import_picocolors69.default.dim("--full")} for agent init: write a commented template covering every block`);
93177
- out.push(` ${import_picocolors69.default.dim("--minimal")} for agent init: write the starter manifest (the default)`);
93178
- out.push(` ${import_picocolors69.default.dim("--all")} for template list: include installs from other folders; for machine ls: include torn-down machines`);
93179
- out.push(` ${import_picocolors69.default.dim("--web <url>")} for login: web app URL (default https://app.brainbaselabs.com)`);
93180
- out.push(` ${import_picocolors69.default.dim("--no-open")} for mcp connect: print the link without opening a browser (implied with no terminal)`);
93181
- out.push(` ${import_picocolors69.default.dim("--no-wait")} for mcp connect: print the link and exit instead of waiting for approval`);
93482
+ out.push(` ${import_picocolors71.default.dim("--agent <id>")} for link/task create: use this agent id explicitly (task list: filter to it)`);
93483
+ out.push(` ${import_picocolors71.default.dim("--message <text>")} for task create: required first user message`);
93484
+ out.push(` ${import_picocolors71.default.dim("--title <text>")} for task create: optional task title`);
93485
+ out.push(` ${import_picocolors71.default.dim("--model <id>")} for task create: optional model override`);
93486
+ out.push(` ${import_picocolors71.default.dim("--wait")} for task create: block until the task finishes; exit 1 unless it succeeded`);
93487
+ out.push(` ${import_picocolors71.default.dim("--timeout <secs>")} for task create --wait: give up after <secs> and exit 1`);
93488
+ out.push(` ${import_picocolors71.default.dim("--limit <n>")} for task list (1-200), task logs (events to print; with --follow, the first page size) and machine ls`);
93489
+ out.push(` ${import_picocolors71.default.dim("--follow, -f")} for task logs: stay attached and print events as they land`);
93490
+ out.push(` ${import_picocolors71.default.dim("--org <id-or-slug>")} pick the organization (team/agent list, agent create, orchestration create/list)`);
93491
+ out.push(` ${import_picocolors71.default.dim("--team <id>")} pick the team, same commands (works without --org)`);
93492
+ out.push(` ${import_picocolors71.default.dim("--json")} machine-readable output for supported commands`);
93493
+ out.push(` ${import_picocolors71.default.dim("--no-tracking")} for link / agent pull --link: skip routing LLM traffic through brainbase`);
93494
+ out.push(` ${import_picocolors71.default.dim("--link")} for agent pull: link this folder to the agent first, as \`brainbase link --agent <id> --yes\` would, in one process`);
93495
+ out.push(` ${import_picocolors71.default.dim("--track")} for agent create: enable tracking non-interactively (off without a TTY)`);
93496
+ out.push(` ${import_picocolors71.default.dim("--shell <sh|fish>")} for agent env: pick output format (auto-detected from $SHELL)`);
93497
+ out.push(` ${import_picocolors71.default.dim("--bot-token <t>")} for agent connect slack (or BRAINBASE_SLACK_BOT_TOKEN, or stdin)`);
93498
+ out.push(` ${import_picocolors71.default.dim("--signing-secret <s>")} for agent connect slack (or BRAINBASE_SLACK_SIGNING_SECRET, or stdin)`);
93499
+ out.push(` ${import_picocolors71.default.dim("--bot-name <name>")} for agent connect meeting: the bot's display name`);
93500
+ out.push(` ${import_picocolors71.default.dim("--full")} for agent init: write a commented template covering every block`);
93501
+ out.push(` ${import_picocolors71.default.dim("--minimal")} for agent init: write the starter manifest (the default)`);
93502
+ out.push(` ${import_picocolors71.default.dim("--all")} for template list: include installs from other folders; for machine ls: include torn-down machines`);
93503
+ out.push(` ${import_picocolors71.default.dim("--web <url>")} for login: web app URL (default https://app.brainbaselabs.com)`);
93504
+ out.push(` ${import_picocolors71.default.dim("--no-open")} for mcp connect: print the link without opening a browser (implied with no terminal)`);
93505
+ out.push(` ${import_picocolors71.default.dim("--no-wait")} for mcp connect: print the link and exit instead of waiting for approval`);
93182
93506
  out.push("");
93183
93507
  out.push(divider("ENV"));
93184
93508
  out.push("");
93185
- out.push(` ${import_picocolors69.default.dim("BRAINBASE_HOME")} override the local config dir (default ~/.brainbase)`);
93186
- out.push(` ${import_picocolors69.default.dim("BRAINBASE_DEBUG")} print full stack traces on error (any value; unset to disable)`);
93187
- out.push(` ${import_picocolors69.default.dim("BRAINBASE_WEB_URL")} override the web app URL used by login`);
93188
- out.push(` ${import_picocolors69.default.dim("BRAINBASE_CONTROL_PLANE_URL")} override the MAS host (/v2/cli; task and interface commands use /v2/tasks and /v2/interfaces)`);
93189
- out.push(` ${import_picocolors69.default.dim("BRAINBASE_API_URL")} legacy KLS host override (uses /api/cli; proxy/registry fallback)`);
93190
- out.push(` ${import_picocolors69.default.dim("BRAINBASE_PROXY_URL")} override the model-proxy URL used by harness traffic (default https://api.v1.brainbaselabs.com)`);
93191
- out.push(` ${import_picocolors69.default.dim("BRAINBASE_REGISTRY_URL")} override the registry API URL (default https://api.v1.brainbaselabs.com)`);
93192
- out.push(` ${import_picocolors69.default.dim("BRAINBASE_TOKEN")} long-lived CLI PAT; the only PAT control-plane commands accept (token.json is not read there)`);
93193
- out.push(` ${import_picocolors69.default.dim("BRAINBASE_SKIP_AUTH")} bypass the auth gate for development`);
93194
- out.push(` ${import_picocolors69.default.dim("BRAINBASE_NON_INTERACTIVE")} force non-interactive mode — skip/auto-default prompts (CI & agents)`);
93195
- out.push(` ${import_picocolors69.default.dim("BRAINBASE_RUN_ENTRYPOINT")} =1 → agent pull executes the agent entrypoint (sandbox boots; or pass --run-entrypoint)`);
93509
+ out.push(` ${import_picocolors71.default.dim("BRAINBASE_HOME")} override the local config dir (default ~/.brainbase)`);
93510
+ out.push(` ${import_picocolors71.default.dim("BRAINBASE_DEBUG")} print full stack traces on error (any value; unset to disable)`);
93511
+ out.push(` ${import_picocolors71.default.dim("BRAINBASE_WEB_URL")} override the web app URL used by login`);
93512
+ out.push(` ${import_picocolors71.default.dim("BRAINBASE_CONTROL_PLANE_URL")} override the MAS host (/v2/cli; task and interface commands use /v2/tasks and /v2/interfaces)`);
93513
+ out.push(` ${import_picocolors71.default.dim("BRAINBASE_API_URL")} legacy KLS host override (uses /api/cli; proxy/registry fallback)`);
93514
+ out.push(` ${import_picocolors71.default.dim("BRAINBASE_PROXY_URL")} override the model-proxy URL used by harness traffic (default https://api.v1.brainbaselabs.com)`);
93515
+ out.push(` ${import_picocolors71.default.dim("BRAINBASE_REGISTRY_URL")} override the registry API URL (default https://api.v1.brainbaselabs.com)`);
93516
+ out.push(` ${import_picocolors71.default.dim("BRAINBASE_TOKEN")} long-lived CLI PAT; the only PAT control-plane commands accept (token.json is not read there)`);
93517
+ out.push(` ${import_picocolors71.default.dim("BRAINBASE_SKIP_AUTH")} bypass the auth gate for development`);
93518
+ out.push(` ${import_picocolors71.default.dim("BRAINBASE_NON_INTERACTIVE")} force non-interactive mode — skip/auto-default prompts (CI & agents)`);
93519
+ out.push(` ${import_picocolors71.default.dim("BRAINBASE_RUN_ENTRYPOINT")} =1 → agent pull executes the agent entrypoint (sandbox boots; or pass --run-entrypoint)`);
93196
93520
  out.push("");
93197
- out.push(` ${import_picocolors69.default.dim("BRAINBASE_MEMORY_MCP_URL")} override the built-in memory MCP host`);
93198
- out.push(` ${import_picocolors69.default.dim("BRAINBASE_BROWSER_MCP_URL")} override the built-in browser MCP host`);
93199
- out.push(` ${import_picocolors69.default.dim("BRAINBASE_SLACK_MCP_URL")} override the built-in Slack MCP host`);
93200
- out.push(` ${import_picocolors69.default.dim("BRAINBASE_MEETING_MCP_URL")} override the built-in meeting MCP host`);
93201
- out.push(` ${import_picocolors69.default.dim("BRAINBASE_GITHUB_MCP_URL")} override the built-in GitHub MCP host`);
93202
- out.push(` ${import_picocolors69.default.dim("BRAINBASE_LINEAR_MCP_URL")} override the built-in Linear MCP host`);
93203
- out.push(` ${import_picocolors69.default.dim("BRAINBASE_ORCHESTRATION_MCP_URL")} override the built-in orchestration MCP host`);
93521
+ out.push(` ${import_picocolors71.default.dim("BRAINBASE_MEMORY_MCP_URL")} override the built-in memory MCP host`);
93522
+ out.push(` ${import_picocolors71.default.dim("BRAINBASE_BROWSER_MCP_URL")} override the built-in browser MCP host`);
93523
+ out.push(` ${import_picocolors71.default.dim("BRAINBASE_SLACK_MCP_URL")} override the built-in Slack MCP host`);
93524
+ out.push(` ${import_picocolors71.default.dim("BRAINBASE_MEETING_MCP_URL")} override the built-in meeting MCP host`);
93525
+ out.push(` ${import_picocolors71.default.dim("BRAINBASE_GITHUB_MCP_URL")} override the built-in GitHub MCP host`);
93526
+ out.push(` ${import_picocolors71.default.dim("BRAINBASE_LINEAR_MCP_URL")} override the built-in Linear MCP host`);
93527
+ out.push(` ${import_picocolors71.default.dim("BRAINBASE_ORCHESTRATION_MCP_URL")} override the built-in orchestration MCP host`);
93204
93528
  out.push("");
93205
93529
  out.push(divider("HARNESSES"));
93206
93530
  out.push("");
93207
- out.push(` ${import_picocolors69.default.dim("•")} ${import_picocolors69.default.bold("claude-code")} ${import_picocolors69.default.dim("skills, mcps, agents, commands, playbooks, instructions, files")}`);
93208
- out.push(` ${import_picocolors69.default.dim("•")} ${import_picocolors69.default.bold("codex")} ${import_picocolors69.default.dim("skills, mcps, commands, playbooks, instructions, files")}`);
93209
- out.push(` ${import_picocolors69.default.dim("•")} ${import_picocolors69.default.bold("kafka")} ${import_picocolors69.default.dim("skills, mcps, agents, commands, playbooks, instructions, files")}`);
93531
+ out.push(` ${import_picocolors71.default.dim("•")} ${import_picocolors71.default.bold("claude-code")} ${import_picocolors71.default.dim("skills, mcps, agents, commands, playbooks, instructions, files")}`);
93532
+ out.push(` ${import_picocolors71.default.dim("•")} ${import_picocolors71.default.bold("codex")} ${import_picocolors71.default.dim("skills, mcps, commands, playbooks, instructions, files")}`);
93533
+ out.push(` ${import_picocolors71.default.dim("•")} ${import_picocolors71.default.bold("kafka")} ${import_picocolors71.default.dim("skills, mcps, agents, commands, playbooks, instructions, files")}`);
93210
93534
  out.push("");
93211
93535
  console.log(out.join(`
93212
93536
  `));
@@ -93360,13 +93684,13 @@ async function requireAuth(cmd) {
93360
93684
  if (STORED_PAT_COMMANDS.has(cmd) && readToken())
93361
93685
  return;
93362
93686
  console.error("");
93363
- console.error(` ${brandTint("◆")} ${import_picocolors69.default.bold("brainbase")}`);
93687
+ console.error(` ${brandTint("◆")} ${import_picocolors71.default.bold("brainbase")}`);
93364
93688
  console.error("");
93365
- console.error(` ${import_picocolors69.default.red("✗")} You need to sign in to use ${import_picocolors69.default.bold("brainbase " + cmd)}.`);
93689
+ console.error(` ${import_picocolors71.default.red("✗")} You need to sign in to use ${import_picocolors71.default.bold("brainbase " + cmd)}.`);
93366
93690
  if (status.reason)
93367
- console.error(` ${import_picocolors69.default.dim(status.reason)}`);
93691
+ console.error(` ${import_picocolors71.default.dim(status.reason)}`);
93368
93692
  console.error("");
93369
- console.error(` Run ${import_picocolors69.default.cyan("brainbase login")} to connect this device.`);
93693
+ console.error(` Run ${import_picocolors71.default.cyan("brainbase login")} to connect this device.`);
93370
93694
  console.error("");
93371
93695
  process14.exit(1);
93372
93696
  }
@@ -93547,6 +93871,12 @@ async function main() {
93547
93871
  await runTeam(sub, argv, { orgId: orgIdFlag, json: jsonFlag });
93548
93872
  break;
93549
93873
  }
93874
+ case "member":
93875
+ case "members": {
93876
+ const sub = argv.shift();
93877
+ await runMember(sub, argv, { orgId: orgIdFlag, json: jsonFlag });
93878
+ break;
93879
+ }
93550
93880
  case "task": {
93551
93881
  const sub = argv.shift();
93552
93882
  await runTask(cwd2, sub, argv);
@@ -93619,10 +93949,10 @@ async function main() {
93619
93949
  process14.exit(1);
93620
93950
  }
93621
93951
  } catch (err) {
93622
- console.error(import_picocolors69.default.red(`
93952
+ console.error(import_picocolors71.default.red(`
93623
93953
  ${err.message}`));
93624
93954
  if (err instanceof ApiError && err.status === 401) {
93625
- console.error(` Run ${import_picocolors69.default.cyan("brainbase login")} to connect this device.`);
93955
+ console.error(` Run ${import_picocolors71.default.cyan("brainbase login")} to connect this device.`);
93626
93956
  }
93627
93957
  if (process14.env.BRAINBASE_DEBUG)
93628
93958
  console.error(err.stack);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brainbase-labs/cli",
3
- "version": "0.42.0",
3
+ "version": "0.43.0",
4
4
  "description": "Pack, share, and install agent templates across harnesses (Claude Code, Codex, ...).",
5
5
  "type": "module",
6
6
  "bin": {