@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.
- package/dist/index.js +976 -364
- 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,
|
|
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,
|
|
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
|
|
35144
|
+
var import_picocolors52 = __toESM(require_picocolors(), 1);
|
|
35145
35145
|
import process14 from "node:process";
|
|
35146
|
-
import
|
|
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.
|
|
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
|
|
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(` ${
|
|
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(` ${
|
|
66496
|
-
out.push(` ${
|
|
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
|
|
66949
|
+
var import_picocolors39 = __toESM(require_picocolors(), 1);
|
|
66509
66950
|
|
|
66510
66951
|
// src/cli/team-list.ts
|
|
66511
|
-
var
|
|
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(` ${
|
|
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 ? ` ${
|
|
66538
|
-
lines.push(` ${
|
|
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(` ${
|
|
66981
|
+
lines.push(` ${import_picocolors38.default.red(`could not load teams: ${error}`)}`);
|
|
66541
66982
|
} else if (teams.length === 0) {
|
|
66542
|
-
lines.push(` ${
|
|
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)} ${
|
|
66986
|
+
lines.push(` ${team.name.padEnd(nameWidth)} ${import_picocolors38.default.dim(team.id)}`);
|
|
66546
66987
|
}
|
|
66547
66988
|
lines.push("");
|
|
66548
66989
|
}
|
|
66549
|
-
lines.push(` ${
|
|
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(` ${
|
|
67021
|
+
out.push(` ${import_picocolors39.default.bold("brainbase team")} ${import_picocolors39.default.dim("<sub> [options]")}`);
|
|
66581
67022
|
out.push("");
|
|
66582
|
-
out.push(` ${
|
|
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(` ${
|
|
66585
|
-
out.push(` ${
|
|
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
|
|
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
|
|
66597
|
-
var
|
|
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
|
|
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
|
|
67098
|
+
return fs75.existsSync(orchManifestPath(cwd2));
|
|
66658
67099
|
}
|
|
66659
67100
|
function readOrchManifest(cwd2) {
|
|
66660
67101
|
const p2 = orchManifestPath(cwd2);
|
|
66661
|
-
if (!
|
|
67102
|
+
if (!fs75.existsSync(p2))
|
|
66662
67103
|
return null;
|
|
66663
|
-
const raw =
|
|
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
|
-
|
|
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
|
|
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
|
|
67214
|
+
const clean2 = {};
|
|
66774
67215
|
for (const [k3, v3] of Object.entries(link2)) {
|
|
66775
67216
|
if (v3 !== null && v3 !== undefined)
|
|
66776
|
-
|
|
67217
|
+
clean2[k3] = v3;
|
|
66777
67218
|
}
|
|
66778
|
-
writeJson(orchLinkPath(cwd2),
|
|
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
|
-
|
|
67243
|
+
fs76.writeFileSync(ignorePath, desired);
|
|
66803
67244
|
return;
|
|
66804
67245
|
}
|
|
66805
|
-
const current =
|
|
67246
|
+
const current = fs76.readFileSync(ignorePath, "utf8");
|
|
66806
67247
|
if (!current.split(/\r?\n/).some((l2) => l2.trim() === ORCH_SYNC_STATE_FILE)) {
|
|
66807
|
-
|
|
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
|
|
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
|
-
|
|
67348
|
+
fs77.rmSync(stageRoot, { recursive: true, force: true });
|
|
66908
67349
|
} catch {}
|
|
66909
67350
|
}
|
|
66910
67351
|
}
|
|
66911
67352
|
function stageManifestComponents2(components) {
|
|
66912
|
-
const root =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 ${
|
|
67118
|
-
or ${
|
|
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(` ${
|
|
67578
|
+
planLines.push(` ${import_picocolors40.default.bold(cloud.name)} ${import_picocolors40.default.dim(`(${cloud.id})`)}`);
|
|
67138
67579
|
if (cloud.description)
|
|
67139
|
-
planLines.push(` ${
|
|
67580
|
+
planLines.push(` ${import_picocolors40.default.dim(cloud.description)}`);
|
|
67140
67581
|
planLines.push("");
|
|
67141
|
-
planLines.push(` ${
|
|
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 ?
|
|
67145
|
-
planLines.push(` ${
|
|
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(` ${
|
|
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 ? ` ${
|
|
67154
|
-
planLines.push(` ${
|
|
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 ${
|
|
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
|
-
|
|
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 ${
|
|
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)}/ ${
|
|
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
|
|
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 ${
|
|
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 ${
|
|
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 ${
|
|
67388
|
-
f2.info(`Run ${
|
|
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 ${
|
|
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(` ${
|
|
67434
|
-
plan.push(` ${
|
|
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(` ${
|
|
67878
|
+
plan.push(` ${import_picocolors41.default.dim("per-member agent push:")}`);
|
|
67438
67879
|
for (const m3 of manifest.members) {
|
|
67439
|
-
plan.push(` ${
|
|
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(`${
|
|
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 ${
|
|
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
|
|
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 ${
|
|
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(` ${
|
|
67563
|
-
lines.push(` ${
|
|
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(` ${
|
|
68018
|
+
lines.push(` ${import_picocolors42.default.bold("members")}`);
|
|
67578
68019
|
for (const slug of membersAdded) {
|
|
67579
|
-
lines.push(` ${
|
|
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(` ${
|
|
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(` ${
|
|
68038
|
+
lines.push(` ${import_picocolors42.default.bold("edges")}`);
|
|
67598
68039
|
for (const k3 of edgesAdded)
|
|
67599
|
-
lines.push(` ${
|
|
68040
|
+
lines.push(` ${import_picocolors42.default.yellow("→ push")} added in yaml: ${k3}`);
|
|
67600
68041
|
for (const k3 of edgesRemoved)
|
|
67601
|
-
lines.push(` ${
|
|
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(` ${
|
|
68080
|
+
lines.push(` ${import_picocolors42.default.bold("schedule triggers")}`);
|
|
67640
68081
|
for (const k3 of triggersAdded)
|
|
67641
|
-
lines.push(` ${
|
|
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(` ${
|
|
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(` ${
|
|
68107
|
+
lines.push(` ${import_picocolors42.default.bold("member content drift")}`);
|
|
67667
68108
|
for (const d3 of memberDrift) {
|
|
67668
|
-
lines.push(` ${
|
|
68109
|
+
lines.push(` ${import_picocolors42.default.cyan("?")} ${import_picocolors42.default.bold(d3.slug)} ${import_picocolors42.default.dim("— " + d3.reason)}`);
|
|
67669
68110
|
}
|
|
67670
|
-
lines.push(` ${
|
|
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(` ${
|
|
67676
|
-
lines.push(` ${
|
|
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(` ${
|
|
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(` ${
|
|
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
|
|
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(` ${
|
|
68166
|
+
lines.push(` ${import_picocolors43.default.bold(o2.name)} ${import_picocolors43.default.dim(o2.id)}`);
|
|
67726
68167
|
if (o2.description)
|
|
67727
|
-
lines.push(` ${
|
|
67728
|
-
lines.push(` ${
|
|
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(` ${
|
|
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
|
|
67739
|
-
var
|
|
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 ${
|
|
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) ||
|
|
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) ||
|
|
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 ${
|
|
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 ${
|
|
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 ${
|
|
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 ${
|
|
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
|
-
|
|
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
|
-
|
|
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 ${
|
|
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
|
|
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 ${
|
|
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 ${
|
|
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
|
-
` ${
|
|
67967
|
-
` ${
|
|
67968
|
-
` ${
|
|
67969
|
-
` ${
|
|
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 ${
|
|
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(` ${
|
|
68553
|
+
out.push(` ${import_picocolors46.default.bold("brainbase orchestration")} ${import_picocolors46.default.dim("<sub> [options]")}`);
|
|
68113
68554
|
out.push("");
|
|
68114
|
-
out.push(` ${
|
|
68115
|
-
out.push(` ${
|
|
68116
|
-
out.push(` ${
|
|
68117
|
-
out.push(` ${
|
|
68118
|
-
out.push(` ${
|
|
68119
|
-
out.push(` ${
|
|
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(` ${
|
|
68122
|
-
out.push(` ${
|
|
68123
|
-
out.push(` ${
|
|
68124
|
-
out.push(` ${
|
|
68125
|
-
out.push(` ${
|
|
68126
|
-
out.push(` ${
|
|
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
|
|
68612
|
+
var import_picocolors47 = __toESM(require_picocolors(), 1);
|
|
68172
68613
|
function runPublish() {
|
|
68173
68614
|
banner("publish — moved");
|
|
68174
|
-
f2.error(`${
|
|
68175
|
-
f2.info(`Use ${
|
|
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
|
|
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} ${
|
|
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 ${
|
|
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, `${
|
|
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 ${
|
|
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, `${
|
|
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 ${
|
|
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(
|
|
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(` ${
|
|
69493
|
+
out.push(` ${import_picocolors48.default.bold("brainbase token")} ${import_picocolors48.default.dim("<command>")}`);
|
|
69053
69494
|
out.push("");
|
|
69054
|
-
out.push(` ${
|
|
69055
|
-
out.push(` ${
|
|
69056
|
-
out.push(` ${
|
|
69057
|
-
out.push(` ${
|
|
69058
|
-
out.push(` ${
|
|
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(` ${
|
|
69061
|
-
out.push(` ${
|
|
69062
|
-
out.push(` ${
|
|
69063
|
-
out.push(` ${
|
|
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(` ${
|
|
69066
|
-
out.push(` ${
|
|
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
|
|
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
|
|
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 =
|
|
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,
|
|
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
|
|
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
|
|
77851
|
+
const report2 = {
|
|
77402
77852
|
check_status: deriveCheckStatus(results),
|
|
77403
77853
|
servers: results
|
|
77404
77854
|
};
|
|
77405
77855
|
if (options.json) {
|
|
77406
|
-
write(JSON.stringify(
|
|
77856
|
+
write(JSON.stringify(report2) + `
|
|
77407
77857
|
`);
|
|
77408
77858
|
} else {
|
|
77409
|
-
write(renderHuman(
|
|
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(
|
|
77868
|
+
function renderHuman(report2) {
|
|
77419
77869
|
const lines = [];
|
|
77420
|
-
if (
|
|
77421
|
-
lines.push(
|
|
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
|
|
77427
|
-
const mark = s3.status === "ok" ?
|
|
77428
|
-
const detail = s3.status === "ok" ?
|
|
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 =
|
|
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
|
|
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(` ${
|
|
78227
|
+
out.push(` ${import_picocolors50.default.bold("brainbase task")} ${import_picocolors50.default.dim("<sub> [options]")}`);
|
|
77641
78228
|
out.push("");
|
|
77642
|
-
out.push(` ${
|
|
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(` ${
|
|
77645
|
-
out.push(` ${
|
|
77646
|
-
out.push(` ${
|
|
77647
|
-
out.push(` ${
|
|
77648
|
-
out.push(` ${
|
|
77649
|
-
out.push(` ${
|
|
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(` ${
|
|
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
|
|
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
|
|
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
|
|
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 (!
|
|
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 =
|
|
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 (!
|
|
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 (!
|
|
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 (
|
|
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 (!
|
|
78578
|
+
if (!fs81.existsSync(current))
|
|
77992
78579
|
continue;
|
|
77993
|
-
if (
|
|
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 =
|
|
78004
|
-
canonicalFile =
|
|
78005
|
-
currentStat =
|
|
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
|
|
78601
|
+
const noFollow = typeof fs81.constants.O_NOFOLLOW === "number" ? fs81.constants.O_NOFOLLOW : 0;
|
|
78015
78602
|
let fd;
|
|
78016
78603
|
try {
|
|
78017
|
-
fd =
|
|
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 =
|
|
78612
|
+
const stat = fs81.fstatSync(fd);
|
|
78026
78613
|
if (!stat.isFile()) {
|
|
78027
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
|
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 (!
|
|
78650
|
+
if (!fs81.existsSync(current))
|
|
78064
78651
|
continue;
|
|
78065
|
-
const stat =
|
|
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 (
|
|
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 =
|
|
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) || !
|
|
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 =
|
|
78725
|
+
const stat = fs81.lstatSync(candidate);
|
|
78139
78726
|
if (record3.kind === "symlink") {
|
|
78140
|
-
const target = stat.isSymbolicLink() ?
|
|
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
|
-
|
|
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
|
-
|
|
78758
|
+
fs81.closeSync(opened.fd);
|
|
78172
78759
|
}
|
|
78173
78760
|
return source;
|
|
78174
78761
|
}
|
|
78175
78762
|
async function atomicCopy(source, destination, mode, sourceRoot) {
|
|
78176
|
-
|
|
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(
|
|
78767
|
+
await pipeline2(fs81.createReadStream("", {
|
|
78181
78768
|
fd: opened.fd,
|
|
78182
78769
|
autoClose: false,
|
|
78183
78770
|
start: 0
|
|
78184
|
-
}),
|
|
78771
|
+
}), fs81.createWriteStream(temporary, {
|
|
78185
78772
|
flags: "wx",
|
|
78186
78773
|
mode: 384
|
|
78187
78774
|
}));
|
|
78188
|
-
|
|
78189
|
-
|
|
78775
|
+
fs81.chmodSync(temporary, mode ?? opened.stat.mode & 511);
|
|
78776
|
+
fs81.renameSync(temporary, destination);
|
|
78190
78777
|
} finally {
|
|
78191
|
-
|
|
78192
|
-
|
|
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 =
|
|
78199
|
-
const target =
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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 (!
|
|
78911
|
+
if (!fs81.existsSync(root) || fs81.lstatSync(root).isSymbolicLink())
|
|
78325
78912
|
return false;
|
|
78326
78913
|
try {
|
|
78327
|
-
const marker = JSON.parse(
|
|
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 (
|
|
78921
|
+
if (fs81.existsSync(root)) {
|
|
78335
78922
|
if (!verifyOwnedDirectory(root, role, spec)) {
|
|
78336
|
-
const stat =
|
|
78337
|
-
if (!stat.isDirectory() ||
|
|
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
|
-
|
|
78928
|
+
fs81.rmSync(root, { recursive: true, force: true });
|
|
78342
78929
|
}
|
|
78343
78930
|
}
|
|
78344
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
79098
|
+
fs81.writeFileSync(temporary, redactCommandOutput(data, spec), {
|
|
78512
79099
|
flag: "wx",
|
|
78513
79100
|
mode: 384
|
|
78514
79101
|
});
|
|
78515
|
-
|
|
79102
|
+
fs81.renameSync(temporary, destination);
|
|
78516
79103
|
} finally {
|
|
78517
|
-
|
|
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
|
-
|
|
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
|
-
|
|
78526
|
-
|
|
79112
|
+
fs81.writeFileSync(temporary, data, { flag: "wx", mode: 384 });
|
|
79113
|
+
fs81.renameSync(temporary, destination);
|
|
78527
79114
|
} finally {
|
|
78528
|
-
|
|
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
|
-
|
|
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 (!
|
|
79205
|
+
if (!fs81.existsSync(candidate))
|
|
78619
79206
|
continue;
|
|
78620
|
-
const stat =
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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 || !
|
|
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
|
-
|
|
79489
|
+
fs81.renameSync(temporary, archive);
|
|
78903
79490
|
} finally {
|
|
78904
|
-
|
|
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
|
|
79591
|
+
const noFollow = typeof fs81.constants.O_NOFOLLOW === "number" ? fs81.constants.O_NOFOLLOW : 0;
|
|
79005
79592
|
let fd;
|
|
79006
79593
|
try {
|
|
79007
|
-
fd =
|
|
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 =
|
|
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
|
-
|
|
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 (
|
|
79649
|
+
if (fs81.existsSync(resultPath)) {
|
|
79063
79650
|
try {
|
|
79064
|
-
const cached2 = JSON.parse(
|
|
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 (
|
|
79758
|
+
if (fs81.existsSync(resultPath)) {
|
|
79172
79759
|
try {
|
|
79173
|
-
const cached2 = JSON.parse(
|
|
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
|
-
|
|
79957
|
+
fs82.writeFileSync(temporary, bytes, { flag: "wx", mode: 384 });
|
|
79371
79958
|
try {
|
|
79372
|
-
const fd =
|
|
79373
|
-
|
|
79959
|
+
const fd = fs82.openSync(temporary, "r");
|
|
79960
|
+
fs82.unlinkSync(temporary);
|
|
79374
79961
|
return fd;
|
|
79375
79962
|
} catch (error2) {
|
|
79376
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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(` ${
|
|
80160
|
+
out.push(` ${import_picocolors51.default.bold("brainbase benchmark")} ${import_picocolors51.default.dim("<sub> [options]")}`);
|
|
79574
80161
|
out.push("");
|
|
79575
|
-
out.push(` ${
|
|
79576
|
-
out.push(` ${
|
|
79577
|
-
out.push(` ${
|
|
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(` ${
|
|
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("◆")} ${
|
|
79607
|
-
out.push(` ${
|
|
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(` ${
|
|
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(` ${
|
|
79616
|
-
out.push(` ${
|
|
79617
|
-
out.push(` ${
|
|
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(` ${
|
|
79622
|
-
out.push(` ${
|
|
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(` ${
|
|
79627
|
-
out.push(` ${
|
|
79628
|
-
out.push(` ${
|
|
79629
|
-
out.push(` ${
|
|
79630
|
-
out.push(` ${
|
|
79631
|
-
out.push(` ${
|
|
79632
|
-
out.push(` ${
|
|
79633
|
-
out.push(` ${
|
|
79634
|
-
out.push(` ${
|
|
79635
|
-
out.push(` ${
|
|
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(` ${
|
|
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(` ${
|
|
79644
|
-
out.push(` ${
|
|
79645
|
-
out.push(` ${
|
|
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(` ${
|
|
79650
|
-
out.push(` ${
|
|
79651
|
-
out.push(` ${
|
|
79652
|
-
out.push(` ${
|
|
79653
|
-
out.push(` ${
|
|
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(` ${
|
|
79658
|
-
out.push(` ${
|
|
79659
|
-
out.push(` ${
|
|
79660
|
-
out.push(` ${
|
|
79661
|
-
out.push(` ${
|
|
79662
|
-
out.push(` ${
|
|
79663
|
-
out.push(` ${
|
|
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(` ${
|
|
79668
|
-
out.push(` ${
|
|
79669
|
-
out.push(` ${
|
|
79670
|
-
out.push(` ${
|
|
79671
|
-
out.push(` ${
|
|
79672
|
-
out.push(` ${
|
|
79673
|
-
out.push(` ${
|
|
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(` ${
|
|
79678
|
-
out.push(` ${
|
|
79679
|
-
out.push(` ${
|
|
79680
|
-
out.push(` ${
|
|
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(` ${
|
|
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(` ${
|
|
79689
|
-
out.push(` ${
|
|
79690
|
-
out.push(` ${
|
|
79691
|
-
out.push(` ${
|
|
79692
|
-
out.push(` ${
|
|
79693
|
-
out.push(` ${
|
|
79694
|
-
out.push(` ${
|
|
79695
|
-
out.push(` ${
|
|
79696
|
-
out.push(` ${
|
|
79697
|
-
out.push(` ${
|
|
79698
|
-
out.push(` ${
|
|
79699
|
-
out.push(` ${
|
|
79700
|
-
out.push(` ${
|
|
79701
|
-
out.push(` ${
|
|
79702
|
-
out.push(` ${
|
|
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(` ${
|
|
79707
|
-
out.push(` ${
|
|
79708
|
-
out.push(` ${
|
|
79709
|
-
out.push(` ${
|
|
79710
|
-
out.push(` ${
|
|
79711
|
-
out.push(` ${
|
|
79712
|
-
out.push(` ${
|
|
79713
|
-
out.push(` ${
|
|
79714
|
-
out.push(` ${
|
|
79715
|
-
out.push(` ${
|
|
79716
|
-
out.push(` ${
|
|
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(` ${
|
|
79719
|
-
out.push(` ${
|
|
79720
|
-
out.push(` ${
|
|
79721
|
-
out.push(` ${
|
|
79722
|
-
out.push(` ${
|
|
79723
|
-
out.push(` ${
|
|
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(` ${
|
|
79728
|
-
out.push(` ${
|
|
79729
|
-
out.push(` ${
|
|
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("◆")} ${
|
|
80475
|
+
console.error(` ${brandTint("◆")} ${import_picocolors52.default.bold("brainbase")}`);
|
|
79876
80476
|
console.error("");
|
|
79877
|
-
console.error(` ${
|
|
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(` ${
|
|
80479
|
+
console.error(` ${import_picocolors52.default.dim(status.reason)}`);
|
|
79880
80480
|
console.error("");
|
|
79881
|
-
console.error(` Run ${
|
|
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
|
|
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(
|
|
80694
|
+
console.error(import_picocolors52.default.red(`
|
|
80083
80695
|
${err.message}`));
|
|
80084
80696
|
if (err instanceof ApiError && err.status === 401) {
|
|
80085
|
-
console.error(` Run ${
|
|
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);
|