@brainbase-labs/cli 0.21.2 → 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 +976 -364
  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.2",
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: {
@@ -54292,6 +54292,19 @@ var masApi = {
54292
54292
  return parseMasTaskCreateResponse(body);
54293
54293
  }
54294
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
+ }
54295
54308
  var api = {
54296
54309
  listOrgs() {
54297
54310
  return request("/orgs");
@@ -54379,6 +54392,21 @@ var api = {
54379
54392
  method: "DELETE"
54380
54393
  });
54381
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
+ },
54382
54410
  listOrchestrations(orgId, teamId) {
54383
54411
  return request(`/orgs/${encodeURIComponent(orgId)}/teams/${encodeURIComponent(teamId)}/orchestrations`);
54384
54412
  },
@@ -63308,7 +63336,7 @@ function runHarnessInstall(harnessId, components, opts, agentName) {
63308
63336
  }
63309
63337
 
63310
63338
  // src/cli/agent.ts
63311
- var import_picocolors34 = __toESM(require_picocolors(), 1);
63339
+ var import_picocolors37 = __toESM(require_picocolors(), 1);
63312
63340
 
63313
63341
  // src/cli/agent-pull.ts
63314
63342
  import { spawn as spawn2 } from "node:child_process";
@@ -66421,6 +66449,396 @@ function formatAgentList(agents, labels) {
66421
66449
  `);
66422
66450
  }
66423
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
+
66424
66842
  // src/cli/agent.ts
66425
66843
  async function runAgent(cwd2, sub, args, opts) {
66426
66844
  if (args.some((arg) => arg === "--help" || arg === "-h")) {
@@ -66471,6 +66889,23 @@ async function runAgent(cwd2, sub, args, opts) {
66471
66889
  case "status":
66472
66890
  await runAgentStatus(cwd2, { json: opts.json });
66473
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;
66474
66909
  case "env":
66475
66910
  await runAgentEnv(cwd2, { shell: opts.shell });
66476
66911
  return;
@@ -66490,25 +66925,31 @@ async function runAgent(cwd2, sub, args, opts) {
66490
66925
  function printHelp() {
66491
66926
  const out = [];
66492
66927
  out.push("");
66493
- 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)"`')}`);
66494
66940
  out.push("");
66495
- 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)")}`);
66496
- out.push(` ${import_picocolors34.default.cyan("create")} ${import_picocolors34.default.dim("claim an unclaimed brainbase.agent.yaml and create the cloud agent")}`);
66497
- 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")}`);
66498
- 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)")}`);
66499
- out.push(` ${import_picocolors34.default.cyan("unpack")} ${import_picocolors34.default.dim("install the claimed agent into a harness layout (--harness to override)")}`);
66500
- 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)")}`);
66501
- 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.')}`);
66502
66943
  out.push("");
66503
66944
  console.log(out.join(`
66504
66945
  `));
66505
66946
  }
66506
66947
 
66507
66948
  // src/cli/team.ts
66508
- var import_picocolors36 = __toESM(require_picocolors(), 1);
66949
+ var import_picocolors39 = __toESM(require_picocolors(), 1);
66509
66950
 
66510
66951
  // src/cli/team-list.ts
66511
- var import_picocolors35 = __toESM(require_picocolors(), 1);
66952
+ var import_picocolors38 = __toESM(require_picocolors(), 1);
66512
66953
  async function runTeamList(args) {
66513
66954
  if (!args.json)
66514
66955
  banner("team list — teams you can put agents in");
@@ -66528,25 +66969,25 @@ async function runTeamList(args) {
66528
66969
  function formatTeamList(grouped) {
66529
66970
  const lines = [""];
66530
66971
  if (grouped.length === 0) {
66531
- 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.")}`, "");
66532
66973
  return lines.join(`
66533
66974
  `);
66534
66975
  }
66535
66976
  const nameWidth = Math.max(...grouped.flatMap(({ teams }) => teams.map((t) => t.name.length)), 0);
66536
66977
  for (const { org, teams, error } of grouped) {
66537
- const slug = org.slug ? ` ${import_picocolors35.default.dim(org.slug)}` : "";
66538
- 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}`);
66539
66980
  if (error) {
66540
- lines.push(` ${import_picocolors35.default.red(`could not load teams: ${error}`)}`);
66981
+ lines.push(` ${import_picocolors38.default.red(`could not load teams: ${error}`)}`);
66541
66982
  } else if (teams.length === 0) {
66542
- 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")}`);
66543
66984
  }
66544
66985
  for (const team of teams) {
66545
- 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)}`);
66546
66987
  }
66547
66988
  lines.push("");
66548
66989
  }
66549
- 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>")}`, "");
66550
66991
  return lines.join(`
66551
66992
  `);
66552
66993
  }
@@ -66577,28 +67018,28 @@ async function runTeam(sub, args, opts) {
66577
67018
  function printHelp2() {
66578
67019
  const out = [];
66579
67020
  out.push("");
66580
- 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]")}`);
66581
67022
  out.push("");
66582
- 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")}`);
66583
67024
  out.push("");
66584
- out.push(` ${import_picocolors36.default.dim("--org <id-or-slug>")} ${import_picocolors36.default.dim("limit to one organization")}`);
66585
- 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")}`);
66586
67027
  out.push("");
66587
67028
  console.log(out.join(`
66588
67029
  `));
66589
67030
  }
66590
67031
 
66591
67032
  // src/cli/orchestration.ts
66592
- var import_picocolors43 = __toESM(require_picocolors(), 1);
67033
+ var import_picocolors46 = __toESM(require_picocolors(), 1);
66593
67034
 
66594
67035
  // src/cli/orchestration-pull.ts
66595
67036
  import path86 from "node:path";
66596
- import fs77 from "node:fs";
66597
- var import_picocolors37 = __toESM(require_picocolors(), 1);
67037
+ import fs78 from "node:fs";
67038
+ var import_picocolors40 = __toESM(require_picocolors(), 1);
66598
67039
 
66599
67040
  // src/core/orchestration-manifest.ts
66600
67041
  import path83 from "node:path";
66601
- import fs74 from "node:fs";
67042
+ import fs75 from "node:fs";
66602
67043
  var import_yaml4 = __toESM(require_dist(), 1);
66603
67044
  var ORCH_MANIFEST_FILE = "brainbase-orchestration.yaml";
66604
67045
  var ORCH_MEMBERS_DIR = "agents";
@@ -66654,13 +67095,13 @@ function orchManifestPath(cwd2) {
66654
67095
  return path83.join(cwd2, ORCH_MANIFEST_FILE);
66655
67096
  }
66656
67097
  function hasOrchManifest(cwd2) {
66657
- return fs74.existsSync(orchManifestPath(cwd2));
67098
+ return fs75.existsSync(orchManifestPath(cwd2));
66658
67099
  }
66659
67100
  function readOrchManifest(cwd2) {
66660
67101
  const p2 = orchManifestPath(cwd2);
66661
- if (!fs74.existsSync(p2))
67102
+ if (!fs75.existsSync(p2))
66662
67103
  return null;
66663
- const raw = fs74.readFileSync(p2, "utf8");
67104
+ const raw = fs75.readFileSync(p2, "utf8");
66664
67105
  let parsed;
66665
67106
  try {
66666
67107
  parsed = import_yaml4.default.parse(raw);
@@ -66681,7 +67122,7 @@ function writeOrchManifest(cwd2, manifest) {
66681
67122
  ` + " `brainbase orchestration push`. Member agents live under ./agents/." + `
66682
67123
  Schedule triggers are writable. App/Pipedream triggers are preserved
66683
67124
  ` + " as read-only context and ignored by `orchestration push`.";
66684
- fs74.writeFileSync(orchManifestPath(cwd2), String(doc), "utf8");
67125
+ fs75.writeFileSync(orchManifestPath(cwd2), String(doc), "utf8");
66685
67126
  }
66686
67127
  function memberDir(cwd2, slug) {
66687
67128
  return path83.join(cwd2, ORCH_MEMBERS_DIR, slug);
@@ -66719,7 +67160,7 @@ function resolveMemberSlugs(members) {
66719
67160
 
66720
67161
  // src/core/orchestration-link.ts
66721
67162
  import path84 from "node:path";
66722
- import fs75 from "node:fs";
67163
+ import fs76 from "node:fs";
66723
67164
  var ORCH_LINK_FILE = "orchestration-link.json";
66724
67165
  var ORCH_SYNC_STATE_FILE = "orchestration-sync-state.json";
66725
67166
  var OrchestrationLinkSchema = exports_external.object({
@@ -66770,12 +67211,12 @@ function readOrchLink(cwd2) {
66770
67211
  }
66771
67212
  function writeOrchLink(cwd2, link2) {
66772
67213
  ensureDir(path84.join(cwd2, LINK_DIR));
66773
- const clean = {};
67214
+ const clean2 = {};
66774
67215
  for (const [k3, v3] of Object.entries(link2)) {
66775
67216
  if (v3 !== null && v3 !== undefined)
66776
- clean[k3] = v3;
67217
+ clean2[k3] = v3;
66777
67218
  }
66778
- writeJson(orchLinkPath(cwd2), clean);
67219
+ writeJson(orchLinkPath(cwd2), clean2);
66779
67220
  ensureGitignore2(cwd2);
66780
67221
  }
66781
67222
  function readOrchSyncState(cwd2) {
@@ -66799,12 +67240,12 @@ function ensureGitignore2(cwd2) {
66799
67240
  `;
66800
67241
  try {
66801
67242
  if (!exists(ignorePath)) {
66802
- fs75.writeFileSync(ignorePath, desired);
67243
+ fs76.writeFileSync(ignorePath, desired);
66803
67244
  return;
66804
67245
  }
66805
- const current = fs75.readFileSync(ignorePath, "utf8");
67246
+ const current = fs76.readFileSync(ignorePath, "utf8");
66806
67247
  if (!current.split(/\r?\n/).some((l2) => l2.trim() === ORCH_SYNC_STATE_FILE)) {
66807
- fs75.writeFileSync(ignorePath, current.endsWith(`
67248
+ fs76.writeFileSync(ignorePath, current.endsWith(`
66808
67249
  `) ? current + desired : current + `
66809
67250
  ` + desired);
66810
67251
  }
@@ -66813,7 +67254,7 @@ function ensureGitignore2(cwd2) {
66813
67254
 
66814
67255
  // src/core/agent-fresh-install.ts
66815
67256
  import path85 from "node:path";
66816
- import fs76 from "node:fs";
67257
+ import fs77 from "node:fs";
66817
67258
  import os15 from "node:os";
66818
67259
  async function installAgentFresh(input) {
66819
67260
  const { cwd: cwd2, agent, cloud, harness } = input;
@@ -66904,19 +67345,19 @@ async function installAgentFresh(input) {
66904
67345
  };
66905
67346
  } finally {
66906
67347
  try {
66907
- fs76.rmSync(stageRoot, { recursive: true, force: true });
67348
+ fs77.rmSync(stageRoot, { recursive: true, force: true });
66908
67349
  } catch {}
66909
67350
  }
66910
67351
  }
66911
67352
  function stageManifestComponents2(components) {
66912
- const root = fs76.mkdtempSync(path85.join(os15.tmpdir(), "brainbase-orch-pull-"));
67353
+ const root = fs77.mkdtempSync(path85.join(os15.tmpdir(), "brainbase-orch-pull-"));
66913
67354
  for (const c2 of components) {
66914
67355
  const compDir = path85.join(root, c2.type, c2.slug);
66915
67356
  ensureDir(compDir);
66916
67357
  for (const f4 of c2.files) {
66917
67358
  const target = path85.join(compDir, f4.path);
66918
67359
  ensureDir(path85.dirname(target));
66919
- fs76.writeFileSync(target, f4.content);
67360
+ fs77.writeFileSync(target, f4.content);
66920
67361
  }
66921
67362
  }
66922
67363
  return root;
@@ -66951,7 +67392,7 @@ function materializeInstructions2(cwd2, cloud) {
66951
67392
  continue;
66952
67393
  const target = path85.join(cwd2, DEFAULT_INSTRUCTIONS_FILE);
66953
67394
  ensureDir(path85.dirname(target));
66954
- fs76.writeFileSync(target, normalizeInstructionBody(body), "utf8");
67395
+ fs77.writeFileSync(target, normalizeInstructionBody(body), "utf8");
66955
67396
  return;
66956
67397
  }
66957
67398
  }
@@ -66965,7 +67406,7 @@ function materializePlaybooks2(cwd2, cloud) {
66965
67406
  const { body } = stripPlaybookFrontmatter(raw);
66966
67407
  const target = path85.join(cwd2, DEFAULT_PLAYBOOKS_DIR, `${c2.slug}.md`);
66967
67408
  ensureDir(path85.dirname(target));
66968
- fs76.writeFileSync(target, body, "utf8");
67409
+ fs77.writeFileSync(target, body, "utf8");
66969
67410
  }
66970
67411
  }
66971
67412
  function buildManifestFromCloud(cloud, agent, localOnly = {}) {
@@ -67114,8 +67555,8 @@ async function runOrchestrationPull(cwd2, args) {
67114
67555
  orchId = args.orchestrationId;
67115
67556
  } else {
67116
67557
  f2.warn("This folder is not linked to any orchestration.");
67117
- f2.info(`Run ${import_picocolors37.default.cyan("brainbase orchestration pull <id>")} with an orchestration id,
67118
- 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.`);
67119
67560
  return;
67120
67561
  }
67121
67562
  const sp = de();
@@ -67134,24 +67575,24 @@ async function runOrchestrationPull(cwd2, args) {
67134
67575
  const slugFor = (agentId) => slugByAgent.get(agentId) ?? agentId;
67135
67576
  const planLines = [];
67136
67577
  planLines.push("");
67137
- 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})`)}`);
67138
67579
  if (cloud.description)
67139
- planLines.push(` ${import_picocolors37.default.dim(cloud.description)}`);
67580
+ planLines.push(` ${import_picocolors40.default.dim(cloud.description)}`);
67140
67581
  planLines.push("");
67141
- planLines.push(` ${import_picocolors37.default.dim("members:")}`);
67582
+ planLines.push(` ${import_picocolors40.default.dim("members:")}`);
67142
67583
  for (const m3 of cloud.members) {
67143
67584
  const skipped = !m3.manifest;
67144
- const tail2 = skipped ? import_picocolors37.default.red(" (manifest unavailable — skipped)") : "";
67145
- 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}`);
67146
67587
  }
67147
67588
  if (cloud.edges.length) {
67148
67589
  planLines.push("");
67149
- planLines.push(` ${import_picocolors37.default.dim("edges:")}`);
67590
+ planLines.push(` ${import_picocolors40.default.dim("edges:")}`);
67150
67591
  for (const e2 of cloud.edges) {
67151
67592
  const from = slugFor(e2.from_agent_id);
67152
67593
  const to2 = slugFor(e2.to_agent_id);
67153
- const desc = e2.description ? ` ${import_picocolors37.default.dim("— " + e2.description)}` : "";
67154
- 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}`);
67155
67596
  }
67156
67597
  }
67157
67598
  planLines.push("");
@@ -67160,7 +67601,7 @@ async function runOrchestrationPull(cwd2, args) {
67160
67601
  const isRefresh = !!existingLink;
67161
67602
  if (!autoProceed(args.yes) && !isRefresh) {
67162
67603
  const ok = await se({
67163
- message: `Pull into ${import_picocolors37.default.bold(cwd2)}?`,
67604
+ message: `Pull into ${import_picocolors40.default.bold(cwd2)}?`,
67164
67605
  initialValue: true
67165
67606
  });
67166
67607
  if (!ensureNotCancelled(ok)) {
@@ -67169,7 +67610,7 @@ async function runOrchestrationPull(cwd2, args) {
67169
67610
  }
67170
67611
  }
67171
67612
  const fallbackHarness = args.harness ?? "claude-code";
67172
- fs77.mkdirSync(cwd2, { recursive: true });
67613
+ fs78.mkdirSync(cwd2, { recursive: true });
67173
67614
  if (hasOrchManifest(cwd2) && existingLink && existingLink.orchestration_id !== orchId) {
67174
67615
  f2.error(`This folder is linked to orchestration ${existingLink.orchestration_id}, not ${orchId}. Move to a fresh directory or unlink first.`);
67175
67616
  return;
@@ -67204,7 +67645,7 @@ async function runOrchestrationPull(cwd2, args) {
67204
67645
  scope: "project",
67205
67646
  pullSecrets: true
67206
67647
  });
67207
- 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)`)}.`);
67208
67649
  installedMembers.push({
67209
67650
  agent_id: m3.agent_id,
67210
67651
  slug,
@@ -67265,7 +67706,7 @@ async function runOrchestrationPull(cwd2, args) {
67265
67706
  payload_schema: e2.payload_schema ?? {}
67266
67707
  }))
67267
67708
  });
67268
- $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)`)}.`);
67269
67710
  }
67270
67711
  function handleApiError5(err) {
67271
67712
  if (err instanceof ApiError) {
@@ -67282,7 +67723,7 @@ function handleApiError5(err) {
67282
67723
  }
67283
67724
 
67284
67725
  // src/cli/orchestration-push.ts
67285
- var import_picocolors38 = __toESM(require_picocolors(), 1);
67726
+ var import_picocolors41 = __toESM(require_picocolors(), 1);
67286
67727
 
67287
67728
  // src/core/orchestration-outgoing.ts
67288
67729
  function buildOrchestrationGraphPayload(manifest, slugToAgentId) {
@@ -67365,7 +67806,7 @@ function findUnpushableMembers(cwd2, members) {
67365
67806
  continue;
67366
67807
  }
67367
67808
  if (!memberManifest.id) {
67368
- 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.`);
67369
67810
  blocked.push(m3.slug);
67370
67811
  continue;
67371
67812
  }
@@ -67380,12 +67821,12 @@ async function runOrchestrationPush(cwd2, args) {
67380
67821
  const link2 = readOrchLink(cwd2);
67381
67822
  if (!link2) {
67382
67823
  f2.warn("This folder is not linked to any orchestration.");
67383
- 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.`);
67384
67825
  return;
67385
67826
  }
67386
67827
  if (!hasOrchManifest(cwd2)) {
67387
- f2.warn(`No ${import_picocolors38.default.bold(ORCH_MANIFEST_FILE)} here.`);
67388
- 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.`);
67389
67830
  return;
67390
67831
  }
67391
67832
  let manifest;
@@ -67409,7 +67850,7 @@ async function runOrchestrationPush(cwd2, args) {
67409
67850
  }
67410
67851
  if (missing.length) {
67411
67852
  f2.error(`Missing local checkouts for: ${missing.join(", ")}.`);
67412
- 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.`);
67413
67854
  process.exitCode = 1;
67414
67855
  return;
67415
67856
  }
@@ -67430,13 +67871,13 @@ async function runOrchestrationPush(cwd2, args) {
67430
67871
  }
67431
67872
  }
67432
67873
  const plan = [""];
67433
- plan.push(` ${import_picocolors38.default.bold(link2.name)} ${import_picocolors38.default.dim(`(${link2.orchestration_id})`)}`);
67434
- 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"}`)}`);
67435
67876
  plan.push("");
67436
67877
  if (!args.graphOnly) {
67437
- plan.push(` ${import_picocolors38.default.dim("per-member agent push:")}`);
67878
+ plan.push(` ${import_picocolors41.default.dim("per-member agent push:")}`);
67438
67879
  for (const m3 of manifest.members) {
67439
- 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)}`);
67440
67881
  }
67441
67882
  plan.push("");
67442
67883
  }
@@ -67456,7 +67897,7 @@ async function runOrchestrationPush(cwd2, args) {
67456
67897
  for (const m3 of manifest.members) {
67457
67898
  const dir = memberDir(cwd2, m3.slug);
67458
67899
  console.log("");
67459
- 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("───")}`);
67460
67901
  const exitCodeBeforePush = process.exitCode;
67461
67902
  try {
67462
67903
  await runAgentPush(dir, { yes: true });
@@ -67520,7 +67961,7 @@ function handleApiError6(err) {
67520
67961
  f2.error("You do not have access to this orchestration.");
67521
67962
  } else if (err.status === 409) {
67522
67963
  f2.error(err.message);
67523
- 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.`);
67524
67965
  } else {
67525
67966
  f2.error(err.message);
67526
67967
  }
@@ -67530,13 +67971,13 @@ function handleApiError6(err) {
67530
67971
  }
67531
67972
 
67532
67973
  // src/cli/orchestration-status.ts
67533
- var import_picocolors39 = __toESM(require_picocolors(), 1);
67974
+ var import_picocolors42 = __toESM(require_picocolors(), 1);
67534
67975
  async function runOrchestrationStatus(cwd2) {
67535
67976
  banner("orchestration status — what changed locally, remotely, both");
67536
67977
  const link2 = readOrchLink(cwd2);
67537
67978
  if (!link2) {
67538
67979
  f2.warn("This folder is not linked to any orchestration.");
67539
- 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.`);
67540
67981
  return;
67541
67982
  }
67542
67983
  const localManifest = hasOrchManifest(cwd2) ? readOrchManifest(cwd2) : null;
@@ -67559,8 +68000,8 @@ async function runOrchestrationStatus(cwd2) {
67559
68000
  }
67560
68001
  const lines = [];
67561
68002
  lines.push("");
67562
- lines.push(` ${import_picocolors39.default.bold(link2.name)} ${import_picocolors39.default.dim(`(${link2.orchestration_id})`)}`);
67563
- 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"}`);
67564
68005
  lines.push("");
67565
68006
  const localSlugByAgentId = new Map;
67566
68007
  for (const m3 of localManifest?.members ?? []) {
@@ -67574,12 +68015,12 @@ async function runOrchestrationStatus(cwd2) {
67574
68015
  const membersAdded = [...localMemberSet].filter((s3) => !cloudMemberSet.has(s3));
67575
68016
  const membersRemoved = [...cloudMemberSet].filter((s3) => !localMemberSet.has(s3));
67576
68017
  if (membersAdded.length || membersRemoved.length) {
67577
- lines.push(` ${import_picocolors39.default.bold("members")}`);
68018
+ lines.push(` ${import_picocolors42.default.bold("members")}`);
67578
68019
  for (const slug of membersAdded) {
67579
- 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)}`);
67580
68021
  }
67581
68022
  for (const slug of membersRemoved) {
67582
- 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)}`);
67583
68024
  }
67584
68025
  lines.push("");
67585
68026
  }
@@ -67594,11 +68035,11 @@ async function runOrchestrationStatus(cwd2) {
67594
68035
  const edgesAdded = [...localEdges.keys()].filter((k3) => !cloudEdges.has(k3));
67595
68036
  const edgesRemoved = [...cloudEdges.keys()].filter((k3) => !localEdges.has(k3));
67596
68037
  if (edgesAdded.length || edgesRemoved.length) {
67597
- lines.push(` ${import_picocolors39.default.bold("edges")}`);
68038
+ lines.push(` ${import_picocolors42.default.bold("edges")}`);
67598
68039
  for (const k3 of edgesAdded)
67599
- lines.push(` ${import_picocolors39.default.yellow("→ push")} added in yaml: ${k3}`);
68040
+ lines.push(` ${import_picocolors42.default.yellow("→ push")} added in yaml: ${k3}`);
67600
68041
  for (const k3 of edgesRemoved)
67601
- lines.push(` ${import_picocolors39.default.cyan("← pull")} added on cloud: ${k3}`);
68042
+ lines.push(` ${import_picocolors42.default.cyan("← pull")} added on cloud: ${k3}`);
67602
68043
  lines.push("");
67603
68044
  }
67604
68045
  const cloudTriggerKey = (t) => {
@@ -67636,11 +68077,11 @@ async function runOrchestrationStatus(cwd2) {
67636
68077
  const triggersAdded = [...localTriggers.keys()].filter((k3) => !cloudTriggers.has(k3));
67637
68078
  const triggersRemoved = [...cloudTriggers.keys()].filter((k3) => !localTriggers.has(k3));
67638
68079
  if (triggersAdded.length || triggersRemoved.length) {
67639
- lines.push(` ${import_picocolors39.default.bold("schedule triggers")}`);
68080
+ lines.push(` ${import_picocolors42.default.bold("schedule triggers")}`);
67640
68081
  for (const k3 of triggersAdded)
67641
- 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}`);
67642
68083
  for (const k3 of triggersRemoved)
67643
- 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}`);
67644
68085
  lines.push("");
67645
68086
  }
67646
68087
  const lockByAgentId = new Map((lock?.members ?? []).map((m3) => [m3.agent_id, m3]));
@@ -67663,27 +68104,27 @@ async function runOrchestrationStatus(cwd2) {
67663
68104
  }
67664
68105
  }
67665
68106
  if (memberDrift.length) {
67666
- lines.push(` ${import_picocolors39.default.bold("member content drift")}`);
68107
+ lines.push(` ${import_picocolors42.default.bold("member content drift")}`);
67667
68108
  for (const d3 of memberDrift) {
67668
- 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)}`);
67669
68110
  }
67670
- 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")}`);
67671
68112
  lines.push("");
67672
68113
  }
67673
68114
  const revisionDrift = lock?.revision != null && cloud.revision !== lock.revision;
67674
68115
  if (revisionDrift) {
67675
- lines.push(` ${import_picocolors39.default.bold("cloud revision")}`);
67676
- 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}`)}`);
67677
68118
  lines.push("");
67678
68119
  }
67679
68120
  if (!membersAdded.length && !membersRemoved.length && !edgesAdded.length && !edgesRemoved.length && !triggersAdded.length && !triggersRemoved.length && !memberDrift.length && !revisionDrift) {
67680
- lines.push(` ${import_picocolors39.default.green("✓")} everything is in sync`);
68121
+ lines.push(` ${import_picocolors42.default.green("✓")} everything is in sync`);
67681
68122
  lines.push("");
67682
68123
  console.log(lines.join(`
67683
68124
  `));
67684
68125
  return;
67685
68126
  }
67686
- 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")}`);
67687
68128
  lines.push("");
67688
68129
  console.log(lines.join(`
67689
68130
  `));
@@ -67698,7 +68139,7 @@ function stableJson(value) {
67698
68139
  }
67699
68140
 
67700
68141
  // src/cli/orchestration-list.ts
67701
- var import_picocolors40 = __toESM(require_picocolors(), 1);
68142
+ var import_picocolors43 = __toESM(require_picocolors(), 1);
67702
68143
  async function runOrchestrationList(args) {
67703
68144
  banner("orchestration list — orchestrations under a team");
67704
68145
  const { org, team } = await resolveOrgAndTeam({
@@ -67722,21 +68163,21 @@ async function runOrchestrationList(args) {
67722
68163
  }
67723
68164
  const lines = [""];
67724
68165
  for (const o2 of items) {
67725
- 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)}`);
67726
68167
  if (o2.description)
67727
- lines.push(` ${import_picocolors40.default.dim(o2.description)}`);
67728
- 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"}`)}`);
67729
68170
  lines.push("");
67730
68171
  }
67731
- 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>")}`);
67732
68173
  lines.push("");
67733
68174
  console.log(lines.join(`
67734
68175
  `));
67735
68176
  }
67736
68177
 
67737
68178
  // src/cli/orchestration-add-agent.ts
67738
- import fs78 from "node:fs";
67739
- var import_picocolors41 = __toESM(require_picocolors(), 1);
68179
+ import fs79 from "node:fs";
68180
+ var import_picocolors44 = __toESM(require_picocolors(), 1);
67740
68181
 
67741
68182
  // src/core/orchestration-add.ts
67742
68183
  function resolveOrgIdForGroup(groupId, orgsWithTeams) {
@@ -67801,7 +68242,7 @@ async function runOrchestrationAddAgent(cwd2, args) {
67801
68242
  const link2 = readOrchLink(cwd2);
67802
68243
  if (!link2 || !hasOrchManifest(cwd2)) {
67803
68244
  f2.warn("This folder is not a linked orchestration.");
67804
- 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.`);
67805
68246
  return;
67806
68247
  }
67807
68248
  let manifest;
@@ -67821,13 +68262,13 @@ async function runOrchestrationAddAgent(cwd2, args) {
67821
68262
  })).trim();
67822
68263
  }
67823
68264
  let slug = slugifyMemberName(name);
67824
- 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))) {
67825
68266
  let n = 2;
67826
68267
  let candidate = `${slug}-${n}`;
67827
- 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))) {
67828
68269
  candidate = `${slug}-${++n}`;
67829
68270
  }
67830
- 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)}.`);
67831
68272
  slug = candidate;
67832
68273
  }
67833
68274
  let payloadSchema;
@@ -67851,7 +68292,7 @@ async function runOrchestrationAddAgent(cwd2, args) {
67851
68292
  const resolved = resolveOrgIdForGroup(link2.group_id, orgsWithTeams);
67852
68293
  if (!resolved) {
67853
68294
  sp.stop("Failed.");
67854
- 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.`);
67855
68296
  return;
67856
68297
  }
67857
68298
  orgId = resolved;
@@ -67868,14 +68309,14 @@ async function runOrchestrationAddAgent(cwd2, args) {
67868
68309
  if (from.length === 0 && to2.length === 0 && isInteractive() && manifest.members.length > 0) {
67869
68310
  const memberOptions = manifest.members.map((m3) => ({ value: m3.slug, label: m3.slug }));
67870
68311
  const pickedFrom = await ae({
67871
- 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)`,
67872
68313
  options: memberOptions,
67873
68314
  required: false
67874
68315
  });
67875
68316
  if (Array.isArray(pickedFrom))
67876
68317
  from = pickedFrom;
67877
68318
  const pickedTo = await ae({
67878
- 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)`,
67879
68320
  options: memberOptions,
67880
68321
  required: false
67881
68322
  });
@@ -67896,7 +68337,7 @@ async function runOrchestrationAddAgent(cwd2, args) {
67896
68337
  }
67897
68338
  const dest = memberDir(cwd2, slug);
67898
68339
  try {
67899
- fs78.mkdirSync(dest, { recursive: true });
68340
+ fs79.mkdirSync(dest, { recursive: true });
67900
68341
  await runAgentCreate(dest, {
67901
68342
  name,
67902
68343
  orgId,
@@ -67907,30 +68348,30 @@ async function runOrchestrationAddAgent(cwd2, args) {
67907
68348
  });
67908
68349
  } catch (err) {
67909
68350
  try {
67910
- fs78.rmSync(dest, { recursive: true, force: true });
68351
+ fs79.rmSync(dest, { recursive: true, force: true });
67911
68352
  } catch {}
67912
68353
  f2.error(`Failed to create ${slug}: ${err.message}`);
67913
68354
  return;
67914
68355
  }
67915
68356
  writeOrchManifest(cwd2, updated);
67916
68357
  if (args.noPush) {
67917
- 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.`);
67918
68359
  return;
67919
68360
  }
67920
68361
  await runOrchestrationPush(cwd2, { yes: true, graphOnly: true });
67921
68362
  }
67922
68363
 
67923
68364
  // src/cli/orchestration-create.ts
67924
- var import_picocolors42 = __toESM(require_picocolors(), 1);
68365
+ var import_picocolors45 = __toESM(require_picocolors(), 1);
67925
68366
  async function runOrchestrationCreate(cwd2, args) {
67926
68367
  banner("orchestration create — claim a brainbase-orchestration.yaml");
67927
68368
  if (readOrchLink(cwd2)) {
67928
68369
  f2.warn("This folder is already linked to an orchestration.");
67929
- 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.`);
67930
68371
  return;
67931
68372
  }
67932
68373
  if (!hasOrchManifest(cwd2)) {
67933
- f2.warn(`No ${import_picocolors42.default.bold(ORCH_MANIFEST_FILE)} here.`);
68374
+ f2.warn(`No ${import_picocolors45.default.bold(ORCH_MANIFEST_FILE)} here.`);
67934
68375
  f2.info(`Create one, or pull an existing orchestration first.`);
67935
68376
  return;
67936
68377
  }
@@ -67963,10 +68404,10 @@ async function runOrchestrationCreate(cwd2, args) {
67963
68404
  });
67964
68405
  const plan = [
67965
68406
  "",
67966
- ` ${import_picocolors42.default.bold(manifest.orchestration.name)}`,
67967
- ` ${import_picocolors42.default.dim("org")} ${import_picocolors42.default.bold(target.org.name)}`,
67968
- ` ${import_picocolors42.default.dim("team")} ${import_picocolors42.default.bold(target.team.name)}`,
67969
- ` ${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"}`,
67970
68411
  ""
67971
68412
  ];
67972
68413
  console.log(plan.join(`
@@ -67996,7 +68437,7 @@ async function runOrchestrationCreate(cwd2, args) {
67996
68437
  edges: graph.edges,
67997
68438
  triggers: graph.triggers
67998
68439
  });
67999
- sp.stop(`Created ${import_picocolors42.default.bold(created.name)}.`);
68440
+ sp.stop(`Created ${import_picocolors45.default.bold(created.name)}.`);
68000
68441
  writeOrchLink(cwd2, {
68001
68442
  schemaVersion: 1,
68002
68443
  orchestration_id: created.id,
@@ -68109,21 +68550,21 @@ async function runOrchestration(cwd2, sub, args, opts) {
68109
68550
  function printHelp3() {
68110
68551
  const out = [];
68111
68552
  out.push("");
68112
- 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]")}`);
68113
68554
  out.push("");
68114
- out.push(` ${import_picocolors43.default.cyan("create")} ${import_picocolors43.default.dim("claim a local orchestration manifest and create it in the cloud")}`);
68115
- out.push(` ${import_picocolors43.default.cyan("pull")} ${import_picocolors43.default.dim("<id>")} ${import_picocolors43.default.dim("fetch orchestration + every member agent into this folder")}`);
68116
- out.push(` ${import_picocolors43.default.cyan("push")} ${import_picocolors43.default.dim("push each member, then update the orchestration graph")}`);
68117
- 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")}`);
68118
- out.push(` ${import_picocolors43.default.cyan("status")} ${import_picocolors43.default.dim("show what would push and what would pull")}`);
68119
- 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")}`);
68120
68561
  out.push("");
68121
- out.push(` ${import_picocolors43.default.bold("Flags")}`);
68122
- out.push(` ${import_picocolors43.default.dim("--yes, -y")} skip confirmations`);
68123
- out.push(` ${import_picocolors43.default.dim("--harness <id>")} harness for newly-created member folders (default claude-code)`);
68124
- out.push(` ${import_picocolors43.default.dim("--graph-only")} for push: only update members + edges, skip per-member push`);
68125
- out.push(` ${import_picocolors43.default.dim("--org <id>")} for create/list: org id or slug (CLI vocab — DB teams.id)`);
68126
- 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)`);
68127
68568
  out.push("");
68128
68569
  console.log(out.join(`
68129
68570
  `));
@@ -68168,11 +68609,11 @@ async function runRun(cwd2, args) {
68168
68609
  }
68169
68610
 
68170
68611
  // src/cli/publish.ts
68171
- var import_picocolors44 = __toESM(require_picocolors(), 1);
68612
+ var import_picocolors47 = __toESM(require_picocolors(), 1);
68172
68613
  function runPublish() {
68173
68614
  banner("publish — moved");
68174
- f2.error(`${import_picocolors44.default.bold("brainbase publish")} does not exist.`);
68175
- 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.`);
68176
68617
  process.exit(1);
68177
68618
  }
68178
68619
 
@@ -68471,7 +68912,7 @@ async function runStatus(cwd2) {
68471
68912
  }
68472
68913
 
68473
68914
  // src/cli/token.ts
68474
- var import_picocolors45 = __toESM(require_picocolors(), 1);
68915
+ var import_picocolors48 = __toESM(require_picocolors(), 1);
68475
68916
 
68476
68917
  // src/ui/ink/TokenCards.tsx
68477
68918
  var jsx_dev_runtime17 = __toESM(require_jsx_dev_runtime(), 1);
@@ -68864,7 +69305,7 @@ async function runTokenRename(args) {
68864
69305
  }
68865
69306
  }
68866
69307
  if (name === target.name.trim()) {
68867
- 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.`);
68868
69309
  return;
68869
69310
  }
68870
69311
  try {
@@ -68872,7 +69313,7 @@ async function runTokenRename(args) {
68872
69313
  } catch (error) {
68873
69314
  throw withLoginHint(error);
68874
69315
  }
68875
- 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)}`);
68876
69317
  }
68877
69318
  async function runTokenRevoke(args) {
68878
69319
  if (!args.id) {
@@ -68890,14 +69331,14 @@ async function runTokenRevoke(args) {
68890
69331
  throw new Error(`No token with id ${args.id}. Run \`brainbase token list\` to see yours.`);
68891
69332
  }
68892
69333
  if (target.revoked_at) {
68893
- reconcileDeadToken(target, `${import_picocolors45.default.bold(target.name)} is already revoked.`);
69334
+ reconcileDeadToken(target, `${import_picocolors48.default.bold(target.name)} is already revoked.`);
68894
69335
  return;
68895
69336
  }
68896
69337
  const stored = readToken();
68897
69338
  const isLocalToken = Boolean(stored && stored.token.startsWith(target.prefix));
68898
69339
  if (!autoProceed(args.yes)) {
68899
69340
  const ok = await se({
68900
- 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.`,
68901
69342
  initialValue: false
68902
69343
  });
68903
69344
  if (!ensureNotCancelled(ok))
@@ -68908,14 +69349,14 @@ async function runTokenRevoke(args) {
68908
69349
  } catch (error) {
68909
69350
  if (error instanceof ApiError && error.status === 404) {
68910
69351
  if (isExpired2(target)) {
68911
- reconcileDeadToken(target, `${import_picocolors45.default.bold(target.name)} had already expired.`);
69352
+ reconcileDeadToken(target, `${import_picocolors48.default.bold(target.name)} had already expired.`);
68912
69353
  return;
68913
69354
  }
68914
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.");
68915
69356
  }
68916
69357
  throw error;
68917
69358
  }
68918
- reconcileDeadToken(target, `Revoked ${import_picocolors45.default.bold(target.name)}.`);
69359
+ reconcileDeadToken(target, `Revoked ${import_picocolors48.default.bold(target.name)}.`);
68919
69360
  }
68920
69361
  function reconcileDeadToken(target, headline) {
68921
69362
  let outcome;
@@ -68949,7 +69390,7 @@ function reportLocalToken(headline, outcome) {
68949
69390
  }
68950
69391
  async function runTokenClear() {
68951
69392
  if (!readToken()) {
68952
- console.log(import_picocolors45.default.dim("No local token stored."));
69393
+ console.log(import_picocolors48.default.dim("No local token stored."));
68953
69394
  return;
68954
69395
  }
68955
69396
  clearToken();
@@ -69049,32 +69490,32 @@ async function runToken(sub, rest2, args) {
69049
69490
  function printTokenHelp() {
69050
69491
  const out = [];
69051
69492
  out.push("");
69052
- 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>")}`);
69053
69494
  out.push("");
69054
- out.push(` ${import_picocolors45.default.cyan("create")} ${import_picocolors45.default.dim("issue a new long-lived CLI key (PAT)")}`);
69055
- out.push(` ${import_picocolors45.default.cyan("list")} ${import_picocolors45.default.dim("show your tokens")}`);
69056
- out.push(` ${import_picocolors45.default.cyan("rename")} ${import_picocolors45.default.dim("<id>")} ${import_picocolors45.default.dim("relabel a token by id")}`);
69057
- out.push(` ${import_picocolors45.default.cyan("revoke")} ${import_picocolors45.default.dim("<id>")} ${import_picocolors45.default.dim("revoke a token by id")}`);
69058
- 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)")}`);
69059
69500
  out.push("");
69060
- out.push(` ${import_picocolors45.default.bold("create flags")}`);
69061
- out.push(` ${import_picocolors45.default.cyan("--name, -n")} ${import_picocolors45.default.dim("<label>")} ${import_picocolors45.default.dim("token label (prompted if omitted)")}`);
69062
- out.push(` ${import_picocolors45.default.cyan("--scopes")} ${import_picocolors45.default.dim("<list>")} ${import_picocolors45.default.dim("comma-separated; allowed: read, publish, admin")}`);
69063
- 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")}`);
69064
69505
  out.push("");
69065
- out.push(` ${import_picocolors45.default.bold("rename flags")}`);
69066
- 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)")}`);
69067
69508
  out.push("");
69068
69509
  console.log(out.join(`
69069
69510
  `));
69070
69511
  }
69071
69512
 
69072
69513
  // src/cli/mcp.ts
69073
- var import_picocolors46 = __toESM(require_picocolors(), 1);
69514
+ var import_picocolors49 = __toESM(require_picocolors(), 1);
69074
69515
 
69075
69516
  // src/core/mcp-check/collect-servers.ts
69076
69517
  import path87 from "node:path";
69077
- import fs79 from "node:fs";
69518
+ import fs80 from "node:fs";
69078
69519
  function collectServers(cwd2, env3 = process.env) {
69079
69520
  const out = [];
69080
69521
  const seen = new Set;
@@ -69128,7 +69569,7 @@ function* readResolvedMcps(cwd2) {
69128
69569
  const p2 = path87.join(cwd2, ".brainbase", "resolved-mcps.json");
69129
69570
  let raw;
69130
69571
  try {
69131
- raw = fs79.readFileSync(p2, "utf-8");
69572
+ raw = fs80.readFileSync(p2, "utf-8");
69132
69573
  } catch {
69133
69574
  return;
69134
69575
  }
@@ -69188,10 +69629,19 @@ function classifyError(err) {
69188
69629
  }
69189
69630
  return "protocol_error";
69190
69631
  }
69632
+ var CREDENTIAL_NAMES = "(x-api-key|api[-_]?key|auth[-_]?token|access[-_]?token|private[-_]?token|secret)";
69191
69633
  var REDACTIONS = [
69192
69634
  [/https?:\/\/[^\s'"`]+/gi, "[url]"],
69193
69635
  [/Bearer\s+\S+/gi, "Bearer [redacted]"],
69194
- [/\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
+ ]
69195
69645
  ];
69196
69646
  function redactSecrets2(msg) {
69197
69647
  let out = msg;
@@ -77318,11 +77768,11 @@ function withTimeout(inner, ms2, label) {
77318
77768
  function isTransient(status) {
77319
77769
  return status === "unreachable";
77320
77770
  }
77321
- async function probeWithConnector(server, connect, opts) {
77771
+ async function probeWithConnector(server, connect2, opts) {
77322
77772
  let lastErr;
77323
77773
  for (let attempt2 = 0;attempt2 < 2; attempt2++) {
77324
77774
  try {
77325
- const { toolCount } = await connect(server, opts.timeoutMs);
77775
+ const { toolCount } = await connect2(server, opts.timeoutMs);
77326
77776
  return { name: server.name, status: "ok", tool_count: toolCount, error: null };
77327
77777
  } catch (err) {
77328
77778
  lastErr = err;
@@ -77398,42 +77848,177 @@ async function runMcpCheck(cwd2, options) {
77398
77848
  }
77399
77849
  }));
77400
77850
  results.sort((a3, b4) => a3.name.localeCompare(b4.name));
77401
- const report = {
77851
+ const report2 = {
77402
77852
  check_status: deriveCheckStatus(results),
77403
77853
  servers: results
77404
77854
  };
77405
77855
  if (options.json) {
77406
- write(JSON.stringify(report) + `
77856
+ write(JSON.stringify(report2) + `
77407
77857
  `);
77408
77858
  } else {
77409
- write(renderHuman(report));
77859
+ write(renderHuman(report2));
77410
77860
  }
77411
- return { exitCode: 0, report };
77861
+ return { exitCode: 0, report: report2 };
77412
77862
  } catch (err) {
77413
77863
  writeErr(`brainbase mcp check failed to run: ${truncateError(err) ?? "unknown error"}
77414
77864
  `);
77415
77865
  return { exitCode: 1 };
77416
77866
  }
77417
77867
  }
77418
- function renderHuman(report) {
77868
+ function renderHuman(report2) {
77419
77869
  const lines = [];
77420
- if (report.check_status === "skipped") {
77421
- 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."));
77422
77872
  return lines.join(`
77423
77873
  `) + `
77424
77874
  `;
77425
77875
  }
77426
- for (const s3 of report.servers) {
77427
- const mark = s3.status === "ok" ? import_picocolors46.default.green("✓") : s3.status === "auth_failed" ? import_picocolors46.default.red("✗") : import_picocolors46.default.yellow("⚠");
77428
- 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}` : ""));
77429
77879
  lines.push(` ${mark} ${s3.name} ${detail}`);
77430
77880
  }
77431
- 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.");
77432
77882
  lines.push("", summary);
77433
77883
  return lines.join(`
77434
77884
  `) + `
77435
77885
  `;
77436
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
+ }
77437
78022
  async function runMcp(cwd2, sub, _argv, options) {
77438
78023
  const writeErr = options.writeErr ?? ((s3) => process.stderr.write(s3));
77439
78024
  switch (sub) {
@@ -77441,17 +78026,19 @@ async function runMcp(cwd2, sub, _argv, options) {
77441
78026
  const { exitCode } = await runMcpCheck(cwd2, options);
77442
78027
  return exitCode;
77443
78028
  }
78029
+ case "list":
78030
+ return runMcpList(cwd2, options);
77444
78031
  default:
77445
78032
  writeErr(`Unknown mcp subcommand: ${sub ?? "(none)"}
77446
78033
  `);
77447
- writeErr(`Usage: brainbase mcp check [--json]
78034
+ writeErr(`Usage: brainbase mcp <check|list> [--json]
77448
78035
  `);
77449
78036
  return 1;
77450
78037
  }
77451
78038
  }
77452
78039
 
77453
78040
  // src/cli/task.ts
77454
- var import_picocolors47 = __toESM(require_picocolors(), 1);
78041
+ var import_picocolors50 = __toESM(require_picocolors(), 1);
77455
78042
 
77456
78043
  // src/cli/task-create.ts
77457
78044
  import { randomUUID as randomUUID2 } from "node:crypto";
@@ -77637,31 +78224,31 @@ async function runTask(cwd2, sub, args) {
77637
78224
  function printHelp4() {
77638
78225
  const out = [];
77639
78226
  out.push("");
77640
- 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]")}`);
77641
78228
  out.push("");
77642
- 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")}`);
77643
78230
  out.push("");
77644
- out.push(` ${import_picocolors47.default.bold("create flags")}`);
77645
- out.push(` ${import_picocolors47.default.dim("--message <text>")} required first user message`);
77646
- out.push(` ${import_picocolors47.default.dim("--agent <id>")} override the claimed agent in brainbase.agent.yaml`);
77647
- out.push(` ${import_picocolors47.default.dim("--title <text>")} optional task title`);
77648
- out.push(` ${import_picocolors47.default.dim("--model <id>")} optional model override`);
77649
- 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`);
77650
78237
  out.push("");
77651
- 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>")}`);
77652
78239
  out.push("");
77653
78240
  console.log(out.join(`
77654
78241
  `));
77655
78242
  }
77656
78243
 
77657
78244
  // src/cli/benchmark.ts
77658
- var import_picocolors48 = __toESM(require_picocolors(), 1);
78245
+ var import_picocolors51 = __toESM(require_picocolors(), 1);
77659
78246
  import {
77660
78247
  execFileSync as execFileSync3,
77661
78248
  spawn as spawn5
77662
78249
  } from "node:child_process";
77663
78250
  import crypto7 from "node:crypto";
77664
- import fs81 from "node:fs";
78251
+ import fs82 from "node:fs";
77665
78252
  import os17 from "node:os";
77666
78253
  import path89 from "node:path";
77667
78254
 
@@ -77671,7 +78258,7 @@ import {
77671
78258
  spawn as spawn4
77672
78259
  } from "node:child_process";
77673
78260
  import crypto6 from "node:crypto";
77674
- import fs80 from "node:fs";
78261
+ import fs81 from "node:fs";
77675
78262
  import os16 from "node:os";
77676
78263
  import path88 from "node:path";
77677
78264
  import { pipeline as pipeline2 } from "node:stream/promises";
@@ -77921,19 +78508,19 @@ function canonicalFuturePath(input) {
77921
78508
  const resolved = path88.resolve(input);
77922
78509
  const suffix = [];
77923
78510
  let current = resolved;
77924
- while (!fs80.existsSync(current)) {
78511
+ while (!fs81.existsSync(current)) {
77925
78512
  const parent = path88.dirname(current);
77926
78513
  if (parent === current)
77927
78514
  break;
77928
78515
  suffix.unshift(path88.basename(current));
77929
78516
  current = parent;
77930
78517
  }
77931
- const canonicalBase = fs80.realpathSync(current);
78518
+ const canonicalBase = fs81.realpathSync(current);
77932
78519
  return path88.join(canonicalBase, ...suffix);
77933
78520
  }
77934
78521
  function validateRoots(spec) {
77935
78522
  const workspace = path88.resolve(spec.workspace_root);
77936
- 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()) {
77937
78524
  throw new BenchmarkPhaseError("invalid_workspace_root", "workspace_root must be an existing real directory");
77938
78525
  }
77939
78526
  const canonicalWorkspace = canonicalFuturePath(workspace);
@@ -77942,7 +78529,7 @@ function validateRoots(spec) {
77942
78529
  if (staging !== expectedStaging) {
77943
78530
  throw new BenchmarkPhaseError("invalid_staging_root", `staging_root must be ${expectedStaging}`);
77944
78531
  }
77945
- 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")) {
77946
78533
  throw new BenchmarkPhaseError("invalid_staging_root", "staging_root must be a real directory under workspace_root");
77947
78534
  }
77948
78535
  const canonicalLogs = validateExternalRoot("logs_root", spec.logs_root, canonicalWorkspace);
@@ -77958,7 +78545,7 @@ function validateExternalRoot(label, input, canonicalWorkspace) {
77958
78545
  if (candidate === path88.parse(candidate).root) {
77959
78546
  throw new BenchmarkPhaseError(`invalid_${label}`, `${label} cannot be a filesystem root`);
77960
78547
  }
77961
- if (fs80.existsSync(candidate) && fs80.lstatSync(candidate).isSymbolicLink()) {
78548
+ if (fs81.existsSync(candidate) && fs81.lstatSync(candidate).isSymbolicLink()) {
77962
78549
  throw new BenchmarkPhaseError(`invalid_${label}`, `${label} cannot be a symlink`);
77963
78550
  }
77964
78551
  const canonicalCandidate = canonicalFuturePath(candidate);
@@ -77988,9 +78575,9 @@ function assertNoSymlinkTraversal(root, relative) {
77988
78575
  let current = path88.resolve(root);
77989
78576
  for (const segment of rel.split("/").slice(0, -1)) {
77990
78577
  current = path88.join(current, segment);
77991
- if (!fs80.existsSync(current))
78578
+ if (!fs81.existsSync(current))
77992
78579
  continue;
77993
- if (fs80.lstatSync(current).isSymbolicLink()) {
78580
+ if (fs81.lstatSync(current).isSymbolicLink()) {
77994
78581
  throw new BenchmarkPhaseError("unsafe_path", `path traverses symlink: ${relative}`);
77995
78582
  }
77996
78583
  }
@@ -78000,9 +78587,9 @@ function assertOpenedFileWithinRoot(root, filePath, openedStat, label) {
78000
78587
  let canonicalFile;
78001
78588
  let currentStat;
78002
78589
  try {
78003
- canonicalRoot = fs80.realpathSync(root);
78004
- canonicalFile = fs80.realpathSync(filePath);
78005
- currentStat = fs80.statSync(filePath);
78590
+ canonicalRoot = fs81.realpathSync(root);
78591
+ canonicalFile = fs81.realpathSync(filePath);
78592
+ currentStat = fs81.statSync(filePath);
78006
78593
  } catch {
78007
78594
  throw new BenchmarkPhaseError("unsafe_path", `${label} changed while it was opened`);
78008
78595
  }
@@ -78011,10 +78598,10 @@ function assertOpenedFileWithinRoot(root, filePath, openedStat, label) {
78011
78598
  }
78012
78599
  }
78013
78600
  function openRegularFileNoFollow(filePath, label, root) {
78014
- 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;
78015
78602
  let fd;
78016
78603
  try {
78017
- fd = fs80.openSync(filePath, fs80.constants.O_RDONLY | noFollow);
78604
+ fd = fs81.openSync(filePath, fs81.constants.O_RDONLY | noFollow);
78018
78605
  } catch (error2) {
78019
78606
  const code = error2.code;
78020
78607
  if (code === "ELOOP") {
@@ -78022,16 +78609,16 @@ function openRegularFileNoFollow(filePath, label, root) {
78022
78609
  }
78023
78610
  throw error2;
78024
78611
  }
78025
- const stat = fs80.fstatSync(fd);
78612
+ const stat = fs81.fstatSync(fd);
78026
78613
  if (!stat.isFile()) {
78027
- fs80.closeSync(fd);
78614
+ fs81.closeSync(fd);
78028
78615
  throw new BenchmarkPhaseError("invalid_input", `${label} must be a regular file`);
78029
78616
  }
78030
78617
  if (root) {
78031
78618
  try {
78032
78619
  assertOpenedFileWithinRoot(root, filePath, stat, label);
78033
78620
  } catch (error2) {
78034
- fs80.closeSync(fd);
78621
+ fs81.closeSync(fd);
78035
78622
  throw error2;
78036
78623
  }
78037
78624
  }
@@ -78039,7 +78626,7 @@ function openRegularFileNoFollow(filePath, label, root) {
78039
78626
  }
78040
78627
  async function sha256OfDescriptor(fd) {
78041
78628
  const hash = crypto6.createHash("sha256");
78042
- const stream = fs80.createReadStream("", {
78629
+ const stream = fs81.createReadStream("", {
78043
78630
  fd,
78044
78631
  autoClose: false,
78045
78632
  start: 0
@@ -78050,7 +78637,7 @@ async function sha256OfDescriptor(fd) {
78050
78637
  return hash.digest("hex");
78051
78638
  }
78052
78639
  function readDescriptor(fd) {
78053
- return fs80.readFileSync(fd);
78640
+ return fs81.readFileSync(fd);
78054
78641
  }
78055
78642
  function assertWritableDestination(root, relative) {
78056
78643
  const rel = normalizedRootRelative(relative);
@@ -78060,9 +78647,9 @@ function assertWritableDestination(root, relative) {
78060
78647
  const segments = rel.split("/");
78061
78648
  for (const segment of segments.slice(0, -1)) {
78062
78649
  current = path88.join(current, segment);
78063
- if (!fs80.existsSync(current))
78650
+ if (!fs81.existsSync(current))
78064
78651
  continue;
78065
- const stat = fs80.lstatSync(current);
78652
+ const stat = fs81.lstatSync(current);
78066
78653
  if (stat.isSymbolicLink()) {
78067
78654
  throw new BenchmarkPhaseError("unsafe_path", `path traverses symlink: ${relative}`);
78068
78655
  }
@@ -78071,7 +78658,7 @@ function assertWritableDestination(root, relative) {
78071
78658
  }
78072
78659
  }
78073
78660
  const destination = path88.resolve(root, rel);
78074
- if (fs80.existsSync(destination) && fs80.lstatSync(destination).isDirectory()) {
78661
+ if (fs81.existsSync(destination) && fs81.lstatSync(destination).isDirectory()) {
78075
78662
  throw new BenchmarkPhaseError("destination_conflict", `file destination is an existing directory: ${relative}`);
78076
78663
  }
78077
78664
  }
@@ -78103,7 +78690,7 @@ function sourcePath(stagingRoot, relative) {
78103
78690
  assertNoSymlinkTraversal(stagingRoot, rel);
78104
78691
  let stat;
78105
78692
  try {
78106
- stat = fs80.lstatSync(source);
78693
+ stat = fs81.lstatSync(source);
78107
78694
  } catch {
78108
78695
  throw new BenchmarkPhaseError("missing_input", `staged input does not exist: ${relative}`);
78109
78696
  }
@@ -78132,12 +78719,12 @@ async function verifyRecordsUnchanged(records, spec) {
78132
78719
  const relative = safeRelPath(record3.path);
78133
78720
  assertNoSymlinkTraversal(root, relative);
78134
78721
  const candidate = path88.resolve(root, relative);
78135
- if (!isWithin(root, candidate) || !fs80.existsSync(candidate)) {
78722
+ if (!isWithin(root, candidate) || !fs81.existsSync(candidate)) {
78136
78723
  throw new BenchmarkPhaseError("evidence_tampered", `evidence was removed during evaluation: ${record3.root}:${record3.path}`);
78137
78724
  }
78138
- const stat = fs80.lstatSync(candidate);
78725
+ const stat = fs81.lstatSync(candidate);
78139
78726
  if (record3.kind === "symlink") {
78140
- const target = stat.isSymbolicLink() ? fs80.readlinkSync(candidate) : null;
78727
+ const target = stat.isSymbolicLink() ? fs81.readlinkSync(candidate) : null;
78141
78728
  if (target === null || Buffer.byteLength(target) !== record3.size || sha256(target) !== record3.sha256) {
78142
78729
  throw new BenchmarkPhaseError("evidence_tampered", `evidence changed during evaluation: ${record3.root}:${record3.path}`);
78143
78730
  }
@@ -78152,7 +78739,7 @@ async function verifyRecordsUnchanged(records, spec) {
78152
78739
  throw new BenchmarkPhaseError("evidence_tampered", `evidence changed during evaluation: ${record3.root}:${record3.path}`);
78153
78740
  }
78154
78741
  } finally {
78155
- fs80.closeSync(opened.fd);
78742
+ fs81.closeSync(opened.fd);
78156
78743
  }
78157
78744
  }
78158
78745
  }
@@ -78168,35 +78755,35 @@ async function verifyInput(stagingRoot, material) {
78168
78755
  throw new BenchmarkPhaseError("digest_mismatch", `checksum mismatch for ${material.source}`, { expected: material.sha256, actual });
78169
78756
  }
78170
78757
  } finally {
78171
- fs80.closeSync(opened.fd);
78758
+ fs81.closeSync(opened.fd);
78172
78759
  }
78173
78760
  return source;
78174
78761
  }
78175
78762
  async function atomicCopy(source, destination, mode, sourceRoot) {
78176
- fs80.mkdirSync(path88.dirname(destination), { recursive: true });
78763
+ fs81.mkdirSync(path88.dirname(destination), { recursive: true });
78177
78764
  const temporary = `${destination}.${process.pid}.${crypto6.randomBytes(6).toString("hex")}.tmp`;
78178
78765
  const opened = openRegularFileNoFollow(source, `copy source ${source}`, sourceRoot);
78179
78766
  try {
78180
- await pipeline2(fs80.createReadStream("", {
78767
+ await pipeline2(fs81.createReadStream("", {
78181
78768
  fd: opened.fd,
78182
78769
  autoClose: false,
78183
78770
  start: 0
78184
- }), fs80.createWriteStream(temporary, {
78771
+ }), fs81.createWriteStream(temporary, {
78185
78772
  flags: "wx",
78186
78773
  mode: 384
78187
78774
  }));
78188
- fs80.chmodSync(temporary, mode ?? opened.stat.mode & 511);
78189
- fs80.renameSync(temporary, destination);
78775
+ fs81.chmodSync(temporary, mode ?? opened.stat.mode & 511);
78776
+ fs81.renameSync(temporary, destination);
78190
78777
  } finally {
78191
- fs80.closeSync(opened.fd);
78192
- fs80.rmSync(temporary, { force: true });
78778
+ fs81.closeSync(opened.fd);
78779
+ fs81.rmSync(temporary, { force: true });
78193
78780
  }
78194
78781
  }
78195
78782
  async function recordFile(root, filePath, rootName, kind = "file") {
78196
78783
  const relative = path88.relative(root, filePath).replace(/\\/g, "/");
78197
78784
  if (kind === "symlink") {
78198
- const stat = fs80.lstatSync(filePath);
78199
- const target = fs80.readlinkSync(filePath);
78785
+ const stat = fs81.lstatSync(filePath);
78786
+ const target = fs81.readlinkSync(filePath);
78200
78787
  return {
78201
78788
  root: rootName,
78202
78789
  path: relative,
@@ -78216,7 +78803,7 @@ async function recordFile(root, filePath, rootName, kind = "file") {
78216
78803
  mode: opened.stat.mode & 511
78217
78804
  };
78218
78805
  } finally {
78219
- fs80.closeSync(opened.fd);
78806
+ fs81.closeSync(opened.fd);
78220
78807
  }
78221
78808
  }
78222
78809
  async function copyMaterial(material, sourceRoot, destinationRoot, destinationRootName, protectWorkspace) {
@@ -78238,7 +78825,7 @@ async function copyMaterial(material, sourceRoot, destinationRoot, destinationRo
78238
78825
  }
78239
78826
  return [record3];
78240
78827
  }
78241
- const temporary = fs80.mkdtempSync(path88.join(os16.tmpdir(), "brainbase-benchmark-"));
78828
+ const temporary = fs81.mkdtempSync(path88.join(os16.tmpdir(), "brainbase-benchmark-"));
78242
78829
  try {
78243
78830
  const verifiedArchive = path88.join(temporary, "material.tar.gz");
78244
78831
  await atomicCopy(source, verifiedArchive, 384, sourceRoot);
@@ -78256,7 +78843,7 @@ async function copyMaterial(material, sourceRoot, destinationRoot, destinationRo
78256
78843
  const outputs = [];
78257
78844
  for (const extractedRel of extracted.sort()) {
78258
78845
  const sourceFile = path88.resolve(extractedRoot, safeRelPath(extractedRel));
78259
- const stat = fs80.lstatSync(sourceFile);
78846
+ const stat = fs81.lstatSync(sourceFile);
78260
78847
  if (!stat.isFile())
78261
78848
  continue;
78262
78849
  const combined = destinationRel === "." ? safeRelPath(extractedRel) : safeRelPath(path88.posix.join(destinationRel, extractedRel));
@@ -78271,7 +78858,7 @@ async function copyMaterial(material, sourceRoot, destinationRoot, destinationRo
78271
78858
  }
78272
78859
  return outputs;
78273
78860
  } finally {
78274
- fs80.rmSync(temporary, { recursive: true, force: true });
78861
+ fs81.rmSync(temporary, { recursive: true, force: true });
78275
78862
  }
78276
78863
  }
78277
78864
  async function preflightMaterial(material, sourceRoot, destinationRoot, protectWorkspace) {
@@ -78287,7 +78874,7 @@ async function preflightMaterial(material, sourceRoot, destinationRoot, protectW
78287
78874
  assertWritableDestination(destinationRoot, destinationRel);
78288
78875
  return [destinationRel];
78289
78876
  }
78290
- const temporary = fs80.mkdtempSync(path88.join(os16.tmpdir(), "brainbase-benchmark-preflight-"));
78877
+ const temporary = fs81.mkdtempSync(path88.join(os16.tmpdir(), "brainbase-benchmark-preflight-"));
78291
78878
  try {
78292
78879
  const verifiedArchive = path88.join(temporary, "material.tar.gz");
78293
78880
  await atomicCopy(source, verifiedArchive, 384, sourceRoot);
@@ -78314,34 +78901,34 @@ async function preflightMaterial(material, sourceRoot, destinationRoot, protectW
78314
78901
  }
78315
78902
  return planned;
78316
78903
  } finally {
78317
- fs80.rmSync(temporary, { recursive: true, force: true });
78904
+ fs81.rmSync(temporary, { recursive: true, force: true });
78318
78905
  }
78319
78906
  }
78320
78907
  function ownerMarker(root) {
78321
78908
  return path88.join(root, ".brainbase-benchmark-owner.json");
78322
78909
  }
78323
78910
  function verifyOwnedDirectory(root, role, spec) {
78324
- if (!fs80.existsSync(root) || fs80.lstatSync(root).isSymbolicLink())
78911
+ if (!fs81.existsSync(root) || fs81.lstatSync(root).isSymbolicLink())
78325
78912
  return false;
78326
78913
  try {
78327
- const marker = JSON.parse(fs80.readFileSync(ownerMarker(root), "utf8"));
78914
+ const marker = JSON.parse(fs81.readFileSync(ownerMarker(root), "utf8"));
78328
78915
  return marker.attempt_id === spec.attempt_id && marker.phase === spec.phase && marker.phase_id === spec.phase_id && marker.role === role;
78329
78916
  } catch {
78330
78917
  return false;
78331
78918
  }
78332
78919
  }
78333
78920
  function prepareOwnedDirectory(root, role, spec) {
78334
- if (fs80.existsSync(root)) {
78921
+ if (fs81.existsSync(root)) {
78335
78922
  if (!verifyOwnedDirectory(root, role, spec)) {
78336
- const stat = fs80.lstatSync(root);
78337
- if (!stat.isDirectory() || fs80.readdirSync(root).length > 0) {
78923
+ const stat = fs81.lstatSync(root);
78924
+ if (!stat.isDirectory() || fs81.readdirSync(root).length > 0) {
78338
78925
  throw new BenchmarkPhaseError(`unowned_${role}_root`, `${role}_root exists without a matching attempt ownership marker`);
78339
78926
  }
78340
78927
  } else {
78341
- fs80.rmSync(root, { recursive: true, force: true });
78928
+ fs81.rmSync(root, { recursive: true, force: true });
78342
78929
  }
78343
78930
  }
78344
- fs80.mkdirSync(root, { recursive: true, mode: 448 });
78931
+ fs81.mkdirSync(root, { recursive: true, mode: 448 });
78345
78932
  writeJsonAtomic(ownerMarker(root), {
78346
78933
  schema_version: SCHEMA_VERSION,
78347
78934
  attempt_id: spec.attempt_id,
@@ -78433,7 +79020,7 @@ async function runCommand(command, root, spec, context, additions = {}) {
78433
79020
  const cwd2 = path88.resolve(root, cwdRel);
78434
79021
  let cwdStat;
78435
79022
  try {
78436
- cwdStat = fs80.lstatSync(cwd2);
79023
+ cwdStat = fs81.lstatSync(cwd2);
78437
79024
  } catch {
78438
79025
  throw new BenchmarkPhaseError("invalid_command_cwd", `command cwd is invalid: ${command.cwd}`);
78439
79026
  }
@@ -78505,27 +79092,27 @@ async function runCommand(command, root, spec, context, additions = {}) {
78505
79092
  }
78506
79093
  async function writeLog(root, name, data, spec) {
78507
79094
  const destination = path88.join(root, name);
78508
- fs80.mkdirSync(path88.dirname(destination), { recursive: true });
79095
+ fs81.mkdirSync(path88.dirname(destination), { recursive: true });
78509
79096
  const temporary = `${destination}.${process.pid}.${crypto6.randomBytes(6).toString("hex")}.tmp`;
78510
79097
  try {
78511
- fs80.writeFileSync(temporary, redactCommandOutput(data, spec), {
79098
+ fs81.writeFileSync(temporary, redactCommandOutput(data, spec), {
78512
79099
  flag: "wx",
78513
79100
  mode: 384
78514
79101
  });
78515
- fs80.renameSync(temporary, destination);
79102
+ fs81.renameSync(temporary, destination);
78516
79103
  } finally {
78517
- fs80.rmSync(temporary, { force: true });
79104
+ fs81.rmSync(temporary, { force: true });
78518
79105
  }
78519
79106
  return await recordFile(root, destination, "logs");
78520
79107
  }
78521
79108
  function writeBufferAtomic(destination, data) {
78522
- fs80.mkdirSync(path88.dirname(destination), { recursive: true });
79109
+ fs81.mkdirSync(path88.dirname(destination), { recursive: true });
78523
79110
  const temporary = `${destination}.${process.pid}.${crypto6.randomBytes(6).toString("hex")}.tmp`;
78524
79111
  try {
78525
- fs80.writeFileSync(temporary, data, { flag: "wx", mode: 384 });
78526
- fs80.renameSync(temporary, destination);
79112
+ fs81.writeFileSync(temporary, data, { flag: "wx", mode: 384 });
79113
+ fs81.renameSync(temporary, destination);
78527
79114
  } finally {
78528
- fs80.rmSync(temporary, { force: true });
79115
+ fs81.rmSync(temporary, { force: true });
78529
79116
  }
78530
79117
  }
78531
79118
  function assertBudget(context) {
@@ -78534,7 +79121,7 @@ function assertBudget(context) {
78534
79121
  }
78535
79122
  }
78536
79123
  async function executeHydrate(spec, context) {
78537
- fs80.mkdirSync(spec.workspace_root, { recursive: true });
79124
+ fs81.mkdirSync(spec.workspace_root, { recursive: true });
78538
79125
  prepareOwnedDirectory(spec.logs_root, "logs", spec);
78539
79126
  context.logsOwned = true;
78540
79127
  const outputs = [];
@@ -78615,9 +79202,9 @@ async function executeHydrate(spec, context) {
78615
79202
  }
78616
79203
  const candidate = path88.resolve(spec.workspace_root, safeRelPath(output.path));
78617
79204
  assertNoSymlinkTraversal(spec.workspace_root, output.path);
78618
- if (!fs80.existsSync(candidate))
79205
+ if (!fs81.existsSync(candidate))
78619
79206
  continue;
78620
- const stat = fs80.lstatSync(candidate);
79207
+ const stat = fs81.lstatSync(candidate);
78621
79208
  if (!stat.isFile() && !stat.isSymbolicLink())
78622
79209
  continue;
78623
79210
  finalOutputs.push(await recordFile(spec.workspace_root, candidate, "workspace", stat.isSymbolicLink() ? "symlink" : "file"));
@@ -78651,7 +79238,7 @@ async function readEvidence(stagingRoot, evidence) {
78651
79238
  }
78652
79239
  };
78653
79240
  } finally {
78654
- fs80.closeSync(opened.fd);
79241
+ fs81.closeSync(opened.fd);
78655
79242
  }
78656
79243
  }
78657
79244
  async function workspaceManifest(spec, context) {
@@ -78660,7 +79247,7 @@ async function workspaceManifest(spec, context) {
78660
79247
  const stack = [path88.resolve(spec.workspace_root)];
78661
79248
  while (stack.length > 0) {
78662
79249
  const directory = stack.pop();
78663
- 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));
78664
79251
  for (const entry of entries) {
78665
79252
  assertBudget(context);
78666
79253
  const full = path88.join(directory, entry.name);
@@ -78769,7 +79356,7 @@ async function evaluateOne(evaluator, spec, finalOutput, trajectory, frozenEvide
78769
79356
  const candidate = path88.resolve(spec.workspace_root, relative);
78770
79357
  let stat = null;
78771
79358
  try {
78772
- stat = fs80.lstatSync(candidate);
79359
+ stat = fs81.lstatSync(candidate);
78773
79360
  } catch (error2) {
78774
79361
  const code = error2.code;
78775
79362
  if (code !== "ENOENT" && code !== "ENOTDIR")
@@ -78790,7 +79377,7 @@ async function evaluateOne(evaluator, spec, finalOutput, trajectory, frozenEvide
78790
79377
  try {
78791
79378
  verdict2 = await sha256OfDescriptor(opened.fd) === evaluator.assertion.expected;
78792
79379
  } finally {
78793
- fs80.closeSync(opened.fd);
79380
+ fs81.closeSync(opened.fd);
78794
79381
  }
78795
79382
  }
78796
79383
  }
@@ -78800,7 +79387,7 @@ async function evaluateOne(evaluator, spec, finalOutput, trajectory, frozenEvide
78800
79387
  try {
78801
79388
  verdict2 = readDescriptor(opened.fd).toString("utf8").includes(evaluator.assertion.expected);
78802
79389
  } finally {
78803
- fs80.closeSync(opened.fd);
79390
+ fs81.closeSync(opened.fd);
78804
79391
  }
78805
79392
  }
78806
79393
  }
@@ -78881,7 +79468,7 @@ async function executeEvaluate(spec, context) {
78881
79468
  assertNoSymlinkTraversal(spec.workspace_root, artifactRel);
78882
79469
  const source = path88.resolve(spec.workspace_root, artifactRel);
78883
79470
  const frozenArtifact = manifest.find((entry) => entry.path === artifactRel && entry.kind !== "symlink");
78884
- if (!frozenArtifact || !fs80.existsSync(source) || !fs80.lstatSync(source).isFile()) {
79471
+ if (!frozenArtifact || !fs81.existsSync(source) || !fs81.lstatSync(source).isFile()) {
78885
79472
  throw new BenchmarkPhaseError("missing_artifact", `candidate artifact is missing: ${artifactRel}`);
78886
79473
  }
78887
79474
  const destination = path88.resolve(spec.logs_root, "candidate-artifacts", artifactRel);
@@ -78899,9 +79486,9 @@ async function executeEvaluate(spec, context) {
78899
79486
  const temporary = `${archive}.${process.pid}.${crypto6.randomBytes(6).toString("hex")}.tmp`;
78900
79487
  try {
78901
79488
  await pack({ rootDir: spec.workspace_root, outFile: temporary, files: regularFiles });
78902
- fs80.renameSync(temporary, archive);
79489
+ fs81.renameSync(temporary, archive);
78903
79490
  } finally {
78904
- fs80.rmSync(temporary, { force: true });
79491
+ fs81.rmSync(temporary, { force: true });
78905
79492
  }
78906
79493
  const archiveRecord = await recordFile(spec.logs_root, archive, "logs");
78907
79494
  outputs.push(archiveRecord);
@@ -79001,21 +79588,21 @@ function rawIdentity(value) {
79001
79588
  }
79002
79589
  function readSpecBytes(specPathInput) {
79003
79590
  const specPath = path88.resolve(specPathInput);
79004
- 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;
79005
79592
  let fd;
79006
79593
  try {
79007
- fd = fs80.openSync(specPath, fs80.constants.O_RDONLY | noFollow);
79594
+ fd = fs81.openSync(specPath, fs81.constants.O_RDONLY | noFollow);
79008
79595
  } catch {
79009
79596
  throw new BenchmarkPhaseError("spec_read_failed", "spec file could not be read");
79010
79597
  }
79011
79598
  try {
79012
- const stat = fs80.fstatSync(fd);
79599
+ const stat = fs81.fstatSync(fd);
79013
79600
  if (!stat.isFile() || stat.size > MAX_SPEC_BYTES) {
79014
79601
  throw new BenchmarkPhaseError("invalid_spec_file", "spec must be a regular JSON file no larger than 20 MiB");
79015
79602
  }
79016
79603
  return readDescriptor(fd);
79017
79604
  } finally {
79018
- fs80.closeSync(fd);
79605
+ fs81.closeSync(fd);
79019
79606
  }
79020
79607
  }
79021
79608
  function validateBenchmarkInvocationBytes(bytes, resultPathInput, expectedPhase) {
@@ -79059,9 +79646,9 @@ function prepareBenchmarkPhaseInvocation(specPathInput, resultPathInput, expecte
79059
79646
  spec_digest: digest,
79060
79647
  timeout_ms: spec.budget.timeout_ms
79061
79648
  };
79062
- if (fs80.existsSync(resultPath)) {
79649
+ if (fs81.existsSync(resultPath)) {
79063
79650
  try {
79064
- const cached2 = JSON.parse(fs80.readFileSync(resultPath, "utf8"));
79651
+ const cached2 = JSON.parse(fs81.readFileSync(resultPath, "utf8"));
79065
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") {
79066
79653
  return {
79067
79654
  ok: true,
@@ -79168,9 +79755,9 @@ async function runBenchmarkPhase(specPathInput, resultPathInput, expectedPhase,
79168
79755
  throw new BenchmarkPhaseError("invalid_result_path", `result path must be ${expectedResultPath}`);
79169
79756
  }
79170
79757
  resultPathValidated = true;
79171
- if (fs80.existsSync(resultPath)) {
79758
+ if (fs81.existsSync(resultPath)) {
79172
79759
  try {
79173
- const cached2 = JSON.parse(fs80.readFileSync(resultPath, "utf8"));
79760
+ const cached2 = JSON.parse(fs81.readFileSync(resultPath, "utf8"));
79174
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") {
79175
79762
  return { exitCode: 0, result: cached2 };
79176
79763
  }
@@ -79367,13 +79954,13 @@ function terminatePhase(child) {
79367
79954
  }
79368
79955
  function createAnonymousSpecFd(bytes) {
79369
79956
  const temporary = path89.join(os17.tmpdir(), `brainbase-benchmark-spec-${process.pid}-${crypto7.randomBytes(12).toString("hex")}`);
79370
- fs81.writeFileSync(temporary, bytes, { flag: "wx", mode: 384 });
79957
+ fs82.writeFileSync(temporary, bytes, { flag: "wx", mode: 384 });
79371
79958
  try {
79372
- const fd = fs81.openSync(temporary, "r");
79373
- fs81.unlinkSync(temporary);
79959
+ const fd = fs82.openSync(temporary, "r");
79960
+ fs82.unlinkSync(temporary);
79374
79961
  return fd;
79375
79962
  } catch (error2) {
79376
- fs81.rmSync(temporary, { force: true });
79963
+ fs82.rmSync(temporary, { force: true });
79377
79964
  throw error2;
79378
79965
  }
79379
79966
  }
@@ -79442,13 +80029,13 @@ async function runSupervisedPhase(phase, parsed, write) {
79442
80029
  detached: process.platform !== "win32"
79443
80030
  });
79444
80031
  } catch {
79445
- fs81.closeSync(specFd);
80032
+ fs82.closeSync(specFd);
79446
80033
  const failure = phaseFailure(invocation, startedAt, started, "phase_supervisor_failed", "benchmark phase child process could not be started");
79447
80034
  write(`${JSON.stringify(failure)}
79448
80035
  `);
79449
80036
  return 1;
79450
80037
  }
79451
- fs81.closeSync(specFd);
80038
+ fs82.closeSync(specFd);
79452
80039
  return await new Promise((resolve) => {
79453
80040
  const stdout = [];
79454
80041
  let settled = false;
@@ -79530,7 +80117,7 @@ async function runBenchmark(sub, args, write = (value) => process.stdout.write(v
79530
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) {
79531
80118
  throw new Error("Invalid internal benchmark phase invocation");
79532
80119
  }
79533
- const specBytes = fs81.readFileSync(specFd);
80120
+ const specBytes = fs82.readFileSync(specFd);
79534
80121
  const { exitCode, result: result2 } = await runBenchmarkPhase("", resultPath, phase, specBytes);
79535
80122
  write(`${JSON.stringify(result2)}
79536
80123
  `);
@@ -79570,13 +80157,13 @@ async function runBenchmark(sub, args, write = (value) => process.stdout.write(v
79570
80157
  function printHelp5() {
79571
80158
  const out = [];
79572
80159
  out.push("");
79573
- 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]")}`);
79574
80161
  out.push("");
79575
- out.push(` ${import_picocolors48.default.cyan("hydrate")} ${import_picocolors48.default.dim("--spec <path> --result <path> --json")}`);
79576
- out.push(` ${import_picocolors48.default.cyan("evaluate")} ${import_picocolors48.default.dim("--spec <path> --result <path> --json")}`);
79577
- 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")}`);
79578
80165
  out.push("");
79579
- 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.")}`);
79580
80167
  out.push("");
79581
80168
  console.log(out.join(`
79582
80169
  `));
@@ -79603,130 +80190,137 @@ var SUBCOMMAND_OWNED_FLAGS = {
79603
80190
  function help() {
79604
80191
  const out = [];
79605
80192
  out.push("");
79606
- out.push(` ${brandTint("◆")} ${import_picocolors49.default.bold("brainbase")} ${import_picocolors49.default.dim(`v${VERSION}`)}`);
79607
- 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")}`);
79608
80195
  out.push("");
79609
80196
  out.push(divider("USAGE"));
79610
80197
  out.push("");
79611
- 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]")}`);
79612
80199
  out.push("");
79613
80200
  out.push(divider("AUTH"));
79614
80201
  out.push("");
79615
- out.push(` ${import_picocolors49.default.cyan("login")} ${import_picocolors49.default.dim(" open the web app and connect this device")}`);
79616
- out.push(` ${import_picocolors49.default.cyan("logout")} ${import_picocolors49.default.dim(" clear the local session")}`);
79617
- 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")}`);
79618
80205
  out.push("");
79619
80206
  out.push(divider("DISCOVERY"));
79620
80207
  out.push("");
79621
- out.push(` ${import_picocolors49.default.cyan("team list")} ${import_picocolors49.default.dim("show the teams you can create agents in")}`);
79622
- 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")}`);
79623
80210
  out.push("");
79624
80211
  out.push(divider("LINKED AGENT"));
79625
80212
  out.push("");
79626
- out.push(` ${import_picocolors49.default.cyan("agent create")} ${import_picocolors49.default.dim("claim an unclaimed brainbase.agent.yaml and create the cloud agent")}`);
79627
- 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)")}`);
79628
- 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)")}`);
79629
- out.push(` ${import_picocolors49.default.cyan("agent unpack")} ${import_picocolors49.default.dim("install the claimed agent into a harness layout")}`);
79630
- out.push(` ${import_picocolors49.default.cyan("link")} ${import_picocolors49.default.dim("attach this folder to an existing agent")}`);
79631
- out.push(` ${import_picocolors49.default.cyan("agent status")} ${import_picocolors49.default.dim("show what would pull and what would push")}`);
79632
- out.push(` ${import_picocolors49.default.cyan("agent env")} ${import_picocolors49.default.dim("print export lines for `eval $(brainbase agent env)`")}`);
79633
- 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")}`);
79634
- out.push(` ${import_picocolors49.default.cyan("status")} ${import_picocolors49.default.dim("show what this folder is linked to")}`);
79635
- 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")}`);
79636
80226
  out.push("");
79637
80227
  out.push(divider("TASKS"));
79638
80228
  out.push("");
79639
- 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")}`);
79640
80230
  out.push("");
79641
80231
  out.push(divider("BENCHMARK RUNTIME"));
79642
80232
  out.push("");
79643
- out.push(` ${import_picocolors49.default.cyan("benchmark hydrate")} ${import_picocolors49.default.dim("--spec <path> --result <path> --json")}`);
79644
- out.push(` ${import_picocolors49.default.cyan("benchmark evaluate")} ${import_picocolors49.default.dim("--spec <path> --result <path> --json")}`);
79645
- 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")}`);
79646
80236
  out.push("");
79647
80237
  out.push(divider("ORCHESTRATIONS"));
79648
80238
  out.push("");
79649
- out.push(` ${import_picocolors49.default.cyan("orchestration create")} ${import_picocolors49.default.dim("claim a local orchestration manifest and create it in the cloud")}`);
79650
- out.push(` ${import_picocolors49.default.cyan("orchestration list")} ${import_picocolors49.default.dim("list orchestrations under a team")}`);
79651
- out.push(` ${import_picocolors49.default.cyan("orchestration pull")} ${import_picocolors49.default.dim("<id>")} ${import_picocolors49.default.dim("recursively fetch an orchestration + every member agent")}`);
79652
- out.push(` ${import_picocolors49.default.cyan("orchestration push")} ${import_picocolors49.default.dim("recursively push each member, then update the graph")}`);
79653
- 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")}`);
79654
80244
  out.push("");
79655
80245
  out.push(divider("TEMPLATES"));
79656
80246
  out.push("");
79657
- out.push(` ${import_picocolors49.default.cyan("template pack")} ${import_picocolors49.default.dim("bundle the current agent into a template")}`);
79658
- out.push(` ${import_picocolors49.default.cyan("template publish")} ${import_picocolors49.default.dim("upload a template to the registry")}`);
79659
- out.push(` ${import_picocolors49.default.cyan("template search")} ${import_picocolors49.default.dim("[query]")} ${import_picocolors49.default.dim("search the registry")}`);
79660
- out.push(` ${import_picocolors49.default.cyan("template info")} ${import_picocolors49.default.dim("<creator/slug>")} ${import_picocolors49.default.dim("show registry details for a template")}`);
79661
- out.push(` ${import_picocolors49.default.cyan("template onboard")} ${import_picocolors49.default.dim("<creator/slug>")} ${import_picocolors49.default.dim("install (or refresh) a template")}`);
79662
- out.push(` ${import_picocolors49.default.cyan("template list")} ${import_picocolors49.default.dim("show installed templates")}`);
79663
- 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")}`);
79664
80254
  out.push("");
79665
80255
  out.push(divider("SKILLS"));
79666
80256
  out.push("");
79667
- out.push(` ${import_picocolors49.default.cyan("skill add")} ${import_picocolors49.default.dim("<source>")} ${import_picocolors49.default.dim("install a skill (github / git / brainbase)")}`);
79668
- out.push(` ${import_picocolors49.default.cyan("skill list")} ${import_picocolors49.default.dim("show locally installed skills + their source")}`);
79669
- 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")}`);
79670
- out.push(` ${import_picocolors49.default.cyan("skill remove")} ${import_picocolors49.default.dim("<slug>")} ${import_picocolors49.default.dim("uninstall a skill")}`);
79671
- out.push(` ${import_picocolors49.default.cyan("skill search")} ${import_picocolors49.default.dim("[query]")} ${import_picocolors49.default.dim("search the brainbase skill registry")}`);
79672
- out.push(` ${import_picocolors49.default.cyan("skill info")} ${import_picocolors49.default.dim("<creator/slug>")} ${import_picocolors49.default.dim("show registry details for a skill")}`);
79673
- 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 .)")}`);
79674
80264
  out.push("");
79675
80265
  out.push(divider("CLI TOKENS"));
79676
80266
  out.push("");
79677
- out.push(` ${import_picocolors49.default.cyan("token create")} ${import_picocolors49.default.dim("issue a long-lived CLI key for CI / scripts")}`);
79678
- out.push(` ${import_picocolors49.default.cyan("token list")} ${import_picocolors49.default.dim("show your tokens")}`);
79679
- out.push(` ${import_picocolors49.default.cyan("token rename")} ${import_picocolors49.default.dim("<id>")} ${import_picocolors49.default.dim("relabel a token")}`);
79680
- 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")}`);
79681
80271
  out.push("");
79682
80272
  out.push(divider("MCP"));
79683
80273
  out.push("");
79684
- 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")}`);
79685
80276
  out.push("");
79686
80277
  out.push(divider("FLAGS"));
79687
80278
  out.push("");
79688
- out.push(` ${import_picocolors49.default.dim("--harness <id>")} force harness for onboard / sync (e.g. claude-code)`);
79689
- out.push(` ${import_picocolors49.default.dim("--scope <s>")} force scope: global | project`);
79690
- out.push(` ${import_picocolors49.default.dim("--yes, -y")} skip confirmations / auto-overwrite`);
79691
- out.push(` ${import_picocolors49.default.dim("--agent <id>")} for link/task create: use this agent id explicitly`);
79692
- out.push(` ${import_picocolors49.default.dim("--message <text>")} for task create: required first user message`);
79693
- out.push(` ${import_picocolors49.default.dim("--title <text>")} for task create: optional task title`);
79694
- out.push(` ${import_picocolors49.default.dim("--model <id>")} for task create: optional model override`);
79695
- out.push(` ${import_picocolors49.default.dim("--org <id-or-slug>")} pick the organization (team/agent list, agent create, orchestration create/list)`);
79696
- out.push(` ${import_picocolors49.default.dim("--team <id>")} pick the team, same commands (works without --org)`);
79697
- out.push(` ${import_picocolors49.default.dim("--json")} machine-readable output for supported commands`);
79698
- out.push(` ${import_picocolors49.default.dim("--no-tracking")} for link: skip routing LLM traffic through brainbase`);
79699
- out.push(` ${import_picocolors49.default.dim("--track")} for agent create: enable tracking non-interactively (off without a TTY)`);
79700
- out.push(` ${import_picocolors49.default.dim("--shell <sh|fish>")} for agent env: pick output format (auto-detected from $SHELL)`);
79701
- out.push(` ${import_picocolors49.default.dim("--all")} for template list: include installs from other folders`);
79702
- 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)`);
79703
80297
  out.push("");
79704
80298
  out.push(divider("ENV"));
79705
80299
  out.push("");
79706
- out.push(` ${import_picocolors49.default.dim("BRAINBASE_HOME")} override the local config dir (default ~/.brainbase)`);
79707
- out.push(` ${import_picocolors49.default.dim("BRAINBASE_DEBUG")} print full stack traces on error (any value; unset to disable)`);
79708
- out.push(` ${import_picocolors49.default.dim("BRAINBASE_WEB_URL")} override the web app URL used by login`);
79709
- out.push(` ${import_picocolors49.default.dim("BRAINBASE_CONTROL_PLANE_URL")} override the MAS host (/v2/cli; task create uses /v2/tasks)`);
79710
- out.push(` ${import_picocolors49.default.dim("BRAINBASE_API_URL")} legacy KLS host override (uses /api/cli; proxy/registry fallback)`);
79711
- out.push(` ${import_picocolors49.default.dim("BRAINBASE_PROXY_URL")} override the model-proxy URL used by harness traffic (default https://api.v1.brainbaselabs.com)`);
79712
- out.push(` ${import_picocolors49.default.dim("BRAINBASE_REGISTRY_URL")} override the registry API URL (default https://api.v1.brainbaselabs.com)`);
79713
- out.push(` ${import_picocolors49.default.dim("BRAINBASE_TOKEN")} long-lived CLI PAT (overrides token.json)`);
79714
- out.push(` ${import_picocolors49.default.dim("BRAINBASE_SKIP_AUTH")} bypass the auth gate for development`);
79715
- out.push(` ${import_picocolors49.default.dim("BRAINBASE_NON_INTERACTIVE")} force non-interactive mode — skip/auto-default prompts (CI & agents)`);
79716
- 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)`);
79717
80311
  out.push("");
79718
- out.push(` ${import_picocolors49.default.dim("BRAINBASE_MEMORY_MCP_URL")} override the built-in memory MCP host`);
79719
- out.push(` ${import_picocolors49.default.dim("BRAINBASE_BROWSER_MCP_URL")} override the built-in browser MCP host`);
79720
- out.push(` ${import_picocolors49.default.dim("BRAINBASE_SLACK_MCP_URL")} override the built-in Slack MCP host`);
79721
- out.push(` ${import_picocolors49.default.dim("BRAINBASE_MEETING_MCP_URL")} override the built-in meeting MCP host`);
79722
- out.push(` ${import_picocolors49.default.dim("BRAINBASE_GITHUB_MCP_URL")} override the built-in GitHub MCP host`);
79723
- 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`);
79724
80318
  out.push("");
79725
80319
  out.push(divider("HARNESSES"));
79726
80320
  out.push("");
79727
- out.push(` ${import_picocolors49.default.dim("•")} ${import_picocolors49.default.bold("claude-code")} ${import_picocolors49.default.dim("skills, mcps, agents, commands, playbooks, instructions, files")}`);
79728
- out.push(` ${import_picocolors49.default.dim("•")} ${import_picocolors49.default.bold("codex")} ${import_picocolors49.default.dim("skills, mcps, commands, playbooks, instructions, files")}`);
79729
- 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")}`);
79730
80324
  out.push("");
79731
80325
  console.log(out.join(`
79732
80326
  `));
@@ -79751,7 +80345,13 @@ var VALUE_TAKING_FLAGS = new Set([
79751
80345
  "--description",
79752
80346
  "--schema",
79753
80347
  "--from",
79754
- "--to"
80348
+ "--to",
80349
+ "--bot-token",
80350
+ "--signing-secret",
80351
+ "--app-id",
80352
+ "--app-name",
80353
+ "--bot-name",
80354
+ "--bot-image-url"
79755
80355
  ]);
79756
80356
  function isValueOfPriorFlag2(args, index) {
79757
80357
  return index > 0 && VALUE_TAKING_FLAGS.has(args[index - 1]);
@@ -79872,13 +80472,13 @@ async function requireAuth(cmd) {
79872
80472
  if (STORED_PAT_COMMANDS.has(cmd) && readToken())
79873
80473
  return;
79874
80474
  console.error("");
79875
- console.error(` ${brandTint("◆")} ${import_picocolors49.default.bold("brainbase")}`);
80475
+ console.error(` ${brandTint("◆")} ${import_picocolors52.default.bold("brainbase")}`);
79876
80476
  console.error("");
79877
- 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)}.`);
79878
80478
  if (status.reason)
79879
- console.error(` ${import_picocolors49.default.dim(status.reason)}`);
80479
+ console.error(` ${import_picocolors52.default.dim(status.reason)}`);
79880
80480
  console.error("");
79881
- 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.`);
79882
80482
  console.error("");
79883
80483
  process14.exit(1);
79884
80484
  }
@@ -79888,7 +80488,7 @@ async function main() {
79888
80488
  const rawCwd = process14.cwd();
79889
80489
  const cwd2 = (() => {
79890
80490
  try {
79891
- return fs82.realpathSync(rawCwd);
80491
+ return fs83.realpathSync(rawCwd);
79892
80492
  } catch {
79893
80493
  return rawCwd;
79894
80494
  }
@@ -79937,6 +80537,12 @@ async function main() {
79937
80537
  const noPushFlag = hasFlag2(sharedArgs, "--no-push");
79938
80538
  const jsonFlag = hasFlag2(sharedArgs, "--json");
79939
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");
79940
80546
  ensureSkillResolversRegistered();
79941
80547
  await requireAuth(cmd);
79942
80548
  try {
@@ -80020,7 +80626,13 @@ async function main() {
80020
80626
  track,
80021
80627
  force: forceFlag,
80022
80628
  runEntrypoint: runEntrypointFlag,
80023
- acp: acpFlag
80629
+ acp: acpFlag,
80630
+ botToken: botTokenFlag,
80631
+ signingSecret: signingSecretFlag,
80632
+ appId: appIdFlag,
80633
+ appName: appNameFlag,
80634
+ botName: botNameFlag,
80635
+ botImageUrl: botImageUrlFlag
80024
80636
  });
80025
80637
  break;
80026
80638
  }
@@ -80079,10 +80691,10 @@ async function main() {
80079
80691
  process14.exit(1);
80080
80692
  }
80081
80693
  } catch (err) {
80082
- console.error(import_picocolors49.default.red(`
80694
+ console.error(import_picocolors52.default.red(`
80083
80695
  ${err.message}`));
80084
80696
  if (err instanceof ApiError && err.status === 401) {
80085
- 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.`);
80086
80698
  }
80087
80699
  if (process14.env.BRAINBASE_DEBUG)
80088
80700
  console.error(err.stack);