@brainbase-labs/cli 0.21.1 → 0.22.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 +1152 -392
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -35128,12 +35128,12 @@ var require_dist2 = __commonJS((exports, module) => {
35128
35128
  throw new Error(`Unknown format "${name}"`);
35129
35129
  return f4;
35130
35130
  };
35131
- function addFormats(ajv, list, fs80, exportName) {
35131
+ function addFormats(ajv, list, fs81, exportName) {
35132
35132
  var _a;
35133
35133
  var _b;
35134
35134
  (_a = (_b = ajv.opts.code).formats) !== null && _a !== undefined || (_b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`);
35135
35135
  for (const f4 of list)
35136
- ajv.addFormat(f4, fs80[f4]);
35136
+ ajv.addFormat(f4, fs81[f4]);
35137
35137
  }
35138
35138
  module.exports = exports = formatsPlugin;
35139
35139
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -35141,9 +35141,9 @@ var require_dist2 = __commonJS((exports, module) => {
35141
35141
  });
35142
35142
 
35143
35143
  // src/index.ts
35144
- var import_picocolors49 = __toESM(require_picocolors(), 1);
35144
+ var import_picocolors52 = __toESM(require_picocolors(), 1);
35145
35145
  import process14 from "node:process";
35146
- import fs82 from "node:fs";
35146
+ import fs83 from "node:fs";
35147
35147
 
35148
35148
  // src/cli/template.ts
35149
35149
  var import_picocolors12 = __toESM(require_picocolors(), 1);
@@ -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.21.1",
36011
+ version: "0.22.0",
36012
36012
  description: "Pack, share, and install agent templates across harnesses (Claude Code, Codex, ...).",
36013
36013
  type: "module",
36014
36014
  bin: {
@@ -53969,6 +53969,7 @@ class NetworkApiError extends ApiError {
53969
53969
 
53970
53970
  class TaskRecoveryDeadlineError extends ApiError {
53971
53971
  }
53972
+ var GET_NETWORK_RETRY_DELAYS_MS = [100, 250];
53972
53973
  function normalizeControlPlaneUrl(url) {
53973
53974
  const normalized = url?.trim().replace(/\/+$/, "");
53974
53975
  return normalized || DEFAULT_CONTROL_PLANE_BASE;
@@ -54101,9 +54102,33 @@ async function sendWithAuthRetry(session, send) {
54101
54102
  }
54102
54103
  async function request(pathname, init = {}) {
54103
54104
  const credential = await resolveCredential();
54104
- const retrySession = credential.source === "session" && !new Headers(init.headers).has("Authorization") ? credential.session : null;
54105
- const res = await sendWithAuthRetry(retrySession, (refreshed) => sendRequest(`${apiBase(refreshed ?? credential.session)}${pathname}`, init, refreshed?.access_token ?? credential.bearer));
54106
- const text2 = await res.text();
54105
+ let currentSession = credential.session;
54106
+ let refreshSessionAvailable = credential.source === "session" && !new Headers(init.headers).has("Authorization");
54107
+ const method2 = (init.method ?? "GET").toUpperCase();
54108
+ let res;
54109
+ let text2;
54110
+ for (let attempt2 = 0;; attempt2 += 1) {
54111
+ try {
54112
+ res = await sendWithAuthRetry(refreshSessionAvailable ? currentSession : null, async (refreshed) => {
54113
+ if (refreshed) {
54114
+ currentSession = refreshed;
54115
+ refreshSessionAvailable = false;
54116
+ }
54117
+ return await sendRequest(`${apiBase(currentSession)}${pathname}`, init, currentSession?.access_token ?? credential.bearer);
54118
+ });
54119
+ try {
54120
+ text2 = await res.text();
54121
+ } catch (error) {
54122
+ throw new NetworkApiError(`Network error while reading response: ${error.message}`, false);
54123
+ }
54124
+ break;
54125
+ } catch (error) {
54126
+ if (method2 !== "GET" || !(error instanceof NetworkApiError) || attempt2 >= GET_NETWORK_RETRY_DELAYS_MS.length) {
54127
+ throw error;
54128
+ }
54129
+ await new Promise((resolve) => setTimeout(resolve, GET_NETWORK_RETRY_DELAYS_MS[attempt2]));
54130
+ }
54131
+ }
54107
54132
  let body = text2;
54108
54133
  try {
54109
54134
  body = text2 ? JSON.parse(text2) : null;
@@ -54267,6 +54292,19 @@ var masApi = {
54267
54292
  return parseMasTaskCreateResponse(body);
54268
54293
  }
54269
54294
  };
54295
+ function isUnroutedPath(body) {
54296
+ return !!body && typeof body === "object" && body.detail === "Not Found";
54297
+ }
54298
+ async function connectionsRequest(pathname, init) {
54299
+ try {
54300
+ return await request(pathname, init);
54301
+ } catch (err) {
54302
+ if (err instanceof ApiError && err.status === 404 && isUnroutedPath(err.body)) {
54303
+ throw new ApiError("This control plane does not support reading or changing connections yet. Update the server, or use the web app.", 404, err.body);
54304
+ }
54305
+ throw err;
54306
+ }
54307
+ }
54270
54308
  var api = {
54271
54309
  listOrgs() {
54272
54310
  return request("/orgs");
@@ -54354,6 +54392,21 @@ var api = {
54354
54392
  method: "DELETE"
54355
54393
  });
54356
54394
  },
54395
+ getAgentConnections(agentId) {
54396
+ return connectionsRequest(`/agents/${encodeURIComponent(agentId)}/connections`);
54397
+ },
54398
+ connectSlack(agentId, input) {
54399
+ return connectionsRequest(`/agents/${encodeURIComponent(agentId)}/connections/slack`, { method: "PUT", body: JSON.stringify(input) });
54400
+ },
54401
+ connectMeeting(agentId, input) {
54402
+ return connectionsRequest(`/agents/${encodeURIComponent(agentId)}/connections/meeting`, { method: "PUT", body: JSON.stringify(input) });
54403
+ },
54404
+ disconnectIntegration(agentId, integration) {
54405
+ return connectionsRequest(`/agents/${encodeURIComponent(agentId)}/connections/${encodeURIComponent(integration)}`, { method: "DELETE" });
54406
+ },
54407
+ listAgentMcpServers(agentId) {
54408
+ return connectionsRequest(`/agents/${encodeURIComponent(agentId)}/mcp-servers`);
54409
+ },
54357
54410
  listOrchestrations(orgId, teamId) {
54358
54411
  return request(`/orgs/${encodeURIComponent(orgId)}/teams/${encodeURIComponent(teamId)}/orchestrations`);
54359
54412
  },
@@ -63283,7 +63336,7 @@ function runHarnessInstall(harnessId, components, opts, agentName) {
63283
63336
  }
63284
63337
 
63285
63338
  // src/cli/agent.ts
63286
- var import_picocolors34 = __toESM(require_picocolors(), 1);
63339
+ var import_picocolors37 = __toESM(require_picocolors(), 1);
63287
63340
 
63288
63341
  // src/cli/agent-pull.ts
63289
63342
  import { spawn as spawn2 } from "node:child_process";
@@ -66396,6 +66449,396 @@ function formatAgentList(agents, labels) {
66396
66449
  `);
66397
66450
  }
66398
66451
 
66452
+ // src/cli/agent-connections.ts
66453
+ var import_picocolors35 = __toESM(require_picocolors(), 1);
66454
+
66455
+ // src/core/integrations.ts
66456
+ var IMPLEMENTED_INTEGRATIONS = ["slack", "meeting"];
66457
+ function isImplemented(name) {
66458
+ return IMPLEMENTED_INTEGRATIONS.includes(name);
66459
+ }
66460
+ function actionability(state) {
66461
+ if (!state.manageable_from_cli) {
66462
+ return { kind: "web-only", ...state.unmanageable_reason ? { reason: state.unmanageable_reason } : {} };
66463
+ }
66464
+ return isImplemented(state.name) ? { kind: "connectable" } : { kind: "needs-newer-cli" };
66465
+ }
66466
+ var GENERIC_WEB_ONLY_REASON = "This integration cannot be connected from the terminal. Use the web app.";
66467
+ var UPGRADE_HINT = "This control plane supports connecting it, but this version of the CLI does not. Upgrade the CLI.";
66468
+ function explain(state) {
66469
+ const action = actionability(state);
66470
+ switch (action.kind) {
66471
+ case "connectable":
66472
+ return `brainbase agent connect ${state.name}`;
66473
+ case "needs-newer-cli":
66474
+ return UPGRADE_HINT;
66475
+ case "web-only":
66476
+ return action.reason ?? GENERIC_WEB_ONLY_REASON;
66477
+ default: {
66478
+ const exhaustive = action;
66479
+ return exhaustive;
66480
+ }
66481
+ }
66482
+ }
66483
+
66484
+ // src/cli/agent-connect.ts
66485
+ var import_picocolors34 = __toESM(require_picocolors(), 1);
66486
+
66487
+ // src/core/secret-input.ts
66488
+ import fs74 from "node:fs";
66489
+ function clean(value) {
66490
+ if (typeof value !== "string")
66491
+ return;
66492
+ const trimmed = value.trim();
66493
+ return trimmed ? trimmed : undefined;
66494
+ }
66495
+ var STDIN_IDLE_TIMEOUT_MS = 5000;
66496
+ var STDIN_TIMEOUT_MIN_MS = 100;
66497
+ var STDIN_TIMEOUT_MAX_MS = 600000;
66498
+ function stdinTimeoutMs(env3) {
66499
+ const raw = Number(env3.BRAINBASE_STDIN_TIMEOUT_MS);
66500
+ if (!Number.isFinite(raw) || raw <= 0)
66501
+ return STDIN_IDLE_TIMEOUT_MS;
66502
+ return Math.min(Math.max(raw, STDIN_TIMEOUT_MIN_MS), STDIN_TIMEOUT_MAX_MS);
66503
+ }
66504
+
66505
+ class StdinTimeoutError extends Error {
66506
+ constructor(idleTimeoutMs, bytesRead) {
66507
+ super(`stdin went quiet for ${idleTimeoutMs}ms after ${bytesRead} byte(s), before it was closed. ` + "Refusing to use a partial value. If the source is slow, raise " + "BRAINBASE_STDIN_TIMEOUT_MS; if it will not close its end of the pipe, " + "pass the value with a flag or an environment variable instead.");
66508
+ this.name = "StdinTimeoutError";
66509
+ }
66510
+ }
66511
+ function readPipeUntilEof(stream, idleTimeoutMs) {
66512
+ return new Promise((resolve, reject2) => {
66513
+ const chunks = [];
66514
+ let received = 0;
66515
+ let timer;
66516
+ const stopTimer = () => {
66517
+ if (timer !== undefined) {
66518
+ clearTimeout(timer);
66519
+ timer = undefined;
66520
+ }
66521
+ };
66522
+ const restartTimer = () => {
66523
+ stopTimer();
66524
+ timer = setTimeout(onIdle, idleTimeoutMs);
66525
+ };
66526
+ const detach = () => {
66527
+ stopTimer();
66528
+ stream.removeListener("data", onData);
66529
+ stream.removeListener("end", onEnd);
66530
+ stream.removeListener("error", onError);
66531
+ stream.pause();
66532
+ stream.unref?.();
66533
+ };
66534
+ function onIdle() {
66535
+ if (received > 0) {
66536
+ detach();
66537
+ reject2(new StdinTimeoutError(idleTimeoutMs, received));
66538
+ return;
66539
+ }
66540
+ detach();
66541
+ resolve("");
66542
+ }
66543
+ function onData(chunk2) {
66544
+ const buf = Buffer.from(chunk2);
66545
+ received += buf.length;
66546
+ chunks.push(buf);
66547
+ restartTimer();
66548
+ }
66549
+ function onEnd() {
66550
+ detach();
66551
+ resolve(Buffer.concat(chunks).toString("utf8"));
66552
+ }
66553
+ function onError(err) {
66554
+ detach();
66555
+ reject2(err);
66556
+ }
66557
+ stream.on("data", onData);
66558
+ stream.on("end", onEnd);
66559
+ stream.on("error", onError);
66560
+ restartTimer();
66561
+ });
66562
+ }
66563
+ async function defaultReadStdin(env3 = process.env) {
66564
+ if (process.stdin.isTTY)
66565
+ return null;
66566
+ let isRegularFile = false;
66567
+ try {
66568
+ isRegularFile = fs74.fstatSync(0).isFile();
66569
+ } catch {
66570
+ return "";
66571
+ }
66572
+ if (isRegularFile) {
66573
+ try {
66574
+ return fs74.readFileSync(0, "utf8");
66575
+ } catch {
66576
+ return "";
66577
+ }
66578
+ }
66579
+ try {
66580
+ return await readPipeUntilEof(process.stdin, stdinTimeoutMs(env3));
66581
+ } catch (err) {
66582
+ if (err instanceof StdinTimeoutError)
66583
+ throw err;
66584
+ return "";
66585
+ }
66586
+ }
66587
+ async function defaultPrompt(field) {
66588
+ const answer = await re({
66589
+ message: field.label,
66590
+ validate: (v3) => v3 && v3.trim() ? undefined : "Required"
66591
+ });
66592
+ return String(ensureNotCancelled(answer)).trim();
66593
+ }
66594
+ function parseStdinSecrets(raw, missing) {
66595
+ const body = raw.trim();
66596
+ if (!body)
66597
+ return {};
66598
+ if (body.startsWith("{")) {
66599
+ let source;
66600
+ try {
66601
+ source = JSON.parse(body);
66602
+ } catch {
66603
+ throw new Error('stdin looked like JSON but could not be parsed. Pass an object such as {"bot_token":"…","signing_secret":"…"}.');
66604
+ }
66605
+ const out = {};
66606
+ for (const field of missing) {
66607
+ const value = clean(source[field.key]);
66608
+ if (value)
66609
+ out[field.key] = value;
66610
+ }
66611
+ return out;
66612
+ }
66613
+ if (missing.length === 1) {
66614
+ return { [missing[0].key]: body };
66615
+ }
66616
+ throw new Error(`stdin supplies one value, but ${missing.length} are still missing (${missing.map((f4) => f4.key).join(", ")}). Pipe a JSON object instead, or pass the rest as flags.`);
66617
+ }
66618
+ async function resolveSecrets(fields, deps = {}) {
66619
+ const env3 = deps.env ?? process.env;
66620
+ const readStdin = deps.readStdin ?? (() => defaultReadStdin(env3));
66621
+ const prompt = deps.prompt ?? defaultPrompt;
66622
+ const interactive = deps.interactive ?? isInteractive;
66623
+ const resolved = {};
66624
+ for (const field of fields) {
66625
+ const value = clean(field.value) ?? clean(env3[field.envVar]);
66626
+ if (value)
66627
+ resolved[field.key] = value;
66628
+ }
66629
+ let missing = fields.filter((f4) => !resolved[f4.key]);
66630
+ if (missing.length > 0) {
66631
+ const raw = await readStdin();
66632
+ if (raw !== null) {
66633
+ Object.assign(resolved, parseStdinSecrets(raw, missing));
66634
+ missing = fields.filter((f4) => !resolved[f4.key]);
66635
+ }
66636
+ }
66637
+ for (const field of missing) {
66638
+ if (!interactive()) {
66639
+ throw new NonInteractiveError(`${field.label} is required. Pass ${field.flag}, set ${field.envVar}, or pipe it on stdin.`);
66640
+ }
66641
+ resolved[field.key] = await prompt(field);
66642
+ }
66643
+ return resolved;
66644
+ }
66645
+
66646
+ // src/cli/agent-connect.ts
66647
+ async function runAgentConnect(cwd2, target, args, deps = {}) {
66648
+ const json = Boolean(args.json);
66649
+ try {
66650
+ report(await connect(cwd2, target, args, deps, json), json);
66651
+ } catch (err) {
66652
+ if (!json)
66653
+ throw err;
66654
+ reportFailure(err);
66655
+ }
66656
+ }
66657
+ async function connect(cwd2, target, args, deps, json) {
66658
+ if (!target) {
66659
+ throw new Error(`Which integration? Try: ${IMPLEMENTED_INTEGRATIONS.join(", ")}.`);
66660
+ }
66661
+ if (!json)
66662
+ banner(`agent connect ${target}`);
66663
+ const link2 = readLink(cwd2);
66664
+ if (!link2) {
66665
+ throw new Error("This folder is not linked to any agent. Run `brainbase link` first.");
66666
+ }
66667
+ await assertConnectable(link2.agent_id, target, deps);
66668
+ return target === "slack" ? connectSlack(link2.agent_id, args, deps, json) : connectMeeting(link2.agent_id, args, deps, json);
66669
+ }
66670
+ async function assertConnectable(agentId, target, deps) {
66671
+ const fetchConnections = deps.fetchConnections ?? ((id) => api.getAgentConnections(id));
66672
+ const { integrations } = await fetchConnections(agentId);
66673
+ const state = integrations.find((i) => i.name === target);
66674
+ if (!state) {
66675
+ const known = integrations.map((i) => i.name).join(", ");
66676
+ throw new Error(`Unknown integration ${JSON.stringify(target)}. This agent has: ${known}.`);
66677
+ }
66678
+ const action = actionability(state);
66679
+ if (action.kind === "connectable")
66680
+ return;
66681
+ throw new Error(explain(state));
66682
+ }
66683
+ async function connectSlack(agentId, args, deps, json) {
66684
+ const secrets = await resolveSecrets([
66685
+ {
66686
+ key: "bot_token",
66687
+ flag: "--bot-token",
66688
+ envVar: "BRAINBASE_SLACK_BOT_TOKEN",
66689
+ label: "Slack bot token (xoxb-…)",
66690
+ value: args.botToken
66691
+ },
66692
+ {
66693
+ key: "signing_secret",
66694
+ flag: "--signing-secret",
66695
+ envVar: "BRAINBASE_SLACK_SIGNING_SECRET",
66696
+ label: "Slack signing secret",
66697
+ value: args.signingSecret
66698
+ }
66699
+ ], { ...deps.secrets, ...json ? { interactive: () => false } : {} });
66700
+ return api.connectSlack(agentId, {
66701
+ bot_token: secrets.bot_token,
66702
+ signing_secret: secrets.signing_secret,
66703
+ ...args.appId ? { app_id: args.appId } : {},
66704
+ ...args.appName ? { app_name: args.appName } : {}
66705
+ });
66706
+ }
66707
+ async function connectMeeting(agentId, args, deps, json) {
66708
+ const ask = deps.askBotName ?? (() => text({
66709
+ message: "Name for the meeting bot",
66710
+ placeholder: "Notetaker",
66711
+ flagHint: "Pass --bot-name <name>."
66712
+ }));
66713
+ let botName = args.botName?.trim();
66714
+ if (!botName) {
66715
+ if (json) {
66716
+ throw new Error("A meeting bot name is required. Pass --bot-name <name>.");
66717
+ }
66718
+ botName = (await ask()).trim();
66719
+ }
66720
+ if (!botName)
66721
+ throw new Error("A meeting bot name is required. Pass --bot-name <name>.");
66722
+ return api.connectMeeting(agentId, {
66723
+ bot_name: botName,
66724
+ ...args.botImageUrl ? { bot_image_url: args.botImageUrl } : {}
66725
+ });
66726
+ }
66727
+ function reportFailure(err) {
66728
+ console.log(JSON.stringify({ error: err.message }, null, 2));
66729
+ process.exitCode = 1;
66730
+ }
66731
+ function report(result2, json) {
66732
+ if (json) {
66733
+ console.log(JSON.stringify(result2, null, 2));
66734
+ return;
66735
+ }
66736
+ const detail = result2.detail ? ` ${import_picocolors34.default.dim(`(${result2.detail})`)}` : "";
66737
+ f2.success(`${result2.name} connected${detail}`);
66738
+ f2.info(`Run ${import_picocolors34.default.cyan("brainbase agent pull")} to pick up the built-in ${result2.name} MCP server.`);
66739
+ }
66740
+
66741
+ // src/cli/agent-connections.ts
66742
+ async function runAgentConnections(cwd2, args) {
66743
+ const json = Boolean(args.json);
66744
+ if (!json)
66745
+ banner("agent connections — what this agent is wired to");
66746
+ const link2 = readLink(cwd2);
66747
+ if (!link2) {
66748
+ if (json) {
66749
+ console.log(JSON.stringify({ linked: false, integrations: [] }, null, 2));
66750
+ process.exitCode = 1;
66751
+ return;
66752
+ }
66753
+ f2.warn("This folder is not linked to any agent.");
66754
+ f2.info(`Run ${import_picocolors35.default.cyan("brainbase link")} first.`);
66755
+ process.exitCode = 1;
66756
+ return;
66757
+ }
66758
+ let connections;
66759
+ try {
66760
+ connections = await api.getAgentConnections(link2.agent_id);
66761
+ } catch (err) {
66762
+ if (!json)
66763
+ throw err;
66764
+ reportFailure(err);
66765
+ return;
66766
+ }
66767
+ if (json) {
66768
+ console.log(JSON.stringify({ linked: true, ...connections }, null, 2));
66769
+ return;
66770
+ }
66771
+ console.log(formatConnections(connections));
66772
+ }
66773
+ function formatConnections(connections) {
66774
+ const lines = [""];
66775
+ for (const integration of connections.integrations) {
66776
+ lines.push(` ${statusMark(integration)} ${import_picocolors35.default.bold(integration.name)}${describe(integration)}`);
66777
+ const hint = hintFor(integration);
66778
+ if (hint)
66779
+ lines.push(` ${import_picocolors35.default.dim(hint)}`);
66780
+ }
66781
+ lines.push("");
66782
+ return lines.join(`
66783
+ `);
66784
+ }
66785
+ function statusMark(integration) {
66786
+ return integration.connected ? import_picocolors35.default.green("✓") : import_picocolors35.default.dim("·");
66787
+ }
66788
+ function describe(integration) {
66789
+ if (!integration.connected)
66790
+ return ` ${import_picocolors35.default.dim("not connected")}`;
66791
+ return integration.detail ? ` ${import_picocolors35.default.dim(integration.detail)}` : ` ${import_picocolors35.default.dim("connected")}`;
66792
+ }
66793
+ function hintFor(integration) {
66794
+ const action = actionability(integration);
66795
+ if (integration.connected) {
66796
+ return action.kind === "connectable" ? `brainbase agent disconnect ${integration.name}` : undefined;
66797
+ }
66798
+ return explain(integration);
66799
+ }
66800
+
66801
+ // src/cli/agent-disconnect.ts
66802
+ var import_picocolors36 = __toESM(require_picocolors(), 1);
66803
+ async function runAgentDisconnect(cwd2, target, args) {
66804
+ const json = Boolean(args.json);
66805
+ try {
66806
+ await disconnect(cwd2, target, args, json);
66807
+ } catch (err) {
66808
+ if (!json)
66809
+ throw err;
66810
+ reportFailure(err);
66811
+ }
66812
+ }
66813
+ async function disconnect(cwd2, target, args, json) {
66814
+ if (!target) {
66815
+ throw new Error(`Which integration? Try: ${IMPLEMENTED_INTEGRATIONS.join(", ")}.`);
66816
+ }
66817
+ if (!isImplemented(target)) {
66818
+ throw new Error(`Cannot disconnect ${JSON.stringify(target)} from the CLI. Try: ${IMPLEMENTED_INTEGRATIONS.join(", ")}.`);
66819
+ }
66820
+ if (!json)
66821
+ banner(`agent disconnect ${target}`);
66822
+ const link2 = readLink(cwd2);
66823
+ if (!link2) {
66824
+ throw new Error("This folder is not linked to any agent. Run `brainbase link` first.");
66825
+ }
66826
+ if (!json && !autoProceed(args.yes)) {
66827
+ const ok = ensureNotCancelled(await se({ message: `Disconnect ${target} from ${link2.name}?` }));
66828
+ if (!ok) {
66829
+ f2.info("Nothing changed.");
66830
+ return;
66831
+ }
66832
+ }
66833
+ const result2 = await api.disconnectIntegration(link2.agent_id, target);
66834
+ if (json) {
66835
+ console.log(JSON.stringify(result2, null, 2));
66836
+ return;
66837
+ }
66838
+ f2.success(`${target} disconnected`);
66839
+ f2.info(`Run ${import_picocolors36.default.cyan("brainbase agent pull")} to drop the built-in ${target} MCP server locally.`);
66840
+ }
66841
+
66399
66842
  // src/cli/agent.ts
66400
66843
  async function runAgent(cwd2, sub, args, opts) {
66401
66844
  if (args.some((arg) => arg === "--help" || arg === "-h")) {
@@ -66446,6 +66889,23 @@ async function runAgent(cwd2, sub, args, opts) {
66446
66889
  case "status":
66447
66890
  await runAgentStatus(cwd2, { json: opts.json });
66448
66891
  return;
66892
+ case "connections":
66893
+ await runAgentConnections(cwd2, { json: opts.json });
66894
+ return;
66895
+ case "connect":
66896
+ await runAgentConnect(cwd2, args[0], {
66897
+ botToken: opts.botToken,
66898
+ signingSecret: opts.signingSecret,
66899
+ appId: opts.appId,
66900
+ appName: opts.appName,
66901
+ botName: opts.botName,
66902
+ botImageUrl: opts.botImageUrl,
66903
+ json: opts.json
66904
+ });
66905
+ return;
66906
+ case "disconnect":
66907
+ await runAgentDisconnect(cwd2, args[0], { yes: opts.yes, json: opts.json });
66908
+ return;
66449
66909
  case "env":
66450
66910
  await runAgentEnv(cwd2, { shell: opts.shell });
66451
66911
  return;
@@ -66465,25 +66925,31 @@ async function runAgent(cwd2, sub, args, opts) {
66465
66925
  function printHelp() {
66466
66926
  const out = [];
66467
66927
  out.push("");
66468
- out.push(` ${import_picocolors34.default.bold("brainbase agent")} ${import_picocolors34.default.dim("<sub> [options]")}`);
66928
+ out.push(` ${import_picocolors37.default.bold("brainbase agent")} ${import_picocolors37.default.dim("<sub> [options]")}`);
66929
+ out.push("");
66930
+ out.push(` ${import_picocolors37.default.cyan("list")} ${import_picocolors37.default.dim("show the agents in a team, with the ids `brainbase link` takes (--json for scripts)")}`);
66931
+ out.push(` ${import_picocolors37.default.cyan("create")} ${import_picocolors37.default.dim("claim an unclaimed brainbase.agent.yaml and create the cloud agent")}`);
66932
+ out.push(` ${import_picocolors37.default.cyan("pull")} ${import_picocolors37.default.dim("[<id>]")} ${import_picocolors37.default.dim("apply cloud changes into this folder — pass <id> to switch (--force to override); --run-entrypoint to also execute the agent entrypoint")}`);
66933
+ out.push(` ${import_picocolors37.default.cyan("push")} ${import_picocolors37.default.dim("send local changes to the cloud — instructions, playbooks, skills, MCPs, entrypoint (--force to overwrite cloud-side conflicts with local)")}`);
66934
+ out.push(` ${import_picocolors37.default.cyan("unpack")} ${import_picocolors37.default.dim("install the claimed agent into a harness layout (--harness to override)")}`);
66935
+ out.push(` ${import_picocolors37.default.cyan("status")} ${import_picocolors37.default.dim("show what would push, what would pull, and which manifest blocks are ignored (--json for scripts)")}`);
66936
+ out.push(` ${import_picocolors37.default.cyan("connections")} ${import_picocolors37.default.dim("show which integrations this agent is wired to (--json for scripts)")}`);
66937
+ out.push(` ${import_picocolors37.default.cyan("connect")} ${import_picocolors37.default.dim("<name>")} ${import_picocolors37.default.dim("connect slack or meeting — credentials come from flags, env, or stdin")}`);
66938
+ out.push(` ${import_picocolors37.default.cyan("disconnect")} ${import_picocolors37.default.dim("<name>")} ${import_picocolors37.default.dim("revoke a slack or meeting install")}`);
66939
+ out.push(` ${import_picocolors37.default.cyan("env")} ${import_picocolors37.default.dim('print export statements — use with `eval "$(brainbase agent env)"`')}`);
66469
66940
  out.push("");
66470
- 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)")}`);
66471
- out.push(` ${import_picocolors34.default.cyan("create")} ${import_picocolors34.default.dim("claim an unclaimed brainbase.agent.yaml and create the cloud agent")}`);
66472
- out.push(` ${import_picocolors34.default.cyan("pull")} ${import_picocolors34.default.dim("[<id>]")} ${import_picocolors34.default.dim("apply cloud changes into this folder — pass <id> to switch (--force to override); --run-entrypoint to also execute the agent entrypoint")}`);
66473
- 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)")}`);
66474
- out.push(` ${import_picocolors34.default.cyan("unpack")} ${import_picocolors34.default.dim("install the claimed agent into a harness layout (--harness to override)")}`);
66475
- out.push(` ${import_picocolors34.default.cyan("status")} ${import_picocolors34.default.dim("show what would push, what would pull, and which manifest blocks are ignored (--json for scripts)")}`);
66476
- out.push(` ${import_picocolors34.default.cyan("env")} ${import_picocolors34.default.dim('print export statements — use with `eval "$(brainbase agent env)"`')}`);
66941
+ out.push(` ${import_picocolors37.default.dim("Slack credentials:")} ${import_picocolors37.default.dim("--bot-token / BRAINBASE_SLACK_BOT_TOKEN, --signing-secret / BRAINBASE_SLACK_SIGNING_SECRET,")}`);
66942
+ out.push(` ${import_picocolors37.default.dim('or pipe {"bot_token":"…","signing_secret":"…"} on stdin to keep them out of argv.')}`);
66477
66943
  out.push("");
66478
66944
  console.log(out.join(`
66479
66945
  `));
66480
66946
  }
66481
66947
 
66482
66948
  // src/cli/team.ts
66483
- var import_picocolors36 = __toESM(require_picocolors(), 1);
66949
+ var import_picocolors39 = __toESM(require_picocolors(), 1);
66484
66950
 
66485
66951
  // src/cli/team-list.ts
66486
- var import_picocolors35 = __toESM(require_picocolors(), 1);
66952
+ var import_picocolors38 = __toESM(require_picocolors(), 1);
66487
66953
  async function runTeamList(args) {
66488
66954
  if (!args.json)
66489
66955
  banner("team list — teams you can put agents in");
@@ -66503,25 +66969,25 @@ async function runTeamList(args) {
66503
66969
  function formatTeamList(grouped) {
66504
66970
  const lines = [""];
66505
66971
  if (grouped.length === 0) {
66506
- lines.push(` ${import_picocolors35.default.dim("You are not a member of any organization.")}`, "");
66972
+ lines.push(` ${import_picocolors38.default.dim("You are not a member of any organization.")}`, "");
66507
66973
  return lines.join(`
66508
66974
  `);
66509
66975
  }
66510
66976
  const nameWidth = Math.max(...grouped.flatMap(({ teams }) => teams.map((t) => t.name.length)), 0);
66511
66977
  for (const { org, teams, error } of grouped) {
66512
- const slug = org.slug ? ` ${import_picocolors35.default.dim(org.slug)}` : "";
66513
- lines.push(` ${import_picocolors35.default.bold(org.name)}${slug}`);
66978
+ const slug = org.slug ? ` ${import_picocolors38.default.dim(org.slug)}` : "";
66979
+ lines.push(` ${import_picocolors38.default.bold(org.name)}${slug}`);
66514
66980
  if (error) {
66515
- lines.push(` ${import_picocolors35.default.red(`could not load teams: ${error}`)}`);
66981
+ lines.push(` ${import_picocolors38.default.red(`could not load teams: ${error}`)}`);
66516
66982
  } else if (teams.length === 0) {
66517
- lines.push(` ${import_picocolors35.default.dim("no teams yet — create one in the web app")}`);
66983
+ lines.push(` ${import_picocolors38.default.dim("no teams yet — create one in the web app")}`);
66518
66984
  }
66519
66985
  for (const team of teams) {
66520
- lines.push(` ${team.name.padEnd(nameWidth)} ${import_picocolors35.default.dim(team.id)}`);
66986
+ lines.push(` ${team.name.padEnd(nameWidth)} ${import_picocolors38.default.dim(team.id)}`);
66521
66987
  }
66522
66988
  lines.push("");
66523
66989
  }
66524
- lines.push(` ${import_picocolors35.default.dim("list a team’s agents with")} ${import_picocolors35.default.cyan("brainbase agent list --team <id>")}`, "");
66990
+ lines.push(` ${import_picocolors38.default.dim("list a team’s agents with")} ${import_picocolors38.default.cyan("brainbase agent list --team <id>")}`, "");
66525
66991
  return lines.join(`
66526
66992
  `);
66527
66993
  }
@@ -66552,28 +67018,28 @@ async function runTeam(sub, args, opts) {
66552
67018
  function printHelp2() {
66553
67019
  const out = [];
66554
67020
  out.push("");
66555
- out.push(` ${import_picocolors36.default.bold("brainbase team")} ${import_picocolors36.default.dim("<sub> [options]")}`);
67021
+ out.push(` ${import_picocolors39.default.bold("brainbase team")} ${import_picocolors39.default.dim("<sub> [options]")}`);
66556
67022
  out.push("");
66557
- out.push(` ${import_picocolors36.default.cyan("list")} ${import_picocolors36.default.dim("show the teams you can create agents in, grouped by organization")}`);
67023
+ out.push(` ${import_picocolors39.default.cyan("list")} ${import_picocolors39.default.dim("show the teams you can create agents in, grouped by organization")}`);
66558
67024
  out.push("");
66559
- out.push(` ${import_picocolors36.default.dim("--org <id-or-slug>")} ${import_picocolors36.default.dim("limit to one organization")}`);
66560
- out.push(` ${import_picocolors36.default.dim("--json")} ${import_picocolors36.default.dim("machine-readable output")}`);
67025
+ out.push(` ${import_picocolors39.default.dim("--org <id-or-slug>")} ${import_picocolors39.default.dim("limit to one organization")}`);
67026
+ out.push(` ${import_picocolors39.default.dim("--json")} ${import_picocolors39.default.dim("machine-readable output")}`);
66561
67027
  out.push("");
66562
67028
  console.log(out.join(`
66563
67029
  `));
66564
67030
  }
66565
67031
 
66566
67032
  // src/cli/orchestration.ts
66567
- var import_picocolors43 = __toESM(require_picocolors(), 1);
67033
+ var import_picocolors46 = __toESM(require_picocolors(), 1);
66568
67034
 
66569
67035
  // src/cli/orchestration-pull.ts
66570
67036
  import path86 from "node:path";
66571
- import fs77 from "node:fs";
66572
- var import_picocolors37 = __toESM(require_picocolors(), 1);
67037
+ import fs78 from "node:fs";
67038
+ var import_picocolors40 = __toESM(require_picocolors(), 1);
66573
67039
 
66574
67040
  // src/core/orchestration-manifest.ts
66575
67041
  import path83 from "node:path";
66576
- import fs74 from "node:fs";
67042
+ import fs75 from "node:fs";
66577
67043
  var import_yaml4 = __toESM(require_dist(), 1);
66578
67044
  var ORCH_MANIFEST_FILE = "brainbase-orchestration.yaml";
66579
67045
  var ORCH_MEMBERS_DIR = "agents";
@@ -66629,13 +67095,13 @@ function orchManifestPath(cwd2) {
66629
67095
  return path83.join(cwd2, ORCH_MANIFEST_FILE);
66630
67096
  }
66631
67097
  function hasOrchManifest(cwd2) {
66632
- return fs74.existsSync(orchManifestPath(cwd2));
67098
+ return fs75.existsSync(orchManifestPath(cwd2));
66633
67099
  }
66634
67100
  function readOrchManifest(cwd2) {
66635
67101
  const p2 = orchManifestPath(cwd2);
66636
- if (!fs74.existsSync(p2))
67102
+ if (!fs75.existsSync(p2))
66637
67103
  return null;
66638
- const raw = fs74.readFileSync(p2, "utf8");
67104
+ const raw = fs75.readFileSync(p2, "utf8");
66639
67105
  let parsed;
66640
67106
  try {
66641
67107
  parsed = import_yaml4.default.parse(raw);
@@ -66656,7 +67122,7 @@ function writeOrchManifest(cwd2, manifest) {
66656
67122
  ` + " `brainbase orchestration push`. Member agents live under ./agents/." + `
66657
67123
  Schedule triggers are writable. App/Pipedream triggers are preserved
66658
67124
  ` + " as read-only context and ignored by `orchestration push`.";
66659
- fs74.writeFileSync(orchManifestPath(cwd2), String(doc), "utf8");
67125
+ fs75.writeFileSync(orchManifestPath(cwd2), String(doc), "utf8");
66660
67126
  }
66661
67127
  function memberDir(cwd2, slug) {
66662
67128
  return path83.join(cwd2, ORCH_MEMBERS_DIR, slug);
@@ -66694,7 +67160,7 @@ function resolveMemberSlugs(members) {
66694
67160
 
66695
67161
  // src/core/orchestration-link.ts
66696
67162
  import path84 from "node:path";
66697
- import fs75 from "node:fs";
67163
+ import fs76 from "node:fs";
66698
67164
  var ORCH_LINK_FILE = "orchestration-link.json";
66699
67165
  var ORCH_SYNC_STATE_FILE = "orchestration-sync-state.json";
66700
67166
  var OrchestrationLinkSchema = exports_external.object({
@@ -66745,12 +67211,12 @@ function readOrchLink(cwd2) {
66745
67211
  }
66746
67212
  function writeOrchLink(cwd2, link2) {
66747
67213
  ensureDir(path84.join(cwd2, LINK_DIR));
66748
- const clean = {};
67214
+ const clean2 = {};
66749
67215
  for (const [k3, v3] of Object.entries(link2)) {
66750
67216
  if (v3 !== null && v3 !== undefined)
66751
- clean[k3] = v3;
67217
+ clean2[k3] = v3;
66752
67218
  }
66753
- writeJson(orchLinkPath(cwd2), clean);
67219
+ writeJson(orchLinkPath(cwd2), clean2);
66754
67220
  ensureGitignore2(cwd2);
66755
67221
  }
66756
67222
  function readOrchSyncState(cwd2) {
@@ -66774,12 +67240,12 @@ function ensureGitignore2(cwd2) {
66774
67240
  `;
66775
67241
  try {
66776
67242
  if (!exists(ignorePath)) {
66777
- fs75.writeFileSync(ignorePath, desired);
67243
+ fs76.writeFileSync(ignorePath, desired);
66778
67244
  return;
66779
67245
  }
66780
- const current = fs75.readFileSync(ignorePath, "utf8");
67246
+ const current = fs76.readFileSync(ignorePath, "utf8");
66781
67247
  if (!current.split(/\r?\n/).some((l2) => l2.trim() === ORCH_SYNC_STATE_FILE)) {
66782
- fs75.writeFileSync(ignorePath, current.endsWith(`
67248
+ fs76.writeFileSync(ignorePath, current.endsWith(`
66783
67249
  `) ? current + desired : current + `
66784
67250
  ` + desired);
66785
67251
  }
@@ -66788,7 +67254,7 @@ function ensureGitignore2(cwd2) {
66788
67254
 
66789
67255
  // src/core/agent-fresh-install.ts
66790
67256
  import path85 from "node:path";
66791
- import fs76 from "node:fs";
67257
+ import fs77 from "node:fs";
66792
67258
  import os15 from "node:os";
66793
67259
  async function installAgentFresh(input) {
66794
67260
  const { cwd: cwd2, agent, cloud, harness } = input;
@@ -66879,19 +67345,19 @@ async function installAgentFresh(input) {
66879
67345
  };
66880
67346
  } finally {
66881
67347
  try {
66882
- fs76.rmSync(stageRoot, { recursive: true, force: true });
67348
+ fs77.rmSync(stageRoot, { recursive: true, force: true });
66883
67349
  } catch {}
66884
67350
  }
66885
67351
  }
66886
67352
  function stageManifestComponents2(components) {
66887
- const root = fs76.mkdtempSync(path85.join(os15.tmpdir(), "brainbase-orch-pull-"));
67353
+ const root = fs77.mkdtempSync(path85.join(os15.tmpdir(), "brainbase-orch-pull-"));
66888
67354
  for (const c2 of components) {
66889
67355
  const compDir = path85.join(root, c2.type, c2.slug);
66890
67356
  ensureDir(compDir);
66891
67357
  for (const f4 of c2.files) {
66892
67358
  const target = path85.join(compDir, f4.path);
66893
67359
  ensureDir(path85.dirname(target));
66894
- fs76.writeFileSync(target, f4.content);
67360
+ fs77.writeFileSync(target, f4.content);
66895
67361
  }
66896
67362
  }
66897
67363
  return root;
@@ -66926,7 +67392,7 @@ function materializeInstructions2(cwd2, cloud) {
66926
67392
  continue;
66927
67393
  const target = path85.join(cwd2, DEFAULT_INSTRUCTIONS_FILE);
66928
67394
  ensureDir(path85.dirname(target));
66929
- fs76.writeFileSync(target, normalizeInstructionBody(body), "utf8");
67395
+ fs77.writeFileSync(target, normalizeInstructionBody(body), "utf8");
66930
67396
  return;
66931
67397
  }
66932
67398
  }
@@ -66940,7 +67406,7 @@ function materializePlaybooks2(cwd2, cloud) {
66940
67406
  const { body } = stripPlaybookFrontmatter(raw);
66941
67407
  const target = path85.join(cwd2, DEFAULT_PLAYBOOKS_DIR, `${c2.slug}.md`);
66942
67408
  ensureDir(path85.dirname(target));
66943
- fs76.writeFileSync(target, body, "utf8");
67409
+ fs77.writeFileSync(target, body, "utf8");
66944
67410
  }
66945
67411
  }
66946
67412
  function buildManifestFromCloud(cloud, agent, localOnly = {}) {
@@ -67089,8 +67555,8 @@ async function runOrchestrationPull(cwd2, args) {
67089
67555
  orchId = args.orchestrationId;
67090
67556
  } else {
67091
67557
  f2.warn("This folder is not linked to any orchestration.");
67092
- f2.info(`Run ${import_picocolors37.default.cyan("brainbase orchestration pull <id>")} with an orchestration id,
67093
- or ${import_picocolors37.default.cyan("brainbase orchestration list")} to find one.`);
67558
+ f2.info(`Run ${import_picocolors40.default.cyan("brainbase orchestration pull <id>")} with an orchestration id,
67559
+ or ${import_picocolors40.default.cyan("brainbase orchestration list")} to find one.`);
67094
67560
  return;
67095
67561
  }
67096
67562
  const sp = de();
@@ -67109,24 +67575,24 @@ async function runOrchestrationPull(cwd2, args) {
67109
67575
  const slugFor = (agentId) => slugByAgent.get(agentId) ?? agentId;
67110
67576
  const planLines = [];
67111
67577
  planLines.push("");
67112
- planLines.push(` ${import_picocolors37.default.bold(cloud.name)} ${import_picocolors37.default.dim(`(${cloud.id})`)}`);
67578
+ planLines.push(` ${import_picocolors40.default.bold(cloud.name)} ${import_picocolors40.default.dim(`(${cloud.id})`)}`);
67113
67579
  if (cloud.description)
67114
- planLines.push(` ${import_picocolors37.default.dim(cloud.description)}`);
67580
+ planLines.push(` ${import_picocolors40.default.dim(cloud.description)}`);
67115
67581
  planLines.push("");
67116
- planLines.push(` ${import_picocolors37.default.dim("members:")}`);
67582
+ planLines.push(` ${import_picocolors40.default.dim("members:")}`);
67117
67583
  for (const m3 of cloud.members) {
67118
67584
  const skipped = !m3.manifest;
67119
- const tail2 = skipped ? import_picocolors37.default.red(" (manifest unavailable — skipped)") : "";
67120
- planLines.push(` ${import_picocolors37.default.cyan("•")} ${import_picocolors37.default.bold(slugFor(m3.agent_id))} ${import_picocolors37.default.dim(`(${m3.name})`)}${tail2}`);
67585
+ const tail2 = skipped ? import_picocolors40.default.red(" (manifest unavailable — skipped)") : "";
67586
+ planLines.push(` ${import_picocolors40.default.cyan("•")} ${import_picocolors40.default.bold(slugFor(m3.agent_id))} ${import_picocolors40.default.dim(`(${m3.name})`)}${tail2}`);
67121
67587
  }
67122
67588
  if (cloud.edges.length) {
67123
67589
  planLines.push("");
67124
- planLines.push(` ${import_picocolors37.default.dim("edges:")}`);
67590
+ planLines.push(` ${import_picocolors40.default.dim("edges:")}`);
67125
67591
  for (const e2 of cloud.edges) {
67126
67592
  const from = slugFor(e2.from_agent_id);
67127
67593
  const to2 = slugFor(e2.to_agent_id);
67128
- const desc = e2.description ? ` ${import_picocolors37.default.dim("— " + e2.description)}` : "";
67129
- planLines.push(` ${import_picocolors37.default.cyan(from)} ${import_picocolors37.default.dim("→")} ${import_picocolors37.default.cyan(to2)}${desc}`);
67594
+ const desc = e2.description ? ` ${import_picocolors40.default.dim("— " + e2.description)}` : "";
67595
+ planLines.push(` ${import_picocolors40.default.cyan(from)} ${import_picocolors40.default.dim("→")} ${import_picocolors40.default.cyan(to2)}${desc}`);
67130
67596
  }
67131
67597
  }
67132
67598
  planLines.push("");
@@ -67135,7 +67601,7 @@ async function runOrchestrationPull(cwd2, args) {
67135
67601
  const isRefresh = !!existingLink;
67136
67602
  if (!autoProceed(args.yes) && !isRefresh) {
67137
67603
  const ok = await se({
67138
- message: `Pull into ${import_picocolors37.default.bold(cwd2)}?`,
67604
+ message: `Pull into ${import_picocolors40.default.bold(cwd2)}?`,
67139
67605
  initialValue: true
67140
67606
  });
67141
67607
  if (!ensureNotCancelled(ok)) {
@@ -67144,7 +67610,7 @@ async function runOrchestrationPull(cwd2, args) {
67144
67610
  }
67145
67611
  }
67146
67612
  const fallbackHarness = args.harness ?? "claude-code";
67147
- fs77.mkdirSync(cwd2, { recursive: true });
67613
+ fs78.mkdirSync(cwd2, { recursive: true });
67148
67614
  if (hasOrchManifest(cwd2) && existingLink && existingLink.orchestration_id !== orchId) {
67149
67615
  f2.error(`This folder is linked to orchestration ${existingLink.orchestration_id}, not ${orchId}. Move to a fresh directory or unlink first.`);
67150
67616
  return;
@@ -67179,7 +67645,7 @@ async function runOrchestrationPull(cwd2, args) {
67179
67645
  scope: "project",
67180
67646
  pullSecrets: true
67181
67647
  });
67182
- memberSp.stop(`Installed ${import_picocolors37.default.bold(slug)} ${import_picocolors37.default.dim(`(${m3.manifest.components.length} components)`)}.`);
67648
+ memberSp.stop(`Installed ${import_picocolors40.default.bold(slug)} ${import_picocolors40.default.dim(`(${m3.manifest.components.length} components)`)}.`);
67183
67649
  installedMembers.push({
67184
67650
  agent_id: m3.agent_id,
67185
67651
  slug,
@@ -67240,7 +67706,7 @@ async function runOrchestrationPull(cwd2, args) {
67240
67706
  payload_schema: e2.payload_schema ?? {}
67241
67707
  }))
67242
67708
  });
67243
- $e(`Pulled ${cloud.name} at revision ${cloud.revision} into ${path86.basename(cwd2)}/ ${import_picocolors37.default.dim(`(${installedMembers.length}/${cloud.members.length} members)`)}.`);
67709
+ $e(`Pulled ${cloud.name} at revision ${cloud.revision} into ${path86.basename(cwd2)}/ ${import_picocolors40.default.dim(`(${installedMembers.length}/${cloud.members.length} members)`)}.`);
67244
67710
  }
67245
67711
  function handleApiError5(err) {
67246
67712
  if (err instanceof ApiError) {
@@ -67257,7 +67723,7 @@ function handleApiError5(err) {
67257
67723
  }
67258
67724
 
67259
67725
  // src/cli/orchestration-push.ts
67260
- var import_picocolors38 = __toESM(require_picocolors(), 1);
67726
+ var import_picocolors41 = __toESM(require_picocolors(), 1);
67261
67727
 
67262
67728
  // src/core/orchestration-outgoing.ts
67263
67729
  function buildOrchestrationGraphPayload(manifest, slugToAgentId) {
@@ -67340,7 +67806,7 @@ function findUnpushableMembers(cwd2, members) {
67340
67806
  continue;
67341
67807
  }
67342
67808
  if (!memberManifest.id) {
67343
- f2.error(`${m3.slug}: ${AGENT_MANIFEST_FILE} is unclaimed (no ${import_picocolors38.default.cyan("id")}), so there is nothing to push to.`);
67809
+ f2.error(`${m3.slug}: ${AGENT_MANIFEST_FILE} is unclaimed (no ${import_picocolors41.default.cyan("id")}), so there is nothing to push to.`);
67344
67810
  blocked.push(m3.slug);
67345
67811
  continue;
67346
67812
  }
@@ -67355,12 +67821,12 @@ async function runOrchestrationPush(cwd2, args) {
67355
67821
  const link2 = readOrchLink(cwd2);
67356
67822
  if (!link2) {
67357
67823
  f2.warn("This folder is not linked to any orchestration.");
67358
- f2.info(`Run ${import_picocolors38.default.cyan("brainbase orchestration pull <id>")} first.`);
67824
+ f2.info(`Run ${import_picocolors41.default.cyan("brainbase orchestration pull <id>")} first.`);
67359
67825
  return;
67360
67826
  }
67361
67827
  if (!hasOrchManifest(cwd2)) {
67362
- f2.warn(`No ${import_picocolors38.default.bold(ORCH_MANIFEST_FILE)} here.`);
67363
- f2.info(`Run ${import_picocolors38.default.cyan("brainbase orchestration pull")} to materialise the manifest before pushing.`);
67828
+ f2.warn(`No ${import_picocolors41.default.bold(ORCH_MANIFEST_FILE)} here.`);
67829
+ f2.info(`Run ${import_picocolors41.default.cyan("brainbase orchestration pull")} to materialise the manifest before pushing.`);
67364
67830
  return;
67365
67831
  }
67366
67832
  let manifest;
@@ -67384,7 +67850,7 @@ async function runOrchestrationPush(cwd2, args) {
67384
67850
  }
67385
67851
  if (missing.length) {
67386
67852
  f2.error(`Missing local checkouts for: ${missing.join(", ")}.`);
67387
- f2.info(`Run ${import_picocolors38.default.cyan("brainbase orchestration pull")} to materialise the missing folders.`);
67853
+ f2.info(`Run ${import_picocolors41.default.cyan("brainbase orchestration pull")} to materialise the missing folders.`);
67388
67854
  process.exitCode = 1;
67389
67855
  return;
67390
67856
  }
@@ -67405,13 +67871,13 @@ async function runOrchestrationPush(cwd2, args) {
67405
67871
  }
67406
67872
  }
67407
67873
  const plan = [""];
67408
- plan.push(` ${import_picocolors38.default.bold(link2.name)} ${import_picocolors38.default.dim(`(${link2.orchestration_id})`)}`);
67409
- 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"}`)}`);
67874
+ plan.push(` ${import_picocolors41.default.bold(link2.name)} ${import_picocolors41.default.dim(`(${link2.orchestration_id})`)}`);
67875
+ plan.push(` ${import_picocolors41.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"}`)}`);
67410
67876
  plan.push("");
67411
67877
  if (!args.graphOnly) {
67412
- plan.push(` ${import_picocolors38.default.dim("per-member agent push:")}`);
67878
+ plan.push(` ${import_picocolors41.default.dim("per-member agent push:")}`);
67413
67879
  for (const m3 of manifest.members) {
67414
- plan.push(` ${import_picocolors38.default.cyan("•")} ${import_picocolors38.default.bold(m3.slug)}`);
67880
+ plan.push(` ${import_picocolors41.default.cyan("•")} ${import_picocolors41.default.bold(m3.slug)}`);
67415
67881
  }
67416
67882
  plan.push("");
67417
67883
  }
@@ -67431,7 +67897,7 @@ async function runOrchestrationPush(cwd2, args) {
67431
67897
  for (const m3 of manifest.members) {
67432
67898
  const dir = memberDir(cwd2, m3.slug);
67433
67899
  console.log("");
67434
- console.log(`${import_picocolors38.default.dim("───")} ${import_picocolors38.default.bold(m3.slug)} ${import_picocolors38.default.dim("───")}`);
67900
+ console.log(`${import_picocolors41.default.dim("───")} ${import_picocolors41.default.bold(m3.slug)} ${import_picocolors41.default.dim("───")}`);
67435
67901
  const exitCodeBeforePush = process.exitCode;
67436
67902
  try {
67437
67903
  await runAgentPush(dir, { yes: true });
@@ -67495,7 +67961,7 @@ function handleApiError6(err) {
67495
67961
  f2.error("You do not have access to this orchestration.");
67496
67962
  } else if (err.status === 409) {
67497
67963
  f2.error(err.message);
67498
- f2.info(`Run ${import_picocolors38.default.cyan("brainbase orchestration pull")} to reconcile, then push again.`);
67964
+ f2.info(`Run ${import_picocolors41.default.cyan("brainbase orchestration pull")} to reconcile, then push again.`);
67499
67965
  } else {
67500
67966
  f2.error(err.message);
67501
67967
  }
@@ -67505,13 +67971,13 @@ function handleApiError6(err) {
67505
67971
  }
67506
67972
 
67507
67973
  // src/cli/orchestration-status.ts
67508
- var import_picocolors39 = __toESM(require_picocolors(), 1);
67974
+ var import_picocolors42 = __toESM(require_picocolors(), 1);
67509
67975
  async function runOrchestrationStatus(cwd2) {
67510
67976
  banner("orchestration status — what changed locally, remotely, both");
67511
67977
  const link2 = readOrchLink(cwd2);
67512
67978
  if (!link2) {
67513
67979
  f2.warn("This folder is not linked to any orchestration.");
67514
- f2.info(`Run ${import_picocolors39.default.cyan("brainbase orchestration pull <id>")} first.`);
67980
+ f2.info(`Run ${import_picocolors42.default.cyan("brainbase orchestration pull <id>")} first.`);
67515
67981
  return;
67516
67982
  }
67517
67983
  const localManifest = hasOrchManifest(cwd2) ? readOrchManifest(cwd2) : null;
@@ -67534,8 +68000,8 @@ async function runOrchestrationStatus(cwd2) {
67534
68000
  }
67535
68001
  const lines = [];
67536
68002
  lines.push("");
67537
- lines.push(` ${import_picocolors39.default.bold(link2.name)} ${import_picocolors39.default.dim(`(${link2.orchestration_id})`)}`);
67538
- lines.push(` ${import_picocolors39.default.dim("revision")} cloud ${cloud.revision}${lock ? ` · lock ${lock.revision}` : " · never pulled"}`);
68003
+ lines.push(` ${import_picocolors42.default.bold(link2.name)} ${import_picocolors42.default.dim(`(${link2.orchestration_id})`)}`);
68004
+ lines.push(` ${import_picocolors42.default.dim("revision")} cloud ${cloud.revision}${lock ? ` · lock ${lock.revision}` : " · never pulled"}`);
67539
68005
  lines.push("");
67540
68006
  const localSlugByAgentId = new Map;
67541
68007
  for (const m3 of localManifest?.members ?? []) {
@@ -67549,12 +68015,12 @@ async function runOrchestrationStatus(cwd2) {
67549
68015
  const membersAdded = [...localMemberSet].filter((s3) => !cloudMemberSet.has(s3));
67550
68016
  const membersRemoved = [...cloudMemberSet].filter((s3) => !localMemberSet.has(s3));
67551
68017
  if (membersAdded.length || membersRemoved.length) {
67552
- lines.push(` ${import_picocolors39.default.bold("members")}`);
68018
+ lines.push(` ${import_picocolors42.default.bold("members")}`);
67553
68019
  for (const slug of membersAdded) {
67554
- lines.push(` ${import_picocolors39.default.yellow("→ push")} added in yaml: ${import_picocolors39.default.bold(slug)}`);
68020
+ lines.push(` ${import_picocolors42.default.yellow("→ push")} added in yaml: ${import_picocolors42.default.bold(slug)}`);
67555
68021
  }
67556
68022
  for (const slug of membersRemoved) {
67557
- lines.push(` ${import_picocolors39.default.cyan("← pull")} added on cloud: ${import_picocolors39.default.bold(slug)}`);
68023
+ lines.push(` ${import_picocolors42.default.cyan("← pull")} added on cloud: ${import_picocolors42.default.bold(slug)}`);
67558
68024
  }
67559
68025
  lines.push("");
67560
68026
  }
@@ -67569,11 +68035,11 @@ async function runOrchestrationStatus(cwd2) {
67569
68035
  const edgesAdded = [...localEdges.keys()].filter((k3) => !cloudEdges.has(k3));
67570
68036
  const edgesRemoved = [...cloudEdges.keys()].filter((k3) => !localEdges.has(k3));
67571
68037
  if (edgesAdded.length || edgesRemoved.length) {
67572
- lines.push(` ${import_picocolors39.default.bold("edges")}`);
68038
+ lines.push(` ${import_picocolors42.default.bold("edges")}`);
67573
68039
  for (const k3 of edgesAdded)
67574
- lines.push(` ${import_picocolors39.default.yellow("→ push")} added in yaml: ${k3}`);
68040
+ lines.push(` ${import_picocolors42.default.yellow("→ push")} added in yaml: ${k3}`);
67575
68041
  for (const k3 of edgesRemoved)
67576
- lines.push(` ${import_picocolors39.default.cyan("← pull")} added on cloud: ${k3}`);
68042
+ lines.push(` ${import_picocolors42.default.cyan("← pull")} added on cloud: ${k3}`);
67577
68043
  lines.push("");
67578
68044
  }
67579
68045
  const cloudTriggerKey = (t) => {
@@ -67611,11 +68077,11 @@ async function runOrchestrationStatus(cwd2) {
67611
68077
  const triggersAdded = [...localTriggers.keys()].filter((k3) => !cloudTriggers.has(k3));
67612
68078
  const triggersRemoved = [...cloudTriggers.keys()].filter((k3) => !localTriggers.has(k3));
67613
68079
  if (triggersAdded.length || triggersRemoved.length) {
67614
- lines.push(` ${import_picocolors39.default.bold("schedule triggers")}`);
68080
+ lines.push(` ${import_picocolors42.default.bold("schedule triggers")}`);
67615
68081
  for (const k3 of triggersAdded)
67616
- lines.push(` ${import_picocolors39.default.yellow("→ push")} added/changed in yaml: ${localTriggers.get(k3) ?? k3}`);
68082
+ lines.push(` ${import_picocolors42.default.yellow("→ push")} added/changed in yaml: ${localTriggers.get(k3) ?? k3}`);
67617
68083
  for (const k3 of triggersRemoved)
67618
- lines.push(` ${import_picocolors39.default.cyan("← pull")} added/changed on cloud: ${cloudTriggers.get(k3) ?? k3}`);
68084
+ lines.push(` ${import_picocolors42.default.cyan("← pull")} added/changed on cloud: ${cloudTriggers.get(k3) ?? k3}`);
67619
68085
  lines.push("");
67620
68086
  }
67621
68087
  const lockByAgentId = new Map((lock?.members ?? []).map((m3) => [m3.agent_id, m3]));
@@ -67638,27 +68104,27 @@ async function runOrchestrationStatus(cwd2) {
67638
68104
  }
67639
68105
  }
67640
68106
  if (memberDrift.length) {
67641
- lines.push(` ${import_picocolors39.default.bold("member content drift")}`);
68107
+ lines.push(` ${import_picocolors42.default.bold("member content drift")}`);
67642
68108
  for (const d3 of memberDrift) {
67643
- lines.push(` ${import_picocolors39.default.cyan("?")} ${import_picocolors39.default.bold(d3.slug)} ${import_picocolors39.default.dim("— " + d3.reason)}`);
68109
+ lines.push(` ${import_picocolors42.default.cyan("?")} ${import_picocolors42.default.bold(d3.slug)} ${import_picocolors42.default.dim("— " + d3.reason)}`);
67644
68110
  }
67645
- lines.push(` ${import_picocolors39.default.dim("cd into each member folder and run")} ${import_picocolors39.default.cyan("brainbase agent status")}`);
68111
+ lines.push(` ${import_picocolors42.default.dim("cd into each member folder and run")} ${import_picocolors42.default.cyan("brainbase agent status")}`);
67646
68112
  lines.push("");
67647
68113
  }
67648
68114
  const revisionDrift = lock?.revision != null && cloud.revision !== lock.revision;
67649
68115
  if (revisionDrift) {
67650
- lines.push(` ${import_picocolors39.default.bold("cloud revision")}`);
67651
- lines.push(` ${import_picocolors39.default.cyan("← pull")} cloud changed since last pull: ${import_picocolors39.default.dim(`lock ${lock.revision} → cloud ${cloud.revision}`)}`);
68116
+ lines.push(` ${import_picocolors42.default.bold("cloud revision")}`);
68117
+ lines.push(` ${import_picocolors42.default.cyan("← pull")} cloud changed since last pull: ${import_picocolors42.default.dim(`lock ${lock.revision} → cloud ${cloud.revision}`)}`);
67652
68118
  lines.push("");
67653
68119
  }
67654
68120
  if (!membersAdded.length && !membersRemoved.length && !edgesAdded.length && !edgesRemoved.length && !triggersAdded.length && !triggersRemoved.length && !memberDrift.length && !revisionDrift) {
67655
- lines.push(` ${import_picocolors39.default.green("✓")} everything is in sync`);
68121
+ lines.push(` ${import_picocolors42.default.green("✓")} everything is in sync`);
67656
68122
  lines.push("");
67657
68123
  console.log(lines.join(`
67658
68124
  `));
67659
68125
  return;
67660
68126
  }
67661
- 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")}`);
68127
+ lines.push(` ${import_picocolors42.default.dim("run")} ${import_picocolors42.default.cyan("brainbase orchestration pull")} ${import_picocolors42.default.dim("to apply cloud changes,")} ${import_picocolors42.default.cyan("brainbase orchestration push")} ${import_picocolors42.default.dim("to send yours")}`);
67662
68128
  lines.push("");
67663
68129
  console.log(lines.join(`
67664
68130
  `));
@@ -67673,7 +68139,7 @@ function stableJson(value) {
67673
68139
  }
67674
68140
 
67675
68141
  // src/cli/orchestration-list.ts
67676
- var import_picocolors40 = __toESM(require_picocolors(), 1);
68142
+ var import_picocolors43 = __toESM(require_picocolors(), 1);
67677
68143
  async function runOrchestrationList(args) {
67678
68144
  banner("orchestration list — orchestrations under a team");
67679
68145
  const { org, team } = await resolveOrgAndTeam({
@@ -67697,21 +68163,21 @@ async function runOrchestrationList(args) {
67697
68163
  }
67698
68164
  const lines = [""];
67699
68165
  for (const o2 of items) {
67700
- lines.push(` ${import_picocolors40.default.bold(o2.name)} ${import_picocolors40.default.dim(o2.id)}`);
68166
+ lines.push(` ${import_picocolors43.default.bold(o2.name)} ${import_picocolors43.default.dim(o2.id)}`);
67701
68167
  if (o2.description)
67702
- lines.push(` ${import_picocolors40.default.dim(o2.description)}`);
67703
- lines.push(` ${import_picocolors40.default.dim(`${o2.member_count} member${o2.member_count === 1 ? "" : "s"} · ${o2.edge_count} edge${o2.edge_count === 1 ? "" : "s"}`)}`);
68168
+ lines.push(` ${import_picocolors43.default.dim(o2.description)}`);
68169
+ lines.push(` ${import_picocolors43.default.dim(`${o2.member_count} member${o2.member_count === 1 ? "" : "s"} · ${o2.edge_count} edge${o2.edge_count === 1 ? "" : "s"}`)}`);
67704
68170
  lines.push("");
67705
68171
  }
67706
- lines.push(` ${import_picocolors40.default.dim("pull one with")} ${import_picocolors40.default.cyan("brainbase orchestration pull <id>")}`);
68172
+ lines.push(` ${import_picocolors43.default.dim("pull one with")} ${import_picocolors43.default.cyan("brainbase orchestration pull <id>")}`);
67707
68173
  lines.push("");
67708
68174
  console.log(lines.join(`
67709
68175
  `));
67710
68176
  }
67711
68177
 
67712
68178
  // src/cli/orchestration-add-agent.ts
67713
- import fs78 from "node:fs";
67714
- var import_picocolors41 = __toESM(require_picocolors(), 1);
68179
+ import fs79 from "node:fs";
68180
+ var import_picocolors44 = __toESM(require_picocolors(), 1);
67715
68181
 
67716
68182
  // src/core/orchestration-add.ts
67717
68183
  function resolveOrgIdForGroup(groupId, orgsWithTeams) {
@@ -67776,7 +68242,7 @@ async function runOrchestrationAddAgent(cwd2, args) {
67776
68242
  const link2 = readOrchLink(cwd2);
67777
68243
  if (!link2 || !hasOrchManifest(cwd2)) {
67778
68244
  f2.warn("This folder is not a linked orchestration.");
67779
- f2.info(`Run ${import_picocolors41.default.cyan("brainbase orchestration pull <id>")} first.`);
68245
+ f2.info(`Run ${import_picocolors44.default.cyan("brainbase orchestration pull <id>")} first.`);
67780
68246
  return;
67781
68247
  }
67782
68248
  let manifest;
@@ -67796,13 +68262,13 @@ async function runOrchestrationAddAgent(cwd2, args) {
67796
68262
  })).trim();
67797
68263
  }
67798
68264
  let slug = slugifyMemberName(name);
67799
- if (manifest.members.some((m3) => m3.slug === slug) || fs78.existsSync(memberDir(cwd2, slug))) {
68265
+ if (manifest.members.some((m3) => m3.slug === slug) || fs79.existsSync(memberDir(cwd2, slug))) {
67800
68266
  let n = 2;
67801
68267
  let candidate = `${slug}-${n}`;
67802
- while (manifest.members.some((m3) => m3.slug === candidate) || fs78.existsSync(memberDir(cwd2, candidate))) {
68268
+ while (manifest.members.some((m3) => m3.slug === candidate) || fs79.existsSync(memberDir(cwd2, candidate))) {
67803
68269
  candidate = `${slug}-${++n}`;
67804
68270
  }
67805
- f2.info(`Slug ${import_picocolors41.default.bold(slug)} is taken — using ${import_picocolors41.default.bold(candidate)}.`);
68271
+ f2.info(`Slug ${import_picocolors44.default.bold(slug)} is taken — using ${import_picocolors44.default.bold(candidate)}.`);
67806
68272
  slug = candidate;
67807
68273
  }
67808
68274
  let payloadSchema;
@@ -67826,7 +68292,7 @@ async function runOrchestrationAddAgent(cwd2, args) {
67826
68292
  const resolved = resolveOrgIdForGroup(link2.group_id, orgsWithTeams);
67827
68293
  if (!resolved) {
67828
68294
  sp.stop("Failed.");
67829
- 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.`);
68295
+ f2.error(`Could not find an org that owns group ${import_picocolors44.default.bold(link2.group_id)}. ` + `Pass ${import_picocolors44.default.cyan("--org <id>")} explicitly.`);
67830
68296
  return;
67831
68297
  }
67832
68298
  orgId = resolved;
@@ -67843,14 +68309,14 @@ async function runOrchestrationAddAgent(cwd2, args) {
67843
68309
  if (from.length === 0 && to2.length === 0 && isInteractive() && manifest.members.length > 0) {
67844
68310
  const memberOptions = manifest.members.map((m3) => ({ value: m3.slug, label: m3.slug }));
67845
68311
  const pickedFrom = await ae({
67846
- message: `Connect ${import_picocolors41.default.bold(slug)} FROM which member(s)? — edges INTO ${slug} (space to select, enter to skip)`,
68312
+ message: `Connect ${import_picocolors44.default.bold(slug)} FROM which member(s)? — edges INTO ${slug} (space to select, enter to skip)`,
67847
68313
  options: memberOptions,
67848
68314
  required: false
67849
68315
  });
67850
68316
  if (Array.isArray(pickedFrom))
67851
68317
  from = pickedFrom;
67852
68318
  const pickedTo = await ae({
67853
- message: `Connect ${import_picocolors41.default.bold(slug)} TO which member(s)? — edges OUT of ${slug} (space to select, enter to skip)`,
68319
+ message: `Connect ${import_picocolors44.default.bold(slug)} TO which member(s)? — edges OUT of ${slug} (space to select, enter to skip)`,
67854
68320
  options: memberOptions,
67855
68321
  required: false
67856
68322
  });
@@ -67871,7 +68337,7 @@ async function runOrchestrationAddAgent(cwd2, args) {
67871
68337
  }
67872
68338
  const dest = memberDir(cwd2, slug);
67873
68339
  try {
67874
- fs78.mkdirSync(dest, { recursive: true });
68340
+ fs79.mkdirSync(dest, { recursive: true });
67875
68341
  await runAgentCreate(dest, {
67876
68342
  name,
67877
68343
  orgId,
@@ -67882,30 +68348,30 @@ async function runOrchestrationAddAgent(cwd2, args) {
67882
68348
  });
67883
68349
  } catch (err) {
67884
68350
  try {
67885
- fs78.rmSync(dest, { recursive: true, force: true });
68351
+ fs79.rmSync(dest, { recursive: true, force: true });
67886
68352
  } catch {}
67887
68353
  f2.error(`Failed to create ${slug}: ${err.message}`);
67888
68354
  return;
67889
68355
  }
67890
68356
  writeOrchManifest(cwd2, updated);
67891
68357
  if (args.noPush) {
67892
- f2.info(`Manifest updated. Run ${import_picocolors41.default.cyan("brainbase orchestration push")} to apply.`);
68358
+ f2.info(`Manifest updated. Run ${import_picocolors44.default.cyan("brainbase orchestration push")} to apply.`);
67893
68359
  return;
67894
68360
  }
67895
68361
  await runOrchestrationPush(cwd2, { yes: true, graphOnly: true });
67896
68362
  }
67897
68363
 
67898
68364
  // src/cli/orchestration-create.ts
67899
- var import_picocolors42 = __toESM(require_picocolors(), 1);
68365
+ var import_picocolors45 = __toESM(require_picocolors(), 1);
67900
68366
  async function runOrchestrationCreate(cwd2, args) {
67901
68367
  banner("orchestration create — claim a brainbase-orchestration.yaml");
67902
68368
  if (readOrchLink(cwd2)) {
67903
68369
  f2.warn("This folder is already linked to an orchestration.");
67904
- f2.info(`Run ${import_picocolors42.default.cyan("brainbase orchestration push")} to update it.`);
68370
+ f2.info(`Run ${import_picocolors45.default.cyan("brainbase orchestration push")} to update it.`);
67905
68371
  return;
67906
68372
  }
67907
68373
  if (!hasOrchManifest(cwd2)) {
67908
- f2.warn(`No ${import_picocolors42.default.bold(ORCH_MANIFEST_FILE)} here.`);
68374
+ f2.warn(`No ${import_picocolors45.default.bold(ORCH_MANIFEST_FILE)} here.`);
67909
68375
  f2.info(`Create one, or pull an existing orchestration first.`);
67910
68376
  return;
67911
68377
  }
@@ -67938,10 +68404,10 @@ async function runOrchestrationCreate(cwd2, args) {
67938
68404
  });
67939
68405
  const plan = [
67940
68406
  "",
67941
- ` ${import_picocolors42.default.bold(manifest.orchestration.name)}`,
67942
- ` ${import_picocolors42.default.dim("org")} ${import_picocolors42.default.bold(target.org.name)}`,
67943
- ` ${import_picocolors42.default.dim("team")} ${import_picocolors42.default.bold(target.team.name)}`,
67944
- ` ${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"}`,
68407
+ ` ${import_picocolors45.default.bold(manifest.orchestration.name)}`,
68408
+ ` ${import_picocolors45.default.dim("org")} ${import_picocolors45.default.bold(target.org.name)}`,
68409
+ ` ${import_picocolors45.default.dim("team")} ${import_picocolors45.default.bold(target.team.name)}`,
68410
+ ` ${import_picocolors45.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"}`,
67945
68411
  ""
67946
68412
  ];
67947
68413
  console.log(plan.join(`
@@ -67971,7 +68437,7 @@ async function runOrchestrationCreate(cwd2, args) {
67971
68437
  edges: graph.edges,
67972
68438
  triggers: graph.triggers
67973
68439
  });
67974
- sp.stop(`Created ${import_picocolors42.default.bold(created.name)}.`);
68440
+ sp.stop(`Created ${import_picocolors45.default.bold(created.name)}.`);
67975
68441
  writeOrchLink(cwd2, {
67976
68442
  schemaVersion: 1,
67977
68443
  orchestration_id: created.id,
@@ -68084,21 +68550,21 @@ async function runOrchestration(cwd2, sub, args, opts) {
68084
68550
  function printHelp3() {
68085
68551
  const out = [];
68086
68552
  out.push("");
68087
- out.push(` ${import_picocolors43.default.bold("brainbase orchestration")} ${import_picocolors43.default.dim("<sub> [options]")}`);
68553
+ out.push(` ${import_picocolors46.default.bold("brainbase orchestration")} ${import_picocolors46.default.dim("<sub> [options]")}`);
68088
68554
  out.push("");
68089
- out.push(` ${import_picocolors43.default.cyan("create")} ${import_picocolors43.default.dim("claim a local orchestration manifest and create it in the cloud")}`);
68090
- out.push(` ${import_picocolors43.default.cyan("pull")} ${import_picocolors43.default.dim("<id>")} ${import_picocolors43.default.dim("fetch orchestration + every member agent into this folder")}`);
68091
- out.push(` ${import_picocolors43.default.cyan("push")} ${import_picocolors43.default.dim("push each member, then update the orchestration graph")}`);
68092
- 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")}`);
68093
- out.push(` ${import_picocolors43.default.cyan("status")} ${import_picocolors43.default.dim("show what would push and what would pull")}`);
68094
- out.push(` ${import_picocolors43.default.cyan("list")} ${import_picocolors43.default.dim("list orchestrations under a team")}`);
68555
+ out.push(` ${import_picocolors46.default.cyan("create")} ${import_picocolors46.default.dim("claim a local orchestration manifest and create it in the cloud")}`);
68556
+ out.push(` ${import_picocolors46.default.cyan("pull")} ${import_picocolors46.default.dim("<id>")} ${import_picocolors46.default.dim("fetch orchestration + every member agent into this folder")}`);
68557
+ out.push(` ${import_picocolors46.default.cyan("push")} ${import_picocolors46.default.dim("push each member, then update the orchestration graph")}`);
68558
+ out.push(` ${import_picocolors46.default.cyan("add-agent")} ${import_picocolors46.default.dim("<name>")} ${import_picocolors46.default.dim("create a member agent, wire edges (--from/--to), and push")}`);
68559
+ out.push(` ${import_picocolors46.default.cyan("status")} ${import_picocolors46.default.dim("show what would push and what would pull")}`);
68560
+ out.push(` ${import_picocolors46.default.cyan("list")} ${import_picocolors46.default.dim("list orchestrations under a team")}`);
68095
68561
  out.push("");
68096
- out.push(` ${import_picocolors43.default.bold("Flags")}`);
68097
- out.push(` ${import_picocolors43.default.dim("--yes, -y")} skip confirmations`);
68098
- out.push(` ${import_picocolors43.default.dim("--harness <id>")} harness for newly-created member folders (default claude-code)`);
68099
- out.push(` ${import_picocolors43.default.dim("--graph-only")} for push: only update members + edges, skip per-member push`);
68100
- out.push(` ${import_picocolors43.default.dim("--org <id>")} for create/list: org id or slug (CLI vocab — DB teams.id)`);
68101
- out.push(` ${import_picocolors43.default.dim("--team <id>")} for create/list: team id (CLI vocab — DB groups.id)`);
68562
+ out.push(` ${import_picocolors46.default.bold("Flags")}`);
68563
+ out.push(` ${import_picocolors46.default.dim("--yes, -y")} skip confirmations`);
68564
+ out.push(` ${import_picocolors46.default.dim("--harness <id>")} harness for newly-created member folders (default claude-code)`);
68565
+ out.push(` ${import_picocolors46.default.dim("--graph-only")} for push: only update members + edges, skip per-member push`);
68566
+ out.push(` ${import_picocolors46.default.dim("--org <id>")} for create/list: org id or slug (CLI vocab — DB teams.id)`);
68567
+ out.push(` ${import_picocolors46.default.dim("--team <id>")} for create/list: team id (CLI vocab — DB groups.id)`);
68102
68568
  out.push("");
68103
68569
  console.log(out.join(`
68104
68570
  `));
@@ -68143,11 +68609,11 @@ async function runRun(cwd2, args) {
68143
68609
  }
68144
68610
 
68145
68611
  // src/cli/publish.ts
68146
- var import_picocolors44 = __toESM(require_picocolors(), 1);
68612
+ var import_picocolors47 = __toESM(require_picocolors(), 1);
68147
68613
  function runPublish() {
68148
68614
  banner("publish — moved");
68149
- f2.error(`${import_picocolors44.default.bold("brainbase publish")} does not exist.`);
68150
- f2.info(`Use ${import_picocolors44.default.cyan("brainbase agent push")} to send your local changes to the cloud.`);
68615
+ f2.error(`${import_picocolors47.default.bold("brainbase publish")} does not exist.`);
68616
+ f2.info(`Use ${import_picocolors47.default.cyan("brainbase agent push")} to send your local changes to the cloud.`);
68151
68617
  process.exit(1);
68152
68618
  }
68153
68619
 
@@ -68446,7 +68912,7 @@ async function runStatus(cwd2) {
68446
68912
  }
68447
68913
 
68448
68914
  // src/cli/token.ts
68449
- var import_picocolors45 = __toESM(require_picocolors(), 1);
68915
+ var import_picocolors48 = __toESM(require_picocolors(), 1);
68450
68916
 
68451
68917
  // src/ui/ink/TokenCards.tsx
68452
68918
  var jsx_dev_runtime17 = __toESM(require_jsx_dev_runtime(), 1);
@@ -68707,6 +69173,10 @@ async function showTokenListCard(props) {
68707
69173
  // src/cli/token.ts
68708
69174
  var DEFAULT_SCOPES = ["read", "publish"];
68709
69175
  var MAX_NAME_LENGTH = 128;
69176
+ var ALLOWED_SCOPES = ["read", "publish", "admin"];
69177
+ function isAllowedScope(value) {
69178
+ return ALLOWED_SCOPES.includes(value);
69179
+ }
68710
69180
  function isExpired2(token) {
68711
69181
  return Boolean(token.expires_at && Date.parse(token.expires_at) <= Date.now());
68712
69182
  }
@@ -68727,7 +69197,14 @@ async function runTokenCreate(args) {
68727
69197
  flagHint: "Pass --name <label>."
68728
69198
  });
68729
69199
  }
68730
- const scopes = args.scopes && args.scopes.length > 0 ? args.scopes : DEFAULT_SCOPES;
69200
+ let scopes;
69201
+ if (args.scopes === undefined) {
69202
+ scopes = DEFAULT_SCOPES;
69203
+ } else if (args.scopes.length === 0) {
69204
+ throw new Error("Usage: brainbase token create --scopes <list> (allowed: read, publish, admin)");
69205
+ } else {
69206
+ scopes = args.scopes;
69207
+ }
68731
69208
  const spinner = de();
68732
69209
  spinner.start("Creating token…");
68733
69210
  const created = await registryApi.createCliToken({
@@ -68812,7 +69289,7 @@ async function runTokenRename(args) {
68812
69289
  return;
68813
69290
  };
68814
69291
  let name;
68815
- if (args.name === undefined) {
69292
+ if (!args.name) {
68816
69293
  const answer = await text({
68817
69294
  message: "New label",
68818
69295
  placeholder: target.name,
@@ -68828,7 +69305,7 @@ async function runTokenRename(args) {
68828
69305
  }
68829
69306
  }
68830
69307
  if (name === target.name.trim()) {
68831
- console.log(`${sym.ok} ${import_picocolors45.default.bold(target.name.trim())} already has that label; nothing to do.`);
69308
+ console.log(`${sym.ok} ${import_picocolors48.default.bold(target.name.trim())} already has that label; nothing to do.`);
68832
69309
  return;
68833
69310
  }
68834
69311
  try {
@@ -68836,27 +69313,32 @@ async function runTokenRename(args) {
68836
69313
  } catch (error) {
68837
69314
  throw withLoginHint(error);
68838
69315
  }
68839
- console.log(`${sym.ok} Renamed ${import_picocolors45.default.dim(target.name)} → ${import_picocolors45.default.bold(name)}`);
69316
+ console.log(`${sym.ok} Renamed ${import_picocolors48.default.dim(target.name)} → ${import_picocolors48.default.bold(name)}`);
68840
69317
  }
68841
69318
  async function runTokenRevoke(args) {
68842
69319
  if (!args.id) {
68843
69320
  console.error("Usage: brainbase token revoke <id>");
68844
69321
  process.exit(1);
68845
69322
  }
68846
- const tokens = await registryApi.listCliTokens();
69323
+ let tokens;
69324
+ try {
69325
+ tokens = await registryApi.listCliTokens();
69326
+ } catch (error) {
69327
+ throw withLoginHint(error);
69328
+ }
68847
69329
  const target = tokens.find((t) => t.id === args.id);
68848
69330
  if (!target) {
68849
69331
  throw new Error(`No token with id ${args.id}. Run \`brainbase token list\` to see yours.`);
68850
69332
  }
68851
69333
  if (target.revoked_at) {
68852
- reconcileDeadToken(target, `${import_picocolors45.default.bold(target.name)} is already revoked.`);
69334
+ reconcileDeadToken(target, `${import_picocolors48.default.bold(target.name)} is already revoked.`);
68853
69335
  return;
68854
69336
  }
68855
69337
  const stored = readToken();
68856
69338
  const isLocalToken = Boolean(stored && stored.token.startsWith(target.prefix));
68857
69339
  if (!autoProceed(args.yes)) {
68858
69340
  const ok = await se({
68859
- message: isLocalToken ? `Revoke ${import_picocolors45.default.bold(target.name)} (${args.id})? This is the token this CLI is using, so it will stop working here too.` : `Revoke ${import_picocolors45.default.bold(target.name)} (${args.id})? CIs and machines using it will stop working.`,
69341
+ message: isLocalToken ? `Revoke ${import_picocolors48.default.bold(target.name)} (${args.id})? This is the token this CLI is using, so it will stop working here too.` : `Revoke ${import_picocolors48.default.bold(target.name)} (${args.id})? CIs and machines using it will stop working.`,
68860
69342
  initialValue: false
68861
69343
  });
68862
69344
  if (!ensureNotCancelled(ok))
@@ -68866,16 +69348,15 @@ async function runTokenRevoke(args) {
68866
69348
  await registryApi.revokeCliToken(args.id);
68867
69349
  } catch (error) {
68868
69350
  if (error instanceof ApiError && error.status === 404) {
68869
- const expiryPassed = Boolean(target.expires_at && Date.parse(target.expires_at) <= Date.now());
68870
- if (expiryPassed) {
68871
- reconcileDeadToken(target, `${import_picocolors45.default.bold(target.name)} had already expired.`);
69351
+ if (isExpired2(target)) {
69352
+ reconcileDeadToken(target, `${import_picocolors48.default.bold(target.name)} had already expired.`);
68872
69353
  return;
68873
69354
  }
68874
69355
  throw new Error(`The server reported no active token with id ${args.id}, but it listed one a moment ago. ` + "The local token has been left alone, since that key may still work. " + "If this server predates `DELETE /v1/registry/cli-tokens/{id}`, revoke from the web app instead.");
68875
69356
  }
68876
69357
  throw error;
68877
69358
  }
68878
- reconcileDeadToken(target, `Revoked ${import_picocolors45.default.bold(target.name)}.`);
69359
+ reconcileDeadToken(target, `Revoked ${import_picocolors48.default.bold(target.name)}.`);
68879
69360
  }
68880
69361
  function reconcileDeadToken(target, headline) {
68881
69362
  let outcome;
@@ -68909,17 +69390,35 @@ function reportLocalToken(headline, outcome) {
68909
69390
  }
68910
69391
  async function runTokenClear() {
68911
69392
  if (!readToken()) {
68912
- console.log(import_picocolors45.default.dim("No local token stored."));
69393
+ console.log(import_picocolors48.default.dim("No local token stored."));
68913
69394
  return;
68914
69395
  }
68915
69396
  clearToken();
68916
69397
  console.log(`${sym.ok} Cleared local token. (Server-side token still active until revoked.)`);
68917
69398
  }
69399
+ var TOKEN_VALUE_FLAGS = new Set(["--name", "-n", "--scope", "--scopes"]);
69400
+ function isValueOfPriorFlag(rest2, index) {
69401
+ return index > 0 && TOKEN_VALUE_FLAGS.has(rest2[index - 1]);
69402
+ }
68918
69403
  function pickFlag(rest2, ...names) {
68919
69404
  for (const n of names) {
68920
- const i = rest2.indexOf(n);
68921
- if (i !== -1 && i + 1 < rest2.length)
68922
- return rest2[i + 1];
69405
+ const prefix = `${n}=`;
69406
+ for (let i = 0;i < rest2.length; i++) {
69407
+ if (isValueOfPriorFlag(rest2, i))
69408
+ continue;
69409
+ const a3 = rest2[i];
69410
+ if (a3 === n) {
69411
+ const v3 = rest2[i + 1];
69412
+ if (v3 === undefined)
69413
+ return "";
69414
+ const label = n === "--name" || n === "-n";
69415
+ if (!label && v3.startsWith("-"))
69416
+ return "";
69417
+ return v3;
69418
+ }
69419
+ if (a3.startsWith(prefix))
69420
+ return a3.slice(prefix.length);
69421
+ }
68923
69422
  }
68924
69423
  return;
68925
69424
  }
@@ -68938,9 +69437,17 @@ function firstPositional(rest2, ...valueFlags) {
68938
69437
  return;
68939
69438
  }
68940
69439
  function parseScopes(raw) {
68941
- if (!raw)
69440
+ if (raw === undefined)
68942
69441
  return;
68943
- return raw.split(",").map((s3) => s3.trim()).filter((s3) => s3.length > 0);
69442
+ const scopes = raw.split(",").map((s3) => s3.trim().toLowerCase()).filter((s3) => s3.length > 0);
69443
+ if (scopes.length === 0) {
69444
+ throw new Error("Usage: brainbase token create --scopes <list> (allowed: read, publish, admin)");
69445
+ }
69446
+ const unknown = scopes.filter((s3) => !isAllowedScope(s3));
69447
+ if (unknown.length > 0) {
69448
+ throw new Error(`Unknown scope${unknown.length === 1 ? "" : "s"} ${unknown.join(", ")} — allowed: read, publish, admin`);
69449
+ }
69450
+ return scopes;
68944
69451
  }
68945
69452
  async function runToken(sub, rest2, args) {
68946
69453
  const nameFlag = args.name || pickFlag(rest2, "--name", "-n");
@@ -68983,32 +69490,32 @@ async function runToken(sub, rest2, args) {
68983
69490
  function printTokenHelp() {
68984
69491
  const out = [];
68985
69492
  out.push("");
68986
- out.push(` ${import_picocolors45.default.bold("brainbase token")} ${import_picocolors45.default.dim("<command>")}`);
69493
+ out.push(` ${import_picocolors48.default.bold("brainbase token")} ${import_picocolors48.default.dim("<command>")}`);
68987
69494
  out.push("");
68988
- out.push(` ${import_picocolors45.default.cyan("create")} ${import_picocolors45.default.dim("issue a new long-lived CLI key (PAT)")}`);
68989
- out.push(` ${import_picocolors45.default.cyan("list")} ${import_picocolors45.default.dim("show your tokens")}`);
68990
- out.push(` ${import_picocolors45.default.cyan("rename")} ${import_picocolors45.default.dim("<id>")} ${import_picocolors45.default.dim("relabel a token by id")}`);
68991
- out.push(` ${import_picocolors45.default.cyan("revoke")} ${import_picocolors45.default.dim("<id>")} ${import_picocolors45.default.dim("revoke a token by id")}`);
68992
- out.push(` ${import_picocolors45.default.cyan("clear")} ${import_picocolors45.default.dim("forget the local token (does not revoke)")}`);
69495
+ out.push(` ${import_picocolors48.default.cyan("create")} ${import_picocolors48.default.dim("issue a new long-lived CLI key (PAT)")}`);
69496
+ out.push(` ${import_picocolors48.default.cyan("list")} ${import_picocolors48.default.dim("show your tokens")}`);
69497
+ out.push(` ${import_picocolors48.default.cyan("rename")} ${import_picocolors48.default.dim("<id>")} ${import_picocolors48.default.dim("relabel a token by id")}`);
69498
+ out.push(` ${import_picocolors48.default.cyan("revoke")} ${import_picocolors48.default.dim("<id>")} ${import_picocolors48.default.dim("revoke a token by id")}`);
69499
+ out.push(` ${import_picocolors48.default.cyan("clear")} ${import_picocolors48.default.dim("forget the local token (does not revoke)")}`);
68993
69500
  out.push("");
68994
- out.push(` ${import_picocolors45.default.bold("create flags")}`);
68995
- out.push(` ${import_picocolors45.default.cyan("--name, -n")} ${import_picocolors45.default.dim("<label>")} ${import_picocolors45.default.dim("token label (prompted if omitted)")}`);
68996
- out.push(` ${import_picocolors45.default.cyan("--scopes")} ${import_picocolors45.default.dim("<list>")} ${import_picocolors45.default.dim("comma-separated; allowed: read, publish, admin")}`);
68997
- out.push(` ${import_picocolors45.default.dim("default: read,publish")}`);
69501
+ out.push(` ${import_picocolors48.default.bold("create flags")}`);
69502
+ out.push(` ${import_picocolors48.default.cyan("--name, -n")} ${import_picocolors48.default.dim("<label>")} ${import_picocolors48.default.dim("token label (prompted if omitted)")}`);
69503
+ out.push(` ${import_picocolors48.default.cyan("--scopes")} ${import_picocolors48.default.dim("<list>")} ${import_picocolors48.default.dim("comma-separated; allowed: read, publish, admin")}`);
69504
+ out.push(` ${import_picocolors48.default.dim("default: read,publish")}`);
68998
69505
  out.push("");
68999
- out.push(` ${import_picocolors45.default.bold("rename flags")}`);
69000
- out.push(` ${import_picocolors45.default.cyan("--name, -n")} ${import_picocolors45.default.dim("<label>")} ${import_picocolors45.default.dim("new label (prompted if omitted)")}`);
69506
+ out.push(` ${import_picocolors48.default.bold("rename flags")}`);
69507
+ out.push(` ${import_picocolors48.default.cyan("--name, -n")} ${import_picocolors48.default.dim("<label>")} ${import_picocolors48.default.dim("new label (prompted if omitted)")}`);
69001
69508
  out.push("");
69002
69509
  console.log(out.join(`
69003
69510
  `));
69004
69511
  }
69005
69512
 
69006
69513
  // src/cli/mcp.ts
69007
- var import_picocolors46 = __toESM(require_picocolors(), 1);
69514
+ var import_picocolors49 = __toESM(require_picocolors(), 1);
69008
69515
 
69009
69516
  // src/core/mcp-check/collect-servers.ts
69010
69517
  import path87 from "node:path";
69011
- import fs79 from "node:fs";
69518
+ import fs80 from "node:fs";
69012
69519
  function collectServers(cwd2, env3 = process.env) {
69013
69520
  const out = [];
69014
69521
  const seen = new Set;
@@ -69062,7 +69569,7 @@ function* readResolvedMcps(cwd2) {
69062
69569
  const p2 = path87.join(cwd2, ".brainbase", "resolved-mcps.json");
69063
69570
  let raw;
69064
69571
  try {
69065
- raw = fs79.readFileSync(p2, "utf-8");
69572
+ raw = fs80.readFileSync(p2, "utf-8");
69066
69573
  } catch {
69067
69574
  return;
69068
69575
  }
@@ -69122,10 +69629,19 @@ function classifyError(err) {
69122
69629
  }
69123
69630
  return "protocol_error";
69124
69631
  }
69632
+ var CREDENTIAL_NAMES = "(x-api-key|api[-_]?key|auth[-_]?token|access[-_]?token|private[-_]?token|secret)";
69125
69633
  var REDACTIONS = [
69126
69634
  [/https?:\/\/[^\s'"`]+/gi, "[url]"],
69127
69635
  [/Bearer\s+\S+/gi, "Bearer [redacted]"],
69128
- [/\bbb(?:pat|_live)_[A-Za-z0-9._-]+/g, "[redacted]"]
69636
+ [/\bbb(?:pat|_live)_[A-Za-z0-9._-]+/g, "[redacted]"],
69637
+ [
69638
+ new RegExp(`\\b${CREDENTIAL_NAMES}\\b([\\s:=]*)(["'])[^"']+\\3`, "gi"),
69639
+ "$1$2$3[redacted]$3"
69640
+ ],
69641
+ [
69642
+ new RegExp(`\\b${CREDENTIAL_NAMES}\\b(\\s*[:=]\\s*)["']?[^\\s,;"'}]+`, "gi"),
69643
+ "$1$2[redacted]"
69644
+ ]
69129
69645
  ];
69130
69646
  function redactSecrets2(msg) {
69131
69647
  let out = msg;
@@ -77252,11 +77768,11 @@ function withTimeout(inner, ms2, label) {
77252
77768
  function isTransient(status) {
77253
77769
  return status === "unreachable";
77254
77770
  }
77255
- async function probeWithConnector(server, connect, opts) {
77771
+ async function probeWithConnector(server, connect2, opts) {
77256
77772
  let lastErr;
77257
77773
  for (let attempt2 = 0;attempt2 < 2; attempt2++) {
77258
77774
  try {
77259
- const { toolCount } = await connect(server, opts.timeoutMs);
77775
+ const { toolCount } = await connect2(server, opts.timeoutMs);
77260
77776
  return { name: server.name, status: "ok", tool_count: toolCount, error: null };
77261
77777
  } catch (err) {
77262
77778
  lastErr = err;
@@ -77332,42 +77848,177 @@ async function runMcpCheck(cwd2, options) {
77332
77848
  }
77333
77849
  }));
77334
77850
  results.sort((a3, b4) => a3.name.localeCompare(b4.name));
77335
- const report = {
77851
+ const report2 = {
77336
77852
  check_status: deriveCheckStatus(results),
77337
77853
  servers: results
77338
77854
  };
77339
77855
  if (options.json) {
77340
- write(JSON.stringify(report) + `
77856
+ write(JSON.stringify(report2) + `
77341
77857
  `);
77342
77858
  } else {
77343
- write(renderHuman(report));
77859
+ write(renderHuman(report2));
77344
77860
  }
77345
- return { exitCode: 0, report };
77861
+ return { exitCode: 0, report: report2 };
77346
77862
  } catch (err) {
77347
77863
  writeErr(`brainbase mcp check failed to run: ${truncateError(err) ?? "unknown error"}
77348
77864
  `);
77349
77865
  return { exitCode: 1 };
77350
77866
  }
77351
77867
  }
77352
- function renderHuman(report) {
77868
+ function renderHuman(report2) {
77353
77869
  const lines = [];
77354
- if (report.check_status === "skipped") {
77355
- lines.push(import_picocolors46.default.dim("No MCP servers configured — nothing to check."));
77870
+ if (report2.check_status === "skipped") {
77871
+ lines.push(import_picocolors49.default.dim("No MCP servers configured — nothing to check."));
77356
77872
  return lines.join(`
77357
77873
  `) + `
77358
77874
  `;
77359
77875
  }
77360
- for (const s3 of report.servers) {
77361
- const mark = s3.status === "ok" ? import_picocolors46.default.green("✓") : s3.status === "auth_failed" ? import_picocolors46.default.red("✗") : import_picocolors46.default.yellow("⚠");
77362
- 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}` : ""));
77876
+ for (const s3 of report2.servers) {
77877
+ const mark = s3.status === "ok" ? import_picocolors49.default.green("✓") : s3.status === "auth_failed" ? import_picocolors49.default.red("✗") : import_picocolors49.default.yellow("⚠");
77878
+ const detail = s3.status === "ok" ? import_picocolors49.default.dim(`${s3.tool_count} tool${s3.tool_count === 1 ? "" : "s"}`) : import_picocolors49.default.dim(s3.status + (s3.error ? ` — ${s3.error}` : ""));
77363
77879
  lines.push(` ${mark} ${s3.name} ${detail}`);
77364
77880
  }
77365
- const summary = report.check_status === "ok" ? import_picocolors46.default.green("All MCP servers connected.") : import_picocolors46.default.yellow("Some MCP servers are unhealthy.");
77881
+ const summary = report2.check_status === "ok" ? import_picocolors49.default.green("All MCP servers connected.") : import_picocolors49.default.yellow("Some MCP servers are unhealthy.");
77366
77882
  lines.push("", summary);
77367
77883
  return lines.join(`
77368
77884
  `) + `
77369
77885
  `;
77370
77886
  }
77887
+ async function runMcpList(cwd2, options) {
77888
+ const write = options.write ?? ((s3) => process.stdout.write(s3));
77889
+ const writeErr = options.writeErr ?? ((s3) => process.stderr.write(s3));
77890
+ const fetchServers = options.fetchServers ?? ((id) => api.listAgentMcpServers(id));
77891
+ const resolveAgentId = options.resolveAgentId ?? ((dir) => readLink(dir)?.agent_id ?? null);
77892
+ const agentId = resolveAgentId(cwd2);
77893
+ if (!agentId) {
77894
+ if (options.json) {
77895
+ write(JSON.stringify({ linked: false, servers: [] }) + `
77896
+ `);
77897
+ } else {
77898
+ writeErr("This folder is not linked to any agent. Run `brainbase link` first.\n");
77899
+ }
77900
+ return 1;
77901
+ }
77902
+ let report2;
77903
+ try {
77904
+ report2 = await fetchServers(agentId);
77905
+ } catch (err) {
77906
+ if (options.json) {
77907
+ write(JSON.stringify({ error: err.message }) + `
77908
+ `);
77909
+ } else {
77910
+ writeErr(`brainbase mcp list failed: ${err.message}
77911
+ `);
77912
+ }
77913
+ return 1;
77914
+ }
77915
+ if (options.json) {
77916
+ write(JSON.stringify({ linked: true, ...sanitizeReport(report2) }) + `
77917
+ `);
77918
+ } else {
77919
+ write(renderServerList(report2.servers));
77920
+ }
77921
+ return 0;
77922
+ }
77923
+ function sanitizeReport(report2) {
77924
+ return {
77925
+ ...report2,
77926
+ servers: report2.servers.map((s3) => ({
77927
+ ...s3,
77928
+ url: sanitizeUrl(s3.url),
77929
+ command: sanitizeCommand(s3.command),
77930
+ last_error: s3.last_error ? truncateError(s3.last_error) : s3.last_error
77931
+ }))
77932
+ };
77933
+ }
77934
+ function sanitizeUrl(url2) {
77935
+ if (!url2)
77936
+ return url2;
77937
+ try {
77938
+ const parsed = new URL(url2);
77939
+ parsed.search = "";
77940
+ parsed.hash = "";
77941
+ parsed.username = "";
77942
+ parsed.password = "";
77943
+ return parsed.toString();
77944
+ } catch {
77945
+ return null;
77946
+ }
77947
+ }
77948
+ function sanitizeCommand(command) {
77949
+ if (!command)
77950
+ return command;
77951
+ return command.trim().split(/\s+/)[0] ?? null;
77952
+ }
77953
+ var AUTH_LABEL = {
77954
+ none: "",
77955
+ oauth_required: "needs authorization",
77956
+ oauth_connected: "authorized",
77957
+ oauth_expired: "authorization expired — reconnect"
77958
+ };
77959
+ var HEALTH_LABEL = {
77960
+ unreachable: "unreachable",
77961
+ protocol_error: "connection error",
77962
+ auth_failed: "last check failed to authenticate",
77963
+ expired: "last check saw an expired token",
77964
+ unknown: "last check inconclusive"
77965
+ };
77966
+ function healthLabel(server) {
77967
+ const status = server.last_status;
77968
+ if (!status || status === "ok")
77969
+ return;
77970
+ return HEALTH_LABEL[status] ?? `last check: ${status}`;
77971
+ }
77972
+ function isUnhealthy(server) {
77973
+ return Boolean(server.last_status) && server.last_status !== "ok";
77974
+ }
77975
+ function renderServerList(servers) {
77976
+ if (servers.length === 0) {
77977
+ return import_picocolors49.default.dim("No MCP servers configured for this agent.") + `
77978
+ `;
77979
+ }
77980
+ const lines = [""];
77981
+ for (const s3 of servers) {
77982
+ const mark = s3.auth === "oauth_expired" ? import_picocolors49.default.red("✗") : s3.auth === "oauth_required" || isUnhealthy(s3) ? import_picocolors49.default.yellow("!") : !s3.is_enabled ? import_picocolors49.default.dim("·") : import_picocolors49.default.green("✓");
77983
+ const bits = [s3.transport];
77984
+ if (!s3.is_enabled)
77985
+ bits.push("disabled");
77986
+ const label = AUTH_LABEL[s3.auth];
77987
+ if (label)
77988
+ bits.push(label);
77989
+ const health = healthLabel(s3);
77990
+ if (health)
77991
+ bits.push(health);
77992
+ const expiry = describeExpiry(s3);
77993
+ if (expiry)
77994
+ bits.push(expiry);
77995
+ lines.push(` ${mark} ${import_picocolors49.default.bold(s3.name)} ${import_picocolors49.default.dim(bits.join(" · "))}`);
77996
+ }
77997
+ if (servers.some((s3) => s3.auth === "oauth_required" || s3.auth === "oauth_expired")) {
77998
+ lines.push("", import_picocolors49.default.dim("Authorize OAuth-backed servers in the web app; the CLI cannot run that flow yet."));
77999
+ }
78000
+ lines.push("");
78001
+ return lines.join(`
78002
+ `);
78003
+ }
78004
+ var MAX_EXPIRY_DAYS = 90;
78005
+ function describeExpiry(server, now2 = Date.now()) {
78006
+ if (server.auth !== "oauth_connected" || !server.oauth_token_expires_at)
78007
+ return;
78008
+ const at3 = Date.parse(server.oauth_token_expires_at);
78009
+ if (!Number.isFinite(at3))
78010
+ return;
78011
+ const minutes = Math.round((at3 - now2) / 60000);
78012
+ if (minutes <= 0)
78013
+ return;
78014
+ if (minutes < 60)
78015
+ return `expires in ${minutes}m`;
78016
+ const hours = Math.round(minutes / 60);
78017
+ if (hours < 48)
78018
+ return `expires in ${hours}h`;
78019
+ const days = Math.round(hours / 24);
78020
+ return days > MAX_EXPIRY_DAYS ? `expires in >${MAX_EXPIRY_DAYS}d` : `expires in ${days}d`;
78021
+ }
77371
78022
  async function runMcp(cwd2, sub, _argv, options) {
77372
78023
  const writeErr = options.writeErr ?? ((s3) => process.stderr.write(s3));
77373
78024
  switch (sub) {
@@ -77375,17 +78026,19 @@ async function runMcp(cwd2, sub, _argv, options) {
77375
78026
  const { exitCode } = await runMcpCheck(cwd2, options);
77376
78027
  return exitCode;
77377
78028
  }
78029
+ case "list":
78030
+ return runMcpList(cwd2, options);
77378
78031
  default:
77379
78032
  writeErr(`Unknown mcp subcommand: ${sub ?? "(none)"}
77380
78033
  `);
77381
- writeErr(`Usage: brainbase mcp check [--json]
78034
+ writeErr(`Usage: brainbase mcp <check|list> [--json]
77382
78035
  `);
77383
78036
  return 1;
77384
78037
  }
77385
78038
  }
77386
78039
 
77387
78040
  // src/cli/task.ts
77388
- var import_picocolors47 = __toESM(require_picocolors(), 1);
78041
+ var import_picocolors50 = __toESM(require_picocolors(), 1);
77389
78042
 
77390
78043
  // src/cli/task-create.ts
77391
78044
  import { randomUUID as randomUUID2 } from "node:crypto";
@@ -77571,31 +78224,31 @@ async function runTask(cwd2, sub, args) {
77571
78224
  function printHelp4() {
77572
78225
  const out = [];
77573
78226
  out.push("");
77574
- out.push(` ${import_picocolors47.default.bold("brainbase task")} ${import_picocolors47.default.dim("<sub> [options]")}`);
78227
+ out.push(` ${import_picocolors50.default.bold("brainbase task")} ${import_picocolors50.default.dim("<sub> [options]")}`);
77575
78228
  out.push("");
77576
- 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")}`);
78229
+ out.push(` ${import_picocolors50.default.cyan("create")} ${import_picocolors50.default.dim("--message <text>")} ${import_picocolors50.default.dim("create a task and start its first run")}`);
77577
78230
  out.push("");
77578
- out.push(` ${import_picocolors47.default.bold("create flags")}`);
77579
- out.push(` ${import_picocolors47.default.dim("--message <text>")} required first user message`);
77580
- out.push(` ${import_picocolors47.default.dim("--agent <id>")} override the claimed agent in brainbase.agent.yaml`);
77581
- out.push(` ${import_picocolors47.default.dim("--title <text>")} optional task title`);
77582
- out.push(` ${import_picocolors47.default.dim("--model <id>")} optional model override`);
77583
- out.push(` ${import_picocolors47.default.dim("--json")} print task_id, agent_id, and status as JSON`);
78231
+ out.push(` ${import_picocolors50.default.bold("create flags")}`);
78232
+ out.push(` ${import_picocolors50.default.dim("--message <text>")} required first user message`);
78233
+ out.push(` ${import_picocolors50.default.dim("--agent <id>")} override the claimed agent in brainbase.agent.yaml`);
78234
+ out.push(` ${import_picocolors50.default.dim("--title <text>")} optional task title`);
78235
+ out.push(` ${import_picocolors50.default.dim("--model <id>")} optional model override`);
78236
+ out.push(` ${import_picocolors50.default.dim("--json")} print task_id, agent_id, and status as JSON`);
77584
78237
  out.push("");
77585
- out.push(` ${import_picocolors47.default.dim("Flag-like values:")} use ${import_picocolors47.default.cyan("--flag=value")} or ${import_picocolors47.default.cyan("--flag -- <value>")}`);
78238
+ out.push(` ${import_picocolors50.default.dim("Flag-like values:")} use ${import_picocolors50.default.cyan("--flag=value")} or ${import_picocolors50.default.cyan("--flag -- <value>")}`);
77586
78239
  out.push("");
77587
78240
  console.log(out.join(`
77588
78241
  `));
77589
78242
  }
77590
78243
 
77591
78244
  // src/cli/benchmark.ts
77592
- var import_picocolors48 = __toESM(require_picocolors(), 1);
78245
+ var import_picocolors51 = __toESM(require_picocolors(), 1);
77593
78246
  import {
77594
78247
  execFileSync as execFileSync3,
77595
78248
  spawn as spawn5
77596
78249
  } from "node:child_process";
77597
78250
  import crypto7 from "node:crypto";
77598
- import fs81 from "node:fs";
78251
+ import fs82 from "node:fs";
77599
78252
  import os17 from "node:os";
77600
78253
  import path89 from "node:path";
77601
78254
 
@@ -77605,7 +78258,7 @@ import {
77605
78258
  spawn as spawn4
77606
78259
  } from "node:child_process";
77607
78260
  import crypto6 from "node:crypto";
77608
- import fs80 from "node:fs";
78261
+ import fs81 from "node:fs";
77609
78262
  import os16 from "node:os";
77610
78263
  import path88 from "node:path";
77611
78264
  import { pipeline as pipeline2 } from "node:stream/promises";
@@ -77855,19 +78508,19 @@ function canonicalFuturePath(input) {
77855
78508
  const resolved = path88.resolve(input);
77856
78509
  const suffix = [];
77857
78510
  let current = resolved;
77858
- while (!fs80.existsSync(current)) {
78511
+ while (!fs81.existsSync(current)) {
77859
78512
  const parent = path88.dirname(current);
77860
78513
  if (parent === current)
77861
78514
  break;
77862
78515
  suffix.unshift(path88.basename(current));
77863
78516
  current = parent;
77864
78517
  }
77865
- const canonicalBase = fs80.realpathSync(current);
78518
+ const canonicalBase = fs81.realpathSync(current);
77866
78519
  return path88.join(canonicalBase, ...suffix);
77867
78520
  }
77868
78521
  function validateRoots(spec) {
77869
78522
  const workspace = path88.resolve(spec.workspace_root);
77870
- if (!fs80.existsSync(workspace) || fs80.lstatSync(workspace).isSymbolicLink() || !fs80.lstatSync(workspace).isDirectory()) {
78523
+ if (!fs81.existsSync(workspace) || fs81.lstatSync(workspace).isSymbolicLink() || !fs81.lstatSync(workspace).isDirectory()) {
77871
78524
  throw new BenchmarkPhaseError("invalid_workspace_root", "workspace_root must be an existing real directory");
77872
78525
  }
77873
78526
  const canonicalWorkspace = canonicalFuturePath(workspace);
@@ -77876,7 +78529,7 @@ function validateRoots(spec) {
77876
78529
  if (staging !== expectedStaging) {
77877
78530
  throw new BenchmarkPhaseError("invalid_staging_root", `staging_root must be ${expectedStaging}`);
77878
78531
  }
77879
- if (!fs80.existsSync(staging) || fs80.lstatSync(staging).isSymbolicLink() || !fs80.lstatSync(staging).isDirectory() || fs80.realpathSync(staging) !== path88.join(canonicalWorkspace, ".brainbase", "benchmark", spec.attempt_id, "incoming")) {
78532
+ if (!fs81.existsSync(staging) || fs81.lstatSync(staging).isSymbolicLink() || !fs81.lstatSync(staging).isDirectory() || fs81.realpathSync(staging) !== path88.join(canonicalWorkspace, ".brainbase", "benchmark", spec.attempt_id, "incoming")) {
77880
78533
  throw new BenchmarkPhaseError("invalid_staging_root", "staging_root must be a real directory under workspace_root");
77881
78534
  }
77882
78535
  const canonicalLogs = validateExternalRoot("logs_root", spec.logs_root, canonicalWorkspace);
@@ -77892,7 +78545,7 @@ function validateExternalRoot(label, input, canonicalWorkspace) {
77892
78545
  if (candidate === path88.parse(candidate).root) {
77893
78546
  throw new BenchmarkPhaseError(`invalid_${label}`, `${label} cannot be a filesystem root`);
77894
78547
  }
77895
- if (fs80.existsSync(candidate) && fs80.lstatSync(candidate).isSymbolicLink()) {
78548
+ if (fs81.existsSync(candidate) && fs81.lstatSync(candidate).isSymbolicLink()) {
77896
78549
  throw new BenchmarkPhaseError(`invalid_${label}`, `${label} cannot be a symlink`);
77897
78550
  }
77898
78551
  const canonicalCandidate = canonicalFuturePath(candidate);
@@ -77922,9 +78575,9 @@ function assertNoSymlinkTraversal(root, relative) {
77922
78575
  let current = path88.resolve(root);
77923
78576
  for (const segment of rel.split("/").slice(0, -1)) {
77924
78577
  current = path88.join(current, segment);
77925
- if (!fs80.existsSync(current))
78578
+ if (!fs81.existsSync(current))
77926
78579
  continue;
77927
- if (fs80.lstatSync(current).isSymbolicLink()) {
78580
+ if (fs81.lstatSync(current).isSymbolicLink()) {
77928
78581
  throw new BenchmarkPhaseError("unsafe_path", `path traverses symlink: ${relative}`);
77929
78582
  }
77930
78583
  }
@@ -77934,9 +78587,9 @@ function assertOpenedFileWithinRoot(root, filePath, openedStat, label) {
77934
78587
  let canonicalFile;
77935
78588
  let currentStat;
77936
78589
  try {
77937
- canonicalRoot = fs80.realpathSync(root);
77938
- canonicalFile = fs80.realpathSync(filePath);
77939
- currentStat = fs80.statSync(filePath);
78590
+ canonicalRoot = fs81.realpathSync(root);
78591
+ canonicalFile = fs81.realpathSync(filePath);
78592
+ currentStat = fs81.statSync(filePath);
77940
78593
  } catch {
77941
78594
  throw new BenchmarkPhaseError("unsafe_path", `${label} changed while it was opened`);
77942
78595
  }
@@ -77945,10 +78598,10 @@ function assertOpenedFileWithinRoot(root, filePath, openedStat, label) {
77945
78598
  }
77946
78599
  }
77947
78600
  function openRegularFileNoFollow(filePath, label, root) {
77948
- const noFollow = typeof fs80.constants.O_NOFOLLOW === "number" ? fs80.constants.O_NOFOLLOW : 0;
78601
+ const noFollow = typeof fs81.constants.O_NOFOLLOW === "number" ? fs81.constants.O_NOFOLLOW : 0;
77949
78602
  let fd;
77950
78603
  try {
77951
- fd = fs80.openSync(filePath, fs80.constants.O_RDONLY | noFollow);
78604
+ fd = fs81.openSync(filePath, fs81.constants.O_RDONLY | noFollow);
77952
78605
  } catch (error2) {
77953
78606
  const code = error2.code;
77954
78607
  if (code === "ELOOP") {
@@ -77956,16 +78609,16 @@ function openRegularFileNoFollow(filePath, label, root) {
77956
78609
  }
77957
78610
  throw error2;
77958
78611
  }
77959
- const stat = fs80.fstatSync(fd);
78612
+ const stat = fs81.fstatSync(fd);
77960
78613
  if (!stat.isFile()) {
77961
- fs80.closeSync(fd);
78614
+ fs81.closeSync(fd);
77962
78615
  throw new BenchmarkPhaseError("invalid_input", `${label} must be a regular file`);
77963
78616
  }
77964
78617
  if (root) {
77965
78618
  try {
77966
78619
  assertOpenedFileWithinRoot(root, filePath, stat, label);
77967
78620
  } catch (error2) {
77968
- fs80.closeSync(fd);
78621
+ fs81.closeSync(fd);
77969
78622
  throw error2;
77970
78623
  }
77971
78624
  }
@@ -77973,7 +78626,7 @@ function openRegularFileNoFollow(filePath, label, root) {
77973
78626
  }
77974
78627
  async function sha256OfDescriptor(fd) {
77975
78628
  const hash = crypto6.createHash("sha256");
77976
- const stream = fs80.createReadStream("", {
78629
+ const stream = fs81.createReadStream("", {
77977
78630
  fd,
77978
78631
  autoClose: false,
77979
78632
  start: 0
@@ -77984,7 +78637,7 @@ async function sha256OfDescriptor(fd) {
77984
78637
  return hash.digest("hex");
77985
78638
  }
77986
78639
  function readDescriptor(fd) {
77987
- return fs80.readFileSync(fd);
78640
+ return fs81.readFileSync(fd);
77988
78641
  }
77989
78642
  function assertWritableDestination(root, relative) {
77990
78643
  const rel = normalizedRootRelative(relative);
@@ -77994,9 +78647,9 @@ function assertWritableDestination(root, relative) {
77994
78647
  const segments = rel.split("/");
77995
78648
  for (const segment of segments.slice(0, -1)) {
77996
78649
  current = path88.join(current, segment);
77997
- if (!fs80.existsSync(current))
78650
+ if (!fs81.existsSync(current))
77998
78651
  continue;
77999
- const stat = fs80.lstatSync(current);
78652
+ const stat = fs81.lstatSync(current);
78000
78653
  if (stat.isSymbolicLink()) {
78001
78654
  throw new BenchmarkPhaseError("unsafe_path", `path traverses symlink: ${relative}`);
78002
78655
  }
@@ -78005,7 +78658,7 @@ function assertWritableDestination(root, relative) {
78005
78658
  }
78006
78659
  }
78007
78660
  const destination = path88.resolve(root, rel);
78008
- if (fs80.existsSync(destination) && fs80.lstatSync(destination).isDirectory()) {
78661
+ if (fs81.existsSync(destination) && fs81.lstatSync(destination).isDirectory()) {
78009
78662
  throw new BenchmarkPhaseError("destination_conflict", `file destination is an existing directory: ${relative}`);
78010
78663
  }
78011
78664
  }
@@ -78037,7 +78690,7 @@ function sourcePath(stagingRoot, relative) {
78037
78690
  assertNoSymlinkTraversal(stagingRoot, rel);
78038
78691
  let stat;
78039
78692
  try {
78040
- stat = fs80.lstatSync(source);
78693
+ stat = fs81.lstatSync(source);
78041
78694
  } catch {
78042
78695
  throw new BenchmarkPhaseError("missing_input", `staged input does not exist: ${relative}`);
78043
78696
  }
@@ -78066,12 +78719,12 @@ async function verifyRecordsUnchanged(records, spec) {
78066
78719
  const relative = safeRelPath(record3.path);
78067
78720
  assertNoSymlinkTraversal(root, relative);
78068
78721
  const candidate = path88.resolve(root, relative);
78069
- if (!isWithin(root, candidate) || !fs80.existsSync(candidate)) {
78722
+ if (!isWithin(root, candidate) || !fs81.existsSync(candidate)) {
78070
78723
  throw new BenchmarkPhaseError("evidence_tampered", `evidence was removed during evaluation: ${record3.root}:${record3.path}`);
78071
78724
  }
78072
- const stat = fs80.lstatSync(candidate);
78725
+ const stat = fs81.lstatSync(candidate);
78073
78726
  if (record3.kind === "symlink") {
78074
- const target = stat.isSymbolicLink() ? fs80.readlinkSync(candidate) : null;
78727
+ const target = stat.isSymbolicLink() ? fs81.readlinkSync(candidate) : null;
78075
78728
  if (target === null || Buffer.byteLength(target) !== record3.size || sha256(target) !== record3.sha256) {
78076
78729
  throw new BenchmarkPhaseError("evidence_tampered", `evidence changed during evaluation: ${record3.root}:${record3.path}`);
78077
78730
  }
@@ -78086,7 +78739,7 @@ async function verifyRecordsUnchanged(records, spec) {
78086
78739
  throw new BenchmarkPhaseError("evidence_tampered", `evidence changed during evaluation: ${record3.root}:${record3.path}`);
78087
78740
  }
78088
78741
  } finally {
78089
- fs80.closeSync(opened.fd);
78742
+ fs81.closeSync(opened.fd);
78090
78743
  }
78091
78744
  }
78092
78745
  }
@@ -78102,35 +78755,35 @@ async function verifyInput(stagingRoot, material) {
78102
78755
  throw new BenchmarkPhaseError("digest_mismatch", `checksum mismatch for ${material.source}`, { expected: material.sha256, actual });
78103
78756
  }
78104
78757
  } finally {
78105
- fs80.closeSync(opened.fd);
78758
+ fs81.closeSync(opened.fd);
78106
78759
  }
78107
78760
  return source;
78108
78761
  }
78109
78762
  async function atomicCopy(source, destination, mode, sourceRoot) {
78110
- fs80.mkdirSync(path88.dirname(destination), { recursive: true });
78763
+ fs81.mkdirSync(path88.dirname(destination), { recursive: true });
78111
78764
  const temporary = `${destination}.${process.pid}.${crypto6.randomBytes(6).toString("hex")}.tmp`;
78112
78765
  const opened = openRegularFileNoFollow(source, `copy source ${source}`, sourceRoot);
78113
78766
  try {
78114
- await pipeline2(fs80.createReadStream("", {
78767
+ await pipeline2(fs81.createReadStream("", {
78115
78768
  fd: opened.fd,
78116
78769
  autoClose: false,
78117
78770
  start: 0
78118
- }), fs80.createWriteStream(temporary, {
78771
+ }), fs81.createWriteStream(temporary, {
78119
78772
  flags: "wx",
78120
78773
  mode: 384
78121
78774
  }));
78122
- fs80.chmodSync(temporary, mode ?? opened.stat.mode & 511);
78123
- fs80.renameSync(temporary, destination);
78775
+ fs81.chmodSync(temporary, mode ?? opened.stat.mode & 511);
78776
+ fs81.renameSync(temporary, destination);
78124
78777
  } finally {
78125
- fs80.closeSync(opened.fd);
78126
- fs80.rmSync(temporary, { force: true });
78778
+ fs81.closeSync(opened.fd);
78779
+ fs81.rmSync(temporary, { force: true });
78127
78780
  }
78128
78781
  }
78129
78782
  async function recordFile(root, filePath, rootName, kind = "file") {
78130
78783
  const relative = path88.relative(root, filePath).replace(/\\/g, "/");
78131
78784
  if (kind === "symlink") {
78132
- const stat = fs80.lstatSync(filePath);
78133
- const target = fs80.readlinkSync(filePath);
78785
+ const stat = fs81.lstatSync(filePath);
78786
+ const target = fs81.readlinkSync(filePath);
78134
78787
  return {
78135
78788
  root: rootName,
78136
78789
  path: relative,
@@ -78150,7 +78803,7 @@ async function recordFile(root, filePath, rootName, kind = "file") {
78150
78803
  mode: opened.stat.mode & 511
78151
78804
  };
78152
78805
  } finally {
78153
- fs80.closeSync(opened.fd);
78806
+ fs81.closeSync(opened.fd);
78154
78807
  }
78155
78808
  }
78156
78809
  async function copyMaterial(material, sourceRoot, destinationRoot, destinationRootName, protectWorkspace) {
@@ -78172,7 +78825,7 @@ async function copyMaterial(material, sourceRoot, destinationRoot, destinationRo
78172
78825
  }
78173
78826
  return [record3];
78174
78827
  }
78175
- const temporary = fs80.mkdtempSync(path88.join(os16.tmpdir(), "brainbase-benchmark-"));
78828
+ const temporary = fs81.mkdtempSync(path88.join(os16.tmpdir(), "brainbase-benchmark-"));
78176
78829
  try {
78177
78830
  const verifiedArchive = path88.join(temporary, "material.tar.gz");
78178
78831
  await atomicCopy(source, verifiedArchive, 384, sourceRoot);
@@ -78190,7 +78843,7 @@ async function copyMaterial(material, sourceRoot, destinationRoot, destinationRo
78190
78843
  const outputs = [];
78191
78844
  for (const extractedRel of extracted.sort()) {
78192
78845
  const sourceFile = path88.resolve(extractedRoot, safeRelPath(extractedRel));
78193
- const stat = fs80.lstatSync(sourceFile);
78846
+ const stat = fs81.lstatSync(sourceFile);
78194
78847
  if (!stat.isFile())
78195
78848
  continue;
78196
78849
  const combined = destinationRel === "." ? safeRelPath(extractedRel) : safeRelPath(path88.posix.join(destinationRel, extractedRel));
@@ -78205,7 +78858,7 @@ async function copyMaterial(material, sourceRoot, destinationRoot, destinationRo
78205
78858
  }
78206
78859
  return outputs;
78207
78860
  } finally {
78208
- fs80.rmSync(temporary, { recursive: true, force: true });
78861
+ fs81.rmSync(temporary, { recursive: true, force: true });
78209
78862
  }
78210
78863
  }
78211
78864
  async function preflightMaterial(material, sourceRoot, destinationRoot, protectWorkspace) {
@@ -78221,7 +78874,7 @@ async function preflightMaterial(material, sourceRoot, destinationRoot, protectW
78221
78874
  assertWritableDestination(destinationRoot, destinationRel);
78222
78875
  return [destinationRel];
78223
78876
  }
78224
- const temporary = fs80.mkdtempSync(path88.join(os16.tmpdir(), "brainbase-benchmark-preflight-"));
78877
+ const temporary = fs81.mkdtempSync(path88.join(os16.tmpdir(), "brainbase-benchmark-preflight-"));
78225
78878
  try {
78226
78879
  const verifiedArchive = path88.join(temporary, "material.tar.gz");
78227
78880
  await atomicCopy(source, verifiedArchive, 384, sourceRoot);
@@ -78248,34 +78901,34 @@ async function preflightMaterial(material, sourceRoot, destinationRoot, protectW
78248
78901
  }
78249
78902
  return planned;
78250
78903
  } finally {
78251
- fs80.rmSync(temporary, { recursive: true, force: true });
78904
+ fs81.rmSync(temporary, { recursive: true, force: true });
78252
78905
  }
78253
78906
  }
78254
78907
  function ownerMarker(root) {
78255
78908
  return path88.join(root, ".brainbase-benchmark-owner.json");
78256
78909
  }
78257
78910
  function verifyOwnedDirectory(root, role, spec) {
78258
- if (!fs80.existsSync(root) || fs80.lstatSync(root).isSymbolicLink())
78911
+ if (!fs81.existsSync(root) || fs81.lstatSync(root).isSymbolicLink())
78259
78912
  return false;
78260
78913
  try {
78261
- const marker = JSON.parse(fs80.readFileSync(ownerMarker(root), "utf8"));
78914
+ const marker = JSON.parse(fs81.readFileSync(ownerMarker(root), "utf8"));
78262
78915
  return marker.attempt_id === spec.attempt_id && marker.phase === spec.phase && marker.phase_id === spec.phase_id && marker.role === role;
78263
78916
  } catch {
78264
78917
  return false;
78265
78918
  }
78266
78919
  }
78267
78920
  function prepareOwnedDirectory(root, role, spec) {
78268
- if (fs80.existsSync(root)) {
78921
+ if (fs81.existsSync(root)) {
78269
78922
  if (!verifyOwnedDirectory(root, role, spec)) {
78270
- const stat = fs80.lstatSync(root);
78271
- if (!stat.isDirectory() || fs80.readdirSync(root).length > 0) {
78923
+ const stat = fs81.lstatSync(root);
78924
+ if (!stat.isDirectory() || fs81.readdirSync(root).length > 0) {
78272
78925
  throw new BenchmarkPhaseError(`unowned_${role}_root`, `${role}_root exists without a matching attempt ownership marker`);
78273
78926
  }
78274
78927
  } else {
78275
- fs80.rmSync(root, { recursive: true, force: true });
78928
+ fs81.rmSync(root, { recursive: true, force: true });
78276
78929
  }
78277
78930
  }
78278
- fs80.mkdirSync(root, { recursive: true, mode: 448 });
78931
+ fs81.mkdirSync(root, { recursive: true, mode: 448 });
78279
78932
  writeJsonAtomic(ownerMarker(root), {
78280
78933
  schema_version: SCHEMA_VERSION,
78281
78934
  attempt_id: spec.attempt_id,
@@ -78367,7 +79020,7 @@ async function runCommand(command, root, spec, context, additions = {}) {
78367
79020
  const cwd2 = path88.resolve(root, cwdRel);
78368
79021
  let cwdStat;
78369
79022
  try {
78370
- cwdStat = fs80.lstatSync(cwd2);
79023
+ cwdStat = fs81.lstatSync(cwd2);
78371
79024
  } catch {
78372
79025
  throw new BenchmarkPhaseError("invalid_command_cwd", `command cwd is invalid: ${command.cwd}`);
78373
79026
  }
@@ -78439,27 +79092,27 @@ async function runCommand(command, root, spec, context, additions = {}) {
78439
79092
  }
78440
79093
  async function writeLog(root, name, data, spec) {
78441
79094
  const destination = path88.join(root, name);
78442
- fs80.mkdirSync(path88.dirname(destination), { recursive: true });
79095
+ fs81.mkdirSync(path88.dirname(destination), { recursive: true });
78443
79096
  const temporary = `${destination}.${process.pid}.${crypto6.randomBytes(6).toString("hex")}.tmp`;
78444
79097
  try {
78445
- fs80.writeFileSync(temporary, redactCommandOutput(data, spec), {
79098
+ fs81.writeFileSync(temporary, redactCommandOutput(data, spec), {
78446
79099
  flag: "wx",
78447
79100
  mode: 384
78448
79101
  });
78449
- fs80.renameSync(temporary, destination);
79102
+ fs81.renameSync(temporary, destination);
78450
79103
  } finally {
78451
- fs80.rmSync(temporary, { force: true });
79104
+ fs81.rmSync(temporary, { force: true });
78452
79105
  }
78453
79106
  return await recordFile(root, destination, "logs");
78454
79107
  }
78455
79108
  function writeBufferAtomic(destination, data) {
78456
- fs80.mkdirSync(path88.dirname(destination), { recursive: true });
79109
+ fs81.mkdirSync(path88.dirname(destination), { recursive: true });
78457
79110
  const temporary = `${destination}.${process.pid}.${crypto6.randomBytes(6).toString("hex")}.tmp`;
78458
79111
  try {
78459
- fs80.writeFileSync(temporary, data, { flag: "wx", mode: 384 });
78460
- fs80.renameSync(temporary, destination);
79112
+ fs81.writeFileSync(temporary, data, { flag: "wx", mode: 384 });
79113
+ fs81.renameSync(temporary, destination);
78461
79114
  } finally {
78462
- fs80.rmSync(temporary, { force: true });
79115
+ fs81.rmSync(temporary, { force: true });
78463
79116
  }
78464
79117
  }
78465
79118
  function assertBudget(context) {
@@ -78468,7 +79121,7 @@ function assertBudget(context) {
78468
79121
  }
78469
79122
  }
78470
79123
  async function executeHydrate(spec, context) {
78471
- fs80.mkdirSync(spec.workspace_root, { recursive: true });
79124
+ fs81.mkdirSync(spec.workspace_root, { recursive: true });
78472
79125
  prepareOwnedDirectory(spec.logs_root, "logs", spec);
78473
79126
  context.logsOwned = true;
78474
79127
  const outputs = [];
@@ -78549,9 +79202,9 @@ async function executeHydrate(spec, context) {
78549
79202
  }
78550
79203
  const candidate = path88.resolve(spec.workspace_root, safeRelPath(output.path));
78551
79204
  assertNoSymlinkTraversal(spec.workspace_root, output.path);
78552
- if (!fs80.existsSync(candidate))
79205
+ if (!fs81.existsSync(candidate))
78553
79206
  continue;
78554
- const stat = fs80.lstatSync(candidate);
79207
+ const stat = fs81.lstatSync(candidate);
78555
79208
  if (!stat.isFile() && !stat.isSymbolicLink())
78556
79209
  continue;
78557
79210
  finalOutputs.push(await recordFile(spec.workspace_root, candidate, "workspace", stat.isSymbolicLink() ? "symlink" : "file"));
@@ -78585,7 +79238,7 @@ async function readEvidence(stagingRoot, evidence) {
78585
79238
  }
78586
79239
  };
78587
79240
  } finally {
78588
- fs80.closeSync(opened.fd);
79241
+ fs81.closeSync(opened.fd);
78589
79242
  }
78590
79243
  }
78591
79244
  async function workspaceManifest(spec, context) {
@@ -78594,7 +79247,7 @@ async function workspaceManifest(spec, context) {
78594
79247
  const stack = [path88.resolve(spec.workspace_root)];
78595
79248
  while (stack.length > 0) {
78596
79249
  const directory = stack.pop();
78597
- const entries = fs80.readdirSync(directory, { withFileTypes: true }).sort((a3, b4) => a3.name.localeCompare(b4.name));
79250
+ const entries = fs81.readdirSync(directory, { withFileTypes: true }).sort((a3, b4) => a3.name.localeCompare(b4.name));
78598
79251
  for (const entry of entries) {
78599
79252
  assertBudget(context);
78600
79253
  const full = path88.join(directory, entry.name);
@@ -78703,7 +79356,7 @@ async function evaluateOne(evaluator, spec, finalOutput, trajectory, frozenEvide
78703
79356
  const candidate = path88.resolve(spec.workspace_root, relative);
78704
79357
  let stat = null;
78705
79358
  try {
78706
- stat = fs80.lstatSync(candidate);
79359
+ stat = fs81.lstatSync(candidate);
78707
79360
  } catch (error2) {
78708
79361
  const code = error2.code;
78709
79362
  if (code !== "ENOENT" && code !== "ENOTDIR")
@@ -78724,7 +79377,7 @@ async function evaluateOne(evaluator, spec, finalOutput, trajectory, frozenEvide
78724
79377
  try {
78725
79378
  verdict2 = await sha256OfDescriptor(opened.fd) === evaluator.assertion.expected;
78726
79379
  } finally {
78727
- fs80.closeSync(opened.fd);
79380
+ fs81.closeSync(opened.fd);
78728
79381
  }
78729
79382
  }
78730
79383
  }
@@ -78734,7 +79387,7 @@ async function evaluateOne(evaluator, spec, finalOutput, trajectory, frozenEvide
78734
79387
  try {
78735
79388
  verdict2 = readDescriptor(opened.fd).toString("utf8").includes(evaluator.assertion.expected);
78736
79389
  } finally {
78737
- fs80.closeSync(opened.fd);
79390
+ fs81.closeSync(opened.fd);
78738
79391
  }
78739
79392
  }
78740
79393
  }
@@ -78815,7 +79468,7 @@ async function executeEvaluate(spec, context) {
78815
79468
  assertNoSymlinkTraversal(spec.workspace_root, artifactRel);
78816
79469
  const source = path88.resolve(spec.workspace_root, artifactRel);
78817
79470
  const frozenArtifact = manifest.find((entry) => entry.path === artifactRel && entry.kind !== "symlink");
78818
- if (!frozenArtifact || !fs80.existsSync(source) || !fs80.lstatSync(source).isFile()) {
79471
+ if (!frozenArtifact || !fs81.existsSync(source) || !fs81.lstatSync(source).isFile()) {
78819
79472
  throw new BenchmarkPhaseError("missing_artifact", `candidate artifact is missing: ${artifactRel}`);
78820
79473
  }
78821
79474
  const destination = path88.resolve(spec.logs_root, "candidate-artifacts", artifactRel);
@@ -78833,9 +79486,9 @@ async function executeEvaluate(spec, context) {
78833
79486
  const temporary = `${archive}.${process.pid}.${crypto6.randomBytes(6).toString("hex")}.tmp`;
78834
79487
  try {
78835
79488
  await pack({ rootDir: spec.workspace_root, outFile: temporary, files: regularFiles });
78836
- fs80.renameSync(temporary, archive);
79489
+ fs81.renameSync(temporary, archive);
78837
79490
  } finally {
78838
- fs80.rmSync(temporary, { force: true });
79491
+ fs81.rmSync(temporary, { force: true });
78839
79492
  }
78840
79493
  const archiveRecord = await recordFile(spec.logs_root, archive, "logs");
78841
79494
  outputs.push(archiveRecord);
@@ -78935,21 +79588,21 @@ function rawIdentity(value) {
78935
79588
  }
78936
79589
  function readSpecBytes(specPathInput) {
78937
79590
  const specPath = path88.resolve(specPathInput);
78938
- const noFollow = typeof fs80.constants.O_NOFOLLOW === "number" ? fs80.constants.O_NOFOLLOW : 0;
79591
+ const noFollow = typeof fs81.constants.O_NOFOLLOW === "number" ? fs81.constants.O_NOFOLLOW : 0;
78939
79592
  let fd;
78940
79593
  try {
78941
- fd = fs80.openSync(specPath, fs80.constants.O_RDONLY | noFollow);
79594
+ fd = fs81.openSync(specPath, fs81.constants.O_RDONLY | noFollow);
78942
79595
  } catch {
78943
79596
  throw new BenchmarkPhaseError("spec_read_failed", "spec file could not be read");
78944
79597
  }
78945
79598
  try {
78946
- const stat = fs80.fstatSync(fd);
79599
+ const stat = fs81.fstatSync(fd);
78947
79600
  if (!stat.isFile() || stat.size > MAX_SPEC_BYTES) {
78948
79601
  throw new BenchmarkPhaseError("invalid_spec_file", "spec must be a regular JSON file no larger than 20 MiB");
78949
79602
  }
78950
79603
  return readDescriptor(fd);
78951
79604
  } finally {
78952
- fs80.closeSync(fd);
79605
+ fs81.closeSync(fd);
78953
79606
  }
78954
79607
  }
78955
79608
  function validateBenchmarkInvocationBytes(bytes, resultPathInput, expectedPhase) {
@@ -78993,9 +79646,9 @@ function prepareBenchmarkPhaseInvocation(specPathInput, resultPathInput, expecte
78993
79646
  spec_digest: digest,
78994
79647
  timeout_ms: spec.budget.timeout_ms
78995
79648
  };
78996
- if (fs80.existsSync(resultPath)) {
79649
+ if (fs81.existsSync(resultPath)) {
78997
79650
  try {
78998
- const cached2 = JSON.parse(fs80.readFileSync(resultPath, "utf8"));
79651
+ const cached2 = JSON.parse(fs81.readFileSync(resultPath, "utf8"));
78999
79652
  if (cached2.schema_version === SCHEMA_VERSION && cached2.phase === spec.phase && cached2.attempt_id === spec.attempt_id && cached2.phase_id === spec.phase_id && cached2.spec_digest === digest && cached2.status === "succeeded") {
79000
79653
  return {
79001
79654
  ok: true,
@@ -79102,9 +79755,9 @@ async function runBenchmarkPhase(specPathInput, resultPathInput, expectedPhase,
79102
79755
  throw new BenchmarkPhaseError("invalid_result_path", `result path must be ${expectedResultPath}`);
79103
79756
  }
79104
79757
  resultPathValidated = true;
79105
- if (fs80.existsSync(resultPath)) {
79758
+ if (fs81.existsSync(resultPath)) {
79106
79759
  try {
79107
- const cached2 = JSON.parse(fs80.readFileSync(resultPath, "utf8"));
79760
+ const cached2 = JSON.parse(fs81.readFileSync(resultPath, "utf8"));
79108
79761
  if (cached2.schema_version === SCHEMA_VERSION && cached2.phase === spec.phase && cached2.attempt_id === spec.attempt_id && cached2.phase_id === spec.phase_id && cached2.spec_digest === digest && cached2.status === "succeeded") {
79109
79762
  return { exitCode: 0, result: cached2 };
79110
79763
  }
@@ -79301,13 +79954,13 @@ function terminatePhase(child) {
79301
79954
  }
79302
79955
  function createAnonymousSpecFd(bytes) {
79303
79956
  const temporary = path89.join(os17.tmpdir(), `brainbase-benchmark-spec-${process.pid}-${crypto7.randomBytes(12).toString("hex")}`);
79304
- fs81.writeFileSync(temporary, bytes, { flag: "wx", mode: 384 });
79957
+ fs82.writeFileSync(temporary, bytes, { flag: "wx", mode: 384 });
79305
79958
  try {
79306
- const fd = fs81.openSync(temporary, "r");
79307
- fs81.unlinkSync(temporary);
79959
+ const fd = fs82.openSync(temporary, "r");
79960
+ fs82.unlinkSync(temporary);
79308
79961
  return fd;
79309
79962
  } catch (error2) {
79310
- fs81.rmSync(temporary, { force: true });
79963
+ fs82.rmSync(temporary, { force: true });
79311
79964
  throw error2;
79312
79965
  }
79313
79966
  }
@@ -79376,13 +80029,13 @@ async function runSupervisedPhase(phase, parsed, write) {
79376
80029
  detached: process.platform !== "win32"
79377
80030
  });
79378
80031
  } catch {
79379
- fs81.closeSync(specFd);
80032
+ fs82.closeSync(specFd);
79380
80033
  const failure = phaseFailure(invocation, startedAt, started, "phase_supervisor_failed", "benchmark phase child process could not be started");
79381
80034
  write(`${JSON.stringify(failure)}
79382
80035
  `);
79383
80036
  return 1;
79384
80037
  }
79385
- fs81.closeSync(specFd);
80038
+ fs82.closeSync(specFd);
79386
80039
  return await new Promise((resolve) => {
79387
80040
  const stdout = [];
79388
80041
  let settled = false;
@@ -79464,7 +80117,7 @@ async function runBenchmark(sub, args, write = (value) => process.stdout.write(v
79464
80117
  if (phase !== "hydrate" && phase !== "evaluate" || resultFlag !== "--result" || !resultPath || specFdFlag !== "--spec-fd" || !Number.isInteger(specFd) || specFd < 3 || tokenFlag !== "--token" || !token || token !== process.env.BRAINBASE_BENCHMARK_PHASE_CHILD_TOKEN) {
79465
80118
  throw new Error("Invalid internal benchmark phase invocation");
79466
80119
  }
79467
- const specBytes = fs81.readFileSync(specFd);
80120
+ const specBytes = fs82.readFileSync(specFd);
79468
80121
  const { exitCode, result: result2 } = await runBenchmarkPhase("", resultPath, phase, specBytes);
79469
80122
  write(`${JSON.stringify(result2)}
79470
80123
  `);
@@ -79504,13 +80157,13 @@ async function runBenchmark(sub, args, write = (value) => process.stdout.write(v
79504
80157
  function printHelp5() {
79505
80158
  const out = [];
79506
80159
  out.push("");
79507
- out.push(` ${import_picocolors48.default.bold("brainbase benchmark")} ${import_picocolors48.default.dim("<sub> [options]")}`);
80160
+ out.push(` ${import_picocolors51.default.bold("brainbase benchmark")} ${import_picocolors51.default.dim("<sub> [options]")}`);
79508
80161
  out.push("");
79509
- out.push(` ${import_picocolors48.default.cyan("hydrate")} ${import_picocolors48.default.dim("--spec <path> --result <path> --json")}`);
79510
- out.push(` ${import_picocolors48.default.cyan("evaluate")} ${import_picocolors48.default.dim("--spec <path> --result <path> --json")}`);
79511
- out.push(` ${import_picocolors48.default.cyan("capabilities")} ${import_picocolors48.default.dim("--json")}`);
80162
+ out.push(` ${import_picocolors51.default.cyan("hydrate")} ${import_picocolors51.default.dim("--spec <path> --result <path> --json")}`);
80163
+ out.push(` ${import_picocolors51.default.cyan("evaluate")} ${import_picocolors51.default.dim("--spec <path> --result <path> --json")}`);
80164
+ out.push(` ${import_picocolors51.default.cyan("capabilities")} ${import_picocolors51.default.dim("--json")}`);
79512
80165
  out.push("");
79513
- out.push(` ${import_picocolors48.default.dim("These machine-only commands execute versioned benchmark phase specs inside a task sandbox.")}`);
80166
+ out.push(` ${import_picocolors51.default.dim("These machine-only commands execute versioned benchmark phase specs inside a task sandbox.")}`);
79514
80167
  out.push("");
79515
80168
  console.log(out.join(`
79516
80169
  `));
@@ -79537,164 +80190,259 @@ var SUBCOMMAND_OWNED_FLAGS = {
79537
80190
  function help() {
79538
80191
  const out = [];
79539
80192
  out.push("");
79540
- out.push(` ${brandTint("◆")} ${import_picocolors49.default.bold("brainbase")} ${import_picocolors49.default.dim(`v${VERSION}`)}`);
79541
- out.push(` ${import_picocolors49.default.dim("connect your local agent to the brainbase platform")}`);
80193
+ out.push(` ${brandTint("◆")} ${import_picocolors52.default.bold("brainbase")} ${import_picocolors52.default.dim(`v${VERSION}`)}`);
80194
+ out.push(` ${import_picocolors52.default.dim("connect your local agent to the brainbase platform")}`);
79542
80195
  out.push("");
79543
80196
  out.push(divider("USAGE"));
79544
80197
  out.push("");
79545
- out.push(` ${import_picocolors49.default.bold("brainbase")} ${import_picocolors49.default.dim("<command> [options]")}`);
80198
+ out.push(` ${import_picocolors52.default.bold("brainbase")} ${import_picocolors52.default.dim("<command> [options]")}`);
79546
80199
  out.push("");
79547
80200
  out.push(divider("AUTH"));
79548
80201
  out.push("");
79549
- out.push(` ${import_picocolors49.default.cyan("login")} ${import_picocolors49.default.dim(" open the web app and connect this device")}`);
79550
- out.push(` ${import_picocolors49.default.cyan("logout")} ${import_picocolors49.default.dim(" clear the local session")}`);
79551
- out.push(` ${import_picocolors49.default.cyan("whoami")} ${import_picocolors49.default.dim(" show the current user")}`);
80202
+ out.push(` ${import_picocolors52.default.cyan("login")} ${import_picocolors52.default.dim(" open the web app and connect this device")}`);
80203
+ out.push(` ${import_picocolors52.default.cyan("logout")} ${import_picocolors52.default.dim(" clear the local session")}`);
80204
+ out.push(` ${import_picocolors52.default.cyan("whoami")} ${import_picocolors52.default.dim(" show the current user")}`);
79552
80205
  out.push("");
79553
80206
  out.push(divider("DISCOVERY"));
79554
80207
  out.push("");
79555
- out.push(` ${import_picocolors49.default.cyan("team list")} ${import_picocolors49.default.dim("show the teams you can create agents in")}`);
79556
- out.push(` ${import_picocolors49.default.cyan("agent list")} ${import_picocolors49.default.dim("show a team's agents and their ids")}`);
80208
+ out.push(` ${import_picocolors52.default.cyan("team list")} ${import_picocolors52.default.dim("show the teams you can create agents in")}`);
80209
+ out.push(` ${import_picocolors52.default.cyan("agent list")} ${import_picocolors52.default.dim("show a team's agents and their ids")}`);
79557
80210
  out.push("");
79558
80211
  out.push(divider("LINKED AGENT"));
79559
80212
  out.push("");
79560
- out.push(` ${import_picocolors49.default.cyan("agent create")} ${import_picocolors49.default.dim("claim an unclaimed brainbase.agent.yaml and create the cloud agent")}`);
79561
- out.push(` ${import_picocolors49.default.cyan("agent pull")} ${import_picocolors49.default.dim("[<id>]")} ${import_picocolors49.default.dim("bring cloud changes into this folder (--force to override; --run-entrypoint to also execute the agent entrypoint)")}`);
79562
- out.push(` ${import_picocolors49.default.cyan("agent push")} ${import_picocolors49.default.dim("send local changes to the cloud (--force to overwrite cloud-side conflicts with local)")}`);
79563
- out.push(` ${import_picocolors49.default.cyan("agent unpack")} ${import_picocolors49.default.dim("install the claimed agent into a harness layout")}`);
79564
- out.push(` ${import_picocolors49.default.cyan("link")} ${import_picocolors49.default.dim("attach this folder to an existing agent")}`);
79565
- out.push(` ${import_picocolors49.default.cyan("agent status")} ${import_picocolors49.default.dim("show what would pull and what would push")}`);
79566
- out.push(` ${import_picocolors49.default.cyan("agent env")} ${import_picocolors49.default.dim("print export lines for `eval $(brainbase agent env)`")}`);
79567
- out.push(` ${import_picocolors49.default.cyan("run")} ${import_picocolors49.default.dim("<cmd> [args...]")} ${import_picocolors49.default.dim("run <cmd> with secrets.env loaded into env")}`);
79568
- out.push(` ${import_picocolors49.default.cyan("status")} ${import_picocolors49.default.dim("show what this folder is linked to")}`);
79569
- out.push(` ${import_picocolors49.default.cyan("unlink")} ${import_picocolors49.default.dim("disconnect this folder")}`);
80213
+ out.push(` ${import_picocolors52.default.cyan("agent create")} ${import_picocolors52.default.dim("claim an unclaimed brainbase.agent.yaml and create the cloud agent")}`);
80214
+ out.push(` ${import_picocolors52.default.cyan("agent pull")} ${import_picocolors52.default.dim("[<id>]")} ${import_picocolors52.default.dim("bring cloud changes into this folder (--force to override; --run-entrypoint to also execute the agent entrypoint)")}`);
80215
+ out.push(` ${import_picocolors52.default.cyan("agent push")} ${import_picocolors52.default.dim("send local changes to the cloud (--force to overwrite cloud-side conflicts with local)")}`);
80216
+ out.push(` ${import_picocolors52.default.cyan("agent unpack")} ${import_picocolors52.default.dim("install the claimed agent into a harness layout")}`);
80217
+ out.push(` ${import_picocolors52.default.cyan("link")} ${import_picocolors52.default.dim("attach this folder to an existing agent")}`);
80218
+ out.push(` ${import_picocolors52.default.cyan("agent status")} ${import_picocolors52.default.dim("show what would pull and what would push")}`);
80219
+ out.push(` ${import_picocolors52.default.cyan("agent connections")} ${import_picocolors52.default.dim("show which integrations this agent is wired to (--json for CI)")}`);
80220
+ out.push(` ${import_picocolors52.default.cyan("agent connect")} ${import_picocolors52.default.dim("<name>")} ${import_picocolors52.default.dim("connect slack or meeting from the terminal")}`);
80221
+ out.push(` ${import_picocolors52.default.cyan("agent disconnect")} ${import_picocolors52.default.dim("<name>")} ${import_picocolors52.default.dim("revoke a slack or meeting install")}`);
80222
+ out.push(` ${import_picocolors52.default.cyan("agent env")} ${import_picocolors52.default.dim("print export lines for `eval $(brainbase agent env)`")}`);
80223
+ out.push(` ${import_picocolors52.default.cyan("run")} ${import_picocolors52.default.dim("<cmd> [args...]")} ${import_picocolors52.default.dim("run <cmd> with secrets.env loaded into env")}`);
80224
+ out.push(` ${import_picocolors52.default.cyan("status")} ${import_picocolors52.default.dim("show what this folder is linked to")}`);
80225
+ out.push(` ${import_picocolors52.default.cyan("unlink")} ${import_picocolors52.default.dim("disconnect this folder")}`);
79570
80226
  out.push("");
79571
80227
  out.push(divider("TASKS"));
79572
80228
  out.push("");
79573
- out.push(` ${import_picocolors49.default.cyan("task create")} ${import_picocolors49.default.dim("--message <text>")} ${import_picocolors49.default.dim("create a managed task and start its first run")}`);
80229
+ out.push(` ${import_picocolors52.default.cyan("task create")} ${import_picocolors52.default.dim("--message <text>")} ${import_picocolors52.default.dim("create a managed task and start its first run")}`);
79574
80230
  out.push("");
79575
80231
  out.push(divider("BENCHMARK RUNTIME"));
79576
80232
  out.push("");
79577
- out.push(` ${import_picocolors49.default.cyan("benchmark hydrate")} ${import_picocolors49.default.dim("--spec <path> --result <path> --json")}`);
79578
- out.push(` ${import_picocolors49.default.cyan("benchmark evaluate")} ${import_picocolors49.default.dim("--spec <path> --result <path> --json")}`);
79579
- out.push(` ${import_picocolors49.default.cyan("benchmark capabilities")} ${import_picocolors49.default.dim("--json")}`);
80233
+ out.push(` ${import_picocolors52.default.cyan("benchmark hydrate")} ${import_picocolors52.default.dim("--spec <path> --result <path> --json")}`);
80234
+ out.push(` ${import_picocolors52.default.cyan("benchmark evaluate")} ${import_picocolors52.default.dim("--spec <path> --result <path> --json")}`);
80235
+ out.push(` ${import_picocolors52.default.cyan("benchmark capabilities")} ${import_picocolors52.default.dim("--json")}`);
79580
80236
  out.push("");
79581
80237
  out.push(divider("ORCHESTRATIONS"));
79582
80238
  out.push("");
79583
- out.push(` ${import_picocolors49.default.cyan("orchestration create")} ${import_picocolors49.default.dim("claim a local orchestration manifest and create it in the cloud")}`);
79584
- out.push(` ${import_picocolors49.default.cyan("orchestration list")} ${import_picocolors49.default.dim("list orchestrations under a team")}`);
79585
- out.push(` ${import_picocolors49.default.cyan("orchestration pull")} ${import_picocolors49.default.dim("<id>")} ${import_picocolors49.default.dim("recursively fetch an orchestration + every member agent")}`);
79586
- out.push(` ${import_picocolors49.default.cyan("orchestration push")} ${import_picocolors49.default.dim("recursively push each member, then update the graph")}`);
79587
- out.push(` ${import_picocolors49.default.cyan("orchestration status")} ${import_picocolors49.default.dim("show what would push and what would pull")}`);
80239
+ out.push(` ${import_picocolors52.default.cyan("orchestration create")} ${import_picocolors52.default.dim("claim a local orchestration manifest and create it in the cloud")}`);
80240
+ out.push(` ${import_picocolors52.default.cyan("orchestration list")} ${import_picocolors52.default.dim("list orchestrations under a team")}`);
80241
+ out.push(` ${import_picocolors52.default.cyan("orchestration pull")} ${import_picocolors52.default.dim("<id>")} ${import_picocolors52.default.dim("recursively fetch an orchestration + every member agent")}`);
80242
+ out.push(` ${import_picocolors52.default.cyan("orchestration push")} ${import_picocolors52.default.dim("recursively push each member, then update the graph")}`);
80243
+ out.push(` ${import_picocolors52.default.cyan("orchestration status")} ${import_picocolors52.default.dim("show what would push and what would pull")}`);
79588
80244
  out.push("");
79589
80245
  out.push(divider("TEMPLATES"));
79590
80246
  out.push("");
79591
- out.push(` ${import_picocolors49.default.cyan("template pack")} ${import_picocolors49.default.dim("bundle the current agent into a template")}`);
79592
- out.push(` ${import_picocolors49.default.cyan("template publish")} ${import_picocolors49.default.dim("upload a template to the registry")}`);
79593
- out.push(` ${import_picocolors49.default.cyan("template search")} ${import_picocolors49.default.dim("[query]")} ${import_picocolors49.default.dim("search the registry")}`);
79594
- out.push(` ${import_picocolors49.default.cyan("template info")} ${import_picocolors49.default.dim("<creator/slug>")} ${import_picocolors49.default.dim("show registry details for a template")}`);
79595
- out.push(` ${import_picocolors49.default.cyan("template onboard")} ${import_picocolors49.default.dim("<creator/slug>")} ${import_picocolors49.default.dim("install (or refresh) a template")}`);
79596
- out.push(` ${import_picocolors49.default.cyan("template list")} ${import_picocolors49.default.dim("show installed templates")}`);
79597
- out.push(` ${import_picocolors49.default.cyan("template remove")} ${import_picocolors49.default.dim("<creator/slug>")} ${import_picocolors49.default.dim("uninstall a template")}`);
80247
+ out.push(` ${import_picocolors52.default.cyan("template pack")} ${import_picocolors52.default.dim("bundle the current agent into a template")}`);
80248
+ out.push(` ${import_picocolors52.default.cyan("template publish")} ${import_picocolors52.default.dim("upload a template to the registry")}`);
80249
+ out.push(` ${import_picocolors52.default.cyan("template search")} ${import_picocolors52.default.dim("[query]")} ${import_picocolors52.default.dim("search the registry")}`);
80250
+ out.push(` ${import_picocolors52.default.cyan("template info")} ${import_picocolors52.default.dim("<creator/slug>")} ${import_picocolors52.default.dim("show registry details for a template")}`);
80251
+ out.push(` ${import_picocolors52.default.cyan("template onboard")} ${import_picocolors52.default.dim("<creator/slug>")} ${import_picocolors52.default.dim("install (or refresh) a template")}`);
80252
+ out.push(` ${import_picocolors52.default.cyan("template list")} ${import_picocolors52.default.dim("show installed templates")}`);
80253
+ out.push(` ${import_picocolors52.default.cyan("template remove")} ${import_picocolors52.default.dim("<creator/slug>")} ${import_picocolors52.default.dim("uninstall a template")}`);
79598
80254
  out.push("");
79599
80255
  out.push(divider("SKILLS"));
79600
80256
  out.push("");
79601
- out.push(` ${import_picocolors49.default.cyan("skill add")} ${import_picocolors49.default.dim("<source>")} ${import_picocolors49.default.dim("install a skill (github / git / brainbase)")}`);
79602
- out.push(` ${import_picocolors49.default.cyan("skill list")} ${import_picocolors49.default.dim("show locally installed skills + their source")}`);
79603
- out.push(` ${import_picocolors49.default.cyan("skill update")} ${import_picocolors49.default.dim("<slug>")} ${import_picocolors49.default.dim("re-fetch a skill from its recorded source")}`);
79604
- out.push(` ${import_picocolors49.default.cyan("skill remove")} ${import_picocolors49.default.dim("<slug>")} ${import_picocolors49.default.dim("uninstall a skill")}`);
79605
- out.push(` ${import_picocolors49.default.cyan("skill search")} ${import_picocolors49.default.dim("[query]")} ${import_picocolors49.default.dim("search the brainbase skill registry")}`);
79606
- out.push(` ${import_picocolors49.default.cyan("skill info")} ${import_picocolors49.default.dim("<creator/slug>")} ${import_picocolors49.default.dim("show registry details for a skill")}`);
79607
- out.push(` ${import_picocolors49.default.cyan("skill publish")} ${import_picocolors49.default.dim("[dir]")} ${import_picocolors49.default.dim("publish a SKILL.md folder (defaults to .)")}`);
80257
+ out.push(` ${import_picocolors52.default.cyan("skill add")} ${import_picocolors52.default.dim("<source>")} ${import_picocolors52.default.dim("install a skill (github / git / brainbase)")}`);
80258
+ out.push(` ${import_picocolors52.default.cyan("skill list")} ${import_picocolors52.default.dim("show locally installed skills + their source")}`);
80259
+ out.push(` ${import_picocolors52.default.cyan("skill update")} ${import_picocolors52.default.dim("<slug>")} ${import_picocolors52.default.dim("re-fetch a skill from its recorded source")}`);
80260
+ out.push(` ${import_picocolors52.default.cyan("skill remove")} ${import_picocolors52.default.dim("<slug>")} ${import_picocolors52.default.dim("uninstall a skill")}`);
80261
+ out.push(` ${import_picocolors52.default.cyan("skill search")} ${import_picocolors52.default.dim("[query]")} ${import_picocolors52.default.dim("search the brainbase skill registry")}`);
80262
+ out.push(` ${import_picocolors52.default.cyan("skill info")} ${import_picocolors52.default.dim("<creator/slug>")} ${import_picocolors52.default.dim("show registry details for a skill")}`);
80263
+ out.push(` ${import_picocolors52.default.cyan("skill publish")} ${import_picocolors52.default.dim("[dir]")} ${import_picocolors52.default.dim("publish a SKILL.md folder (defaults to .)")}`);
79608
80264
  out.push("");
79609
80265
  out.push(divider("CLI TOKENS"));
79610
80266
  out.push("");
79611
- out.push(` ${import_picocolors49.default.cyan("token create")} ${import_picocolors49.default.dim("issue a long-lived CLI key for CI / scripts")}`);
79612
- out.push(` ${import_picocolors49.default.cyan("token list")} ${import_picocolors49.default.dim("show your tokens")}`);
79613
- out.push(` ${import_picocolors49.default.cyan("token rename")} ${import_picocolors49.default.dim("<id>")} ${import_picocolors49.default.dim("relabel a token")}`);
79614
- out.push(` ${import_picocolors49.default.cyan("token revoke")} ${import_picocolors49.default.dim("<id>")} ${import_picocolors49.default.dim("revoke a token")}`);
80267
+ out.push(` ${import_picocolors52.default.cyan("token create")} ${import_picocolors52.default.dim("issue a long-lived CLI key for CI / scripts")}`);
80268
+ out.push(` ${import_picocolors52.default.cyan("token list")} ${import_picocolors52.default.dim("show your tokens")}`);
80269
+ out.push(` ${import_picocolors52.default.cyan("token rename")} ${import_picocolors52.default.dim("<id>")} ${import_picocolors52.default.dim("relabel a token")}`);
80270
+ out.push(` ${import_picocolors52.default.cyan("token revoke")} ${import_picocolors52.default.dim("<id>")} ${import_picocolors52.default.dim("revoke a token")}`);
79615
80271
  out.push("");
79616
80272
  out.push(divider("MCP"));
79617
80273
  out.push("");
79618
- out.push(` ${import_picocolors49.default.cyan("mcp check")} ${import_picocolors49.default.dim("[--json]")} ${import_picocolors49.default.dim("verify MCP server connectivity through the brainbase proxy (runs at sandbox bootstrap)")}`);
80274
+ out.push(` ${import_picocolors52.default.cyan("mcp check")} ${import_picocolors52.default.dim("[--json]")} ${import_picocolors52.default.dim("verify MCP server connectivity through the brainbase proxy (runs at sandbox bootstrap)")}`);
80275
+ out.push(` ${import_picocolors52.default.cyan("mcp list")} ${import_picocolors52.default.dim("[--json]")} ${import_picocolors52.default.dim("show configured servers with OAuth state and expiry")}`);
79619
80276
  out.push("");
79620
80277
  out.push(divider("FLAGS"));
79621
80278
  out.push("");
79622
- out.push(` ${import_picocolors49.default.dim("--harness <id>")} force harness for onboard / sync (e.g. claude-code)`);
79623
- out.push(` ${import_picocolors49.default.dim("--scope <s>")} force scope: global | project`);
79624
- out.push(` ${import_picocolors49.default.dim("--yes, -y")} skip confirmations / auto-overwrite`);
79625
- out.push(` ${import_picocolors49.default.dim("--agent <id>")} for link/task create: use this agent id explicitly`);
79626
- out.push(` ${import_picocolors49.default.dim("--message <text>")} for task create: required first user message`);
79627
- out.push(` ${import_picocolors49.default.dim("--title <text>")} for task create: optional task title`);
79628
- out.push(` ${import_picocolors49.default.dim("--model <id>")} for task create: optional model override`);
79629
- out.push(` ${import_picocolors49.default.dim("--org <id-or-slug>")} pick the organization (team/agent list, agent create, orchestration create/list)`);
79630
- out.push(` ${import_picocolors49.default.dim("--team <id>")} pick the team, same commands (works without --org)`);
79631
- out.push(` ${import_picocolors49.default.dim("--json")} machine-readable output for supported commands`);
79632
- out.push(` ${import_picocolors49.default.dim("--no-tracking")} for link: skip routing LLM traffic through brainbase`);
79633
- out.push(` ${import_picocolors49.default.dim("--track")} for agent create: enable tracking non-interactively (off without a TTY)`);
79634
- out.push(` ${import_picocolors49.default.dim("--shell <sh|fish>")} for agent env: pick output format (auto-detected from $SHELL)`);
79635
- out.push(` ${import_picocolors49.default.dim("--all")} for template list: include installs from other folders`);
79636
- out.push(` ${import_picocolors49.default.dim("--web <url>")} for login: web app URL (default https://app.brainbaselabs.com)`);
80279
+ out.push(` ${import_picocolors52.default.dim("--harness <id>")} force harness for onboard / sync (e.g. claude-code)`);
80280
+ out.push(` ${import_picocolors52.default.dim("--scope <s>")} force scope: global | project`);
80281
+ out.push(` ${import_picocolors52.default.dim("--yes, -y")} skip confirmations / auto-overwrite`);
80282
+ out.push(` ${import_picocolors52.default.dim("--agent <id>")} for link/task create: use this agent id explicitly`);
80283
+ out.push(` ${import_picocolors52.default.dim("--message <text>")} for task create: required first user message`);
80284
+ out.push(` ${import_picocolors52.default.dim("--title <text>")} for task create: optional task title`);
80285
+ out.push(` ${import_picocolors52.default.dim("--model <id>")} for task create: optional model override`);
80286
+ out.push(` ${import_picocolors52.default.dim("--org <id-or-slug>")} pick the organization (team/agent list, agent create, orchestration create/list)`);
80287
+ out.push(` ${import_picocolors52.default.dim("--team <id>")} pick the team, same commands (works without --org)`);
80288
+ out.push(` ${import_picocolors52.default.dim("--json")} machine-readable output for supported commands`);
80289
+ out.push(` ${import_picocolors52.default.dim("--no-tracking")} for link: skip routing LLM traffic through brainbase`);
80290
+ out.push(` ${import_picocolors52.default.dim("--track")} for agent create: enable tracking non-interactively (off without a TTY)`);
80291
+ out.push(` ${import_picocolors52.default.dim("--shell <sh|fish>")} for agent env: pick output format (auto-detected from $SHELL)`);
80292
+ out.push(` ${import_picocolors52.default.dim("--bot-token <t>")} for agent connect slack (or BRAINBASE_SLACK_BOT_TOKEN, or stdin)`);
80293
+ out.push(` ${import_picocolors52.default.dim("--signing-secret <s>")} for agent connect slack (or BRAINBASE_SLACK_SIGNING_SECRET, or stdin)`);
80294
+ out.push(` ${import_picocolors52.default.dim("--bot-name <name>")} for agent connect meeting: the bot's display name`);
80295
+ out.push(` ${import_picocolors52.default.dim("--all")} for template list: include installs from other folders`);
80296
+ out.push(` ${import_picocolors52.default.dim("--web <url>")} for login: web app URL (default https://app.brainbaselabs.com)`);
79637
80297
  out.push("");
79638
80298
  out.push(divider("ENV"));
79639
80299
  out.push("");
79640
- out.push(` ${import_picocolors49.default.dim("BRAINBASE_HOME")} override the local config dir (default ~/.brainbase)`);
79641
- out.push(` ${import_picocolors49.default.dim("BRAINBASE_DEBUG")} print full stack traces on error (any value; unset to disable)`);
79642
- out.push(` ${import_picocolors49.default.dim("BRAINBASE_WEB_URL")} override the web app URL used by login`);
79643
- out.push(` ${import_picocolors49.default.dim("BRAINBASE_CONTROL_PLANE_URL")} override the MAS host (/v2/cli; task create uses /v2/tasks)`);
79644
- out.push(` ${import_picocolors49.default.dim("BRAINBASE_API_URL")} legacy KLS host override (uses /api/cli; proxy/registry fallback)`);
79645
- out.push(` ${import_picocolors49.default.dim("BRAINBASE_PROXY_URL")} override the model-proxy URL used by harness traffic (default https://api.v1.brainbaselabs.com)`);
79646
- out.push(` ${import_picocolors49.default.dim("BRAINBASE_REGISTRY_URL")} override the registry API URL (default https://api.v1.brainbaselabs.com)`);
79647
- out.push(` ${import_picocolors49.default.dim("BRAINBASE_TOKEN")} long-lived CLI PAT (overrides token.json)`);
79648
- out.push(` ${import_picocolors49.default.dim("BRAINBASE_SKIP_AUTH")} bypass the auth gate for development`);
79649
- out.push(` ${import_picocolors49.default.dim("BRAINBASE_NON_INTERACTIVE")} force non-interactive mode — skip/auto-default prompts (CI & agents)`);
79650
- out.push(` ${import_picocolors49.default.dim("BRAINBASE_RUN_ENTRYPOINT")} =1 → agent pull executes the agent entrypoint (sandbox boots; or pass --run-entrypoint)`);
80300
+ out.push(` ${import_picocolors52.default.dim("BRAINBASE_HOME")} override the local config dir (default ~/.brainbase)`);
80301
+ out.push(` ${import_picocolors52.default.dim("BRAINBASE_DEBUG")} print full stack traces on error (any value; unset to disable)`);
80302
+ out.push(` ${import_picocolors52.default.dim("BRAINBASE_WEB_URL")} override the web app URL used by login`);
80303
+ out.push(` ${import_picocolors52.default.dim("BRAINBASE_CONTROL_PLANE_URL")} override the MAS host (/v2/cli; task create uses /v2/tasks)`);
80304
+ out.push(` ${import_picocolors52.default.dim("BRAINBASE_API_URL")} legacy KLS host override (uses /api/cli; proxy/registry fallback)`);
80305
+ out.push(` ${import_picocolors52.default.dim("BRAINBASE_PROXY_URL")} override the model-proxy URL used by harness traffic (default https://api.v1.brainbaselabs.com)`);
80306
+ out.push(` ${import_picocolors52.default.dim("BRAINBASE_REGISTRY_URL")} override the registry API URL (default https://api.v1.brainbaselabs.com)`);
80307
+ out.push(` ${import_picocolors52.default.dim("BRAINBASE_TOKEN")} long-lived CLI PAT (overrides token.json)`);
80308
+ out.push(` ${import_picocolors52.default.dim("BRAINBASE_SKIP_AUTH")} bypass the auth gate for development`);
80309
+ out.push(` ${import_picocolors52.default.dim("BRAINBASE_NON_INTERACTIVE")} force non-interactive mode — skip/auto-default prompts (CI & agents)`);
80310
+ out.push(` ${import_picocolors52.default.dim("BRAINBASE_RUN_ENTRYPOINT")} =1 → agent pull executes the agent entrypoint (sandbox boots; or pass --run-entrypoint)`);
79651
80311
  out.push("");
79652
- out.push(` ${import_picocolors49.default.dim("BRAINBASE_MEMORY_MCP_URL")} override the built-in memory MCP host`);
79653
- out.push(` ${import_picocolors49.default.dim("BRAINBASE_BROWSER_MCP_URL")} override the built-in browser MCP host`);
79654
- out.push(` ${import_picocolors49.default.dim("BRAINBASE_SLACK_MCP_URL")} override the built-in Slack MCP host`);
79655
- out.push(` ${import_picocolors49.default.dim("BRAINBASE_MEETING_MCP_URL")} override the built-in meeting MCP host`);
79656
- out.push(` ${import_picocolors49.default.dim("BRAINBASE_GITHUB_MCP_URL")} override the built-in GitHub MCP host`);
79657
- out.push(` ${import_picocolors49.default.dim("BRAINBASE_ORCHESTRATION_MCP_URL")} override the built-in orchestration MCP host`);
80312
+ out.push(` ${import_picocolors52.default.dim("BRAINBASE_MEMORY_MCP_URL")} override the built-in memory MCP host`);
80313
+ out.push(` ${import_picocolors52.default.dim("BRAINBASE_BROWSER_MCP_URL")} override the built-in browser MCP host`);
80314
+ out.push(` ${import_picocolors52.default.dim("BRAINBASE_SLACK_MCP_URL")} override the built-in Slack MCP host`);
80315
+ out.push(` ${import_picocolors52.default.dim("BRAINBASE_MEETING_MCP_URL")} override the built-in meeting MCP host`);
80316
+ out.push(` ${import_picocolors52.default.dim("BRAINBASE_GITHUB_MCP_URL")} override the built-in GitHub MCP host`);
80317
+ out.push(` ${import_picocolors52.default.dim("BRAINBASE_ORCHESTRATION_MCP_URL")} override the built-in orchestration MCP host`);
79658
80318
  out.push("");
79659
80319
  out.push(divider("HARNESSES"));
79660
80320
  out.push("");
79661
- out.push(` ${import_picocolors49.default.dim("•")} ${import_picocolors49.default.bold("claude-code")} ${import_picocolors49.default.dim("skills, mcps, agents, commands, playbooks, instructions, files")}`);
79662
- out.push(` ${import_picocolors49.default.dim("•")} ${import_picocolors49.default.bold("codex")} ${import_picocolors49.default.dim("skills, mcps, commands, playbooks, instructions, files")}`);
79663
- out.push(` ${import_picocolors49.default.dim("•")} ${import_picocolors49.default.bold("kafka")} ${import_picocolors49.default.dim("skills, mcps, agents, commands, playbooks, instructions, files")}`);
80321
+ out.push(` ${import_picocolors52.default.dim("•")} ${import_picocolors52.default.bold("claude-code")} ${import_picocolors52.default.dim("skills, mcps, agents, commands, playbooks, instructions, files")}`);
80322
+ out.push(` ${import_picocolors52.default.dim("•")} ${import_picocolors52.default.bold("codex")} ${import_picocolors52.default.dim("skills, mcps, commands, playbooks, instructions, files")}`);
80323
+ out.push(` ${import_picocolors52.default.dim("•")} ${import_picocolors52.default.bold("kafka")} ${import_picocolors52.default.dim("skills, mcps, agents, commands, playbooks, instructions, files")}`);
79664
80324
  out.push("");
79665
80325
  console.log(out.join(`
79666
80326
  `));
79667
80327
  }
79668
- function getFlag(args, ...names) {
80328
+ var VALUE_TAKING_FLAGS = new Set([
80329
+ "--scope",
80330
+ "--name",
80331
+ "-n",
80332
+ "--harness",
80333
+ "--web",
80334
+ "--visibility",
80335
+ "--category",
80336
+ "--target",
80337
+ "--page",
80338
+ "--as",
80339
+ "--agent",
80340
+ "--shell",
80341
+ "--skill-version",
80342
+ "--tagline",
80343
+ "--org",
80344
+ "--team",
80345
+ "--description",
80346
+ "--schema",
80347
+ "--from",
80348
+ "--to",
80349
+ "--bot-token",
80350
+ "--signing-secret",
80351
+ "--app-id",
80352
+ "--app-name",
80353
+ "--bot-name",
80354
+ "--bot-image-url"
80355
+ ]);
80356
+ function isValueOfPriorFlag2(args, index) {
80357
+ return index > 0 && VALUE_TAKING_FLAGS.has(args[index - 1]);
80358
+ }
80359
+ function findFlag(args, name) {
80360
+ const prefix = `${name}=`;
80361
+ for (let i = 0;i < args.length; i++) {
80362
+ if (isValueOfPriorFlag2(args, i))
80363
+ continue;
80364
+ const a3 = args[i];
80365
+ if (a3 === name)
80366
+ return { index: i };
80367
+ if (a3.startsWith(prefix))
80368
+ return { index: i, joinedValue: a3.slice(prefix.length) };
80369
+ }
80370
+ return null;
80371
+ }
80372
+ function takeFlagOnce(args, names) {
80373
+ let best = null;
79669
80374
  for (const n of names) {
79670
- const i = args.indexOf(n);
79671
- if (i >= 0) {
79672
- const v3 = args[i + 1];
79673
- args.splice(i, v3 && !v3.startsWith("--") && !(n.startsWith("-") && v3.startsWith("-")) ? 2 : 1);
79674
- return v3 && !v3.startsWith("--") ? v3 : "";
79675
- }
80375
+ const hit = findFlag(args, n);
80376
+ if (hit && (!best || hit.index < best.index))
80377
+ best = hit;
79676
80378
  }
79677
- return;
80379
+ if (!best)
80380
+ return;
80381
+ if (best.joinedValue !== undefined) {
80382
+ args.splice(best.index, 1);
80383
+ return best.joinedValue;
80384
+ }
80385
+ const v3 = args[best.index + 1];
80386
+ if (v3 && !v3.startsWith("-")) {
80387
+ args.splice(best.index, 2);
80388
+ return v3;
80389
+ }
80390
+ args.splice(best.index, 1);
80391
+ return "";
80392
+ }
80393
+ function getFlag(args, ...names) {
80394
+ const first = takeFlagOnce(args, names);
80395
+ if (first === undefined)
80396
+ return;
80397
+ while (takeFlagOnce(args, names) !== undefined) {}
80398
+ return first;
79678
80399
  }
79679
80400
  function getFlagAll(args, ...names) {
79680
80401
  const out = [];
79681
- let v3 = getFlag(args, ...names);
80402
+ let v3 = takeFlagOnce(args, names);
79682
80403
  while (v3 !== undefined) {
79683
80404
  if (v3)
79684
80405
  out.push(v3);
79685
- v3 = getFlag(args, ...names);
80406
+ v3 = takeFlagOnce(args, names);
79686
80407
  }
79687
80408
  return out;
79688
80409
  }
79689
- function hasFlag2(args, ...names) {
79690
- for (const n of names) {
79691
- const i = args.indexOf(n);
79692
- if (i >= 0) {
79693
- args.splice(i, 1);
80410
+ function interpretJoinedBoolean(value, name) {
80411
+ const v3 = value.trim().toLowerCase();
80412
+ if (v3 === "")
80413
+ return false;
80414
+ switch (v3) {
80415
+ case "false":
80416
+ case "0":
80417
+ case "no":
80418
+ case "off":
80419
+ return false;
80420
+ case "true":
80421
+ case "1":
80422
+ case "yes":
80423
+ case "on":
79694
80424
  return true;
80425
+ default:
80426
+ throw new Error(`Unrecognised value for ${name}: ${value}`);
80427
+ }
80428
+ }
80429
+ function hasFlag2(args, ...names) {
80430
+ let leftmost;
80431
+ while (true) {
80432
+ let best = null;
80433
+ for (const n of names) {
80434
+ const hit = findFlag(args, n);
80435
+ if (hit && (!best || hit.index < best.index))
80436
+ best = { ...hit, name: n };
79695
80437
  }
80438
+ if (!best)
80439
+ break;
80440
+ args.splice(best.index, 1);
80441
+ const enabled = best.joinedValue === undefined ? true : interpretJoinedBoolean(best.joinedValue, best.name);
80442
+ if (leftmost === undefined)
80443
+ leftmost = enabled;
79696
80444
  }
79697
- return false;
80445
+ return leftmost ?? false;
79698
80446
  }
79699
80447
  async function requireAuth(cmd) {
79700
80448
  if (!PROTECTED.has(cmd))
@@ -79724,13 +80472,13 @@ async function requireAuth(cmd) {
79724
80472
  if (STORED_PAT_COMMANDS.has(cmd) && readToken())
79725
80473
  return;
79726
80474
  console.error("");
79727
- console.error(` ${brandTint("◆")} ${import_picocolors49.default.bold("brainbase")}`);
80475
+ console.error(` ${brandTint("◆")} ${import_picocolors52.default.bold("brainbase")}`);
79728
80476
  console.error("");
79729
- console.error(` ${import_picocolors49.default.red("✗")} You need to sign in to use ${import_picocolors49.default.bold("brainbase " + cmd)}.`);
80477
+ console.error(` ${import_picocolors52.default.red("✗")} You need to sign in to use ${import_picocolors52.default.bold("brainbase " + cmd)}.`);
79730
80478
  if (status.reason)
79731
- console.error(` ${import_picocolors49.default.dim(status.reason)}`);
80479
+ console.error(` ${import_picocolors52.default.dim(status.reason)}`);
79732
80480
  console.error("");
79733
- console.error(` Run ${import_picocolors49.default.cyan("brainbase login")} to connect this device.`);
80481
+ console.error(` Run ${import_picocolors52.default.cyan("brainbase login")} to connect this device.`);
79734
80482
  console.error("");
79735
80483
  process14.exit(1);
79736
80484
  }
@@ -79740,7 +80488,7 @@ async function main() {
79740
80488
  const rawCwd = process14.cwd();
79741
80489
  const cwd2 = (() => {
79742
80490
  try {
79743
- return fs82.realpathSync(rawCwd);
80491
+ return fs83.realpathSync(rawCwd);
79744
80492
  } catch {
79745
80493
  return rawCwd;
79746
80494
  }
@@ -79789,6 +80537,12 @@ async function main() {
79789
80537
  const noPushFlag = hasFlag2(sharedArgs, "--no-push");
79790
80538
  const jsonFlag = hasFlag2(sharedArgs, "--json");
79791
80539
  const acpFlag = hasFlag2(sharedArgs, "--acp");
80540
+ const botTokenFlag = getFlag(sharedArgs, "--bot-token");
80541
+ const signingSecretFlag = getFlag(sharedArgs, "--signing-secret");
80542
+ const appIdFlag = getFlag(sharedArgs, "--app-id");
80543
+ const appNameFlag = getFlag(sharedArgs, "--app-name");
80544
+ const botNameFlag = getFlag(sharedArgs, "--bot-name");
80545
+ const botImageUrlFlag = getFlag(sharedArgs, "--bot-image-url");
79792
80546
  ensureSkillResolversRegistered();
79793
80547
  await requireAuth(cmd);
79794
80548
  try {
@@ -79872,7 +80626,13 @@ async function main() {
79872
80626
  track,
79873
80627
  force: forceFlag,
79874
80628
  runEntrypoint: runEntrypointFlag,
79875
- acp: acpFlag
80629
+ acp: acpFlag,
80630
+ botToken: botTokenFlag,
80631
+ signingSecret: signingSecretFlag,
80632
+ appId: appIdFlag,
80633
+ appName: appNameFlag,
80634
+ botName: botNameFlag,
80635
+ botImageUrl: botImageUrlFlag
79876
80636
  });
79877
80637
  break;
79878
80638
  }
@@ -79931,10 +80691,10 @@ async function main() {
79931
80691
  process14.exit(1);
79932
80692
  }
79933
80693
  } catch (err) {
79934
- console.error(import_picocolors49.default.red(`
80694
+ console.error(import_picocolors52.default.red(`
79935
80695
  ${err.message}`));
79936
80696
  if (err instanceof ApiError && err.status === 401) {
79937
- console.error(` Run ${import_picocolors49.default.cyan("brainbase login")} to connect this device.`);
80697
+ console.error(` Run ${import_picocolors52.default.cyan("brainbase login")} to connect this device.`);
79938
80698
  }
79939
80699
  if (process14.env.BRAINBASE_DEBUG)
79940
80700
  console.error(err.stack);