@brainbase-labs/cli 0.25.0 → 0.26.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 +872 -473
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -31708,8 +31708,8 @@ var require_utils = __commonJS((exports, module) => {
|
|
|
31708
31708
|
}
|
|
31709
31709
|
return ind;
|
|
31710
31710
|
}
|
|
31711
|
-
function removeDotSegments(
|
|
31712
|
-
let input =
|
|
31711
|
+
function removeDotSegments(path89) {
|
|
31712
|
+
let input = path89;
|
|
31713
31713
|
const output = [];
|
|
31714
31714
|
let nextSlash = -1;
|
|
31715
31715
|
let len = 0;
|
|
@@ -31952,8 +31952,8 @@ var require_schemes = __commonJS((exports, module) => {
|
|
|
31952
31952
|
wsComponent.secure = undefined;
|
|
31953
31953
|
}
|
|
31954
31954
|
if (wsComponent.resourceName) {
|
|
31955
|
-
const [
|
|
31956
|
-
wsComponent.path =
|
|
31955
|
+
const [path89, query] = wsComponent.resourceName.split("?");
|
|
31956
|
+
wsComponent.path = path89 && path89 !== "/" ? path89 : undefined;
|
|
31957
31957
|
wsComponent.query = query;
|
|
31958
31958
|
wsComponent.resourceName = undefined;
|
|
31959
31959
|
}
|
|
@@ -35141,7 +35141,7 @@ var require_dist2 = __commonJS((exports, module) => {
|
|
|
35141
35141
|
});
|
|
35142
35142
|
|
|
35143
35143
|
// src/index.ts
|
|
35144
|
-
var
|
|
35144
|
+
var import_picocolors53 = __toESM(require_picocolors(), 1);
|
|
35145
35145
|
import process14 from "node:process";
|
|
35146
35146
|
import fs83 from "node:fs";
|
|
35147
35147
|
|
|
@@ -36008,7 +36008,7 @@ function padStart(s, n) {
|
|
|
36008
36008
|
// package.json
|
|
36009
36009
|
var package_default = {
|
|
36010
36010
|
name: "@brainbase-labs/cli",
|
|
36011
|
-
version: "0.
|
|
36011
|
+
version: "0.26.0",
|
|
36012
36012
|
description: "Pack, share, and install agent templates across harnesses (Claude Code, Codex, ...).",
|
|
36013
36013
|
type: "module",
|
|
36014
36014
|
bin: {
|
|
@@ -61950,6 +61950,7 @@ import fs66 from "node:fs";
|
|
|
61950
61950
|
// src/core/agent-manifest.ts
|
|
61951
61951
|
import path73 from "node:path";
|
|
61952
61952
|
import fs65 from "node:fs";
|
|
61953
|
+
import { randomBytes } from "node:crypto";
|
|
61953
61954
|
var import_yaml2 = __toESM(require_dist(), 1);
|
|
61954
61955
|
var AGENT_MANIFEST_FILE = "brainbase.agent.yaml";
|
|
61955
61956
|
var LEGACY_AGENT_MANIFEST_FILE = "brainbase.yaml";
|
|
@@ -62121,30 +62122,54 @@ function existingManifestPath(cwd2) {
|
|
|
62121
62122
|
function hasManifest(cwd2) {
|
|
62122
62123
|
return existingManifestPath(cwd2) !== null;
|
|
62123
62124
|
}
|
|
62124
|
-
function
|
|
62125
|
-
const p2 = existingManifestPath(cwd2);
|
|
62126
|
-
if (!p2)
|
|
62127
|
-
return null;
|
|
62128
|
-
const raw = fs65.readFileSync(p2, "utf8");
|
|
62125
|
+
function parseManifest(raw, label = AGENT_MANIFEST_FILE) {
|
|
62129
62126
|
let parsed;
|
|
62130
62127
|
try {
|
|
62131
62128
|
parsed = import_yaml2.default.parse(raw);
|
|
62132
62129
|
} catch (err) {
|
|
62133
|
-
throw new Error(`${
|
|
62130
|
+
throw new Error(`${label} is not valid YAML: ${err.message}`);
|
|
62134
62131
|
}
|
|
62135
62132
|
const result2 = AgentManifestSchema.safeParse(parsed);
|
|
62136
62133
|
if (!result2.success) {
|
|
62137
|
-
throw new Error(`${
|
|
62134
|
+
throw new Error(`${label} is invalid: ${result2.error.issues.map((i) => `${i.path.join(".") || "(root)"} — ${i.message}`).join("; ")}`);
|
|
62138
62135
|
}
|
|
62139
62136
|
return result2.data;
|
|
62140
62137
|
}
|
|
62141
|
-
function
|
|
62138
|
+
function readManifest(cwd2) {
|
|
62139
|
+
const p2 = existingManifestPath(cwd2);
|
|
62140
|
+
if (!p2)
|
|
62141
|
+
return null;
|
|
62142
|
+
return parseManifest(fs65.readFileSync(p2, "utf8"), path73.basename(p2));
|
|
62143
|
+
}
|
|
62144
|
+
function renderManifest(manifest) {
|
|
62142
62145
|
const doc = new import_yaml2.default.Document;
|
|
62143
62146
|
doc.contents = manifest;
|
|
62144
62147
|
doc.commentBefore = ` brainbase.agent.yaml — declarative agent manifest.
|
|
62145
62148
|
` + " Committed to source control. Edit by hand, then `brainbase agent push`.";
|
|
62146
|
-
|
|
62147
|
-
|
|
62149
|
+
return String(doc);
|
|
62150
|
+
}
|
|
62151
|
+
function writeManifestText(cwd2, body) {
|
|
62152
|
+
const target = manifestPath(cwd2);
|
|
62153
|
+
const tmp = `${target}.${randomBytes(8).toString("hex")}.tmp`;
|
|
62154
|
+
const fd = fs65.openSync(tmp, "wx");
|
|
62155
|
+
let closed = false;
|
|
62156
|
+
try {
|
|
62157
|
+
fs65.writeFileSync(fd, body, "utf8");
|
|
62158
|
+
fs65.closeSync(fd);
|
|
62159
|
+
closed = true;
|
|
62160
|
+
fs65.renameSync(tmp, target);
|
|
62161
|
+
} catch (err) {
|
|
62162
|
+
if (!closed) {
|
|
62163
|
+
try {
|
|
62164
|
+
fs65.closeSync(fd);
|
|
62165
|
+
} catch {}
|
|
62166
|
+
}
|
|
62167
|
+
fs65.rmSync(tmp, { force: true });
|
|
62168
|
+
throw err;
|
|
62169
|
+
}
|
|
62170
|
+
}
|
|
62171
|
+
function writeManifest(cwd2, manifest) {
|
|
62172
|
+
writeManifestText(cwd2, renderManifest(manifest));
|
|
62148
62173
|
}
|
|
62149
62174
|
function resolveInstructionsPath(cwd2, manifest) {
|
|
62150
62175
|
if (!manifest.instructions?.file)
|
|
@@ -62318,7 +62343,9 @@ var AgentMetaSnapshotSchema = exports_external.object({
|
|
|
62318
62343
|
tagline: exports_external.string().nullish().transform((v3) => v3 ?? undefined),
|
|
62319
62344
|
entrypoint: exports_external.string().optional(),
|
|
62320
62345
|
machine_kind: exports_external.string().min(1).optional(),
|
|
62321
|
-
default_model: exports_external.string().nullable().optional()
|
|
62346
|
+
default_model: exports_external.string().nullable().optional(),
|
|
62347
|
+
memory: exports_external.boolean().nullable().optional(),
|
|
62348
|
+
browser: exports_external.boolean().nullable().optional()
|
|
62322
62349
|
});
|
|
62323
62350
|
var SyncStateSchema = exports_external.object({
|
|
62324
62351
|
schemaVersion: exports_external.literal(1),
|
|
@@ -63518,7 +63545,7 @@ function runHarnessInstall(harnessId, components, opts, agentName) {
|
|
|
63518
63545
|
}
|
|
63519
63546
|
|
|
63520
63547
|
// src/cli/agent.ts
|
|
63521
|
-
var
|
|
63548
|
+
var import_picocolors38 = __toESM(require_picocolors(), 1);
|
|
63522
63549
|
|
|
63523
63550
|
// src/cli/agent-pull.ts
|
|
63524
63551
|
import { spawn as spawn2 } from "node:child_process";
|
|
@@ -63931,9 +63958,44 @@ function diffAgentMeta(manifestMeta, lockMeta, cloudMeta) {
|
|
|
63931
63958
|
cloudChanged: !!cloudMeta && !!lockMeta && !eq(cloudMeta, lockMeta)
|
|
63932
63959
|
};
|
|
63933
63960
|
}
|
|
63961
|
+
var WRITABLE_CAPABILITIES = ["memory", "browser"];
|
|
63962
|
+
var MIRRORED_CAPABILITIES = ["slack", "meeting", "github"];
|
|
63963
|
+
function manifestConfigState(manifest) {
|
|
63964
|
+
return {
|
|
63965
|
+
...manifest.machine_kind !== undefined ? { machine_kind: manifest.machine_kind } : {},
|
|
63966
|
+
...hasOwn(manifest, "default_model") ? { default_model: manifest.default_model ?? null } : {},
|
|
63967
|
+
...manifest.capabilities?.memory !== undefined ? { memory: manifest.capabilities.memory } : {},
|
|
63968
|
+
...manifest.capabilities?.browser !== undefined ? { browser: manifest.capabilities.browser } : {}
|
|
63969
|
+
};
|
|
63970
|
+
}
|
|
63971
|
+
function cloudConfigState(agent) {
|
|
63972
|
+
return {
|
|
63973
|
+
...agent.machine_kind !== undefined ? { machine_kind: agent.machine_kind } : {},
|
|
63974
|
+
...hasOwn(agent, "default_model") ? { default_model: agent.default_model ?? null } : {},
|
|
63975
|
+
...agent.memory_enabled !== undefined ? { memory: agent.memory_enabled } : {},
|
|
63976
|
+
...agent.browser_enabled !== undefined ? { browser: agent.browser_enabled } : {}
|
|
63977
|
+
};
|
|
63978
|
+
}
|
|
63934
63979
|
function hasOwn(value, key2) {
|
|
63935
63980
|
return !!value && Object.prototype.hasOwnProperty.call(value, key2);
|
|
63936
63981
|
}
|
|
63982
|
+
function staleConnectionMirrors(manifest, cloud) {
|
|
63983
|
+
const actualByName = {
|
|
63984
|
+
slack: cloud.slack_connected,
|
|
63985
|
+
meeting: cloud.meeting_connected,
|
|
63986
|
+
github: cloud.github_connected
|
|
63987
|
+
};
|
|
63988
|
+
const stale = [];
|
|
63989
|
+
for (const name of MIRRORED_CAPABILITIES) {
|
|
63990
|
+
const authored = manifest.capabilities?.[name];
|
|
63991
|
+
const actual = actualByName[name];
|
|
63992
|
+
if (authored === undefined || actual === undefined)
|
|
63993
|
+
continue;
|
|
63994
|
+
if (authored !== actual)
|
|
63995
|
+
stale.push({ name, authored, actual });
|
|
63996
|
+
}
|
|
63997
|
+
return stale;
|
|
63998
|
+
}
|
|
63937
63999
|
function diffAgentConfig(manifest, lock, cloud) {
|
|
63938
64000
|
const unsupported = [];
|
|
63939
64001
|
const machineSupported = cloud.machine_kind !== undefined;
|
|
@@ -63948,43 +64010,95 @@ function diffAgentConfig(manifest, lock, cloud) {
|
|
|
63948
64010
|
const machineLocalChanged = manifest.machine_kind !== undefined && machineSupported && (lock?.machine_kind !== undefined ? manifest.machine_kind !== lock.machine_kind && manifest.machine_kind !== cloud.machine_kind : manifest.machine_kind !== cloud.machine_kind);
|
|
63949
64011
|
const machineCloudChanged = lock?.machine_kind !== undefined && machineSupported && lock.machine_kind !== cloud.machine_kind && manifest.machine_kind !== cloud.machine_kind;
|
|
63950
64012
|
const machineConverged = manifest.machine_kind !== undefined && machineSupported && manifest.machine_kind === cloud.machine_kind && (lock?.machine_kind === undefined || lock.machine_kind !== cloud.machine_kind);
|
|
63951
|
-
|
|
63952
|
-
|
|
63953
|
-
|
|
63954
|
-
|
|
63955
|
-
|
|
63956
|
-
|
|
63957
|
-
|
|
63958
|
-
|
|
63959
|
-
if (localAuthored) {
|
|
63960
|
-
const localValue = manifest.default_model ?? null;
|
|
63961
|
-
if (lockSupported) {
|
|
63962
|
-
const lockValue = lock?.default_model ?? null;
|
|
63963
|
-
const localMoved = localValue !== lockValue;
|
|
63964
|
-
const cloudMoved = cloudValue !== lockValue;
|
|
63965
|
-
defaultModelConflict = localMoved && cloudMoved && localValue !== cloudValue;
|
|
63966
|
-
defaultModelLocalChanged = localMoved && localValue !== cloudValue;
|
|
63967
|
-
defaultModelCloudChanged = cloudMoved && localValue !== cloudValue;
|
|
63968
|
-
defaultModelConverged = localMoved && cloudMoved && localValue === cloudValue;
|
|
63969
|
-
} else {
|
|
63970
|
-
defaultModelLocalChanged = localValue !== cloudValue;
|
|
63971
|
-
defaultModelConverged = localValue === cloudValue;
|
|
63972
|
-
}
|
|
63973
|
-
} else if (lockSupported) {
|
|
63974
|
-
defaultModelCloudChanged = cloudValue !== (lock?.default_model ?? null);
|
|
63975
|
-
}
|
|
64013
|
+
const defaultModel = threeWayField(defaultModelSupported, manifest.default_model, cloud.default_model, lock, "default_model");
|
|
64014
|
+
const memory = threeWayField(hasOwn(cloud, "memory"), manifest.memory, cloud.memory, lock, "memory");
|
|
64015
|
+
const browser = threeWayField(hasOwn(cloud, "browser"), manifest.browser, cloud.browser, lock, "browser");
|
|
64016
|
+
if (manifest.memory !== undefined && !hasOwn(cloud, "memory")) {
|
|
64017
|
+
unsupported.push("memory");
|
|
64018
|
+
}
|
|
64019
|
+
if (manifest.browser !== undefined && !hasOwn(cloud, "browser")) {
|
|
64020
|
+
unsupported.push("browser");
|
|
63976
64021
|
}
|
|
63977
64022
|
return {
|
|
63978
64023
|
unsupported,
|
|
63979
64024
|
machineMismatch,
|
|
63980
64025
|
machineLocalChanged,
|
|
63981
64026
|
machineCloudChanged,
|
|
63982
|
-
defaultModelLocalChanged,
|
|
63983
|
-
defaultModelCloudChanged,
|
|
63984
|
-
defaultModelConflict,
|
|
63985
|
-
|
|
64027
|
+
defaultModelLocalChanged: defaultModel.localChanged,
|
|
64028
|
+
defaultModelCloudChanged: defaultModel.cloudChanged,
|
|
64029
|
+
defaultModelConflict: defaultModel.conflict,
|
|
64030
|
+
memory,
|
|
64031
|
+
browser,
|
|
64032
|
+
baselineConverged: machineConverged || defaultModel.converged || memory.converged || browser.converged
|
|
63986
64033
|
};
|
|
63987
64034
|
}
|
|
64035
|
+
function threeWayField(supported, authored, cloudRaw, lock, key2) {
|
|
64036
|
+
const result2 = {
|
|
64037
|
+
localChanged: false,
|
|
64038
|
+
cloudChanged: false,
|
|
64039
|
+
conflict: false,
|
|
64040
|
+
converged: false
|
|
64041
|
+
};
|
|
64042
|
+
if (!supported)
|
|
64043
|
+
return result2;
|
|
64044
|
+
const cloudValue = cloudRaw ?? null;
|
|
64045
|
+
const lockSupported = hasOwn(lock, key2);
|
|
64046
|
+
const lockValue = lock?.[key2] ?? null;
|
|
64047
|
+
if (authored === undefined) {
|
|
64048
|
+
if (lockSupported)
|
|
64049
|
+
result2.cloudChanged = cloudValue !== lockValue;
|
|
64050
|
+
return result2;
|
|
64051
|
+
}
|
|
64052
|
+
const localValue = authored ?? null;
|
|
64053
|
+
if (!lockSupported) {
|
|
64054
|
+
result2.localChanged = localValue !== cloudValue;
|
|
64055
|
+
result2.converged = localValue === cloudValue;
|
|
64056
|
+
return result2;
|
|
64057
|
+
}
|
|
64058
|
+
const localMoved = localValue !== lockValue;
|
|
64059
|
+
const cloudMoved = cloudValue !== lockValue;
|
|
64060
|
+
result2.conflict = localMoved && cloudMoved && localValue !== cloudValue;
|
|
64061
|
+
result2.localChanged = localMoved && localValue !== cloudValue;
|
|
64062
|
+
result2.cloudChanged = cloudMoved && localValue !== cloudValue;
|
|
64063
|
+
result2.converged = localMoved && cloudMoved && localValue === cloudValue;
|
|
64064
|
+
return result2;
|
|
64065
|
+
}
|
|
64066
|
+
|
|
64067
|
+
// src/core/capability-baseline.ts
|
|
64068
|
+
var CLOUD_KEY = {
|
|
64069
|
+
memory: "memory_enabled",
|
|
64070
|
+
browser: "browser_enabled"
|
|
64071
|
+
};
|
|
64072
|
+
function carryForward(previous, name) {
|
|
64073
|
+
return previous && Object.prototype.hasOwnProperty.call(previous, name) ? { [name]: previous[name] ?? null } : {};
|
|
64074
|
+
}
|
|
64075
|
+
function capabilityBaseline(cloudAgent, previous) {
|
|
64076
|
+
const out = {};
|
|
64077
|
+
for (const name of WRITABLE_CAPABILITIES) {
|
|
64078
|
+
const fromCloud = cloudAgent?.[CLOUD_KEY[name]];
|
|
64079
|
+
if (fromCloud !== undefined) {
|
|
64080
|
+
out[name] = fromCloud;
|
|
64081
|
+
continue;
|
|
64082
|
+
}
|
|
64083
|
+
Object.assign(out, carryForward(previous, name));
|
|
64084
|
+
}
|
|
64085
|
+
return out;
|
|
64086
|
+
}
|
|
64087
|
+
function capabilityBaselineAfterPush(cloudAgent, previous, diff2) {
|
|
64088
|
+
const out = {};
|
|
64089
|
+
for (const name of WRITABLE_CAPABILITIES) {
|
|
64090
|
+
if (diff2[name].cloudChanged && !diff2[name].localChanged) {
|
|
64091
|
+
Object.assign(out, carryForward(previous, name));
|
|
64092
|
+
continue;
|
|
64093
|
+
}
|
|
64094
|
+
const fromCloud = cloudAgent[CLOUD_KEY[name]];
|
|
64095
|
+
if (fromCloud !== undefined)
|
|
64096
|
+
out[name] = fromCloud;
|
|
64097
|
+
else
|
|
64098
|
+
Object.assign(out, carryForward(previous, name));
|
|
64099
|
+
}
|
|
64100
|
+
return out;
|
|
64101
|
+
}
|
|
63988
64102
|
|
|
63989
64103
|
// src/core/secrets-env.ts
|
|
63990
64104
|
import path78 from "node:path";
|
|
@@ -64650,7 +64764,8 @@ async function runAgentPull(cwd2, args) {
|
|
|
64650
64764
|
tagline: cloudAgent.tagline,
|
|
64651
64765
|
...cloudAgent.entrypoint ? { entrypoint: cloudAgent.entrypoint.trim() } : {},
|
|
64652
64766
|
...cloudAgent.machine_kind ? { machine_kind: cloudAgent.machine_kind } : lock?.agentMeta?.machine_kind ? { machine_kind: lock.agentMeta.machine_kind } : {},
|
|
64653
|
-
...Object.prototype.hasOwnProperty.call(cloudAgent, "default_model") ? { default_model: cloudAgent.default_model ?? null } : Object.prototype.hasOwnProperty.call(lock?.agentMeta ?? {}, "default_model") ? { default_model: lock.agentMeta.default_model ?? null } : {}
|
|
64767
|
+
...Object.prototype.hasOwnProperty.call(cloudAgent, "default_model") ? { default_model: cloudAgent.default_model ?? null } : Object.prototype.hasOwnProperty.call(lock?.agentMeta ?? {}, "default_model") ? { default_model: lock.agentMeta.default_model ?? null } : {},
|
|
64768
|
+
...capabilityBaseline(cloudAgent, lock?.agentMeta)
|
|
64654
64769
|
}
|
|
64655
64770
|
};
|
|
64656
64771
|
writeSyncState(cwd2, newState);
|
|
@@ -64941,7 +65056,8 @@ function buildLockFromCloud(agent_id, cloud, prev, cloudAgent) {
|
|
|
64941
65056
|
tagline: cloudAgent.tagline,
|
|
64942
65057
|
...cloudAgent.entrypoint ? { entrypoint: cloudAgent.entrypoint.trim() } : {},
|
|
64943
65058
|
...cloudAgent.machine_kind ? { machine_kind: cloudAgent.machine_kind } : prev?.agentMeta?.machine_kind ? { machine_kind: prev.agentMeta.machine_kind } : {},
|
|
64944
|
-
...Object.prototype.hasOwnProperty.call(cloudAgent, "default_model") ? { default_model: cloudAgent.default_model ?? null } : Object.prototype.hasOwnProperty.call(prev?.agentMeta ?? {}, "default_model") ? { default_model: prev.agentMeta.default_model ?? null } : {}
|
|
65059
|
+
...Object.prototype.hasOwnProperty.call(cloudAgent, "default_model") ? { default_model: cloudAgent.default_model ?? null } : Object.prototype.hasOwnProperty.call(prev?.agentMeta ?? {}, "default_model") ? { default_model: prev.agentMeta.default_model ?? null } : {},
|
|
65060
|
+
...capabilityBaseline(cloudAgent, prev?.agentMeta)
|
|
64945
65061
|
} : prev?.agentMeta
|
|
64946
65062
|
};
|
|
64947
65063
|
}
|
|
@@ -65289,13 +65405,25 @@ async function runAgentPush(cwd2, args) {
|
|
|
65289
65405
|
lock: lock?.components ?? [],
|
|
65290
65406
|
cloud: cloud.components
|
|
65291
65407
|
});
|
|
65292
|
-
const config = diffAgentConfig(manifest, lock?.agentMeta, cloudAgent);
|
|
65408
|
+
const config = diffAgentConfig(manifestConfigState(manifest), lock?.agentMeta, cloudConfigState(cloudAgent));
|
|
65293
65409
|
if (config.unsupported.length > 0) {
|
|
65294
65410
|
f2.error(`This control plane does not support declarative ${config.unsupported.join(" / ")} config.`);
|
|
65295
65411
|
f2.info(`Use the MAS control plane, then run ${import_picocolors28.default.cyan("brainbase agent pull")} before retrying.`);
|
|
65296
65412
|
process.exitCode = 1;
|
|
65297
65413
|
return;
|
|
65298
65414
|
}
|
|
65415
|
+
const staleMirrors = staleConnectionMirrors(manifest, cloudAgent);
|
|
65416
|
+
if (staleMirrors.length > 0) {
|
|
65417
|
+
f2.error(`This manifest's connection state is out of date: ${staleMirrors.map((m3) => `${m3.name} says ${m3.authored}, actually ${m3.actual}`).join("; ")}.`);
|
|
65418
|
+
f2.info(`Run ${import_picocolors28.default.cyan("brainbase agent pull")} to refresh it. These are reported by the cloud, not set from the manifest.`);
|
|
65419
|
+
for (const m3 of staleMirrors) {
|
|
65420
|
+
if (!m3.actual) {
|
|
65421
|
+
f2.info(`To actually connect ${m3.name}, run ${import_picocolors28.default.cyan(`brainbase agent connect ${m3.name}`)}.`);
|
|
65422
|
+
}
|
|
65423
|
+
}
|
|
65424
|
+
process.exitCode = 1;
|
|
65425
|
+
return;
|
|
65426
|
+
}
|
|
65299
65427
|
if (config.machineMismatch) {
|
|
65300
65428
|
if (config.machineCloudChanged && !config.machineLocalChanged) {
|
|
65301
65429
|
f2.error("Cannot push: machine_kind changed on the cloud.");
|
|
@@ -65316,6 +65444,17 @@ async function runAgentPush(cwd2, args) {
|
|
|
65316
65444
|
if (config.defaultModelConflict && args.force) {
|
|
65317
65445
|
f2.warn(`${import_picocolors28.default.yellow("--force")}: overwriting the cloud default_model with the local value.`);
|
|
65318
65446
|
}
|
|
65447
|
+
const conflictedCapabilities = WRITABLE_CAPABILITIES.filter((name) => config[name].conflict);
|
|
65448
|
+
if (conflictedCapabilities.length > 0) {
|
|
65449
|
+
const label = conflictedCapabilities.map((name) => `capabilities.${name}`).join(" and ");
|
|
65450
|
+
if (!args.force) {
|
|
65451
|
+
f2.error(`Cannot push: ${label} changed both locally and on the cloud.`);
|
|
65452
|
+
f2.info(`Run ${import_picocolors28.default.cyan("brainbase agent pull")} first to reconcile, or ${import_picocolors28.default.cyan("brainbase agent push --force")} to keep the local value.`);
|
|
65453
|
+
process.exitCode = 1;
|
|
65454
|
+
return;
|
|
65455
|
+
}
|
|
65456
|
+
f2.warn(`${import_picocolors28.default.yellow("--force")}: overwriting the cloud ${label} with the local value.`);
|
|
65457
|
+
}
|
|
65319
65458
|
const registryRefs = new Map;
|
|
65320
65459
|
for (const entry of manifest.skills) {
|
|
65321
65460
|
try {
|
|
@@ -65455,7 +65594,7 @@ async function runAgentPush(cwd2, args) {
|
|
|
65455
65594
|
f2.warn(`Cloud runtime config changed since the last sync. Run ${import_picocolors28.default.cyan("brainbase agent pull")} to accept it locally.`);
|
|
65456
65595
|
}
|
|
65457
65596
|
const shouldPushManifest = meta.localChanged || entrypointChanged || toSend.length > 0;
|
|
65458
|
-
const shouldUpdateAgent = meta.localChanged || entrypointChanged || config.defaultModelLocalChanged;
|
|
65597
|
+
const shouldUpdateAgent = meta.localChanged || entrypointChanged || config.defaultModelLocalChanged || config.memory.localChanged || config.browser.localChanged;
|
|
65459
65598
|
const hasAgentChanges = shouldPushManifest || shouldUpdateAgent;
|
|
65460
65599
|
const outgoing = hasAgentChanges ? await buildOutgoingComponents(cwd2, manifest, cloud, resolvedVersions) : null;
|
|
65461
65600
|
if (hasAgentChanges && outgoing === null) {
|
|
@@ -65499,7 +65638,7 @@ async function runAgentPush(cwd2, args) {
|
|
|
65499
65638
|
});
|
|
65500
65639
|
}
|
|
65501
65640
|
if (!hasAgentChanges && !secretPlan) {
|
|
65502
|
-
if (config.defaultModelCloudChanged || config.machineCloudChanged) {
|
|
65641
|
+
if (config.defaultModelCloudChanged || config.machineCloudChanged || config.memory.cloudChanged || config.browser.cloudChanged) {
|
|
65503
65642
|
f2.info("Nothing local to push; cloud runtime config is awaiting pull.");
|
|
65504
65643
|
return;
|
|
65505
65644
|
}
|
|
@@ -65571,7 +65710,7 @@ async function runAgentPush(cwd2, args) {
|
|
|
65571
65710
|
$e(`Pushed secrets for ${manifest.agent.name}.`);
|
|
65572
65711
|
return;
|
|
65573
65712
|
}
|
|
65574
|
-
if (meta.localChanged || entrypointChanged || config.defaultModelLocalChanged) {
|
|
65713
|
+
if (meta.localChanged || entrypointChanged || config.defaultModelLocalChanged || config.memory.localChanged || config.browser.localChanged) {
|
|
65575
65714
|
const metaSpinner = de();
|
|
65576
65715
|
metaSpinner.start("Updating agent config…");
|
|
65577
65716
|
try {
|
|
@@ -65586,6 +65725,12 @@ async function runAgentPush(cwd2, args) {
|
|
|
65586
65725
|
if (config.defaultModelLocalChanged) {
|
|
65587
65726
|
update2.default_model = manifest.default_model ?? null;
|
|
65588
65727
|
}
|
|
65728
|
+
if (config.memory.localChanged) {
|
|
65729
|
+
update2.memory_enabled = manifest.capabilities?.memory;
|
|
65730
|
+
}
|
|
65731
|
+
if (config.browser.localChanged) {
|
|
65732
|
+
update2.browser_enabled = manifest.capabilities?.browser;
|
|
65733
|
+
}
|
|
65589
65734
|
cloudAgent = await api.updateAgent(agentId, update2);
|
|
65590
65735
|
metaSpinner.stop("Agent config updated.");
|
|
65591
65736
|
} catch (err) {
|
|
@@ -65702,7 +65847,8 @@ function buildAgentMetaAfterPush({
|
|
|
65702
65847
|
tagline: manifest.agent.tagline,
|
|
65703
65848
|
entrypoint: resolvedEntrypoint !== undefined ? resolvedEntrypoint.trim() : lock?.agentMeta?.entrypoint,
|
|
65704
65849
|
...config.machineCloudChanged ? lock?.agentMeta?.machine_kind ? { machine_kind: lock.agentMeta.machine_kind } : {} : cloudAgent.machine_kind ? { machine_kind: cloudAgent.machine_kind } : lock?.agentMeta?.machine_kind ? { machine_kind: lock.agentMeta.machine_kind } : {},
|
|
65705
|
-
...config.defaultModelCloudChanged && !config.defaultModelLocalChanged ? Object.prototype.hasOwnProperty.call(lock?.agentMeta ?? {}, "default_model") ? { default_model: lock.agentMeta.default_model ?? null } : {} : Object.prototype.hasOwnProperty.call(cloudAgent, "default_model") ? { default_model: cloudAgent.default_model ?? null } : Object.prototype.hasOwnProperty.call(lock?.agentMeta ?? {}, "default_model") ? { default_model: lock.agentMeta.default_model ?? null } : {}
|
|
65850
|
+
...config.defaultModelCloudChanged && !config.defaultModelLocalChanged ? Object.prototype.hasOwnProperty.call(lock?.agentMeta ?? {}, "default_model") ? { default_model: lock.agentMeta.default_model ?? null } : {} : Object.prototype.hasOwnProperty.call(cloudAgent, "default_model") ? { default_model: cloudAgent.default_model ?? null } : Object.prototype.hasOwnProperty.call(lock?.agentMeta ?? {}, "default_model") ? { default_model: lock.agentMeta.default_model ?? null } : {},
|
|
65851
|
+
...capabilityBaselineAfterPush(cloudAgent, lock?.agentMeta, config)
|
|
65706
65852
|
};
|
|
65707
65853
|
}
|
|
65708
65854
|
async function planSecretPush(cwd2, agentId) {
|
|
@@ -65751,6 +65897,9 @@ function handleApiError3(err) {
|
|
|
65751
65897
|
// src/cli/agent-status.ts
|
|
65752
65898
|
import path81 from "node:path";
|
|
65753
65899
|
var import_picocolors29 = __toESM(require_picocolors(), 1);
|
|
65900
|
+
function capabilityDrifted(field) {
|
|
65901
|
+
return field.localChanged || field.cloudChanged || field.conflict;
|
|
65902
|
+
}
|
|
65754
65903
|
async function runAgentStatus(cwd2, args = {}) {
|
|
65755
65904
|
const json = args.json === true;
|
|
65756
65905
|
if (!json)
|
|
@@ -65818,7 +65967,7 @@ async function runAgentStatus(cwd2, args = {}) {
|
|
|
65818
65967
|
cloud: cloud.components
|
|
65819
65968
|
});
|
|
65820
65969
|
const meta = diffAgentMeta(manifest.agent, lock?.agentMeta, cloudAgent);
|
|
65821
|
-
const config = diffAgentConfig(manifest, lock?.agentMeta, cloudAgent);
|
|
65970
|
+
const config = diffAgentConfig(manifestConfigState(manifest), lock?.agentMeta, cloudConfigState(cloudAgent));
|
|
65822
65971
|
const toPush = [];
|
|
65823
65972
|
const toPull = [];
|
|
65824
65973
|
const conflicts = [];
|
|
@@ -65865,7 +66014,7 @@ async function runAgentStatus(cwd2, args = {}) {
|
|
|
65865
66014
|
}
|
|
65866
66015
|
const componentsDrifted = conflicts.length > 0 || toPush.length > 0 || toPull.length > 0;
|
|
65867
66016
|
const metaDrifted = meta.localChanged || meta.cloudChanged;
|
|
65868
|
-
const configDrifted = config.unsupported.length > 0 || config.machineMismatch || config.machineCloudChanged || config.defaultModelLocalChanged || config.defaultModelCloudChanged;
|
|
66017
|
+
const configDrifted = config.unsupported.length > 0 || config.machineMismatch || config.machineCloudChanged || config.defaultModelLocalChanged || config.defaultModelCloudChanged || capabilityDrifted(config.memory) || capabilityDrifted(config.browser);
|
|
65869
66018
|
const secretsDrifted = secretDrift.localOnly.length > 0 || secretDrift.cloudOnly.length > 0 || secretDrift.changed.length > 0;
|
|
65870
66019
|
const everythingInSync = !componentsDrifted && !metaDrifted && !configDrifted && !secretsDrifted;
|
|
65871
66020
|
const unchecked = secretsChecked ? [] : [{ signal: "secrets", reason: secretsUncheckedReason }];
|
|
@@ -65883,7 +66032,9 @@ async function runAgentStatus(cwd2, args = {}) {
|
|
|
65883
66032
|
machineCloudChanged: config.machineCloudChanged,
|
|
65884
66033
|
defaultModelLocalChanged: config.defaultModelLocalChanged,
|
|
65885
66034
|
defaultModelCloudChanged: config.defaultModelCloudChanged,
|
|
65886
|
-
defaultModelConflict: config.defaultModelConflict
|
|
66035
|
+
defaultModelConflict: config.defaultModelConflict,
|
|
66036
|
+
memory: config.memory,
|
|
66037
|
+
browser: config.browser
|
|
65887
66038
|
},
|
|
65888
66039
|
secrets: secretsChecked ? {
|
|
65889
66040
|
localOnly: secretDrift.localOnly,
|
|
@@ -65944,6 +66095,19 @@ async function runAgentStatus(cwd2, args = {}) {
|
|
|
65944
66095
|
lines.push(` ${import_picocolors29.default.cyan("← pull")} default_model changed on cloud`);
|
|
65945
66096
|
}
|
|
65946
66097
|
}
|
|
66098
|
+
for (const name of WRITABLE_CAPABILITIES) {
|
|
66099
|
+
const field = config[name];
|
|
66100
|
+
if (field.conflict) {
|
|
66101
|
+
lines.push(` ${import_picocolors29.default.red("! conflict")} capabilities.${name} changed locally and on cloud`);
|
|
66102
|
+
continue;
|
|
66103
|
+
}
|
|
66104
|
+
if (field.localChanged) {
|
|
66105
|
+
lines.push(` ${import_picocolors29.default.yellow("→ push")} capabilities.${name} edited locally`);
|
|
66106
|
+
}
|
|
66107
|
+
if (field.cloudChanged) {
|
|
66108
|
+
lines.push(` ${import_picocolors29.default.cyan("← pull")} capabilities.${name} changed on cloud`);
|
|
66109
|
+
}
|
|
66110
|
+
}
|
|
65947
66111
|
lines.push("");
|
|
65948
66112
|
}
|
|
65949
66113
|
if (secretsDrifted || !secretsChecked) {
|
|
@@ -66065,7 +66229,6 @@ function formatExport(shell, key2, value) {
|
|
|
66065
66229
|
}
|
|
66066
66230
|
|
|
66067
66231
|
// src/cli/agent-create.ts
|
|
66068
|
-
import path82 from "node:path";
|
|
66069
66232
|
var import_picocolors32 = __toESM(require_picocolors(), 1);
|
|
66070
66233
|
|
|
66071
66234
|
// src/ui/box.ts
|
|
@@ -66258,6 +66421,153 @@ async function listTeamsPerOrg(orgs) {
|
|
|
66258
66421
|
return { entries, resolved, failures };
|
|
66259
66422
|
}
|
|
66260
66423
|
|
|
66424
|
+
// src/core/agent-scaffold.ts
|
|
66425
|
+
var import_yaml4 = __toESM(require_dist(), 1);
|
|
66426
|
+
import path82 from "node:path";
|
|
66427
|
+
var STARTER_TAGLINE = "A starter agent.";
|
|
66428
|
+
var FALLBACK_NAME = "my-agent";
|
|
66429
|
+
var FALLBACK_HARNESS = "claude-code";
|
|
66430
|
+
function isKnownHarness(id) {
|
|
66431
|
+
return adapters.some((a3) => a3.id === id);
|
|
66432
|
+
}
|
|
66433
|
+
function knownHarnessIds() {
|
|
66434
|
+
return adapters.map((a3) => a3.id);
|
|
66435
|
+
}
|
|
66436
|
+
async function resolveScaffoldHarness(cwd2, flag) {
|
|
66437
|
+
const forced = flag?.trim();
|
|
66438
|
+
if (forced)
|
|
66439
|
+
return { id: normalizeHarnessId(forced), source: "flag" };
|
|
66440
|
+
const detections = await detectHarnesses(cwd2);
|
|
66441
|
+
const inProject = detections.find((d3) => d3.detection.hasProject);
|
|
66442
|
+
if (inProject)
|
|
66443
|
+
return { id: inProject.adapter.id, source: "project" };
|
|
66444
|
+
const installed = detections.find((d3) => d3.detection.detected);
|
|
66445
|
+
if (installed)
|
|
66446
|
+
return { id: installed.adapter.id, source: "installed" };
|
|
66447
|
+
return { id: FALLBACK_HARNESS, source: "default" };
|
|
66448
|
+
}
|
|
66449
|
+
function describeHarnessSource(source) {
|
|
66450
|
+
switch (source) {
|
|
66451
|
+
case "flag":
|
|
66452
|
+
return "from --harness";
|
|
66453
|
+
case "project":
|
|
66454
|
+
return "detected in this folder";
|
|
66455
|
+
case "installed":
|
|
66456
|
+
return "installed on this machine";
|
|
66457
|
+
case "default":
|
|
66458
|
+
return "nothing detected — pass --harness to change it";
|
|
66459
|
+
default: {
|
|
66460
|
+
const never = source;
|
|
66461
|
+
return never;
|
|
66462
|
+
}
|
|
66463
|
+
}
|
|
66464
|
+
}
|
|
66465
|
+
function singleLine(value) {
|
|
66466
|
+
return (value ?? "").replace(/\s+/g, " ").trim();
|
|
66467
|
+
}
|
|
66468
|
+
function resolveScaffoldName(cwd2, flag) {
|
|
66469
|
+
return singleLine(flag) || singleLine(path82.basename(path82.resolve(cwd2))) || FALLBACK_NAME;
|
|
66470
|
+
}
|
|
66471
|
+
function harnessDisplayName(id) {
|
|
66472
|
+
try {
|
|
66473
|
+
return getAdapter(id).displayName;
|
|
66474
|
+
} catch {
|
|
66475
|
+
return id;
|
|
66476
|
+
}
|
|
66477
|
+
}
|
|
66478
|
+
function starterInstructions(harnessId) {
|
|
66479
|
+
return `You are a helpful ${harnessDisplayName(harnessId)} agent.`;
|
|
66480
|
+
}
|
|
66481
|
+
function buildStarterManifest(seed) {
|
|
66482
|
+
return {
|
|
66483
|
+
schema: 1,
|
|
66484
|
+
harness: seed.harness,
|
|
66485
|
+
agent: {
|
|
66486
|
+
name: seed.name,
|
|
66487
|
+
tagline: singleLine(seed.tagline) || STARTER_TAGLINE
|
|
66488
|
+
},
|
|
66489
|
+
instructions: { text: starterInstructions(seed.harness) }
|
|
66490
|
+
};
|
|
66491
|
+
}
|
|
66492
|
+
function scalar(value) {
|
|
66493
|
+
return import_yaml4.default.stringify(value, { lineWidth: 0 }).trimEnd();
|
|
66494
|
+
}
|
|
66495
|
+
function renderFullTemplate(seed) {
|
|
66496
|
+
return `# ${AGENT_MANIFEST_FILE} — declarative agent manifest.
|
|
66497
|
+
# Committed to source control. Edit by hand, then \`brainbase agent push\`.
|
|
66498
|
+
#
|
|
66499
|
+
# Only \`schema\` and \`agent.name\` are required — uncomment the blocks you
|
|
66500
|
+
# need and delete the rest. Full reference:
|
|
66501
|
+
# https://docs.brainbaselabs.com/cli/reference/agent-manifest
|
|
66502
|
+
|
|
66503
|
+
schema: 1
|
|
66504
|
+
|
|
66505
|
+
# Which harness runs this agent locally. One of:
|
|
66506
|
+
# ${knownHarnessIds().join(", ")}.
|
|
66507
|
+
harness: ${scalar(seed.harness)}
|
|
66508
|
+
|
|
66509
|
+
# Sandbox provider, applied when \`brainbase agent create\` claims this file.
|
|
66510
|
+
# Immutable afterwards — recreate the agent to change it.
|
|
66511
|
+
# machine_kind: daytona
|
|
66512
|
+
|
|
66513
|
+
# Agent-level model override. Omit it to leave the cloud value alone, or set
|
|
66514
|
+
# null to clear an override that is already set.
|
|
66515
|
+
# default_model: openai/gpt-5.6-terra
|
|
66516
|
+
|
|
66517
|
+
agent:
|
|
66518
|
+
name: ${scalar(seed.name)}
|
|
66519
|
+
tagline: ${scalar(singleLine(seed.tagline) || STARTER_TAGLINE)}
|
|
66520
|
+
|
|
66521
|
+
# The agent's system prompt. Exactly one of \`text\` or \`file\`.
|
|
66522
|
+
instructions:
|
|
66523
|
+
text: ${scalar(starterInstructions(seed.harness))}
|
|
66524
|
+
# file: ./.brainbase/instructions.md
|
|
66525
|
+
|
|
66526
|
+
# Bash that runs in the sandbox before the agent starts. Exactly one of
|
|
66527
|
+
# \`commands\`, \`file\`, or \`text\`.
|
|
66528
|
+
# entrypoint:
|
|
66529
|
+
# commands:
|
|
66530
|
+
# - npm install
|
|
66531
|
+
|
|
66532
|
+
# Named procedures the agent can follow. Each \`content\` takes exactly one of
|
|
66533
|
+
# \`text\` or \`file\`.
|
|
66534
|
+
# playbooks:
|
|
66535
|
+
# - title: Release checklist
|
|
66536
|
+
# description: Steps to cut a release
|
|
66537
|
+
# content:
|
|
66538
|
+
# file: ./playbooks/release.md
|
|
66539
|
+
|
|
66540
|
+
# Skills to install. A registry ref pins an exact version or omits it to track
|
|
66541
|
+
# the latest; ranges are not supported. Local paths start with \`./\`.
|
|
66542
|
+
# skills:
|
|
66543
|
+
# - source: registry:brainbase/changelog@1.0.0
|
|
66544
|
+
# - source: ./skills/local-linter
|
|
66545
|
+
|
|
66546
|
+
# MCP servers. Each entry needs either \`url\` or \`command\`. Keep tokens out
|
|
66547
|
+
# of this file — put them in the gitignored \`.brainbase/secrets.env\`.
|
|
66548
|
+
# mcp:
|
|
66549
|
+
# - name: github
|
|
66550
|
+
# url: https://api.githubcopilot.com/mcp/
|
|
66551
|
+
# is_enabled: true
|
|
66552
|
+
|
|
66553
|
+
# Criteria a judge scores every completed turn against.
|
|
66554
|
+
# evals:
|
|
66555
|
+
# - slug: answered-the-question
|
|
66556
|
+
# criteria: The reply answers what was asked without inventing facts.
|
|
66557
|
+
|
|
66558
|
+
# Not shown above: \`capabilities\` is written by \`brainbase agent pull\` from
|
|
66559
|
+
# the cloud and never pushed, and \`commands\` / \`hooks\` / \`files\` parse but
|
|
66560
|
+
# no command syncs them yet — \`agent push\` refuses them rather than dropping
|
|
66561
|
+
# them silently.
|
|
66562
|
+
`;
|
|
66563
|
+
}
|
|
66564
|
+
function writeStarterManifest(cwd2, seed, opts = {}) {
|
|
66565
|
+
const body = opts.full ? renderFullTemplate(seed) : renderManifest(buildStarterManifest(seed));
|
|
66566
|
+
const manifest = parseManifest(body);
|
|
66567
|
+
writeManifestText(cwd2, body);
|
|
66568
|
+
return manifest;
|
|
66569
|
+
}
|
|
66570
|
+
|
|
66261
66571
|
// src/cli/agent-create.ts
|
|
66262
66572
|
async function runAgentCreate(cwd2, args) {
|
|
66263
66573
|
banner("agent create — claim a brainbase.agent.yaml and link this folder");
|
|
@@ -66495,7 +66805,8 @@ async function runAgentCreate(cwd2, args) {
|
|
|
66495
66805
|
tagline: agent.tagline,
|
|
66496
66806
|
...resolvedEntrypoint ? { entrypoint: resolvedEntrypoint.trim() } : {},
|
|
66497
66807
|
...agent.machine_kind ? { machine_kind: agent.machine_kind } : {},
|
|
66498
|
-
...Object.prototype.hasOwnProperty.call(agent, "default_model") ? { default_model: agent.default_model ?? null } : {}
|
|
66808
|
+
...Object.prototype.hasOwnProperty.call(agent, "default_model") ? { default_model: agent.default_model ?? null } : {},
|
|
66809
|
+
...capabilityBaseline(agent, undefined)
|
|
66499
66810
|
}
|
|
66500
66811
|
};
|
|
66501
66812
|
writeSyncState(cwd2, state);
|
|
@@ -66528,12 +66839,9 @@ async function loadOrScaffoldManifest(cwd2, args) {
|
|
|
66528
66839
|
}
|
|
66529
66840
|
}
|
|
66530
66841
|
f2.warn(`No ${import_picocolors32.default.bold(AGENT_MANIFEST_FILE)} here.`);
|
|
66531
|
-
if (!args.yes) {
|
|
66532
|
-
if (!isInteractive()) {
|
|
66533
|
-
throw new NonInteractiveError(`No ${AGENT_MANIFEST_FILE} here. Create one first, or re-run with --yes to scaffold a minimal one.`);
|
|
66534
|
-
}
|
|
66842
|
+
if (!autoProceed(args.yes)) {
|
|
66535
66843
|
const ans = await se({
|
|
66536
|
-
message: `Scaffold a
|
|
66844
|
+
message: `Scaffold a starter ${import_picocolors32.default.bold(AGENT_MANIFEST_FILE)} and continue?`,
|
|
66537
66845
|
initialValue: true
|
|
66538
66846
|
});
|
|
66539
66847
|
if (!ensureNotCancelled(ans)) {
|
|
@@ -66541,25 +66849,21 @@ async function loadOrScaffoldManifest(cwd2, args) {
|
|
|
66541
66849
|
return null;
|
|
66542
66850
|
}
|
|
66543
66851
|
}
|
|
66544
|
-
const
|
|
66545
|
-
const seedHarness = args.harness ? normalizeHarnessId(args.harness) : undefined;
|
|
66546
|
-
const scaffold = {
|
|
66547
|
-
schema: 1,
|
|
66548
|
-
...seedHarness ? { harness: seedHarness } : {},
|
|
66549
|
-
agent: { name: seedName, ...args.tagline ? { tagline: args.tagline } : {} },
|
|
66550
|
-
playbooks: [],
|
|
66551
|
-
evals: [],
|
|
66552
|
-
skills: [],
|
|
66553
|
-
mcp: []
|
|
66554
|
-
};
|
|
66852
|
+
const harness = await resolveScaffoldHarness(cwd2, args.harness);
|
|
66555
66853
|
try {
|
|
66556
|
-
|
|
66854
|
+
const scaffold = writeStarterManifest(cwd2, {
|
|
66855
|
+
name: resolveScaffoldName(cwd2, args.name),
|
|
66856
|
+
harness: harness.id,
|
|
66857
|
+
tagline: args.tagline
|
|
66858
|
+
});
|
|
66859
|
+
f2.info(`harness ${import_picocolors32.default.bold(harness.id)} ${import_picocolors32.default.dim(`(${describeHarnessSource(harness.source)})`)}`);
|
|
66557
66860
|
f2.info(`Wrote ${import_picocolors32.default.bold(AGENT_MANIFEST_FILE)}.`);
|
|
66861
|
+
return scaffold;
|
|
66558
66862
|
} catch (err) {
|
|
66559
66863
|
f2.error(`Failed to write manifest: ${err.message}`);
|
|
66864
|
+
process.exitCode = 1;
|
|
66560
66865
|
return null;
|
|
66561
66866
|
}
|
|
66562
|
-
return scaffold;
|
|
66563
66867
|
}
|
|
66564
66868
|
async function pickHarness2(cwd2) {
|
|
66565
66869
|
const detections = await detectHarnesses(cwd2);
|
|
@@ -66591,8 +66895,83 @@ function handleApiError4(err) {
|
|
|
66591
66895
|
$e("Aborted.");
|
|
66592
66896
|
}
|
|
66593
66897
|
|
|
66594
|
-
// src/cli/agent-
|
|
66898
|
+
// src/cli/agent-init.ts
|
|
66899
|
+
import path83 from "node:path";
|
|
66595
66900
|
var import_picocolors33 = __toESM(require_picocolors(), 1);
|
|
66901
|
+
function emit(result2) {
|
|
66902
|
+
console.log(JSON.stringify(result2, null, 2));
|
|
66903
|
+
}
|
|
66904
|
+
async function runAgentInit(cwd2, args = {}) {
|
|
66905
|
+
const json = args.json === true;
|
|
66906
|
+
const target = manifestPath(cwd2);
|
|
66907
|
+
if (args.minimal && args.full) {
|
|
66908
|
+
return refuse(json, {
|
|
66909
|
+
path: target,
|
|
66910
|
+
created: false,
|
|
66911
|
+
reason: "conflicting-flags",
|
|
66912
|
+
message: `Pass either ${import_picocolors33.default.cyan("--minimal")} or ${import_picocolors33.default.cyan("--full")}, not both.`
|
|
66913
|
+
});
|
|
66914
|
+
}
|
|
66915
|
+
const existing = existingManifestPath(cwd2);
|
|
66916
|
+
if (existing && !args.force) {
|
|
66917
|
+
return refuse(json, {
|
|
66918
|
+
path: existing,
|
|
66919
|
+
created: false,
|
|
66920
|
+
reason: "manifest-exists",
|
|
66921
|
+
message: `${import_picocolors33.default.bold(path83.basename(existing))} already exists here. Edit it, or pass ${import_picocolors33.default.cyan("--force")} to overwrite it.`
|
|
66922
|
+
});
|
|
66923
|
+
}
|
|
66924
|
+
const harness = await resolveScaffoldHarness(cwd2, args.harness);
|
|
66925
|
+
if (!isKnownHarness(harness.id)) {
|
|
66926
|
+
return refuse(json, {
|
|
66927
|
+
path: target,
|
|
66928
|
+
created: false,
|
|
66929
|
+
reason: "unknown-harness",
|
|
66930
|
+
message: `Unknown harness ${import_picocolors33.default.bold(harness.id)}. Pick one of: ${knownHarnessIds().join(", ")}.`
|
|
66931
|
+
});
|
|
66932
|
+
}
|
|
66933
|
+
const name = resolveScaffoldName(cwd2, args.name);
|
|
66934
|
+
const template2 = args.full ? "full" : "minimal";
|
|
66935
|
+
if (!json)
|
|
66936
|
+
banner("agent init — write a starter brainbase.agent.yaml");
|
|
66937
|
+
try {
|
|
66938
|
+
writeStarterManifest(cwd2, { name, harness: harness.id, tagline: args.tagline }, { full: args.full });
|
|
66939
|
+
} catch (err) {
|
|
66940
|
+
console.error(import_picocolors33.default.red(`Failed to write ${AGENT_MANIFEST_FILE}: ${err.message}`));
|
|
66941
|
+
process.exitCode = 1;
|
|
66942
|
+
return;
|
|
66943
|
+
}
|
|
66944
|
+
if (json) {
|
|
66945
|
+
emit({
|
|
66946
|
+
path: target,
|
|
66947
|
+
created: true,
|
|
66948
|
+
name,
|
|
66949
|
+
harness: harness.id,
|
|
66950
|
+
harness_source: harness.source,
|
|
66951
|
+
template: template2
|
|
66952
|
+
});
|
|
66953
|
+
return;
|
|
66954
|
+
}
|
|
66955
|
+
f2.info(`harness ${import_picocolors33.default.bold(harness.id)} ${import_picocolors33.default.dim(`(${describeHarnessSource(harness.source)})`)}`);
|
|
66956
|
+
f2.success(`Wrote ${import_picocolors33.default.bold(AGENT_MANIFEST_FILE)}${existing ? " (overwritten)" : ""}.`);
|
|
66957
|
+
console.log();
|
|
66958
|
+
console.log(tip(`Edit it, then run ${import_picocolors33.default.cyan("brainbase agent create")} ${import_picocolors33.default.dim("— creates the cloud agent and stamps its id back into the file.")}`));
|
|
66959
|
+
console.log();
|
|
66960
|
+
}
|
|
66961
|
+
function refuse(json, outcome) {
|
|
66962
|
+
const { message, ...result2 } = outcome;
|
|
66963
|
+
process.exitCode = 1;
|
|
66964
|
+
if (json) {
|
|
66965
|
+
emit(result2);
|
|
66966
|
+
return;
|
|
66967
|
+
}
|
|
66968
|
+
console.error(`
|
|
66969
|
+
${import_picocolors33.default.red(message)}
|
|
66970
|
+
`);
|
|
66971
|
+
}
|
|
66972
|
+
|
|
66973
|
+
// src/cli/agent-list.ts
|
|
66974
|
+
var import_picocolors34 = __toESM(require_picocolors(), 1);
|
|
66596
66975
|
async function runAgentList(args) {
|
|
66597
66976
|
if (!args.json)
|
|
66598
66977
|
banner("agent list — agents in this team");
|
|
@@ -66612,27 +66991,27 @@ async function runAgentList(args) {
|
|
|
66612
66991
|
function formatAgentList(agents, labels) {
|
|
66613
66992
|
const lines = [""];
|
|
66614
66993
|
if (agents.length === 0) {
|
|
66615
|
-
lines.push(` ${
|
|
66994
|
+
lines.push(` ${import_picocolors34.default.dim(`No agents in ${labels.orgName} → ${labels.teamName} yet.`)}`, "", ` ${import_picocolors34.default.dim("create one with")} ${import_picocolors34.default.cyan("brainbase agent create")}`, "");
|
|
66616
66995
|
return lines.join(`
|
|
66617
66996
|
`);
|
|
66618
66997
|
}
|
|
66619
66998
|
for (const agent of agents) {
|
|
66620
|
-
lines.push(` ${
|
|
66999
|
+
lines.push(` ${import_picocolors34.default.bold(agent.name)} ${import_picocolors34.default.dim(agent.slug)}`);
|
|
66621
67000
|
if (agent.tagline)
|
|
66622
|
-
lines.push(` ${
|
|
67001
|
+
lines.push(` ${import_picocolors34.default.dim(agent.tagline)}`);
|
|
66623
67002
|
const meta = [agent.harness, agent.machine_kind, agent.default_model].filter((value) => !!value).join(" · ");
|
|
66624
67003
|
if (meta)
|
|
66625
|
-
lines.push(` ${
|
|
66626
|
-
lines.push(` ${
|
|
67004
|
+
lines.push(` ${import_picocolors34.default.dim(meta)}`);
|
|
67005
|
+
lines.push(` ${import_picocolors34.default.dim(agent.id)}`);
|
|
66627
67006
|
lines.push("");
|
|
66628
67007
|
}
|
|
66629
|
-
lines.push(` ${
|
|
67008
|
+
lines.push(` ${import_picocolors34.default.dim("link this folder to one with")} ${import_picocolors34.default.cyan("brainbase link --agent <id>")}`, "");
|
|
66630
67009
|
return lines.join(`
|
|
66631
67010
|
`);
|
|
66632
67011
|
}
|
|
66633
67012
|
|
|
66634
67013
|
// src/cli/agent-connections.ts
|
|
66635
|
-
var
|
|
67014
|
+
var import_picocolors36 = __toESM(require_picocolors(), 1);
|
|
66636
67015
|
|
|
66637
67016
|
// src/core/integrations.ts
|
|
66638
67017
|
var IMPLEMENTED_INTEGRATIONS = ["slack", "meeting"];
|
|
@@ -66664,7 +67043,7 @@ function explain(state) {
|
|
|
66664
67043
|
}
|
|
66665
67044
|
|
|
66666
67045
|
// src/cli/agent-connect.ts
|
|
66667
|
-
var
|
|
67046
|
+
var import_picocolors35 = __toESM(require_picocolors(), 1);
|
|
66668
67047
|
|
|
66669
67048
|
// src/core/secret-input.ts
|
|
66670
67049
|
import fs74 from "node:fs";
|
|
@@ -66915,9 +67294,9 @@ function report(result2, json) {
|
|
|
66915
67294
|
console.log(JSON.stringify(result2, null, 2));
|
|
66916
67295
|
return;
|
|
66917
67296
|
}
|
|
66918
|
-
const detail = result2.detail ? ` ${
|
|
67297
|
+
const detail = result2.detail ? ` ${import_picocolors35.default.dim(`(${result2.detail})`)}` : "";
|
|
66919
67298
|
f2.success(`${result2.name} connected${detail}`);
|
|
66920
|
-
f2.info(`Run ${
|
|
67299
|
+
f2.info(`Run ${import_picocolors35.default.cyan("brainbase agent pull")} to pick up the built-in ${result2.name} MCP server.`);
|
|
66921
67300
|
}
|
|
66922
67301
|
|
|
66923
67302
|
// src/cli/agent-connections.ts
|
|
@@ -66933,7 +67312,7 @@ async function runAgentConnections(cwd2, args) {
|
|
|
66933
67312
|
return;
|
|
66934
67313
|
}
|
|
66935
67314
|
f2.warn("This folder is not linked to any agent.");
|
|
66936
|
-
f2.info(`Run ${
|
|
67315
|
+
f2.info(`Run ${import_picocolors36.default.cyan("brainbase link")} first.`);
|
|
66937
67316
|
process.exitCode = 1;
|
|
66938
67317
|
return;
|
|
66939
67318
|
}
|
|
@@ -66955,22 +67334,22 @@ async function runAgentConnections(cwd2, args) {
|
|
|
66955
67334
|
function formatConnections(connections) {
|
|
66956
67335
|
const lines = [""];
|
|
66957
67336
|
for (const integration of connections.integrations) {
|
|
66958
|
-
lines.push(` ${statusMark(integration)} ${
|
|
67337
|
+
lines.push(` ${statusMark(integration)} ${import_picocolors36.default.bold(integration.name)}${describe(integration)}`);
|
|
66959
67338
|
const hint = hintFor(integration);
|
|
66960
67339
|
if (hint)
|
|
66961
|
-
lines.push(` ${
|
|
67340
|
+
lines.push(` ${import_picocolors36.default.dim(hint)}`);
|
|
66962
67341
|
}
|
|
66963
67342
|
lines.push("");
|
|
66964
67343
|
return lines.join(`
|
|
66965
67344
|
`);
|
|
66966
67345
|
}
|
|
66967
67346
|
function statusMark(integration) {
|
|
66968
|
-
return integration.connected ?
|
|
67347
|
+
return integration.connected ? import_picocolors36.default.green("✓") : import_picocolors36.default.dim("·");
|
|
66969
67348
|
}
|
|
66970
67349
|
function describe(integration) {
|
|
66971
67350
|
if (!integration.connected)
|
|
66972
|
-
return ` ${
|
|
66973
|
-
return integration.detail ? ` ${
|
|
67351
|
+
return ` ${import_picocolors36.default.dim("not connected")}`;
|
|
67352
|
+
return integration.detail ? ` ${import_picocolors36.default.dim(integration.detail)}` : ` ${import_picocolors36.default.dim("connected")}`;
|
|
66974
67353
|
}
|
|
66975
67354
|
function hintFor(integration) {
|
|
66976
67355
|
const action = actionability(integration);
|
|
@@ -66981,7 +67360,7 @@ function hintFor(integration) {
|
|
|
66981
67360
|
}
|
|
66982
67361
|
|
|
66983
67362
|
// src/cli/agent-disconnect.ts
|
|
66984
|
-
var
|
|
67363
|
+
var import_picocolors37 = __toESM(require_picocolors(), 1);
|
|
66985
67364
|
async function runAgentDisconnect(cwd2, target, args) {
|
|
66986
67365
|
const json = Boolean(args.json);
|
|
66987
67366
|
try {
|
|
@@ -67018,7 +67397,7 @@ async function disconnect(cwd2, target, args, json) {
|
|
|
67018
67397
|
return;
|
|
67019
67398
|
}
|
|
67020
67399
|
f2.success(`${target} disconnected`);
|
|
67021
|
-
f2.info(`Run ${
|
|
67400
|
+
f2.info(`Run ${import_picocolors37.default.cyan("brainbase agent pull")} to drop the built-in ${target} MCP server locally.`);
|
|
67022
67401
|
}
|
|
67023
67402
|
|
|
67024
67403
|
// src/cli/agent.ts
|
|
@@ -67028,6 +67407,17 @@ async function runAgent(cwd2, sub, args, opts) {
|
|
|
67028
67407
|
return;
|
|
67029
67408
|
}
|
|
67030
67409
|
switch (sub) {
|
|
67410
|
+
case "init":
|
|
67411
|
+
await runAgentInit(cwd2, {
|
|
67412
|
+
name: opts.name,
|
|
67413
|
+
tagline: opts.tagline,
|
|
67414
|
+
harness: opts.harness,
|
|
67415
|
+
minimal: opts.minimal,
|
|
67416
|
+
full: opts.full,
|
|
67417
|
+
force: opts.force,
|
|
67418
|
+
json: opts.json
|
|
67419
|
+
});
|
|
67420
|
+
return;
|
|
67031
67421
|
case "create":
|
|
67032
67422
|
await runAgentCreate(cwd2, {
|
|
67033
67423
|
yes: opts.yes,
|
|
@@ -67107,31 +67497,32 @@ async function runAgent(cwd2, sub, args, opts) {
|
|
|
67107
67497
|
function printHelp() {
|
|
67108
67498
|
const out = [];
|
|
67109
67499
|
out.push("");
|
|
67110
|
-
out.push(` ${
|
|
67500
|
+
out.push(` ${import_picocolors38.default.bold("brainbase agent")} ${import_picocolors38.default.dim("<sub> [options]")}`);
|
|
67111
67501
|
out.push("");
|
|
67112
|
-
out.push(` ${
|
|
67113
|
-
out.push(` ${
|
|
67114
|
-
out.push(` ${
|
|
67115
|
-
out.push(` ${
|
|
67116
|
-
out.push(` ${
|
|
67117
|
-
out.push(` ${
|
|
67118
|
-
out.push(` ${
|
|
67119
|
-
out.push(` ${
|
|
67120
|
-
out.push(` ${
|
|
67121
|
-
out.push(` ${
|
|
67502
|
+
out.push(` ${import_picocolors38.default.cyan("list")} ${import_picocolors38.default.dim("show the agents in a team, with the ids `brainbase link` takes (--json for scripts)")}`);
|
|
67503
|
+
out.push(` ${import_picocolors38.default.cyan("init")} ${import_picocolors38.default.dim("write a starter brainbase.agent.yaml here — offline, no login (--full for a commented template, --force to overwrite)")}`);
|
|
67504
|
+
out.push(` ${import_picocolors38.default.cyan("create")} ${import_picocolors38.default.dim("claim an unclaimed brainbase.agent.yaml and create the cloud agent (scaffolds one if the folder has none)")}`);
|
|
67505
|
+
out.push(` ${import_picocolors38.default.cyan("pull")} ${import_picocolors38.default.dim("[<id>]")} ${import_picocolors38.default.dim("apply cloud changes into this folder — pass <id> to switch (--force to override); --run-entrypoint to also execute the agent entrypoint")}`);
|
|
67506
|
+
out.push(` ${import_picocolors38.default.cyan("push")} ${import_picocolors38.default.dim("send local changes to the cloud — instructions, playbooks, skills, MCPs, entrypoint (--force to overwrite cloud-side conflicts with local)")}`);
|
|
67507
|
+
out.push(` ${import_picocolors38.default.cyan("unpack")} ${import_picocolors38.default.dim("install the claimed agent into a harness layout (--harness to override)")}`);
|
|
67508
|
+
out.push(` ${import_picocolors38.default.cyan("status")} ${import_picocolors38.default.dim("show what would push, what would pull, and which manifest blocks are ignored (--json for scripts)")}`);
|
|
67509
|
+
out.push(` ${import_picocolors38.default.cyan("connections")} ${import_picocolors38.default.dim("show which integrations this agent is wired to (--json for scripts)")}`);
|
|
67510
|
+
out.push(` ${import_picocolors38.default.cyan("connect")} ${import_picocolors38.default.dim("<name>")} ${import_picocolors38.default.dim("connect slack or meeting — credentials come from flags, env, or stdin")}`);
|
|
67511
|
+
out.push(` ${import_picocolors38.default.cyan("disconnect")} ${import_picocolors38.default.dim("<name>")} ${import_picocolors38.default.dim("revoke a slack or meeting install")}`);
|
|
67512
|
+
out.push(` ${import_picocolors38.default.cyan("env")} ${import_picocolors38.default.dim('print export statements — use with `eval "$(brainbase agent env)"`')}`);
|
|
67122
67513
|
out.push("");
|
|
67123
|
-
out.push(` ${
|
|
67124
|
-
out.push(` ${
|
|
67514
|
+
out.push(` ${import_picocolors38.default.dim("Slack credentials:")} ${import_picocolors38.default.dim("--bot-token / BRAINBASE_SLACK_BOT_TOKEN, --signing-secret / BRAINBASE_SLACK_SIGNING_SECRET,")}`);
|
|
67515
|
+
out.push(` ${import_picocolors38.default.dim('or pipe {"bot_token":"…","signing_secret":"…"} on stdin to keep them out of argv.')}`);
|
|
67125
67516
|
out.push("");
|
|
67126
67517
|
console.log(out.join(`
|
|
67127
67518
|
`));
|
|
67128
67519
|
}
|
|
67129
67520
|
|
|
67130
67521
|
// src/cli/team.ts
|
|
67131
|
-
var
|
|
67522
|
+
var import_picocolors40 = __toESM(require_picocolors(), 1);
|
|
67132
67523
|
|
|
67133
67524
|
// src/cli/team-list.ts
|
|
67134
|
-
var
|
|
67525
|
+
var import_picocolors39 = __toESM(require_picocolors(), 1);
|
|
67135
67526
|
async function runTeamList(args) {
|
|
67136
67527
|
if (!args.json)
|
|
67137
67528
|
banner("team list — teams you can put agents in");
|
|
@@ -67151,25 +67542,25 @@ async function runTeamList(args) {
|
|
|
67151
67542
|
function formatTeamList(grouped) {
|
|
67152
67543
|
const lines = [""];
|
|
67153
67544
|
if (grouped.length === 0) {
|
|
67154
|
-
lines.push(` ${
|
|
67545
|
+
lines.push(` ${import_picocolors39.default.dim("You are not a member of any organization.")}`, "");
|
|
67155
67546
|
return lines.join(`
|
|
67156
67547
|
`);
|
|
67157
67548
|
}
|
|
67158
67549
|
const nameWidth = Math.max(...grouped.flatMap(({ teams }) => teams.map((t) => t.name.length)), 0);
|
|
67159
67550
|
for (const { org, teams, error } of grouped) {
|
|
67160
|
-
const slug = org.slug ? ` ${
|
|
67161
|
-
lines.push(` ${
|
|
67551
|
+
const slug = org.slug ? ` ${import_picocolors39.default.dim(org.slug)}` : "";
|
|
67552
|
+
lines.push(` ${import_picocolors39.default.bold(org.name)}${slug}`);
|
|
67162
67553
|
if (error) {
|
|
67163
|
-
lines.push(` ${
|
|
67554
|
+
lines.push(` ${import_picocolors39.default.red(`could not load teams: ${error}`)}`);
|
|
67164
67555
|
} else if (teams.length === 0) {
|
|
67165
|
-
lines.push(` ${
|
|
67556
|
+
lines.push(` ${import_picocolors39.default.dim("no teams yet — create one in the web app")}`);
|
|
67166
67557
|
}
|
|
67167
67558
|
for (const team of teams) {
|
|
67168
|
-
lines.push(` ${team.name.padEnd(nameWidth)} ${
|
|
67559
|
+
lines.push(` ${team.name.padEnd(nameWidth)} ${import_picocolors39.default.dim(team.id)}`);
|
|
67169
67560
|
}
|
|
67170
67561
|
lines.push("");
|
|
67171
67562
|
}
|
|
67172
|
-
lines.push(` ${
|
|
67563
|
+
lines.push(` ${import_picocolors39.default.dim("list a team’s agents with")} ${import_picocolors39.default.cyan("brainbase agent list --team <id>")}`, "");
|
|
67173
67564
|
return lines.join(`
|
|
67174
67565
|
`);
|
|
67175
67566
|
}
|
|
@@ -67200,29 +67591,29 @@ async function runTeam(sub, args, opts) {
|
|
|
67200
67591
|
function printHelp2() {
|
|
67201
67592
|
const out = [];
|
|
67202
67593
|
out.push("");
|
|
67203
|
-
out.push(` ${
|
|
67594
|
+
out.push(` ${import_picocolors40.default.bold("brainbase team")} ${import_picocolors40.default.dim("<sub> [options]")}`);
|
|
67204
67595
|
out.push("");
|
|
67205
|
-
out.push(` ${
|
|
67596
|
+
out.push(` ${import_picocolors40.default.cyan("list")} ${import_picocolors40.default.dim("show the teams you can create agents in, grouped by organization")}`);
|
|
67206
67597
|
out.push("");
|
|
67207
|
-
out.push(` ${
|
|
67208
|
-
out.push(` ${
|
|
67598
|
+
out.push(` ${import_picocolors40.default.dim("--org <id-or-slug>")} ${import_picocolors40.default.dim("limit to one organization")}`);
|
|
67599
|
+
out.push(` ${import_picocolors40.default.dim("--json")} ${import_picocolors40.default.dim("machine-readable output")}`);
|
|
67209
67600
|
out.push("");
|
|
67210
67601
|
console.log(out.join(`
|
|
67211
67602
|
`));
|
|
67212
67603
|
}
|
|
67213
67604
|
|
|
67214
67605
|
// src/cli/orchestration.ts
|
|
67215
|
-
var
|
|
67606
|
+
var import_picocolors47 = __toESM(require_picocolors(), 1);
|
|
67216
67607
|
|
|
67217
67608
|
// src/cli/orchestration-pull.ts
|
|
67218
|
-
import
|
|
67609
|
+
import path87 from "node:path";
|
|
67219
67610
|
import fs78 from "node:fs";
|
|
67220
|
-
var
|
|
67611
|
+
var import_picocolors41 = __toESM(require_picocolors(), 1);
|
|
67221
67612
|
|
|
67222
67613
|
// src/core/orchestration-manifest.ts
|
|
67223
|
-
import
|
|
67614
|
+
import path84 from "node:path";
|
|
67224
67615
|
import fs75 from "node:fs";
|
|
67225
|
-
var
|
|
67616
|
+
var import_yaml5 = __toESM(require_dist(), 1);
|
|
67226
67617
|
var ORCH_MANIFEST_FILE = "brainbase-orchestration.yaml";
|
|
67227
67618
|
var ORCH_MEMBERS_DIR = "agents";
|
|
67228
67619
|
var OrchMetaSchema = exports_external.object({
|
|
@@ -67274,7 +67665,7 @@ var OrchestrationManifestSchema = exports_external.object({
|
|
|
67274
67665
|
triggers: exports_external.array(TriggerSchema).optional()
|
|
67275
67666
|
});
|
|
67276
67667
|
function orchManifestPath(cwd2) {
|
|
67277
|
-
return
|
|
67668
|
+
return path84.join(cwd2, ORCH_MANIFEST_FILE);
|
|
67278
67669
|
}
|
|
67279
67670
|
function hasOrchManifest(cwd2) {
|
|
67280
67671
|
return fs75.existsSync(orchManifestPath(cwd2));
|
|
@@ -67286,7 +67677,7 @@ function readOrchManifest(cwd2) {
|
|
|
67286
67677
|
const raw = fs75.readFileSync(p2, "utf8");
|
|
67287
67678
|
let parsed;
|
|
67288
67679
|
try {
|
|
67289
|
-
parsed =
|
|
67680
|
+
parsed = import_yaml5.default.parse(raw);
|
|
67290
67681
|
} catch (err) {
|
|
67291
67682
|
throw new Error(`${ORCH_MANIFEST_FILE} is not valid YAML: ${err.message}`);
|
|
67292
67683
|
}
|
|
@@ -67297,7 +67688,7 @@ function readOrchManifest(cwd2) {
|
|
|
67297
67688
|
return result2.data;
|
|
67298
67689
|
}
|
|
67299
67690
|
function writeOrchManifest(cwd2, manifest) {
|
|
67300
|
-
const doc = new
|
|
67691
|
+
const doc = new import_yaml5.default.Document;
|
|
67301
67692
|
doc.contents = manifest;
|
|
67302
67693
|
doc.commentBefore = ` brainbase-orchestration.yaml — declarative orchestration manifest.
|
|
67303
67694
|
` + ` Committed to source control. Edit by hand, then
|
|
@@ -67307,7 +67698,7 @@ function writeOrchManifest(cwd2, manifest) {
|
|
|
67307
67698
|
fs75.writeFileSync(orchManifestPath(cwd2), String(doc), "utf8");
|
|
67308
67699
|
}
|
|
67309
67700
|
function memberDir(cwd2, slug) {
|
|
67310
|
-
return
|
|
67701
|
+
return path84.join(cwd2, ORCH_MEMBERS_DIR, slug);
|
|
67311
67702
|
}
|
|
67312
67703
|
var MEMBER_SLUG_MAX = 50;
|
|
67313
67704
|
function slugifyRaw(raw) {
|
|
@@ -67341,7 +67732,7 @@ function resolveMemberSlugs(members) {
|
|
|
67341
67732
|
}
|
|
67342
67733
|
|
|
67343
67734
|
// src/core/orchestration-link.ts
|
|
67344
|
-
import
|
|
67735
|
+
import path85 from "node:path";
|
|
67345
67736
|
import fs76 from "node:fs";
|
|
67346
67737
|
var ORCH_LINK_FILE = "orchestration-link.json";
|
|
67347
67738
|
var ORCH_SYNC_STATE_FILE = "orchestration-sync-state.json";
|
|
@@ -67376,10 +67767,10 @@ var OrchestrationSyncStateSchema = exports_external.object({
|
|
|
67376
67767
|
edges: exports_external.array(SyncedEdgeSchema)
|
|
67377
67768
|
});
|
|
67378
67769
|
function orchLinkPath(cwd2) {
|
|
67379
|
-
return
|
|
67770
|
+
return path85.join(cwd2, LINK_DIR, ORCH_LINK_FILE);
|
|
67380
67771
|
}
|
|
67381
67772
|
function orchSyncStatePath(cwd2) {
|
|
67382
|
-
return
|
|
67773
|
+
return path85.join(cwd2, LINK_DIR, ORCH_SYNC_STATE_FILE);
|
|
67383
67774
|
}
|
|
67384
67775
|
function readOrchLink(cwd2) {
|
|
67385
67776
|
const p2 = orchLinkPath(cwd2);
|
|
@@ -67392,7 +67783,7 @@ function readOrchLink(cwd2) {
|
|
|
67392
67783
|
}
|
|
67393
67784
|
}
|
|
67394
67785
|
function writeOrchLink(cwd2, link2) {
|
|
67395
|
-
ensureDir(
|
|
67786
|
+
ensureDir(path85.join(cwd2, LINK_DIR));
|
|
67396
67787
|
const clean2 = {};
|
|
67397
67788
|
for (const [k3, v3] of Object.entries(link2)) {
|
|
67398
67789
|
if (v3 !== null && v3 !== undefined)
|
|
@@ -67412,12 +67803,12 @@ function readOrchSyncState(cwd2) {
|
|
|
67412
67803
|
}
|
|
67413
67804
|
}
|
|
67414
67805
|
function writeOrchSyncState(cwd2, state) {
|
|
67415
|
-
ensureDir(
|
|
67806
|
+
ensureDir(path85.join(cwd2, LINK_DIR));
|
|
67416
67807
|
writeJson(orchSyncStatePath(cwd2), state);
|
|
67417
67808
|
ensureGitignore2(cwd2);
|
|
67418
67809
|
}
|
|
67419
67810
|
function ensureGitignore2(cwd2) {
|
|
67420
|
-
const ignorePath =
|
|
67811
|
+
const ignorePath = path85.join(cwd2, LINK_DIR, ".gitignore");
|
|
67421
67812
|
const desired = `${ORCH_SYNC_STATE_FILE}
|
|
67422
67813
|
`;
|
|
67423
67814
|
try {
|
|
@@ -67435,7 +67826,7 @@ function ensureGitignore2(cwd2) {
|
|
|
67435
67826
|
}
|
|
67436
67827
|
|
|
67437
67828
|
// src/core/agent-fresh-install.ts
|
|
67438
|
-
import
|
|
67829
|
+
import path86 from "node:path";
|
|
67439
67830
|
import fs77 from "node:fs";
|
|
67440
67831
|
import os15 from "node:os";
|
|
67441
67832
|
async function installAgentFresh(input) {
|
|
@@ -67458,7 +67849,7 @@ async function installAgentFresh(input) {
|
|
|
67458
67849
|
type: c2.type,
|
|
67459
67850
|
slug: c2.slug,
|
|
67460
67851
|
scope,
|
|
67461
|
-
rootDir:
|
|
67852
|
+
rootDir: path86.join(stageRoot, c2.type, c2.slug),
|
|
67462
67853
|
description: c2.description,
|
|
67463
67854
|
meta: c2.meta,
|
|
67464
67855
|
payload: proxifyMcpPayload(structuredClone(c2.meta?.mcp)),
|
|
@@ -67483,7 +67874,7 @@ async function installAgentFresh(input) {
|
|
|
67483
67874
|
const claimedByOther = folderClaimedByOtherAgent(cwd2, agent.id);
|
|
67484
67875
|
const localOnly = input.preserveManifest || claimedByOther ? {} : readLocalOnlyContentReporting(cwd2);
|
|
67485
67876
|
if (claimedByOther) {
|
|
67486
|
-
f2.warn(`${
|
|
67877
|
+
f2.warn(`${path86.basename(cwd2)} was linked to a different agent; its local-only blocks were left out of the rebuilt manifest.`);
|
|
67487
67878
|
}
|
|
67488
67879
|
const manifest = input.preserveManifest ? null : buildManifestFromCloud(cloud, agent, localOnly);
|
|
67489
67880
|
if (manifest)
|
|
@@ -67516,7 +67907,8 @@ async function installAgentFresh(input) {
|
|
|
67516
67907
|
name: agent.name,
|
|
67517
67908
|
tagline: agent.tagline,
|
|
67518
67909
|
...agent.machine_kind ? { machine_kind: agent.machine_kind } : {},
|
|
67519
|
-
...Object.prototype.hasOwnProperty.call(agent, "default_model") ? { default_model: agent.default_model ?? null } : {}
|
|
67910
|
+
...Object.prototype.hasOwnProperty.call(agent, "default_model") ? { default_model: agent.default_model ?? null } : {},
|
|
67911
|
+
...capabilityBaseline(agent, undefined)
|
|
67520
67912
|
}
|
|
67521
67913
|
});
|
|
67522
67914
|
const returnedManifest = manifest ?? buildManifestFromCloud(cloud, agent, localOnly);
|
|
@@ -67532,13 +67924,13 @@ async function installAgentFresh(input) {
|
|
|
67532
67924
|
}
|
|
67533
67925
|
}
|
|
67534
67926
|
function stageManifestComponents2(components) {
|
|
67535
|
-
const root = fs77.mkdtempSync(
|
|
67927
|
+
const root = fs77.mkdtempSync(path86.join(os15.tmpdir(), "brainbase-orch-pull-"));
|
|
67536
67928
|
for (const c2 of components) {
|
|
67537
|
-
const compDir =
|
|
67929
|
+
const compDir = path86.join(root, c2.type, c2.slug);
|
|
67538
67930
|
ensureDir(compDir);
|
|
67539
67931
|
for (const f4 of c2.files) {
|
|
67540
|
-
const target =
|
|
67541
|
-
ensureDir(
|
|
67932
|
+
const target = path86.join(compDir, f4.path);
|
|
67933
|
+
ensureDir(path86.dirname(target));
|
|
67542
67934
|
fs77.writeFileSync(target, f4.content);
|
|
67543
67935
|
}
|
|
67544
67936
|
}
|
|
@@ -67572,8 +67964,8 @@ function materializeInstructions2(cwd2, cloud) {
|
|
|
67572
67964
|
const body = c2.files[0]?.content ?? "";
|
|
67573
67965
|
if (!body.trim())
|
|
67574
67966
|
continue;
|
|
67575
|
-
const target =
|
|
67576
|
-
ensureDir(
|
|
67967
|
+
const target = path86.join(cwd2, DEFAULT_INSTRUCTIONS_FILE);
|
|
67968
|
+
ensureDir(path86.dirname(target));
|
|
67577
67969
|
fs77.writeFileSync(target, normalizeInstructionBody(body), "utf8");
|
|
67578
67970
|
return;
|
|
67579
67971
|
}
|
|
@@ -67586,8 +67978,8 @@ function materializePlaybooks2(cwd2, cloud) {
|
|
|
67586
67978
|
if (!raw.trim())
|
|
67587
67979
|
continue;
|
|
67588
67980
|
const { body } = stripPlaybookFrontmatter(raw);
|
|
67589
|
-
const target =
|
|
67590
|
-
ensureDir(
|
|
67981
|
+
const target = path86.join(cwd2, DEFAULT_PLAYBOOKS_DIR, `${c2.slug}.md`);
|
|
67982
|
+
ensureDir(path86.dirname(target));
|
|
67591
67983
|
fs77.writeFileSync(target, body, "utf8");
|
|
67592
67984
|
}
|
|
67593
67985
|
}
|
|
@@ -67630,7 +68022,7 @@ function buildManifestFromCloud(cloud, agent, localOnly = {}) {
|
|
|
67630
68022
|
title,
|
|
67631
68023
|
...description ? { description } : {},
|
|
67632
68024
|
...typeof pbMeta.icon === "string" && pbMeta.icon ? { icon: pbMeta.icon } : {},
|
|
67633
|
-
content: { file:
|
|
68025
|
+
content: { file: path86.join(DEFAULT_PLAYBOOKS_DIR, `${c2.slug}.md`) }
|
|
67634
68026
|
};
|
|
67635
68027
|
});
|
|
67636
68028
|
const caps = capabilitiesFromAgent(agent);
|
|
@@ -67737,8 +68129,8 @@ async function runOrchestrationPull(cwd2, args) {
|
|
|
67737
68129
|
orchId = args.orchestrationId;
|
|
67738
68130
|
} else {
|
|
67739
68131
|
f2.warn("This folder is not linked to any orchestration.");
|
|
67740
|
-
f2.info(`Run ${
|
|
67741
|
-
or ${
|
|
68132
|
+
f2.info(`Run ${import_picocolors41.default.cyan("brainbase orchestration pull <id>")} with an orchestration id,
|
|
68133
|
+
or ${import_picocolors41.default.cyan("brainbase orchestration list")} to find one.`);
|
|
67742
68134
|
return;
|
|
67743
68135
|
}
|
|
67744
68136
|
const sp = de();
|
|
@@ -67757,24 +68149,24 @@ async function runOrchestrationPull(cwd2, args) {
|
|
|
67757
68149
|
const slugFor = (agentId) => slugByAgent.get(agentId) ?? agentId;
|
|
67758
68150
|
const planLines = [];
|
|
67759
68151
|
planLines.push("");
|
|
67760
|
-
planLines.push(` ${
|
|
68152
|
+
planLines.push(` ${import_picocolors41.default.bold(cloud.name)} ${import_picocolors41.default.dim(`(${cloud.id})`)}`);
|
|
67761
68153
|
if (cloud.description)
|
|
67762
|
-
planLines.push(` ${
|
|
68154
|
+
planLines.push(` ${import_picocolors41.default.dim(cloud.description)}`);
|
|
67763
68155
|
planLines.push("");
|
|
67764
|
-
planLines.push(` ${
|
|
68156
|
+
planLines.push(` ${import_picocolors41.default.dim("members:")}`);
|
|
67765
68157
|
for (const m3 of cloud.members) {
|
|
67766
68158
|
const skipped = !m3.manifest;
|
|
67767
|
-
const tail2 = skipped ?
|
|
67768
|
-
planLines.push(` ${
|
|
68159
|
+
const tail2 = skipped ? import_picocolors41.default.red(" (manifest unavailable — skipped)") : "";
|
|
68160
|
+
planLines.push(` ${import_picocolors41.default.cyan("•")} ${import_picocolors41.default.bold(slugFor(m3.agent_id))} ${import_picocolors41.default.dim(`(${m3.name})`)}${tail2}`);
|
|
67769
68161
|
}
|
|
67770
68162
|
if (cloud.edges.length) {
|
|
67771
68163
|
planLines.push("");
|
|
67772
|
-
planLines.push(` ${
|
|
68164
|
+
planLines.push(` ${import_picocolors41.default.dim("edges:")}`);
|
|
67773
68165
|
for (const e2 of cloud.edges) {
|
|
67774
68166
|
const from = slugFor(e2.from_agent_id);
|
|
67775
68167
|
const to2 = slugFor(e2.to_agent_id);
|
|
67776
|
-
const desc = e2.description ? ` ${
|
|
67777
|
-
planLines.push(` ${
|
|
68168
|
+
const desc = e2.description ? ` ${import_picocolors41.default.dim("— " + e2.description)}` : "";
|
|
68169
|
+
planLines.push(` ${import_picocolors41.default.cyan(from)} ${import_picocolors41.default.dim("→")} ${import_picocolors41.default.cyan(to2)}${desc}`);
|
|
67778
68170
|
}
|
|
67779
68171
|
}
|
|
67780
68172
|
planLines.push("");
|
|
@@ -67783,7 +68175,7 @@ async function runOrchestrationPull(cwd2, args) {
|
|
|
67783
68175
|
const isRefresh = !!existingLink;
|
|
67784
68176
|
if (!autoProceed(args.yes) && !isRefresh) {
|
|
67785
68177
|
const ok = await se({
|
|
67786
|
-
message: `Pull into ${
|
|
68178
|
+
message: `Pull into ${import_picocolors41.default.bold(cwd2)}?`,
|
|
67787
68179
|
initialValue: true
|
|
67788
68180
|
});
|
|
67789
68181
|
if (!ensureNotCancelled(ok)) {
|
|
@@ -67827,7 +68219,7 @@ async function runOrchestrationPull(cwd2, args) {
|
|
|
67827
68219
|
scope: "project",
|
|
67828
68220
|
pullSecrets: true
|
|
67829
68221
|
});
|
|
67830
|
-
memberSp.stop(`Installed ${
|
|
68222
|
+
memberSp.stop(`Installed ${import_picocolors41.default.bold(slug)} ${import_picocolors41.default.dim(`(${m3.manifest.components.length} components)`)}.`);
|
|
67831
68223
|
installedMembers.push({
|
|
67832
68224
|
agent_id: m3.agent_id,
|
|
67833
68225
|
slug,
|
|
@@ -67888,7 +68280,7 @@ async function runOrchestrationPull(cwd2, args) {
|
|
|
67888
68280
|
payload_schema: e2.payload_schema ?? {}
|
|
67889
68281
|
}))
|
|
67890
68282
|
});
|
|
67891
|
-
$e(`Pulled ${cloud.name} at revision ${cloud.revision} into ${
|
|
68283
|
+
$e(`Pulled ${cloud.name} at revision ${cloud.revision} into ${path87.basename(cwd2)}/ ${import_picocolors41.default.dim(`(${installedMembers.length}/${cloud.members.length} members)`)}.`);
|
|
67892
68284
|
}
|
|
67893
68285
|
function handleApiError5(err) {
|
|
67894
68286
|
if (err instanceof ApiError) {
|
|
@@ -67905,7 +68297,7 @@ function handleApiError5(err) {
|
|
|
67905
68297
|
}
|
|
67906
68298
|
|
|
67907
68299
|
// src/cli/orchestration-push.ts
|
|
67908
|
-
var
|
|
68300
|
+
var import_picocolors42 = __toESM(require_picocolors(), 1);
|
|
67909
68301
|
|
|
67910
68302
|
// src/core/orchestration-outgoing.ts
|
|
67911
68303
|
function buildOrchestrationGraphPayload(manifest, slugToAgentId) {
|
|
@@ -67988,7 +68380,7 @@ function findUnpushableMembers(cwd2, members) {
|
|
|
67988
68380
|
continue;
|
|
67989
68381
|
}
|
|
67990
68382
|
if (!memberManifest.id) {
|
|
67991
|
-
f2.error(`${m3.slug}: ${AGENT_MANIFEST_FILE} is unclaimed (no ${
|
|
68383
|
+
f2.error(`${m3.slug}: ${AGENT_MANIFEST_FILE} is unclaimed (no ${import_picocolors42.default.cyan("id")}), so there is nothing to push to.`);
|
|
67992
68384
|
blocked.push(m3.slug);
|
|
67993
68385
|
continue;
|
|
67994
68386
|
}
|
|
@@ -68003,12 +68395,12 @@ async function runOrchestrationPush(cwd2, args) {
|
|
|
68003
68395
|
const link2 = readOrchLink(cwd2);
|
|
68004
68396
|
if (!link2) {
|
|
68005
68397
|
f2.warn("This folder is not linked to any orchestration.");
|
|
68006
|
-
f2.info(`Run ${
|
|
68398
|
+
f2.info(`Run ${import_picocolors42.default.cyan("brainbase orchestration pull <id>")} first.`);
|
|
68007
68399
|
return;
|
|
68008
68400
|
}
|
|
68009
68401
|
if (!hasOrchManifest(cwd2)) {
|
|
68010
|
-
f2.warn(`No ${
|
|
68011
|
-
f2.info(`Run ${
|
|
68402
|
+
f2.warn(`No ${import_picocolors42.default.bold(ORCH_MANIFEST_FILE)} here.`);
|
|
68403
|
+
f2.info(`Run ${import_picocolors42.default.cyan("brainbase orchestration pull")} to materialise the manifest before pushing.`);
|
|
68012
68404
|
return;
|
|
68013
68405
|
}
|
|
68014
68406
|
let manifest;
|
|
@@ -68032,7 +68424,7 @@ async function runOrchestrationPush(cwd2, args) {
|
|
|
68032
68424
|
}
|
|
68033
68425
|
if (missing.length) {
|
|
68034
68426
|
f2.error(`Missing local checkouts for: ${missing.join(", ")}.`);
|
|
68035
|
-
f2.info(`Run ${
|
|
68427
|
+
f2.info(`Run ${import_picocolors42.default.cyan("brainbase orchestration pull")} to materialise the missing folders.`);
|
|
68036
68428
|
process.exitCode = 1;
|
|
68037
68429
|
return;
|
|
68038
68430
|
}
|
|
@@ -68053,13 +68445,13 @@ async function runOrchestrationPush(cwd2, args) {
|
|
|
68053
68445
|
}
|
|
68054
68446
|
}
|
|
68055
68447
|
const plan = [""];
|
|
68056
|
-
plan.push(` ${
|
|
68057
|
-
plan.push(` ${
|
|
68448
|
+
plan.push(` ${import_picocolors42.default.bold(link2.name)} ${import_picocolors42.default.dim(`(${link2.orchestration_id})`)}`);
|
|
68449
|
+
plan.push(` ${import_picocolors42.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"}`)}`);
|
|
68058
68450
|
plan.push("");
|
|
68059
68451
|
if (!args.graphOnly) {
|
|
68060
|
-
plan.push(` ${
|
|
68452
|
+
plan.push(` ${import_picocolors42.default.dim("per-member agent push:")}`);
|
|
68061
68453
|
for (const m3 of manifest.members) {
|
|
68062
|
-
plan.push(` ${
|
|
68454
|
+
plan.push(` ${import_picocolors42.default.cyan("•")} ${import_picocolors42.default.bold(m3.slug)}`);
|
|
68063
68455
|
}
|
|
68064
68456
|
plan.push("");
|
|
68065
68457
|
}
|
|
@@ -68079,7 +68471,7 @@ async function runOrchestrationPush(cwd2, args) {
|
|
|
68079
68471
|
for (const m3 of manifest.members) {
|
|
68080
68472
|
const dir = memberDir(cwd2, m3.slug);
|
|
68081
68473
|
console.log("");
|
|
68082
|
-
console.log(`${
|
|
68474
|
+
console.log(`${import_picocolors42.default.dim("───")} ${import_picocolors42.default.bold(m3.slug)} ${import_picocolors42.default.dim("───")}`);
|
|
68083
68475
|
const exitCodeBeforePush = process.exitCode;
|
|
68084
68476
|
try {
|
|
68085
68477
|
await runAgentPush(dir, { yes: true });
|
|
@@ -68143,7 +68535,7 @@ function handleApiError6(err) {
|
|
|
68143
68535
|
f2.error("You do not have access to this orchestration.");
|
|
68144
68536
|
} else if (err.status === 409) {
|
|
68145
68537
|
f2.error(err.message);
|
|
68146
|
-
f2.info(`Run ${
|
|
68538
|
+
f2.info(`Run ${import_picocolors42.default.cyan("brainbase orchestration pull")} to reconcile, then push again.`);
|
|
68147
68539
|
} else {
|
|
68148
68540
|
f2.error(err.message);
|
|
68149
68541
|
}
|
|
@@ -68153,13 +68545,13 @@ function handleApiError6(err) {
|
|
|
68153
68545
|
}
|
|
68154
68546
|
|
|
68155
68547
|
// src/cli/orchestration-status.ts
|
|
68156
|
-
var
|
|
68548
|
+
var import_picocolors43 = __toESM(require_picocolors(), 1);
|
|
68157
68549
|
async function runOrchestrationStatus(cwd2) {
|
|
68158
68550
|
banner("orchestration status — what changed locally, remotely, both");
|
|
68159
68551
|
const link2 = readOrchLink(cwd2);
|
|
68160
68552
|
if (!link2) {
|
|
68161
68553
|
f2.warn("This folder is not linked to any orchestration.");
|
|
68162
|
-
f2.info(`Run ${
|
|
68554
|
+
f2.info(`Run ${import_picocolors43.default.cyan("brainbase orchestration pull <id>")} first.`);
|
|
68163
68555
|
return;
|
|
68164
68556
|
}
|
|
68165
68557
|
const localManifest = hasOrchManifest(cwd2) ? readOrchManifest(cwd2) : null;
|
|
@@ -68182,8 +68574,8 @@ async function runOrchestrationStatus(cwd2) {
|
|
|
68182
68574
|
}
|
|
68183
68575
|
const lines = [];
|
|
68184
68576
|
lines.push("");
|
|
68185
|
-
lines.push(` ${
|
|
68186
|
-
lines.push(` ${
|
|
68577
|
+
lines.push(` ${import_picocolors43.default.bold(link2.name)} ${import_picocolors43.default.dim(`(${link2.orchestration_id})`)}`);
|
|
68578
|
+
lines.push(` ${import_picocolors43.default.dim("revision")} cloud ${cloud.revision}${lock ? ` · lock ${lock.revision}` : " · never pulled"}`);
|
|
68187
68579
|
lines.push("");
|
|
68188
68580
|
const localSlugByAgentId = new Map;
|
|
68189
68581
|
for (const m3 of localManifest?.members ?? []) {
|
|
@@ -68197,12 +68589,12 @@ async function runOrchestrationStatus(cwd2) {
|
|
|
68197
68589
|
const membersAdded = [...localMemberSet].filter((s3) => !cloudMemberSet.has(s3));
|
|
68198
68590
|
const membersRemoved = [...cloudMemberSet].filter((s3) => !localMemberSet.has(s3));
|
|
68199
68591
|
if (membersAdded.length || membersRemoved.length) {
|
|
68200
|
-
lines.push(` ${
|
|
68592
|
+
lines.push(` ${import_picocolors43.default.bold("members")}`);
|
|
68201
68593
|
for (const slug of membersAdded) {
|
|
68202
|
-
lines.push(` ${
|
|
68594
|
+
lines.push(` ${import_picocolors43.default.yellow("→ push")} added in yaml: ${import_picocolors43.default.bold(slug)}`);
|
|
68203
68595
|
}
|
|
68204
68596
|
for (const slug of membersRemoved) {
|
|
68205
|
-
lines.push(` ${
|
|
68597
|
+
lines.push(` ${import_picocolors43.default.cyan("← pull")} added on cloud: ${import_picocolors43.default.bold(slug)}`);
|
|
68206
68598
|
}
|
|
68207
68599
|
lines.push("");
|
|
68208
68600
|
}
|
|
@@ -68217,11 +68609,11 @@ async function runOrchestrationStatus(cwd2) {
|
|
|
68217
68609
|
const edgesAdded = [...localEdges.keys()].filter((k3) => !cloudEdges.has(k3));
|
|
68218
68610
|
const edgesRemoved = [...cloudEdges.keys()].filter((k3) => !localEdges.has(k3));
|
|
68219
68611
|
if (edgesAdded.length || edgesRemoved.length) {
|
|
68220
|
-
lines.push(` ${
|
|
68612
|
+
lines.push(` ${import_picocolors43.default.bold("edges")}`);
|
|
68221
68613
|
for (const k3 of edgesAdded)
|
|
68222
|
-
lines.push(` ${
|
|
68614
|
+
lines.push(` ${import_picocolors43.default.yellow("→ push")} added in yaml: ${k3}`);
|
|
68223
68615
|
for (const k3 of edgesRemoved)
|
|
68224
|
-
lines.push(` ${
|
|
68616
|
+
lines.push(` ${import_picocolors43.default.cyan("← pull")} added on cloud: ${k3}`);
|
|
68225
68617
|
lines.push("");
|
|
68226
68618
|
}
|
|
68227
68619
|
const cloudTriggerKey = (t) => {
|
|
@@ -68259,11 +68651,11 @@ async function runOrchestrationStatus(cwd2) {
|
|
|
68259
68651
|
const triggersAdded = [...localTriggers.keys()].filter((k3) => !cloudTriggers.has(k3));
|
|
68260
68652
|
const triggersRemoved = [...cloudTriggers.keys()].filter((k3) => !localTriggers.has(k3));
|
|
68261
68653
|
if (triggersAdded.length || triggersRemoved.length) {
|
|
68262
|
-
lines.push(` ${
|
|
68654
|
+
lines.push(` ${import_picocolors43.default.bold("schedule triggers")}`);
|
|
68263
68655
|
for (const k3 of triggersAdded)
|
|
68264
|
-
lines.push(` ${
|
|
68656
|
+
lines.push(` ${import_picocolors43.default.yellow("→ push")} added/changed in yaml: ${localTriggers.get(k3) ?? k3}`);
|
|
68265
68657
|
for (const k3 of triggersRemoved)
|
|
68266
|
-
lines.push(` ${
|
|
68658
|
+
lines.push(` ${import_picocolors43.default.cyan("← pull")} added/changed on cloud: ${cloudTriggers.get(k3) ?? k3}`);
|
|
68267
68659
|
lines.push("");
|
|
68268
68660
|
}
|
|
68269
68661
|
const lockByAgentId = new Map((lock?.members ?? []).map((m3) => [m3.agent_id, m3]));
|
|
@@ -68286,27 +68678,27 @@ async function runOrchestrationStatus(cwd2) {
|
|
|
68286
68678
|
}
|
|
68287
68679
|
}
|
|
68288
68680
|
if (memberDrift.length) {
|
|
68289
|
-
lines.push(` ${
|
|
68681
|
+
lines.push(` ${import_picocolors43.default.bold("member content drift")}`);
|
|
68290
68682
|
for (const d3 of memberDrift) {
|
|
68291
|
-
lines.push(` ${
|
|
68683
|
+
lines.push(` ${import_picocolors43.default.cyan("?")} ${import_picocolors43.default.bold(d3.slug)} ${import_picocolors43.default.dim("— " + d3.reason)}`);
|
|
68292
68684
|
}
|
|
68293
|
-
lines.push(` ${
|
|
68685
|
+
lines.push(` ${import_picocolors43.default.dim("cd into each member folder and run")} ${import_picocolors43.default.cyan("brainbase agent status")}`);
|
|
68294
68686
|
lines.push("");
|
|
68295
68687
|
}
|
|
68296
68688
|
const revisionDrift = lock?.revision != null && cloud.revision !== lock.revision;
|
|
68297
68689
|
if (revisionDrift) {
|
|
68298
|
-
lines.push(` ${
|
|
68299
|
-
lines.push(` ${
|
|
68690
|
+
lines.push(` ${import_picocolors43.default.bold("cloud revision")}`);
|
|
68691
|
+
lines.push(` ${import_picocolors43.default.cyan("← pull")} cloud changed since last pull: ${import_picocolors43.default.dim(`lock ${lock.revision} → cloud ${cloud.revision}`)}`);
|
|
68300
68692
|
lines.push("");
|
|
68301
68693
|
}
|
|
68302
68694
|
if (!membersAdded.length && !membersRemoved.length && !edgesAdded.length && !edgesRemoved.length && !triggersAdded.length && !triggersRemoved.length && !memberDrift.length && !revisionDrift) {
|
|
68303
|
-
lines.push(` ${
|
|
68695
|
+
lines.push(` ${import_picocolors43.default.green("✓")} everything is in sync`);
|
|
68304
68696
|
lines.push("");
|
|
68305
68697
|
console.log(lines.join(`
|
|
68306
68698
|
`));
|
|
68307
68699
|
return;
|
|
68308
68700
|
}
|
|
68309
|
-
lines.push(` ${
|
|
68701
|
+
lines.push(` ${import_picocolors43.default.dim("run")} ${import_picocolors43.default.cyan("brainbase orchestration pull")} ${import_picocolors43.default.dim("to apply cloud changes,")} ${import_picocolors43.default.cyan("brainbase orchestration push")} ${import_picocolors43.default.dim("to send yours")}`);
|
|
68310
68702
|
lines.push("");
|
|
68311
68703
|
console.log(lines.join(`
|
|
68312
68704
|
`));
|
|
@@ -68321,7 +68713,7 @@ function stableJson(value) {
|
|
|
68321
68713
|
}
|
|
68322
68714
|
|
|
68323
68715
|
// src/cli/orchestration-list.ts
|
|
68324
|
-
var
|
|
68716
|
+
var import_picocolors44 = __toESM(require_picocolors(), 1);
|
|
68325
68717
|
async function runOrchestrationList(args) {
|
|
68326
68718
|
banner("orchestration list — orchestrations under a team");
|
|
68327
68719
|
const { org, team } = await resolveOrgAndTeam({
|
|
@@ -68345,13 +68737,13 @@ async function runOrchestrationList(args) {
|
|
|
68345
68737
|
}
|
|
68346
68738
|
const lines = [""];
|
|
68347
68739
|
for (const o2 of items) {
|
|
68348
|
-
lines.push(` ${
|
|
68740
|
+
lines.push(` ${import_picocolors44.default.bold(o2.name)} ${import_picocolors44.default.dim(o2.id)}`);
|
|
68349
68741
|
if (o2.description)
|
|
68350
|
-
lines.push(` ${
|
|
68351
|
-
lines.push(` ${
|
|
68742
|
+
lines.push(` ${import_picocolors44.default.dim(o2.description)}`);
|
|
68743
|
+
lines.push(` ${import_picocolors44.default.dim(`${o2.member_count} member${o2.member_count === 1 ? "" : "s"} · ${o2.edge_count} edge${o2.edge_count === 1 ? "" : "s"}`)}`);
|
|
68352
68744
|
lines.push("");
|
|
68353
68745
|
}
|
|
68354
|
-
lines.push(` ${
|
|
68746
|
+
lines.push(` ${import_picocolors44.default.dim("pull one with")} ${import_picocolors44.default.cyan("brainbase orchestration pull <id>")}`);
|
|
68355
68747
|
lines.push("");
|
|
68356
68748
|
console.log(lines.join(`
|
|
68357
68749
|
`));
|
|
@@ -68359,7 +68751,7 @@ async function runOrchestrationList(args) {
|
|
|
68359
68751
|
|
|
68360
68752
|
// src/cli/orchestration-add-agent.ts
|
|
68361
68753
|
import fs79 from "node:fs";
|
|
68362
|
-
var
|
|
68754
|
+
var import_picocolors45 = __toESM(require_picocolors(), 1);
|
|
68363
68755
|
|
|
68364
68756
|
// src/core/orchestration-add.ts
|
|
68365
68757
|
function resolveOrgIdForGroup(groupId, orgsWithTeams) {
|
|
@@ -68424,7 +68816,7 @@ async function runOrchestrationAddAgent(cwd2, args) {
|
|
|
68424
68816
|
const link2 = readOrchLink(cwd2);
|
|
68425
68817
|
if (!link2 || !hasOrchManifest(cwd2)) {
|
|
68426
68818
|
f2.warn("This folder is not a linked orchestration.");
|
|
68427
|
-
f2.info(`Run ${
|
|
68819
|
+
f2.info(`Run ${import_picocolors45.default.cyan("brainbase orchestration pull <id>")} first.`);
|
|
68428
68820
|
return;
|
|
68429
68821
|
}
|
|
68430
68822
|
let manifest;
|
|
@@ -68450,7 +68842,7 @@ async function runOrchestrationAddAgent(cwd2, args) {
|
|
|
68450
68842
|
while (manifest.members.some((m3) => m3.slug === candidate) || fs79.existsSync(memberDir(cwd2, candidate))) {
|
|
68451
68843
|
candidate = `${slug}-${++n}`;
|
|
68452
68844
|
}
|
|
68453
|
-
f2.info(`Slug ${
|
|
68845
|
+
f2.info(`Slug ${import_picocolors45.default.bold(slug)} is taken — using ${import_picocolors45.default.bold(candidate)}.`);
|
|
68454
68846
|
slug = candidate;
|
|
68455
68847
|
}
|
|
68456
68848
|
let payloadSchema;
|
|
@@ -68474,7 +68866,7 @@ async function runOrchestrationAddAgent(cwd2, args) {
|
|
|
68474
68866
|
const resolved = resolveOrgIdForGroup(link2.group_id, orgsWithTeams);
|
|
68475
68867
|
if (!resolved) {
|
|
68476
68868
|
sp.stop("Failed.");
|
|
68477
|
-
f2.error(`Could not find an org that owns group ${
|
|
68869
|
+
f2.error(`Could not find an org that owns group ${import_picocolors45.default.bold(link2.group_id)}. ` + `Pass ${import_picocolors45.default.cyan("--org <id>")} explicitly.`);
|
|
68478
68870
|
return;
|
|
68479
68871
|
}
|
|
68480
68872
|
orgId = resolved;
|
|
@@ -68491,14 +68883,14 @@ async function runOrchestrationAddAgent(cwd2, args) {
|
|
|
68491
68883
|
if (from.length === 0 && to2.length === 0 && isInteractive() && manifest.members.length > 0) {
|
|
68492
68884
|
const memberOptions = manifest.members.map((m3) => ({ value: m3.slug, label: m3.slug }));
|
|
68493
68885
|
const pickedFrom = await ae({
|
|
68494
|
-
message: `Connect ${
|
|
68886
|
+
message: `Connect ${import_picocolors45.default.bold(slug)} FROM which member(s)? — edges INTO ${slug} (space to select, enter to skip)`,
|
|
68495
68887
|
options: memberOptions,
|
|
68496
68888
|
required: false
|
|
68497
68889
|
});
|
|
68498
68890
|
if (Array.isArray(pickedFrom))
|
|
68499
68891
|
from = pickedFrom;
|
|
68500
68892
|
const pickedTo = await ae({
|
|
68501
|
-
message: `Connect ${
|
|
68893
|
+
message: `Connect ${import_picocolors45.default.bold(slug)} TO which member(s)? — edges OUT of ${slug} (space to select, enter to skip)`,
|
|
68502
68894
|
options: memberOptions,
|
|
68503
68895
|
required: false
|
|
68504
68896
|
});
|
|
@@ -68537,23 +68929,23 @@ async function runOrchestrationAddAgent(cwd2, args) {
|
|
|
68537
68929
|
}
|
|
68538
68930
|
writeOrchManifest(cwd2, updated);
|
|
68539
68931
|
if (args.noPush) {
|
|
68540
|
-
f2.info(`Manifest updated. Run ${
|
|
68932
|
+
f2.info(`Manifest updated. Run ${import_picocolors45.default.cyan("brainbase orchestration push")} to apply.`);
|
|
68541
68933
|
return;
|
|
68542
68934
|
}
|
|
68543
68935
|
await runOrchestrationPush(cwd2, { yes: true, graphOnly: true });
|
|
68544
68936
|
}
|
|
68545
68937
|
|
|
68546
68938
|
// src/cli/orchestration-create.ts
|
|
68547
|
-
var
|
|
68939
|
+
var import_picocolors46 = __toESM(require_picocolors(), 1);
|
|
68548
68940
|
async function runOrchestrationCreate(cwd2, args) {
|
|
68549
68941
|
banner("orchestration create — claim a brainbase-orchestration.yaml");
|
|
68550
68942
|
if (readOrchLink(cwd2)) {
|
|
68551
68943
|
f2.warn("This folder is already linked to an orchestration.");
|
|
68552
|
-
f2.info(`Run ${
|
|
68944
|
+
f2.info(`Run ${import_picocolors46.default.cyan("brainbase orchestration push")} to update it.`);
|
|
68553
68945
|
return;
|
|
68554
68946
|
}
|
|
68555
68947
|
if (!hasOrchManifest(cwd2)) {
|
|
68556
|
-
f2.warn(`No ${
|
|
68948
|
+
f2.warn(`No ${import_picocolors46.default.bold(ORCH_MANIFEST_FILE)} here.`);
|
|
68557
68949
|
f2.info(`Create one, or pull an existing orchestration first.`);
|
|
68558
68950
|
return;
|
|
68559
68951
|
}
|
|
@@ -68586,10 +68978,10 @@ async function runOrchestrationCreate(cwd2, args) {
|
|
|
68586
68978
|
});
|
|
68587
68979
|
const plan = [
|
|
68588
68980
|
"",
|
|
68589
|
-
` ${
|
|
68590
|
-
` ${
|
|
68591
|
-
` ${
|
|
68592
|
-
` ${
|
|
68981
|
+
` ${import_picocolors46.default.bold(manifest.orchestration.name)}`,
|
|
68982
|
+
` ${import_picocolors46.default.dim("org")} ${import_picocolors46.default.bold(target.org.name)}`,
|
|
68983
|
+
` ${import_picocolors46.default.dim("team")} ${import_picocolors46.default.bold(target.team.name)}`,
|
|
68984
|
+
` ${import_picocolors46.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"}`,
|
|
68593
68985
|
""
|
|
68594
68986
|
];
|
|
68595
68987
|
console.log(plan.join(`
|
|
@@ -68619,7 +69011,7 @@ async function runOrchestrationCreate(cwd2, args) {
|
|
|
68619
69011
|
edges: graph.edges,
|
|
68620
69012
|
triggers: graph.triggers
|
|
68621
69013
|
});
|
|
68622
|
-
sp.stop(`Created ${
|
|
69014
|
+
sp.stop(`Created ${import_picocolors46.default.bold(created.name)}.`);
|
|
68623
69015
|
writeOrchLink(cwd2, {
|
|
68624
69016
|
schemaVersion: 1,
|
|
68625
69017
|
orchestration_id: created.id,
|
|
@@ -68732,21 +69124,21 @@ async function runOrchestration(cwd2, sub, args, opts) {
|
|
|
68732
69124
|
function printHelp3() {
|
|
68733
69125
|
const out = [];
|
|
68734
69126
|
out.push("");
|
|
68735
|
-
out.push(` ${
|
|
69127
|
+
out.push(` ${import_picocolors47.default.bold("brainbase orchestration")} ${import_picocolors47.default.dim("<sub> [options]")}`);
|
|
68736
69128
|
out.push("");
|
|
68737
|
-
out.push(` ${
|
|
68738
|
-
out.push(` ${
|
|
68739
|
-
out.push(` ${
|
|
68740
|
-
out.push(` ${
|
|
68741
|
-
out.push(` ${
|
|
68742
|
-
out.push(` ${
|
|
69129
|
+
out.push(` ${import_picocolors47.default.cyan("create")} ${import_picocolors47.default.dim("claim a local orchestration manifest and create it in the cloud")}`);
|
|
69130
|
+
out.push(` ${import_picocolors47.default.cyan("pull")} ${import_picocolors47.default.dim("<id>")} ${import_picocolors47.default.dim("fetch orchestration + every member agent into this folder")}`);
|
|
69131
|
+
out.push(` ${import_picocolors47.default.cyan("push")} ${import_picocolors47.default.dim("push each member, then update the orchestration graph")}`);
|
|
69132
|
+
out.push(` ${import_picocolors47.default.cyan("add-agent")} ${import_picocolors47.default.dim("<name>")} ${import_picocolors47.default.dim("create a member agent, wire edges (--from/--to), and push")}`);
|
|
69133
|
+
out.push(` ${import_picocolors47.default.cyan("status")} ${import_picocolors47.default.dim("show what would push and what would pull")}`);
|
|
69134
|
+
out.push(` ${import_picocolors47.default.cyan("list")} ${import_picocolors47.default.dim("list orchestrations under a team")}`);
|
|
68743
69135
|
out.push("");
|
|
68744
|
-
out.push(` ${
|
|
68745
|
-
out.push(` ${
|
|
68746
|
-
out.push(` ${
|
|
68747
|
-
out.push(` ${
|
|
68748
|
-
out.push(` ${
|
|
68749
|
-
out.push(` ${
|
|
69136
|
+
out.push(` ${import_picocolors47.default.bold("Flags")}`);
|
|
69137
|
+
out.push(` ${import_picocolors47.default.dim("--yes, -y")} skip confirmations`);
|
|
69138
|
+
out.push(` ${import_picocolors47.default.dim("--harness <id>")} harness for newly-created member folders (default claude-code)`);
|
|
69139
|
+
out.push(` ${import_picocolors47.default.dim("--graph-only")} for push: only update members + edges, skip per-member push`);
|
|
69140
|
+
out.push(` ${import_picocolors47.default.dim("--org <id>")} for create/list: org id or slug (CLI vocab — DB teams.id)`);
|
|
69141
|
+
out.push(` ${import_picocolors47.default.dim("--team <id>")} for create/list: team id (CLI vocab — DB groups.id)`);
|
|
68750
69142
|
out.push("");
|
|
68751
69143
|
console.log(out.join(`
|
|
68752
69144
|
`));
|
|
@@ -68791,11 +69183,11 @@ async function runRun(cwd2, args) {
|
|
|
68791
69183
|
}
|
|
68792
69184
|
|
|
68793
69185
|
// src/cli/publish.ts
|
|
68794
|
-
var
|
|
69186
|
+
var import_picocolors48 = __toESM(require_picocolors(), 1);
|
|
68795
69187
|
function runPublish() {
|
|
68796
69188
|
banner("publish — moved");
|
|
68797
|
-
f2.error(`${
|
|
68798
|
-
f2.info(`Use ${
|
|
69189
|
+
f2.error(`${import_picocolors48.default.bold("brainbase publish")} does not exist.`);
|
|
69190
|
+
f2.info(`Use ${import_picocolors48.default.cyan("brainbase agent push")} to send your local changes to the cloud.`);
|
|
68799
69191
|
process.exit(1);
|
|
68800
69192
|
}
|
|
68801
69193
|
|
|
@@ -69094,7 +69486,7 @@ async function runStatus(cwd2) {
|
|
|
69094
69486
|
}
|
|
69095
69487
|
|
|
69096
69488
|
// src/cli/token.ts
|
|
69097
|
-
var
|
|
69489
|
+
var import_picocolors49 = __toESM(require_picocolors(), 1);
|
|
69098
69490
|
|
|
69099
69491
|
// src/ui/ink/TokenCards.tsx
|
|
69100
69492
|
var jsx_dev_runtime17 = __toESM(require_jsx_dev_runtime(), 1);
|
|
@@ -69516,7 +69908,7 @@ async function runTokenRename(args) {
|
|
|
69516
69908
|
}
|
|
69517
69909
|
}
|
|
69518
69910
|
if (name === target.name.trim()) {
|
|
69519
|
-
console.log(`${sym.ok} ${
|
|
69911
|
+
console.log(`${sym.ok} ${import_picocolors49.default.bold(target.name.trim())} already has that label; nothing to do.`);
|
|
69520
69912
|
return;
|
|
69521
69913
|
}
|
|
69522
69914
|
try {
|
|
@@ -69524,7 +69916,7 @@ async function runTokenRename(args) {
|
|
|
69524
69916
|
} catch (error) {
|
|
69525
69917
|
throw withLoginHint(error);
|
|
69526
69918
|
}
|
|
69527
|
-
console.log(`${sym.ok} Renamed ${
|
|
69919
|
+
console.log(`${sym.ok} Renamed ${import_picocolors49.default.dim(target.name)} → ${import_picocolors49.default.bold(name)}`);
|
|
69528
69920
|
}
|
|
69529
69921
|
async function runTokenRevoke(args) {
|
|
69530
69922
|
if (!args.id) {
|
|
@@ -69542,14 +69934,14 @@ async function runTokenRevoke(args) {
|
|
|
69542
69934
|
throw new Error(`No token with id ${args.id}. Run \`brainbase token list\` to see yours.`);
|
|
69543
69935
|
}
|
|
69544
69936
|
if (target.revoked_at) {
|
|
69545
|
-
reconcileDeadToken(target, `${
|
|
69937
|
+
reconcileDeadToken(target, `${import_picocolors49.default.bold(target.name)} is already revoked.`);
|
|
69546
69938
|
return;
|
|
69547
69939
|
}
|
|
69548
69940
|
const stored = readToken();
|
|
69549
69941
|
const isLocalToken = Boolean(stored && stored.token.startsWith(target.prefix));
|
|
69550
69942
|
if (!autoProceed(args.yes)) {
|
|
69551
69943
|
const ok = await se({
|
|
69552
|
-
message: isLocalToken ? `Revoke ${
|
|
69944
|
+
message: isLocalToken ? `Revoke ${import_picocolors49.default.bold(target.name)} (${args.id})? This is the token this CLI is using, so it will stop working here too.` : `Revoke ${import_picocolors49.default.bold(target.name)} (${args.id})? CIs and machines using it will stop working.`,
|
|
69553
69945
|
initialValue: false
|
|
69554
69946
|
});
|
|
69555
69947
|
if (!ensureNotCancelled(ok))
|
|
@@ -69560,14 +69952,14 @@ async function runTokenRevoke(args) {
|
|
|
69560
69952
|
} catch (error) {
|
|
69561
69953
|
if (error instanceof ApiError && error.status === 404) {
|
|
69562
69954
|
if (isExpired2(target)) {
|
|
69563
|
-
reconcileDeadToken(target, `${
|
|
69955
|
+
reconcileDeadToken(target, `${import_picocolors49.default.bold(target.name)} had already expired.`);
|
|
69564
69956
|
return;
|
|
69565
69957
|
}
|
|
69566
69958
|
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.");
|
|
69567
69959
|
}
|
|
69568
69960
|
throw withLoginHint(error);
|
|
69569
69961
|
}
|
|
69570
|
-
reconcileDeadToken(target, `Revoked ${
|
|
69962
|
+
reconcileDeadToken(target, `Revoked ${import_picocolors49.default.bold(target.name)}.`);
|
|
69571
69963
|
}
|
|
69572
69964
|
function reconcileDeadToken(target, headline) {
|
|
69573
69965
|
let outcome;
|
|
@@ -69601,7 +69993,7 @@ function reportLocalToken(headline, outcome) {
|
|
|
69601
69993
|
}
|
|
69602
69994
|
async function runTokenClear() {
|
|
69603
69995
|
if (!readToken()) {
|
|
69604
|
-
console.log(
|
|
69996
|
+
console.log(import_picocolors49.default.dim("No local token stored."));
|
|
69605
69997
|
return;
|
|
69606
69998
|
}
|
|
69607
69999
|
clearToken();
|
|
@@ -69701,31 +70093,31 @@ async function runToken(sub, rest2, args) {
|
|
|
69701
70093
|
function printTokenHelp() {
|
|
69702
70094
|
const out = [];
|
|
69703
70095
|
out.push("");
|
|
69704
|
-
out.push(` ${
|
|
70096
|
+
out.push(` ${import_picocolors49.default.bold("brainbase token")} ${import_picocolors49.default.dim("<command>")}`);
|
|
69705
70097
|
out.push("");
|
|
69706
|
-
out.push(` ${
|
|
69707
|
-
out.push(` ${
|
|
69708
|
-
out.push(` ${
|
|
69709
|
-
out.push(` ${
|
|
69710
|
-
out.push(` ${
|
|
70098
|
+
out.push(` ${import_picocolors49.default.cyan("create")} ${import_picocolors49.default.dim("issue a new long-lived CLI key (PAT)")}`);
|
|
70099
|
+
out.push(` ${import_picocolors49.default.cyan("list")} ${import_picocolors49.default.dim("show your tokens")}`);
|
|
70100
|
+
out.push(` ${import_picocolors49.default.cyan("rename")} ${import_picocolors49.default.dim("<id>")} ${import_picocolors49.default.dim("relabel a token by id")}`);
|
|
70101
|
+
out.push(` ${import_picocolors49.default.cyan("revoke")} ${import_picocolors49.default.dim("<id>")} ${import_picocolors49.default.dim("revoke a token by id")}`);
|
|
70102
|
+
out.push(` ${import_picocolors49.default.cyan("clear")} ${import_picocolors49.default.dim("forget the local token (does not revoke)")}`);
|
|
69711
70103
|
out.push("");
|
|
69712
|
-
out.push(` ${
|
|
69713
|
-
out.push(` ${
|
|
69714
|
-
out.push(` ${
|
|
69715
|
-
out.push(` ${
|
|
70104
|
+
out.push(` ${import_picocolors49.default.bold("create flags")}`);
|
|
70105
|
+
out.push(` ${import_picocolors49.default.cyan("--name, -n")} ${import_picocolors49.default.dim("<label>")} ${import_picocolors49.default.dim("token label (prompted if omitted)")}`);
|
|
70106
|
+
out.push(` ${import_picocolors49.default.cyan("--scopes")} ${import_picocolors49.default.dim("<list>")} ${import_picocolors49.default.dim("comma-separated; allowed: read, publish, admin")}`);
|
|
70107
|
+
out.push(` ${import_picocolors49.default.dim("default: read,publish")}`);
|
|
69716
70108
|
out.push("");
|
|
69717
|
-
out.push(` ${
|
|
69718
|
-
out.push(` ${
|
|
70109
|
+
out.push(` ${import_picocolors49.default.bold("rename flags")}`);
|
|
70110
|
+
out.push(` ${import_picocolors49.default.cyan("--name, -n")} ${import_picocolors49.default.dim("<label>")} ${import_picocolors49.default.dim("new label (prompted if omitted)")}`);
|
|
69719
70111
|
out.push("");
|
|
69720
70112
|
console.log(out.join(`
|
|
69721
70113
|
`));
|
|
69722
70114
|
}
|
|
69723
70115
|
|
|
69724
70116
|
// src/cli/mcp.ts
|
|
69725
|
-
var
|
|
70117
|
+
var import_picocolors50 = __toESM(require_picocolors(), 1);
|
|
69726
70118
|
|
|
69727
70119
|
// src/core/mcp-check/collect-servers.ts
|
|
69728
|
-
import
|
|
70120
|
+
import path88 from "node:path";
|
|
69729
70121
|
import fs80 from "node:fs";
|
|
69730
70122
|
function collectServers(cwd2, env3 = process.env) {
|
|
69731
70123
|
const out = [];
|
|
@@ -69777,7 +70169,7 @@ function pushResolved(out, seen, name, entry, env3) {
|
|
|
69777
70169
|
out.push({ name, url: finalUrl, headers });
|
|
69778
70170
|
}
|
|
69779
70171
|
function* readResolvedMcps(cwd2) {
|
|
69780
|
-
const p2 =
|
|
70172
|
+
const p2 = path88.join(cwd2, ".brainbase", "resolved-mcps.json");
|
|
69781
70173
|
let raw;
|
|
69782
70174
|
try {
|
|
69783
70175
|
raw = fs80.readFileSync(p2, "utf-8");
|
|
@@ -69804,12 +70196,12 @@ function* readResolvedMcps(cwd2) {
|
|
|
69804
70196
|
}
|
|
69805
70197
|
}
|
|
69806
70198
|
function readClaudeCode(cwd2) {
|
|
69807
|
-
const file =
|
|
70199
|
+
const file = path88.join(cwd2, ".mcp.json");
|
|
69808
70200
|
const map2 = listMcpServersFromMcpJson(file);
|
|
69809
70201
|
return Object.entries(map2);
|
|
69810
70202
|
}
|
|
69811
70203
|
function readCodex(cwd2) {
|
|
69812
|
-
const file =
|
|
70204
|
+
const file = path88.join(cwd2, ".codex", "config.toml");
|
|
69813
70205
|
try {
|
|
69814
70206
|
return Object.entries(listMcpServers2(file));
|
|
69815
70207
|
} catch {
|
|
@@ -69817,7 +70209,7 @@ function readCodex(cwd2) {
|
|
|
69817
70209
|
}
|
|
69818
70210
|
}
|
|
69819
70211
|
function readKafka(cwd2) {
|
|
69820
|
-
const file =
|
|
70212
|
+
const file = path88.join(cwd2, ".kafka", "kafka.json");
|
|
69821
70213
|
try {
|
|
69822
70214
|
return Object.entries(listMcpServers3(file));
|
|
69823
70215
|
} catch {
|
|
@@ -70105,10 +70497,10 @@ function assignProp(target, prop, value) {
|
|
|
70105
70497
|
configurable: true
|
|
70106
70498
|
});
|
|
70107
70499
|
}
|
|
70108
|
-
function getElementAtPath(obj,
|
|
70109
|
-
if (!
|
|
70500
|
+
function getElementAtPath(obj, path89) {
|
|
70501
|
+
if (!path89)
|
|
70110
70502
|
return obj;
|
|
70111
|
-
return
|
|
70503
|
+
return path89.reduce((acc, key2) => acc?.[key2], obj);
|
|
70112
70504
|
}
|
|
70113
70505
|
function promiseAllObject(promisesObj) {
|
|
70114
70506
|
const keys2 = Object.keys(promisesObj);
|
|
@@ -70424,11 +70816,11 @@ function aborted(x3, startIndex = 0) {
|
|
|
70424
70816
|
}
|
|
70425
70817
|
return false;
|
|
70426
70818
|
}
|
|
70427
|
-
function prefixIssues(
|
|
70819
|
+
function prefixIssues(path89, issues) {
|
|
70428
70820
|
return issues.map((iss) => {
|
|
70429
70821
|
var _a;
|
|
70430
70822
|
(_a = iss).path ?? (_a.path = []);
|
|
70431
|
-
iss.path.unshift(
|
|
70823
|
+
iss.path.unshift(path89);
|
|
70432
70824
|
return iss;
|
|
70433
70825
|
});
|
|
70434
70826
|
}
|
|
@@ -76194,8 +76586,8 @@ async function random2(size2) {
|
|
|
76194
76586
|
const evenDistCutoff = Math.pow(2, 8) - Math.pow(2, 8) % mask.length;
|
|
76195
76587
|
let result2 = "";
|
|
76196
76588
|
while (result2.length < size2) {
|
|
76197
|
-
const
|
|
76198
|
-
for (const randomByte of
|
|
76589
|
+
const randomBytes2 = await getRandomValues(size2 - result2.length);
|
|
76590
|
+
for (const randomByte of randomBytes2) {
|
|
76199
76591
|
if (randomByte < evenDistCutoff) {
|
|
76200
76592
|
result2 += mask[randomByte % mask.length];
|
|
76201
76593
|
}
|
|
@@ -78079,17 +78471,17 @@ async function runMcpCheck(cwd2, options) {
|
|
|
78079
78471
|
function renderHuman(report2) {
|
|
78080
78472
|
const lines = [];
|
|
78081
78473
|
if (report2.check_status === "skipped") {
|
|
78082
|
-
lines.push(
|
|
78474
|
+
lines.push(import_picocolors50.default.dim("No MCP servers configured — nothing to check."));
|
|
78083
78475
|
return lines.join(`
|
|
78084
78476
|
`) + `
|
|
78085
78477
|
`;
|
|
78086
78478
|
}
|
|
78087
78479
|
for (const s3 of report2.servers) {
|
|
78088
|
-
const mark = s3.status === "ok" ?
|
|
78089
|
-
const detail = s3.status === "ok" ?
|
|
78480
|
+
const mark = s3.status === "ok" ? import_picocolors50.default.green("✓") : s3.status === "auth_failed" ? import_picocolors50.default.red("✗") : import_picocolors50.default.yellow("⚠");
|
|
78481
|
+
const detail = s3.status === "ok" ? import_picocolors50.default.dim(`${s3.tool_count} tool${s3.tool_count === 1 ? "" : "s"}`) : import_picocolors50.default.dim(s3.status + (s3.error ? ` — ${s3.error}` : ""));
|
|
78090
78482
|
lines.push(` ${mark} ${s3.name} ${detail}`);
|
|
78091
78483
|
}
|
|
78092
|
-
const summary = report2.check_status === "ok" ?
|
|
78484
|
+
const summary = report2.check_status === "ok" ? import_picocolors50.default.green("All MCP servers connected.") : import_picocolors50.default.yellow("Some MCP servers are unhealthy.");
|
|
78093
78485
|
lines.push("", summary);
|
|
78094
78486
|
return lines.join(`
|
|
78095
78487
|
`) + `
|
|
@@ -78185,12 +78577,12 @@ function isUnhealthy(server) {
|
|
|
78185
78577
|
}
|
|
78186
78578
|
function renderServerList(servers) {
|
|
78187
78579
|
if (servers.length === 0) {
|
|
78188
|
-
return
|
|
78580
|
+
return import_picocolors50.default.dim("No MCP servers configured for this agent.") + `
|
|
78189
78581
|
`;
|
|
78190
78582
|
}
|
|
78191
78583
|
const lines = [""];
|
|
78192
78584
|
for (const s3 of servers) {
|
|
78193
|
-
const mark = s3.auth === "oauth_expired" ?
|
|
78585
|
+
const mark = s3.auth === "oauth_expired" ? import_picocolors50.default.red("✗") : s3.auth === "oauth_required" || isUnhealthy(s3) ? import_picocolors50.default.yellow("!") : !s3.is_enabled ? import_picocolors50.default.dim("·") : import_picocolors50.default.green("✓");
|
|
78194
78586
|
const bits = [s3.transport];
|
|
78195
78587
|
if (!s3.is_enabled)
|
|
78196
78588
|
bits.push("disabled");
|
|
@@ -78203,10 +78595,10 @@ function renderServerList(servers) {
|
|
|
78203
78595
|
const expiry = describeExpiry(s3);
|
|
78204
78596
|
if (expiry)
|
|
78205
78597
|
bits.push(expiry);
|
|
78206
|
-
lines.push(` ${mark} ${
|
|
78598
|
+
lines.push(` ${mark} ${import_picocolors50.default.bold(s3.name)} ${import_picocolors50.default.dim(bits.join(" · "))}`);
|
|
78207
78599
|
}
|
|
78208
78600
|
if (servers.some((s3) => s3.auth === "oauth_required" || s3.auth === "oauth_expired")) {
|
|
78209
|
-
lines.push("",
|
|
78601
|
+
lines.push("", import_picocolors50.default.dim("Authorize OAuth-backed servers in the web app; the CLI cannot run that flow yet."));
|
|
78210
78602
|
}
|
|
78211
78603
|
lines.push("");
|
|
78212
78604
|
return lines.join(`
|
|
@@ -78249,7 +78641,7 @@ async function runMcp(cwd2, sub, _argv, options) {
|
|
|
78249
78641
|
}
|
|
78250
78642
|
|
|
78251
78643
|
// src/cli/task.ts
|
|
78252
|
-
var
|
|
78644
|
+
var import_picocolors51 = __toESM(require_picocolors(), 1);
|
|
78253
78645
|
|
|
78254
78646
|
// src/cli/task-create.ts
|
|
78255
78647
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
@@ -78435,25 +78827,25 @@ async function runTask(cwd2, sub, args) {
|
|
|
78435
78827
|
function printHelp4() {
|
|
78436
78828
|
const out = [];
|
|
78437
78829
|
out.push("");
|
|
78438
|
-
out.push(` ${
|
|
78830
|
+
out.push(` ${import_picocolors51.default.bold("brainbase task")} ${import_picocolors51.default.dim("<sub> [options]")}`);
|
|
78439
78831
|
out.push("");
|
|
78440
|
-
out.push(` ${
|
|
78832
|
+
out.push(` ${import_picocolors51.default.cyan("create")} ${import_picocolors51.default.dim("--message <text>")} ${import_picocolors51.default.dim("create a task and start its first run")}`);
|
|
78441
78833
|
out.push("");
|
|
78442
|
-
out.push(` ${
|
|
78443
|
-
out.push(` ${
|
|
78444
|
-
out.push(` ${
|
|
78445
|
-
out.push(` ${
|
|
78446
|
-
out.push(` ${
|
|
78447
|
-
out.push(` ${
|
|
78834
|
+
out.push(` ${import_picocolors51.default.bold("create flags")}`);
|
|
78835
|
+
out.push(` ${import_picocolors51.default.dim("--message <text>")} required first user message`);
|
|
78836
|
+
out.push(` ${import_picocolors51.default.dim("--agent <id>")} override the claimed agent in brainbase.agent.yaml`);
|
|
78837
|
+
out.push(` ${import_picocolors51.default.dim("--title <text>")} optional task title`);
|
|
78838
|
+
out.push(` ${import_picocolors51.default.dim("--model <id>")} optional model override`);
|
|
78839
|
+
out.push(` ${import_picocolors51.default.dim("--json")} print task_id, agent_id, and status as JSON`);
|
|
78448
78840
|
out.push("");
|
|
78449
|
-
out.push(` ${
|
|
78841
|
+
out.push(` ${import_picocolors51.default.dim("Flag-like values:")} use ${import_picocolors51.default.cyan("--flag=value")} or ${import_picocolors51.default.cyan("--flag -- <value>")}`);
|
|
78450
78842
|
out.push("");
|
|
78451
78843
|
console.log(out.join(`
|
|
78452
78844
|
`));
|
|
78453
78845
|
}
|
|
78454
78846
|
|
|
78455
78847
|
// src/cli/benchmark.ts
|
|
78456
|
-
var
|
|
78848
|
+
var import_picocolors52 = __toESM(require_picocolors(), 1);
|
|
78457
78849
|
import {
|
|
78458
78850
|
execFileSync as execFileSync3,
|
|
78459
78851
|
spawn as spawn5
|
|
@@ -78461,7 +78853,7 @@ import {
|
|
|
78461
78853
|
import crypto7 from "node:crypto";
|
|
78462
78854
|
import fs82 from "node:fs";
|
|
78463
78855
|
import os17 from "node:os";
|
|
78464
|
-
import
|
|
78856
|
+
import path90 from "node:path";
|
|
78465
78857
|
|
|
78466
78858
|
// src/core/benchmark-phase.ts
|
|
78467
78859
|
import {
|
|
@@ -78471,7 +78863,7 @@ import {
|
|
|
78471
78863
|
import crypto6 from "node:crypto";
|
|
78472
78864
|
import fs81 from "node:fs";
|
|
78473
78865
|
import os16 from "node:os";
|
|
78474
|
-
import
|
|
78866
|
+
import path89 from "node:path";
|
|
78475
78867
|
import { Readable, Transform as Transform2 } from "node:stream";
|
|
78476
78868
|
import { pipeline as pipeline2 } from "node:stream/promises";
|
|
78477
78869
|
import { createGunzip, createInflateRaw } from "node:zlib";
|
|
@@ -78515,7 +78907,7 @@ var BASE_ENV_NAMES = [
|
|
|
78515
78907
|
"USER"
|
|
78516
78908
|
];
|
|
78517
78909
|
var SENSITIVE_ENV_NAME_RE = /(?:^|_)(?:TOKEN|SECRET|PASSWORD|PASSWD|API_KEY|PRIVATE_KEY|ACCESS_KEY|PAT|CREDENTIAL)(?:$|_)|^(?:PGPASSWORD|DATABASE_URL|REDIS_URL|MONGODB_URI)$/i;
|
|
78518
|
-
var AbsolutePathSchema = exports_external.string().min(1).refine(
|
|
78910
|
+
var AbsolutePathSchema = exports_external.string().min(1).refine(path89.isAbsolute, {
|
|
78519
78911
|
message: "must be an absolute path"
|
|
78520
78912
|
});
|
|
78521
78913
|
var Sha256Schema = exports_external.string().regex(SHA256_RE).transform((value) => value.toLowerCase());
|
|
@@ -78933,35 +79325,35 @@ function normalizedRootRelative(input) {
|
|
|
78933
79325
|
return safeRelPath(input);
|
|
78934
79326
|
}
|
|
78935
79327
|
function isWithin(root, candidate) {
|
|
78936
|
-
const relative =
|
|
78937
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
79328
|
+
const relative = path89.relative(path89.resolve(root), path89.resolve(candidate));
|
|
79329
|
+
return relative === "" || !relative.startsWith("..") && !path89.isAbsolute(relative);
|
|
78938
79330
|
}
|
|
78939
79331
|
function canonicalFuturePath(input) {
|
|
78940
|
-
const resolved =
|
|
79332
|
+
const resolved = path89.resolve(input);
|
|
78941
79333
|
const suffix = [];
|
|
78942
79334
|
let current = resolved;
|
|
78943
79335
|
while (!fs81.existsSync(current)) {
|
|
78944
|
-
const parent =
|
|
79336
|
+
const parent = path89.dirname(current);
|
|
78945
79337
|
if (parent === current)
|
|
78946
79338
|
break;
|
|
78947
|
-
suffix.unshift(
|
|
79339
|
+
suffix.unshift(path89.basename(current));
|
|
78948
79340
|
current = parent;
|
|
78949
79341
|
}
|
|
78950
79342
|
const canonicalBase = fs81.realpathSync(current);
|
|
78951
|
-
return
|
|
79343
|
+
return path89.join(canonicalBase, ...suffix);
|
|
78952
79344
|
}
|
|
78953
79345
|
function validateRoots(spec) {
|
|
78954
|
-
const workspace =
|
|
79346
|
+
const workspace = path89.resolve(spec.workspace_root);
|
|
78955
79347
|
if (!fs81.existsSync(workspace) || fs81.lstatSync(workspace).isSymbolicLink() || !fs81.lstatSync(workspace).isDirectory()) {
|
|
78956
79348
|
throw new BenchmarkPhaseError("invalid_workspace_root", "workspace_root must be an existing real directory");
|
|
78957
79349
|
}
|
|
78958
79350
|
const canonicalWorkspace = canonicalFuturePath(workspace);
|
|
78959
|
-
const staging =
|
|
78960
|
-
const expectedStaging =
|
|
79351
|
+
const staging = path89.resolve(spec.staging_root);
|
|
79352
|
+
const expectedStaging = path89.join(workspace, ".brainbase", "benchmark", spec.attempt_id, "incoming");
|
|
78961
79353
|
if (staging !== expectedStaging) {
|
|
78962
79354
|
throw new BenchmarkPhaseError("invalid_staging_root", `staging_root must be ${expectedStaging}`);
|
|
78963
79355
|
}
|
|
78964
|
-
if (!fs81.existsSync(staging) || fs81.lstatSync(staging).isSymbolicLink() || !fs81.lstatSync(staging).isDirectory() || fs81.realpathSync(staging) !==
|
|
79356
|
+
if (!fs81.existsSync(staging) || fs81.lstatSync(staging).isSymbolicLink() || !fs81.lstatSync(staging).isDirectory() || fs81.realpathSync(staging) !== path89.join(canonicalWorkspace, ".brainbase", "benchmark", spec.attempt_id, "incoming")) {
|
|
78965
79357
|
throw new BenchmarkPhaseError("invalid_staging_root", "staging_root must be a real directory under workspace_root");
|
|
78966
79358
|
}
|
|
78967
79359
|
const canonicalLogs = validateExternalRoot("logs_root", spec.logs_root, canonicalWorkspace);
|
|
@@ -78973,8 +79365,8 @@ function validateRoots(spec) {
|
|
|
78973
79365
|
}
|
|
78974
79366
|
}
|
|
78975
79367
|
function validateExternalRoot(label, input, canonicalWorkspace) {
|
|
78976
|
-
const candidate =
|
|
78977
|
-
if (candidate ===
|
|
79368
|
+
const candidate = path89.resolve(input);
|
|
79369
|
+
if (candidate === path89.parse(candidate).root) {
|
|
78978
79370
|
throw new BenchmarkPhaseError(`invalid_${label}`, `${label} cannot be a filesystem root`);
|
|
78979
79371
|
}
|
|
78980
79372
|
if (fs81.existsSync(candidate) && fs81.lstatSync(candidate).isSymbolicLink()) {
|
|
@@ -79004,9 +79396,9 @@ function assertNoSymlinkTraversal(root, relative) {
|
|
|
79004
79396
|
const rel = normalizedRootRelative(relative);
|
|
79005
79397
|
if (rel === ".")
|
|
79006
79398
|
return;
|
|
79007
|
-
let current =
|
|
79399
|
+
let current = path89.resolve(root);
|
|
79008
79400
|
for (const segment of rel.split("/").slice(0, -1)) {
|
|
79009
|
-
current =
|
|
79401
|
+
current = path89.join(current, segment);
|
|
79010
79402
|
if (!fs81.existsSync(current))
|
|
79011
79403
|
continue;
|
|
79012
79404
|
if (fs81.lstatSync(current).isSymbolicLink()) {
|
|
@@ -79075,10 +79467,10 @@ function assertWritableDestination(root, relative) {
|
|
|
79075
79467
|
const rel = normalizedRootRelative(relative);
|
|
79076
79468
|
if (rel === ".")
|
|
79077
79469
|
return;
|
|
79078
|
-
let current =
|
|
79470
|
+
let current = path89.resolve(root);
|
|
79079
79471
|
const segments = rel.split("/");
|
|
79080
79472
|
for (const segment of segments.slice(0, -1)) {
|
|
79081
|
-
current =
|
|
79473
|
+
current = path89.join(current, segment);
|
|
79082
79474
|
if (!fs81.existsSync(current))
|
|
79083
79475
|
continue;
|
|
79084
79476
|
const stat = fs81.lstatSync(current);
|
|
@@ -79089,7 +79481,7 @@ function assertWritableDestination(root, relative) {
|
|
|
79089
79481
|
throw new BenchmarkPhaseError("destination_conflict", `destination parent is not a directory: ${relative}`);
|
|
79090
79482
|
}
|
|
79091
79483
|
}
|
|
79092
|
-
const destination =
|
|
79484
|
+
const destination = path89.resolve(root, rel);
|
|
79093
79485
|
if (fs81.existsSync(destination) && fs81.lstatSync(destination).isDirectory()) {
|
|
79094
79486
|
throw new BenchmarkPhaseError("destination_conflict", `file destination is an existing directory: ${relative}`);
|
|
79095
79487
|
}
|
|
@@ -79115,7 +79507,7 @@ function validateDestinationGraph(paths) {
|
|
|
79115
79507
|
}
|
|
79116
79508
|
function sourcePath(stagingRoot, relative) {
|
|
79117
79509
|
const rel = safeRelPath(relative);
|
|
79118
|
-
const source =
|
|
79510
|
+
const source = path89.resolve(stagingRoot, rel);
|
|
79119
79511
|
if (!isWithin(stagingRoot, source)) {
|
|
79120
79512
|
throw new BenchmarkPhaseError("unsafe_path", `source escapes staging root: ${relative}`);
|
|
79121
79513
|
}
|
|
@@ -79150,7 +79542,7 @@ async function verifyRecordsUnchanged(records, spec) {
|
|
|
79150
79542
|
}
|
|
79151
79543
|
const relative = safeRelPath(record3.path);
|
|
79152
79544
|
assertNoSymlinkTraversal(root, relative);
|
|
79153
|
-
const candidate =
|
|
79545
|
+
const candidate = path89.resolve(root, relative);
|
|
79154
79546
|
if (!isWithin(root, candidate)) {
|
|
79155
79547
|
throw new BenchmarkPhaseError("evidence_tampered", `evidence was removed during evaluation: ${record3.root}:${record3.path}`);
|
|
79156
79548
|
}
|
|
@@ -79220,7 +79612,7 @@ async function cachedVerifiedInput(stagingRoot, input, context) {
|
|
|
79220
79612
|
function stagedInputRecord(stagingRoot, verified) {
|
|
79221
79613
|
return {
|
|
79222
79614
|
root: "staging",
|
|
79223
|
-
path:
|
|
79615
|
+
path: path89.relative(stagingRoot, verified.source).replace(/\\/g, "/"),
|
|
79224
79616
|
sha256: verified.sha256,
|
|
79225
79617
|
size: verified.size,
|
|
79226
79618
|
mode: verified.mode,
|
|
@@ -79241,7 +79633,7 @@ function removeRemoteHydrationInputs(spec) {
|
|
|
79241
79633
|
if (!material.download_url_env || removedSources.has(material.source))
|
|
79242
79634
|
continue;
|
|
79243
79635
|
const relative = safeRelPath(material.source);
|
|
79244
|
-
const source =
|
|
79636
|
+
const source = path89.resolve(spec.staging_root, relative);
|
|
79245
79637
|
if (!isWithin(spec.staging_root, source)) {
|
|
79246
79638
|
throw new BenchmarkPhaseError("unsafe_path", `source escapes staging root: ${material.source}`);
|
|
79247
79639
|
}
|
|
@@ -79273,7 +79665,7 @@ async function downloadInputReference(stagingRoot, input, context) {
|
|
|
79273
79665
|
return await cachedVerifiedInput(stagingRoot, input, context);
|
|
79274
79666
|
}
|
|
79275
79667
|
const relative = safeRelPath(input.source);
|
|
79276
|
-
const destination =
|
|
79668
|
+
const destination = path89.resolve(stagingRoot, relative);
|
|
79277
79669
|
if (!isWithin(stagingRoot, destination)) {
|
|
79278
79670
|
throw new BenchmarkPhaseError("unsafe_path", `source escapes staging root: ${input.source}`);
|
|
79279
79671
|
}
|
|
@@ -79302,7 +79694,7 @@ async function downloadInputReference(stagingRoot, input, context) {
|
|
|
79302
79694
|
if (remainingMs <= 0) {
|
|
79303
79695
|
throw new BenchmarkPhaseError("phase_timeout", "phase budget expired");
|
|
79304
79696
|
}
|
|
79305
|
-
fs81.mkdirSync(
|
|
79697
|
+
fs81.mkdirSync(path89.dirname(destination), { recursive: true, mode: 448 });
|
|
79306
79698
|
assertNoSymlinkTraversal(stagingRoot, relative);
|
|
79307
79699
|
assertWritableDestination(stagingRoot, relative);
|
|
79308
79700
|
const temporary = `${destination}.${process.pid}.${crypto6.randomBytes(6).toString("hex")}.download`;
|
|
@@ -79521,7 +79913,7 @@ function findZipMembers(archivePath, requested, context) {
|
|
|
79521
79913
|
}
|
|
79522
79914
|
}
|
|
79523
79915
|
async function writeVerifiedArchiveMember(source, destination, material, context) {
|
|
79524
|
-
fs81.mkdirSync(
|
|
79916
|
+
fs81.mkdirSync(path89.dirname(destination), { recursive: true, mode: 448 });
|
|
79525
79917
|
const temporary = `${destination}.${process.pid}.${crypto6.randomBytes(6).toString("hex")}.tmp`;
|
|
79526
79918
|
const descriptor = fs81.openSync(temporary, "wx", 384);
|
|
79527
79919
|
const hash = crypto6.createHash("sha256");
|
|
@@ -79636,7 +80028,7 @@ async function extractArchiveMembers(archivePath, outputRoot, materials, context
|
|
|
79636
80028
|
const indexed = findZipMembers(archivePath, requested, context);
|
|
79637
80029
|
for (const [memberPath, material] of requested) {
|
|
79638
80030
|
assertBudget(context);
|
|
79639
|
-
const destination =
|
|
80031
|
+
const destination = path89.resolve(outputRoot, memberPath);
|
|
79640
80032
|
if (!isWithin(outputRoot, destination)) {
|
|
79641
80033
|
throw new BenchmarkPhaseError("unsafe_path", `archive member escapes output root: ${memberPath}`);
|
|
79642
80034
|
}
|
|
@@ -79712,7 +80104,7 @@ async function extractArchiveMembers(archivePath, outputRoot, materials, context
|
|
|
79712
80104
|
return extracted;
|
|
79713
80105
|
}
|
|
79714
80106
|
async function atomicCopy(source, destination, mode, sourceRoot) {
|
|
79715
|
-
fs81.mkdirSync(
|
|
80107
|
+
fs81.mkdirSync(path89.dirname(destination), { recursive: true });
|
|
79716
80108
|
const temporary = `${destination}.${process.pid}.${crypto6.randomBytes(6).toString("hex")}.tmp`;
|
|
79717
80109
|
const opened = openRegularFileNoFollow(source, `copy source ${source}`, sourceRoot);
|
|
79718
80110
|
try {
|
|
@@ -79732,7 +80124,7 @@ async function atomicCopy(source, destination, mode, sourceRoot) {
|
|
|
79732
80124
|
}
|
|
79733
80125
|
}
|
|
79734
80126
|
async function recordFile(root, filePath, rootName, kind = "file") {
|
|
79735
|
-
const relative =
|
|
80127
|
+
const relative = path89.relative(root, filePath).replace(/\\/g, "/");
|
|
79736
80128
|
if (kind === "symlink") {
|
|
79737
80129
|
const stat = fs81.lstatSync(filePath);
|
|
79738
80130
|
const target = fs81.readlinkSync(filePath);
|
|
@@ -79773,11 +80165,11 @@ async function copyMaterial(material, sourceRoot, destinationRoot, destinationRo
|
|
|
79773
80165
|
throw new BenchmarkPhaseError("unsafe_path", "file destination cannot be a directory root");
|
|
79774
80166
|
}
|
|
79775
80167
|
assertWritableDestination(destinationRoot, destinationRel);
|
|
79776
|
-
const destination =
|
|
80168
|
+
const destination = path89.resolve(destinationRoot, destinationRel);
|
|
79777
80169
|
if (material.kind === "file") {
|
|
79778
80170
|
await atomicCopy(source, destination, material.mode ?? verifiedSource?.mode, sourceRoot);
|
|
79779
80171
|
} else {
|
|
79780
|
-
await atomicCopy(source, destination, material.mode,
|
|
80172
|
+
await atomicCopy(source, destination, material.mode, path89.dirname(source));
|
|
79781
80173
|
}
|
|
79782
80174
|
const record3 = await recordFile(destinationRoot, destination, destinationRootName);
|
|
79783
80175
|
const expectedSha256 = material.kind === "archive_file" ? material.file_sha256 : material.sha256;
|
|
@@ -79787,15 +80179,15 @@ async function copyMaterial(material, sourceRoot, destinationRoot, destinationRo
|
|
|
79787
80179
|
}
|
|
79788
80180
|
return [record3];
|
|
79789
80181
|
}
|
|
79790
|
-
const temporary = fs81.mkdtempSync(
|
|
80182
|
+
const temporary = fs81.mkdtempSync(path89.join(os16.tmpdir(), "brainbase-benchmark-"));
|
|
79791
80183
|
try {
|
|
79792
|
-
const verifiedArchive =
|
|
80184
|
+
const verifiedArchive = path89.join(temporary, "material.tar.gz");
|
|
79793
80185
|
await atomicCopy(source, verifiedArchive, 384, sourceRoot);
|
|
79794
80186
|
const archiveRecord = await recordFile(temporary, verifiedArchive, "staging");
|
|
79795
80187
|
if (archiveRecord.sha256 !== material.sha256 || archiveRecord.size !== material.size_bytes) {
|
|
79796
80188
|
throw new BenchmarkPhaseError("evidence_tampered", `material changed while it was copied: ${material.source}`);
|
|
79797
80189
|
}
|
|
79798
|
-
const extractedRoot =
|
|
80190
|
+
const extractedRoot = path89.join(temporary, "extracted");
|
|
79799
80191
|
const extracted = await extract({
|
|
79800
80192
|
tarFile: verifiedArchive,
|
|
79801
80193
|
outDir: extractedRoot,
|
|
@@ -79804,17 +80196,17 @@ async function copyMaterial(material, sourceRoot, destinationRoot, destinationRo
|
|
|
79804
80196
|
});
|
|
79805
80197
|
const outputs = [];
|
|
79806
80198
|
for (const extractedRel of extracted.sort()) {
|
|
79807
|
-
const sourceFile =
|
|
80199
|
+
const sourceFile = path89.resolve(extractedRoot, safeRelPath(extractedRel));
|
|
79808
80200
|
const stat = fs81.lstatSync(sourceFile);
|
|
79809
80201
|
if (!stat.isFile())
|
|
79810
80202
|
continue;
|
|
79811
|
-
const combined = destinationRel === "." ? safeRelPath(extractedRel) : safeRelPath(
|
|
80203
|
+
const combined = destinationRel === "." ? safeRelPath(extractedRel) : safeRelPath(path89.posix.join(destinationRel, extractedRel));
|
|
79812
80204
|
const checked = protectWorkspace ? workspaceRel(combined) : combined;
|
|
79813
80205
|
if (!protectWorkspace && checked.toLowerCase() === ".brainbase-benchmark-owner.json") {
|
|
79814
80206
|
throw new BenchmarkPhaseError("reserved_path", "benchmark input cannot replace the phase ownership marker");
|
|
79815
80207
|
}
|
|
79816
80208
|
assertWritableDestination(destinationRoot, checked);
|
|
79817
|
-
const destination =
|
|
80209
|
+
const destination = path89.resolve(destinationRoot, checked);
|
|
79818
80210
|
await atomicCopy(sourceFile, destination, material.mode, extractedRoot);
|
|
79819
80211
|
outputs.push(await recordFile(destinationRoot, destination, destinationRootName));
|
|
79820
80212
|
}
|
|
@@ -79838,7 +80230,7 @@ async function preflightMaterial(material, materials, sourceRoot, destinationRoo
|
|
|
79838
80230
|
const cacheKey = archiveMemberCacheKey(material);
|
|
79839
80231
|
let extracted = context.preparedArchiveFiles.get(cacheKey);
|
|
79840
80232
|
if (!extracted) {
|
|
79841
|
-
const temporary2 = fs81.mkdtempSync(
|
|
80233
|
+
const temporary2 = fs81.mkdtempSync(path89.join(os16.tmpdir(), "brainbase-benchmark-member-"));
|
|
79842
80234
|
context.temporaryRoots.add(temporary2);
|
|
79843
80235
|
const archiveKey = archiveSourceCacheKey(material);
|
|
79844
80236
|
const related = materials.filter((candidate) => candidate.kind === "archive_file" && archiveSourceCacheKey(candidate) === archiveKey);
|
|
@@ -79858,15 +80250,15 @@ async function preflightMaterial(material, materials, sourceRoot, destinationRoo
|
|
|
79858
80250
|
}
|
|
79859
80251
|
return [destinationRel];
|
|
79860
80252
|
}
|
|
79861
|
-
const temporary = fs81.mkdtempSync(
|
|
80253
|
+
const temporary = fs81.mkdtempSync(path89.join(os16.tmpdir(), "brainbase-benchmark-preflight-"));
|
|
79862
80254
|
try {
|
|
79863
|
-
const verifiedArchive =
|
|
80255
|
+
const verifiedArchive = path89.join(temporary, "material.tar.gz");
|
|
79864
80256
|
await atomicCopy(source, verifiedArchive, 384, sourceRoot);
|
|
79865
80257
|
const archiveRecord = await recordFile(temporary, verifiedArchive, "staging");
|
|
79866
80258
|
if (archiveRecord.sha256 !== material.sha256 || archiveRecord.size !== material.size_bytes) {
|
|
79867
80259
|
throw new BenchmarkPhaseError("evidence_tampered", `material changed while it was copied: ${material.source}`);
|
|
79868
80260
|
}
|
|
79869
|
-
const extractedRoot =
|
|
80261
|
+
const extractedRoot = path89.join(temporary, "extracted");
|
|
79870
80262
|
const extracted = await extract({
|
|
79871
80263
|
tarFile: verifiedArchive,
|
|
79872
80264
|
outDir: extractedRoot,
|
|
@@ -79875,7 +80267,7 @@ async function preflightMaterial(material, materials, sourceRoot, destinationRoo
|
|
|
79875
80267
|
});
|
|
79876
80268
|
const planned = [];
|
|
79877
80269
|
for (const extractedRel of extracted) {
|
|
79878
|
-
const combined = destinationRel === "." ? safeRelPath(extractedRel) : safeRelPath(
|
|
80270
|
+
const combined = destinationRel === "." ? safeRelPath(extractedRel) : safeRelPath(path89.posix.join(destinationRel, extractedRel));
|
|
79879
80271
|
const checked = protectWorkspace ? workspaceRel(combined) : combined;
|
|
79880
80272
|
if (!protectWorkspace && checked.toLowerCase() === ".brainbase-benchmark-owner.json") {
|
|
79881
80273
|
throw new BenchmarkPhaseError("reserved_path", "benchmark input cannot replace the phase ownership marker");
|
|
@@ -79889,7 +80281,7 @@ async function preflightMaterial(material, materials, sourceRoot, destinationRoo
|
|
|
79889
80281
|
}
|
|
79890
80282
|
}
|
|
79891
80283
|
function ownerMarker(root) {
|
|
79892
|
-
return
|
|
80284
|
+
return path89.join(root, ".brainbase-benchmark-owner.json");
|
|
79893
80285
|
}
|
|
79894
80286
|
function verifyOwnedDirectory(root, role, spec) {
|
|
79895
80287
|
if (!fs81.existsSync(root) || fs81.lstatSync(root).isSymbolicLink())
|
|
@@ -80027,7 +80419,7 @@ function markedProcessPids(marker) {
|
|
|
80027
80419
|
if (pid === process.pid)
|
|
80028
80420
|
continue;
|
|
80029
80421
|
try {
|
|
80030
|
-
const environment = fs81.readFileSync(
|
|
80422
|
+
const environment = fs81.readFileSync(path89.join("/proc", entry, "environ"), "utf8");
|
|
80031
80423
|
if (environment.split("\x00").includes(assignment))
|
|
80032
80424
|
matches2.push(pid);
|
|
80033
80425
|
} catch {}
|
|
@@ -80061,7 +80453,7 @@ function markedProcessPids(marker) {
|
|
|
80061
80453
|
function processExists(pid) {
|
|
80062
80454
|
if (process.platform === "linux") {
|
|
80063
80455
|
try {
|
|
80064
|
-
const stat = fs81.readFileSync(
|
|
80456
|
+
const stat = fs81.readFileSync(path89.join("/proc", String(pid), "stat"), "utf8");
|
|
80065
80457
|
const commandEnd = stat.lastIndexOf(")");
|
|
80066
80458
|
const state = commandEnd >= 0 ? stat.slice(commandEnd + 2, commandEnd + 3) : "";
|
|
80067
80459
|
if (state === "Z" || state === "X")
|
|
@@ -80105,7 +80497,7 @@ async function terminateCommandProcesses(child, marker, observedDescendants) {
|
|
|
80105
80497
|
async function runCommand(command, root, spec, context, options = {}) {
|
|
80106
80498
|
const cwdRel = normalizedRootRelative(command.cwd);
|
|
80107
80499
|
assertNoSymlinkTraversal(root, cwdRel);
|
|
80108
|
-
const cwd2 =
|
|
80500
|
+
const cwd2 = path89.resolve(root, cwdRel);
|
|
80109
80501
|
let cwdStat;
|
|
80110
80502
|
try {
|
|
80111
80503
|
cwdStat = fs81.lstatSync(cwd2);
|
|
@@ -80228,8 +80620,8 @@ async function runCommand(command, root, spec, context, options = {}) {
|
|
|
80228
80620
|
});
|
|
80229
80621
|
}
|
|
80230
80622
|
async function writeLog(root, name, data, spec) {
|
|
80231
|
-
const destination =
|
|
80232
|
-
fs81.mkdirSync(
|
|
80623
|
+
const destination = path89.join(root, name);
|
|
80624
|
+
fs81.mkdirSync(path89.dirname(destination), { recursive: true });
|
|
80233
80625
|
const temporary = `${destination}.${process.pid}.${crypto6.randomBytes(6).toString("hex")}.tmp`;
|
|
80234
80626
|
try {
|
|
80235
80627
|
fs81.writeFileSync(temporary, redactCommandOutput(data, spec), {
|
|
@@ -80243,7 +80635,7 @@ async function writeLog(root, name, data, spec) {
|
|
|
80243
80635
|
return await recordFile(root, destination, "logs");
|
|
80244
80636
|
}
|
|
80245
80637
|
function writeBufferAtomic(destination, data) {
|
|
80246
|
-
fs81.mkdirSync(
|
|
80638
|
+
fs81.mkdirSync(path89.dirname(destination), { recursive: true });
|
|
80247
80639
|
const temporary = `${destination}.${process.pid}.${crypto6.randomBytes(6).toString("hex")}.tmp`;
|
|
80248
80640
|
try {
|
|
80249
80641
|
fs81.writeFileSync(temporary, data, { flag: "wx", mode: 384 });
|
|
@@ -80343,7 +80735,7 @@ async function executeHydrate(spec, context) {
|
|
|
80343
80735
|
finalOutputs.push(output);
|
|
80344
80736
|
continue;
|
|
80345
80737
|
}
|
|
80346
|
-
const candidate =
|
|
80738
|
+
const candidate = path89.resolve(spec.workspace_root, safeRelPath(output.path));
|
|
80347
80739
|
assertNoSymlinkTraversal(spec.workspace_root, output.path);
|
|
80348
80740
|
if (!fs81.existsSync(candidate))
|
|
80349
80741
|
continue;
|
|
@@ -80374,7 +80766,7 @@ async function readEvidence(stagingRoot, evidence) {
|
|
|
80374
80766
|
buffer,
|
|
80375
80767
|
record: {
|
|
80376
80768
|
root: "staging",
|
|
80377
|
-
path:
|
|
80769
|
+
path: path89.relative(stagingRoot, filePath).replace(/\\/g, "/"),
|
|
80378
80770
|
sha256: evidence.sha256,
|
|
80379
80771
|
size: opened.stat.size,
|
|
80380
80772
|
mode: opened.stat.mode & 511
|
|
@@ -80387,14 +80779,14 @@ async function readEvidence(stagingRoot, evidence) {
|
|
|
80387
80779
|
async function workspaceManifest(spec, context) {
|
|
80388
80780
|
const records = [];
|
|
80389
80781
|
let totalBytes = 0;
|
|
80390
|
-
const stack = [
|
|
80782
|
+
const stack = [path89.resolve(spec.workspace_root)];
|
|
80391
80783
|
while (stack.length > 0) {
|
|
80392
80784
|
const directory = stack.pop();
|
|
80393
80785
|
const entries = fs81.readdirSync(directory, { withFileTypes: true }).sort((a3, b4) => a3.name.localeCompare(b4.name));
|
|
80394
80786
|
for (const entry of entries) {
|
|
80395
80787
|
assertBudget(context);
|
|
80396
|
-
const full =
|
|
80397
|
-
const relative =
|
|
80788
|
+
const full = path89.join(directory, entry.name);
|
|
80789
|
+
const relative = path89.relative(spec.workspace_root, full).replace(/\\/g, "/");
|
|
80398
80790
|
if (relative === ".brainbase" || relative.startsWith(".brainbase/"))
|
|
80399
80791
|
continue;
|
|
80400
80792
|
if (relative === ".git" || relative.startsWith(".git/"))
|
|
@@ -80427,13 +80819,13 @@ async function verifyWorkspaceManifestUnchanged(expected, spec, context) {
|
|
|
80427
80819
|
}
|
|
80428
80820
|
function treeBytes(root, context) {
|
|
80429
80821
|
let totalBytes = 0;
|
|
80430
|
-
const stack = [
|
|
80822
|
+
const stack = [path89.resolve(root)];
|
|
80431
80823
|
while (stack.length > 0) {
|
|
80432
80824
|
const directory = stack.pop();
|
|
80433
80825
|
const entries = fs81.readdirSync(directory, { withFileTypes: true });
|
|
80434
80826
|
for (const entry of entries) {
|
|
80435
80827
|
assertBudget(context);
|
|
80436
|
-
const candidate =
|
|
80828
|
+
const candidate = path89.join(directory, entry.name);
|
|
80437
80829
|
const stat = fs81.lstatSync(candidate);
|
|
80438
80830
|
if (stat.isDirectory()) {
|
|
80439
80831
|
stack.push(candidate);
|
|
@@ -80447,7 +80839,7 @@ function treeBytes(root, context) {
|
|
|
80447
80839
|
totalBytes += Buffer.byteLength(fs81.readlinkSync(candidate));
|
|
80448
80840
|
continue;
|
|
80449
80841
|
}
|
|
80450
|
-
throw new BenchmarkPhaseError("unsafe_path", `evaluate output contains an unsupported filesystem entry: ${
|
|
80842
|
+
throw new BenchmarkPhaseError("unsafe_path", `evaluate output contains an unsupported filesystem entry: ${path89.relative(root, candidate)}`);
|
|
80451
80843
|
}
|
|
80452
80844
|
}
|
|
80453
80845
|
return totalBytes;
|
|
@@ -80493,11 +80885,11 @@ function manifestDirectories(manifest, context) {
|
|
|
80493
80885
|
assertBudget(context);
|
|
80494
80886
|
if (entry.kind === "symlink")
|
|
80495
80887
|
continue;
|
|
80496
|
-
let current =
|
|
80888
|
+
let current = path89.posix.dirname(entry.path);
|
|
80497
80889
|
while (current !== ".") {
|
|
80498
80890
|
assertBudget(context);
|
|
80499
80891
|
directories.add(current);
|
|
80500
|
-
current =
|
|
80892
|
+
current = path89.posix.dirname(current);
|
|
80501
80893
|
}
|
|
80502
80894
|
}
|
|
80503
80895
|
return [...directories].sort();
|
|
@@ -80566,8 +80958,8 @@ async function copyCandidateOutput(output, manifest, spec, context) {
|
|
|
80566
80958
|
const copied = [];
|
|
80567
80959
|
for (const frozenFile of selected.files) {
|
|
80568
80960
|
assertBudget(context);
|
|
80569
|
-
const source =
|
|
80570
|
-
const destination =
|
|
80961
|
+
const source = path89.resolve(spec.workspace_root, safeRelPath(frozenFile.path));
|
|
80962
|
+
const destination = path89.resolve(spec.logs_root, "candidate-outputs", output.id, safeRelPath(frozenFile.path));
|
|
80571
80963
|
if (fs81.existsSync(destination)) {
|
|
80572
80964
|
throw new BenchmarkPhaseError("destination_conflict", `candidate output destination already exists: ${output.id}/${frozenFile.path}`);
|
|
80573
80965
|
}
|
|
@@ -80581,24 +80973,24 @@ async function copyCandidateOutput(output, manifest, spec, context) {
|
|
|
80581
80973
|
return copied;
|
|
80582
80974
|
}
|
|
80583
80975
|
async function copyFrozenWorkspace(manifest, spec, context, sourceRoot = spec.workspace_root, symlinkPolicy = "preserve") {
|
|
80584
|
-
const destinationRoot = fs81.mkdtempSync(
|
|
80976
|
+
const destinationRoot = fs81.mkdtempSync(path89.join(os16.tmpdir(), "brainbase-benchmark-workspace-"));
|
|
80585
80977
|
fs81.chmodSync(destinationRoot, 448);
|
|
80586
80978
|
context.temporaryRoots.add(destinationRoot);
|
|
80587
80979
|
for (const frozenFile of manifest) {
|
|
80588
80980
|
assertBudget(context);
|
|
80589
|
-
const source =
|
|
80590
|
-
const destination =
|
|
80981
|
+
const source = path89.resolve(sourceRoot, safeRelPath(frozenFile.path));
|
|
80982
|
+
const destination = path89.resolve(destinationRoot, safeRelPath(frozenFile.path));
|
|
80591
80983
|
if (frozenFile.kind === "symlink") {
|
|
80592
80984
|
const stat = fs81.lstatSync(source);
|
|
80593
80985
|
const target = stat.isSymbolicLink() ? fs81.readlinkSync(source) : null;
|
|
80594
80986
|
if (target === null || Buffer.byteLength(target) !== frozenFile.size || sha256(target) !== frozenFile.sha256) {
|
|
80595
80987
|
throw new BenchmarkPhaseError("evidence_tampered", `workspace changed after it was frozen: ${frozenFile.path}`);
|
|
80596
80988
|
}
|
|
80597
|
-
const resolvedTarget =
|
|
80598
|
-
if (symlinkPolicy === "contained_relative_only" && (
|
|
80989
|
+
const resolvedTarget = path89.resolve(path89.dirname(source), target);
|
|
80990
|
+
if (symlinkPolicy === "contained_relative_only" && (path89.isAbsolute(target) || !isWithin(sourceRoot, resolvedTarget))) {
|
|
80599
80991
|
continue;
|
|
80600
80992
|
}
|
|
80601
|
-
fs81.mkdirSync(
|
|
80993
|
+
fs81.mkdirSync(path89.dirname(destination), { recursive: true, mode: 448 });
|
|
80602
80994
|
fs81.symlinkSync(target, destination);
|
|
80603
80995
|
continue;
|
|
80604
80996
|
}
|
|
@@ -80611,12 +81003,12 @@ async function copyFrozenWorkspace(manifest, spec, context, sourceRoot = spec.wo
|
|
|
80611
81003
|
return destinationRoot;
|
|
80612
81004
|
}
|
|
80613
81005
|
async function copyEvaluatorTests(spec, evaluator, context) {
|
|
80614
|
-
const destinationRoot = fs81.mkdtempSync(
|
|
81006
|
+
const destinationRoot = fs81.mkdtempSync(path89.join(os16.tmpdir(), "brainbase-benchmark-tests-"));
|
|
80615
81007
|
fs81.chmodSync(destinationRoot, 448);
|
|
80616
81008
|
context.temporaryRoots.add(destinationRoot);
|
|
80617
81009
|
const sourceRoot = evaluatorTestsPath(evaluator, spec.tests_root);
|
|
80618
81010
|
const relativeRoot = evaluator.tests_path ? normalizedRootRelative(evaluator.tests_path) : ".";
|
|
80619
|
-
const destinationStart = relativeRoot === "." ? destinationRoot :
|
|
81011
|
+
const destinationStart = relativeRoot === "." ? destinationRoot : path89.resolve(destinationRoot, relativeRoot);
|
|
80620
81012
|
fs81.mkdirSync(destinationStart, { recursive: true, mode: 448 });
|
|
80621
81013
|
const stack = [{ source: sourceRoot, destination: destinationStart }];
|
|
80622
81014
|
while (stack.length > 0) {
|
|
@@ -80625,11 +81017,11 @@ async function copyEvaluatorTests(spec, evaluator, context) {
|
|
|
80625
81017
|
const entries = fs81.readdirSync(current.source, { withFileTypes: true }).sort((left, right) => left.name.localeCompare(right.name));
|
|
80626
81018
|
for (const entry of entries) {
|
|
80627
81019
|
assertBudget(context);
|
|
80628
|
-
const source =
|
|
80629
|
-
const destination =
|
|
81020
|
+
const source = path89.join(current.source, entry.name);
|
|
81021
|
+
const destination = path89.join(current.destination, entry.name);
|
|
80630
81022
|
const stat = fs81.lstatSync(source);
|
|
80631
81023
|
if (stat.isSymbolicLink()) {
|
|
80632
|
-
throw new BenchmarkPhaseError("unsafe_path", `evaluator reference tree contains a symlink: ${
|
|
81024
|
+
throw new BenchmarkPhaseError("unsafe_path", `evaluator reference tree contains a symlink: ${path89.relative(spec.tests_root, source)}`);
|
|
80633
81025
|
}
|
|
80634
81026
|
if (stat.isDirectory()) {
|
|
80635
81027
|
fs81.mkdirSync(destination, { recursive: true, mode: stat.mode & 511 });
|
|
@@ -80637,7 +81029,7 @@ async function copyEvaluatorTests(spec, evaluator, context) {
|
|
|
80637
81029
|
continue;
|
|
80638
81030
|
}
|
|
80639
81031
|
if (!stat.isFile()) {
|
|
80640
|
-
throw new BenchmarkPhaseError("unsafe_path", `evaluator reference tree contains an unsupported filesystem entry: ${
|
|
81032
|
+
throw new BenchmarkPhaseError("unsafe_path", `evaluator reference tree contains an unsupported filesystem entry: ${path89.relative(spec.tests_root, source)}`);
|
|
80641
81033
|
}
|
|
80642
81034
|
await atomicCopy(source, destination, stat.mode & 511, spec.tests_root);
|
|
80643
81035
|
const sourceRecord = await recordFile(spec.tests_root, source, "tests");
|
|
@@ -80654,7 +81046,7 @@ function evaluatorTestsPath(evaluator, testsRoot) {
|
|
|
80654
81046
|
return testsRoot;
|
|
80655
81047
|
const relative = normalizedRootRelative(evaluator.tests_path);
|
|
80656
81048
|
assertNoSymlinkTraversal(testsRoot, relative);
|
|
80657
|
-
const candidate =
|
|
81049
|
+
const candidate = path89.resolve(testsRoot, relative);
|
|
80658
81050
|
if (!isWithin(testsRoot, candidate) || !fs81.existsSync(candidate)) {
|
|
80659
81051
|
throw new BenchmarkPhaseError("invalid_tests_path", `evaluator tests_path does not exist: ${evaluator.tests_path}`);
|
|
80660
81052
|
}
|
|
@@ -80715,7 +81107,7 @@ function structuredJudgeError(stderr) {
|
|
|
80715
81107
|
function readCriterionResults(resultPath, criterionKeys, allowedEvidenceIds, spec, additionalSecrets = []) {
|
|
80716
81108
|
let opened;
|
|
80717
81109
|
try {
|
|
80718
|
-
opened = openRegularFileNoFollow(resultPath, "criterion result",
|
|
81110
|
+
opened = openRegularFileNoFollow(resultPath, "criterion result", path89.dirname(resultPath));
|
|
80719
81111
|
} catch (error2) {
|
|
80720
81112
|
if (error2.code === "ENOENT") {
|
|
80721
81113
|
throw new BenchmarkPhaseError("missing_criterion_result", "sandbox evaluator did not write its criterion result");
|
|
@@ -80862,7 +81254,7 @@ async function evaluateOne(evaluator, spec, manifest, frozenWorkspaceRoot, final
|
|
|
80862
81254
|
if (evaluator.type === "workspace_assertion") {
|
|
80863
81255
|
const relative = workspaceRel(evaluator.path);
|
|
80864
81256
|
assertNoSymlinkTraversal(frozenWorkspaceRoot, relative);
|
|
80865
|
-
const candidate =
|
|
81257
|
+
const candidate = path89.resolve(frozenWorkspaceRoot, relative);
|
|
80866
81258
|
let stat = null;
|
|
80867
81259
|
try {
|
|
80868
81260
|
stat = fs81.lstatSync(candidate);
|
|
@@ -80942,10 +81334,10 @@ async function evaluateOne(evaluator, spec, manifest, frozenWorkspaceRoot, final
|
|
|
80942
81334
|
};
|
|
80943
81335
|
let criterionResultPath;
|
|
80944
81336
|
if (evaluator.criterion_keys) {
|
|
80945
|
-
privateResultRoot = fs81.mkdtempSync(
|
|
81337
|
+
privateResultRoot = fs81.mkdtempSync(path89.join(os16.tmpdir(), "brainbase-benchmark-criteria-"));
|
|
80946
81338
|
fs81.chmodSync(privateResultRoot, 448);
|
|
80947
81339
|
context.temporaryRoots.add(privateResultRoot);
|
|
80948
|
-
criterionResultPath =
|
|
81340
|
+
criterionResultPath = path89.join(privateResultRoot, "result.json");
|
|
80949
81341
|
environment.BRAINBASE_BENCHMARK_CRITERIA_RESULT = criterionResultPath;
|
|
80950
81342
|
}
|
|
80951
81343
|
const result2 = await runCommand(command, commandRoot, spec, context, {
|
|
@@ -81036,8 +81428,8 @@ async function executeEvaluate(spec, context) {
|
|
|
81036
81428
|
context.logsOwned = true;
|
|
81037
81429
|
validateRoots(spec);
|
|
81038
81430
|
const outputs = [];
|
|
81039
|
-
const finalOutputPath =
|
|
81040
|
-
const trajectoryPath =
|
|
81431
|
+
const finalOutputPath = path89.join(spec.logs_root, "candidate-evidence", "final-output");
|
|
81432
|
+
const trajectoryPath = path89.join(spec.logs_root, "candidate-evidence", "trajectory.json");
|
|
81041
81433
|
writeBufferAtomic(finalOutputPath, finalOutput.buffer);
|
|
81042
81434
|
writeBufferAtomic(trajectoryPath, trajectoryEvidence.buffer);
|
|
81043
81435
|
const frozenEvidenceRecords = [
|
|
@@ -81049,7 +81441,7 @@ async function executeEvaluate(spec, context) {
|
|
|
81049
81441
|
assertEvaluateOutputBudget(spec, context);
|
|
81050
81442
|
assertBudget(context);
|
|
81051
81443
|
const manifest = await workspaceManifest(spec, context);
|
|
81052
|
-
const manifestPath2 =
|
|
81444
|
+
const manifestPath2 = path89.join(spec.logs_root, "candidate-workspace-manifest.json");
|
|
81053
81445
|
writeJsonAtomic(manifestPath2, {
|
|
81054
81446
|
schema_version: SCHEMA_VERSION,
|
|
81055
81447
|
attempt_id: spec.attempt_id,
|
|
@@ -81063,12 +81455,12 @@ async function executeEvaluate(spec, context) {
|
|
|
81063
81455
|
for (const artifactRelInput of spec.candidate_artifacts) {
|
|
81064
81456
|
const artifactRel = workspaceRel(artifactRelInput);
|
|
81065
81457
|
assertNoSymlinkTraversal(spec.workspace_root, artifactRel);
|
|
81066
|
-
const source =
|
|
81458
|
+
const source = path89.resolve(spec.workspace_root, artifactRel);
|
|
81067
81459
|
const frozenArtifact = manifest.find((entry) => entry.path === artifactRel && entry.kind !== "symlink");
|
|
81068
81460
|
if (!frozenArtifact || !fs81.existsSync(source) || !fs81.lstatSync(source).isFile()) {
|
|
81069
81461
|
throw new BenchmarkPhaseError("missing_artifact", `candidate artifact is missing: ${artifactRel}`);
|
|
81070
81462
|
}
|
|
81071
|
-
const destination =
|
|
81463
|
+
const destination = path89.resolve(spec.logs_root, "candidate-artifacts", artifactRel);
|
|
81072
81464
|
await atomicCopy(source, destination, undefined, spec.workspace_root);
|
|
81073
81465
|
const artifact = await recordFile(spec.logs_root, destination, "logs");
|
|
81074
81466
|
if (artifact.sha256 !== frozenArtifact.sha256 || artifact.size !== frozenArtifact.size || artifact.mode !== frozenArtifact.mode) {
|
|
@@ -81086,7 +81478,7 @@ async function executeEvaluate(spec, context) {
|
|
|
81086
81478
|
assertEvaluateOutputBudget(spec, context);
|
|
81087
81479
|
if (spec.capture_workspace_archive) {
|
|
81088
81480
|
const regularFiles = manifest.filter((entry) => entry.kind !== "symlink").map((entry) => entry.path);
|
|
81089
|
-
const archive =
|
|
81481
|
+
const archive = path89.join(spec.logs_root, "candidate-workspace.tar.gz");
|
|
81090
81482
|
const temporary = `${archive}.${process.pid}.${crypto6.randomBytes(6).toString("hex")}.tmp`;
|
|
81091
81483
|
try {
|
|
81092
81484
|
await pack({ rootDir: spec.workspace_root, outFile: temporary, files: regularFiles });
|
|
@@ -81273,7 +81665,7 @@ function rawIdentity(value) {
|
|
|
81273
81665
|
};
|
|
81274
81666
|
}
|
|
81275
81667
|
function readSpecBytes(specPathInput) {
|
|
81276
|
-
const specPath =
|
|
81668
|
+
const specPath = path89.resolve(specPathInput);
|
|
81277
81669
|
const noFollow = typeof fs81.constants.O_NOFOLLOW === "number" ? fs81.constants.O_NOFOLLOW : 0;
|
|
81278
81670
|
let fd;
|
|
81279
81671
|
try {
|
|
@@ -81304,8 +81696,8 @@ function validateBenchmarkInvocationBytes(bytes, resultPathInput, expectedPhase)
|
|
|
81304
81696
|
throw new BenchmarkPhaseError("phase_mismatch", `the ${expectedPhase} command cannot execute a ${spec.phase} spec`);
|
|
81305
81697
|
}
|
|
81306
81698
|
validateRoots(spec);
|
|
81307
|
-
const resultPath =
|
|
81308
|
-
const expectedResultPath =
|
|
81699
|
+
const resultPath = path89.resolve(resultPathInput);
|
|
81700
|
+
const expectedResultPath = path89.join(path89.resolve(spec.logs_root), "result.json");
|
|
81309
81701
|
if (resultPath !== expectedResultPath) {
|
|
81310
81702
|
throw new BenchmarkPhaseError("invalid_result_path", `result path must be ${expectedResultPath}`);
|
|
81311
81703
|
}
|
|
@@ -81405,7 +81797,7 @@ function writeBenchmarkPhaseTimeoutResult(specBytes, resultPathInput, expectedPh
|
|
|
81405
81797
|
async function runBenchmarkPhase(specPathInput, resultPathInput, expectedPhase, immutableSpecBytes) {
|
|
81406
81798
|
const startedAt = nowIso();
|
|
81407
81799
|
const started = Date.now();
|
|
81408
|
-
const resultPath =
|
|
81800
|
+
const resultPath = path89.resolve(resultPathInput);
|
|
81409
81801
|
let raw = undefined;
|
|
81410
81802
|
let digest = null;
|
|
81411
81803
|
let identity2 = rawIdentity(raw);
|
|
@@ -81441,7 +81833,7 @@ async function runBenchmarkPhase(specPathInput, resultPathInput, expectedPhase,
|
|
|
81441
81833
|
throw new BenchmarkPhaseError("phase_mismatch", `the ${expectedPhase} command cannot execute a ${spec.phase} spec`);
|
|
81442
81834
|
}
|
|
81443
81835
|
validateRoots(spec);
|
|
81444
|
-
const expectedResultPath =
|
|
81836
|
+
const expectedResultPath = path89.join(path89.resolve(spec.logs_root), "result.json");
|
|
81445
81837
|
if (resultPath !== expectedResultPath) {
|
|
81446
81838
|
throw new BenchmarkPhaseError("invalid_result_path", `result path must be ${expectedResultPath}`);
|
|
81447
81839
|
}
|
|
@@ -81669,7 +82061,7 @@ function terminatePhase(child) {
|
|
|
81669
82061
|
}
|
|
81670
82062
|
}
|
|
81671
82063
|
function createAnonymousSpecFd(bytes) {
|
|
81672
|
-
const temporary =
|
|
82064
|
+
const temporary = path90.join(os17.tmpdir(), `brainbase-benchmark-spec-${process.pid}-${crypto7.randomBytes(12).toString("hex")}`);
|
|
81673
82065
|
fs82.writeFileSync(temporary, bytes, { flag: "wx", mode: 384 });
|
|
81674
82066
|
try {
|
|
81675
82067
|
const fd = fs82.openSync(temporary, "r");
|
|
@@ -81873,13 +82265,13 @@ async function runBenchmark(sub, args, write = (value) => process.stdout.write(v
|
|
|
81873
82265
|
function printHelp5() {
|
|
81874
82266
|
const out = [];
|
|
81875
82267
|
out.push("");
|
|
81876
|
-
out.push(` ${
|
|
82268
|
+
out.push(` ${import_picocolors52.default.bold("brainbase benchmark")} ${import_picocolors52.default.dim("<sub> [options]")}`);
|
|
81877
82269
|
out.push("");
|
|
81878
|
-
out.push(` ${
|
|
81879
|
-
out.push(` ${
|
|
81880
|
-
out.push(` ${
|
|
82270
|
+
out.push(` ${import_picocolors52.default.cyan("hydrate")} ${import_picocolors52.default.dim("--spec <path> --result <path> --json")}`);
|
|
82271
|
+
out.push(` ${import_picocolors52.default.cyan("evaluate")} ${import_picocolors52.default.dim("--spec <path> --result <path> --json")}`);
|
|
82272
|
+
out.push(` ${import_picocolors52.default.cyan("capabilities")} ${import_picocolors52.default.dim("--json")}`);
|
|
81881
82273
|
out.push("");
|
|
81882
|
-
out.push(` ${
|
|
82274
|
+
out.push(` ${import_picocolors52.default.dim("These machine-only commands execute versioned benchmark phase specs inside a task sandbox.")}`);
|
|
81883
82275
|
out.push("");
|
|
81884
82276
|
console.log(out.join(`
|
|
81885
82277
|
`));
|
|
@@ -81906,137 +82298,140 @@ var SUBCOMMAND_OWNED_FLAGS = {
|
|
|
81906
82298
|
function help() {
|
|
81907
82299
|
const out = [];
|
|
81908
82300
|
out.push("");
|
|
81909
|
-
out.push(` ${brandTint("◆")} ${
|
|
81910
|
-
out.push(` ${
|
|
82301
|
+
out.push(` ${brandTint("◆")} ${import_picocolors53.default.bold("brainbase")} ${import_picocolors53.default.dim(`v${VERSION}`)}`);
|
|
82302
|
+
out.push(` ${import_picocolors53.default.dim("connect your local agent to the brainbase platform")}`);
|
|
81911
82303
|
out.push("");
|
|
81912
82304
|
out.push(divider("USAGE"));
|
|
81913
82305
|
out.push("");
|
|
81914
|
-
out.push(` ${
|
|
82306
|
+
out.push(` ${import_picocolors53.default.bold("brainbase")} ${import_picocolors53.default.dim("<command> [options]")}`);
|
|
81915
82307
|
out.push("");
|
|
81916
82308
|
out.push(divider("AUTH"));
|
|
81917
82309
|
out.push("");
|
|
81918
|
-
out.push(` ${
|
|
81919
|
-
out.push(` ${
|
|
81920
|
-
out.push(` ${
|
|
82310
|
+
out.push(` ${import_picocolors53.default.cyan("login")} ${import_picocolors53.default.dim(" open the web app and connect this device")}`);
|
|
82311
|
+
out.push(` ${import_picocolors53.default.cyan("logout")} ${import_picocolors53.default.dim(" clear the local session")}`);
|
|
82312
|
+
out.push(` ${import_picocolors53.default.cyan("whoami")} ${import_picocolors53.default.dim("[--json]")} ${import_picocolors53.default.dim(" show which credential is in use and what it covers")}`);
|
|
81921
82313
|
out.push("");
|
|
81922
82314
|
out.push(divider("DISCOVERY"));
|
|
81923
82315
|
out.push("");
|
|
81924
|
-
out.push(` ${
|
|
81925
|
-
out.push(` ${
|
|
82316
|
+
out.push(` ${import_picocolors53.default.cyan("team list")} ${import_picocolors53.default.dim("show the teams you can create agents in")}`);
|
|
82317
|
+
out.push(` ${import_picocolors53.default.cyan("agent list")} ${import_picocolors53.default.dim("show a team's agents and their ids")}`);
|
|
81926
82318
|
out.push("");
|
|
81927
82319
|
out.push(divider("LINKED AGENT"));
|
|
81928
82320
|
out.push("");
|
|
81929
|
-
out.push(` ${
|
|
81930
|
-
out.push(` ${
|
|
81931
|
-
out.push(` ${
|
|
81932
|
-
out.push(` ${
|
|
81933
|
-
out.push(` ${
|
|
81934
|
-
out.push(` ${
|
|
81935
|
-
out.push(` ${
|
|
81936
|
-
out.push(` ${
|
|
81937
|
-
out.push(` ${
|
|
81938
|
-
out.push(` ${
|
|
81939
|
-
out.push(` ${
|
|
81940
|
-
out.push(` ${
|
|
81941
|
-
out.push(` ${
|
|
82321
|
+
out.push(` ${import_picocolors53.default.cyan("agent init")} ${import_picocolors53.default.dim("write a starter brainbase.agent.yaml here — offline, no login needed")}`);
|
|
82322
|
+
out.push(` ${import_picocolors53.default.cyan("agent create")} ${import_picocolors53.default.dim("claim an unclaimed brainbase.agent.yaml and create the cloud agent")}`);
|
|
82323
|
+
out.push(` ${import_picocolors53.default.cyan("agent pull")} ${import_picocolors53.default.dim("[<id>]")} ${import_picocolors53.default.dim("bring cloud changes into this folder (--force to override; --run-entrypoint to also execute the agent entrypoint)")}`);
|
|
82324
|
+
out.push(` ${import_picocolors53.default.cyan("agent push")} ${import_picocolors53.default.dim("send local changes to the cloud (--force to overwrite cloud-side conflicts with local)")}`);
|
|
82325
|
+
out.push(` ${import_picocolors53.default.cyan("agent unpack")} ${import_picocolors53.default.dim("install the claimed agent into a harness layout")}`);
|
|
82326
|
+
out.push(` ${import_picocolors53.default.cyan("link")} ${import_picocolors53.default.dim("attach this folder to an existing agent")}`);
|
|
82327
|
+
out.push(` ${import_picocolors53.default.cyan("agent status")} ${import_picocolors53.default.dim("show what would pull and what would push")}`);
|
|
82328
|
+
out.push(` ${import_picocolors53.default.cyan("agent connections")} ${import_picocolors53.default.dim("show which integrations this agent is wired to (--json for CI)")}`);
|
|
82329
|
+
out.push(` ${import_picocolors53.default.cyan("agent connect")} ${import_picocolors53.default.dim("<name>")} ${import_picocolors53.default.dim("connect slack or meeting from the terminal")}`);
|
|
82330
|
+
out.push(` ${import_picocolors53.default.cyan("agent disconnect")} ${import_picocolors53.default.dim("<name>")} ${import_picocolors53.default.dim("revoke a slack or meeting install")}`);
|
|
82331
|
+
out.push(` ${import_picocolors53.default.cyan("agent env")} ${import_picocolors53.default.dim("print export lines for `eval $(brainbase agent env)`")}`);
|
|
82332
|
+
out.push(` ${import_picocolors53.default.cyan("run")} ${import_picocolors53.default.dim("<cmd> [args...]")} ${import_picocolors53.default.dim("run <cmd> with secrets.env loaded into env")}`);
|
|
82333
|
+
out.push(` ${import_picocolors53.default.cyan("status")} ${import_picocolors53.default.dim("show what this folder is linked to")}`);
|
|
82334
|
+
out.push(` ${import_picocolors53.default.cyan("unlink")} ${import_picocolors53.default.dim("disconnect this folder")}`);
|
|
81942
82335
|
out.push("");
|
|
81943
82336
|
out.push(divider("TASKS"));
|
|
81944
82337
|
out.push("");
|
|
81945
|
-
out.push(` ${
|
|
82338
|
+
out.push(` ${import_picocolors53.default.cyan("task create")} ${import_picocolors53.default.dim("--message <text>")} ${import_picocolors53.default.dim("create a managed task and start its first run")}`);
|
|
81946
82339
|
out.push("");
|
|
81947
82340
|
out.push(divider("BENCHMARK RUNTIME"));
|
|
81948
82341
|
out.push("");
|
|
81949
|
-
out.push(` ${
|
|
81950
|
-
out.push(` ${
|
|
81951
|
-
out.push(` ${
|
|
82342
|
+
out.push(` ${import_picocolors53.default.cyan("benchmark hydrate")} ${import_picocolors53.default.dim("--spec <path> --result <path> --json")}`);
|
|
82343
|
+
out.push(` ${import_picocolors53.default.cyan("benchmark evaluate")} ${import_picocolors53.default.dim("--spec <path> --result <path> --json")}`);
|
|
82344
|
+
out.push(` ${import_picocolors53.default.cyan("benchmark capabilities")} ${import_picocolors53.default.dim("--json")}`);
|
|
81952
82345
|
out.push("");
|
|
81953
82346
|
out.push(divider("ORCHESTRATIONS"));
|
|
81954
82347
|
out.push("");
|
|
81955
|
-
out.push(` ${
|
|
81956
|
-
out.push(` ${
|
|
81957
|
-
out.push(` ${
|
|
81958
|
-
out.push(` ${
|
|
81959
|
-
out.push(` ${
|
|
82348
|
+
out.push(` ${import_picocolors53.default.cyan("orchestration create")} ${import_picocolors53.default.dim("claim a local orchestration manifest and create it in the cloud")}`);
|
|
82349
|
+
out.push(` ${import_picocolors53.default.cyan("orchestration list")} ${import_picocolors53.default.dim("list orchestrations under a team")}`);
|
|
82350
|
+
out.push(` ${import_picocolors53.default.cyan("orchestration pull")} ${import_picocolors53.default.dim("<id>")} ${import_picocolors53.default.dim("recursively fetch an orchestration + every member agent")}`);
|
|
82351
|
+
out.push(` ${import_picocolors53.default.cyan("orchestration push")} ${import_picocolors53.default.dim("recursively push each member, then update the graph")}`);
|
|
82352
|
+
out.push(` ${import_picocolors53.default.cyan("orchestration status")} ${import_picocolors53.default.dim("show what would push and what would pull")}`);
|
|
81960
82353
|
out.push("");
|
|
81961
82354
|
out.push(divider("TEMPLATES"));
|
|
81962
82355
|
out.push("");
|
|
81963
|
-
out.push(` ${
|
|
81964
|
-
out.push(` ${
|
|
81965
|
-
out.push(` ${
|
|
81966
|
-
out.push(` ${
|
|
81967
|
-
out.push(` ${
|
|
81968
|
-
out.push(` ${
|
|
81969
|
-
out.push(` ${
|
|
82356
|
+
out.push(` ${import_picocolors53.default.cyan("template pack")} ${import_picocolors53.default.dim("bundle the current agent into a template")}`);
|
|
82357
|
+
out.push(` ${import_picocolors53.default.cyan("template publish")} ${import_picocolors53.default.dim("upload a template to the registry")}`);
|
|
82358
|
+
out.push(` ${import_picocolors53.default.cyan("template search")} ${import_picocolors53.default.dim("[query]")} ${import_picocolors53.default.dim("search the registry")}`);
|
|
82359
|
+
out.push(` ${import_picocolors53.default.cyan("template info")} ${import_picocolors53.default.dim("<creator/slug>")} ${import_picocolors53.default.dim("show registry details for a template")}`);
|
|
82360
|
+
out.push(` ${import_picocolors53.default.cyan("template onboard")} ${import_picocolors53.default.dim("<creator/slug>")} ${import_picocolors53.default.dim("install (or refresh) a template")}`);
|
|
82361
|
+
out.push(` ${import_picocolors53.default.cyan("template list")} ${import_picocolors53.default.dim("show installed templates")}`);
|
|
82362
|
+
out.push(` ${import_picocolors53.default.cyan("template remove")} ${import_picocolors53.default.dim("<creator/slug>")} ${import_picocolors53.default.dim("uninstall a template")}`);
|
|
81970
82363
|
out.push("");
|
|
81971
82364
|
out.push(divider("SKILLS"));
|
|
81972
82365
|
out.push("");
|
|
81973
|
-
out.push(` ${
|
|
81974
|
-
out.push(` ${
|
|
81975
|
-
out.push(` ${
|
|
81976
|
-
out.push(` ${
|
|
81977
|
-
out.push(` ${
|
|
81978
|
-
out.push(` ${
|
|
81979
|
-
out.push(` ${
|
|
82366
|
+
out.push(` ${import_picocolors53.default.cyan("skill add")} ${import_picocolors53.default.dim("<source>")} ${import_picocolors53.default.dim("install a skill (github / git / brainbase)")}`);
|
|
82367
|
+
out.push(` ${import_picocolors53.default.cyan("skill list")} ${import_picocolors53.default.dim("show locally installed skills + their source")}`);
|
|
82368
|
+
out.push(` ${import_picocolors53.default.cyan("skill update")} ${import_picocolors53.default.dim("<slug>")} ${import_picocolors53.default.dim("re-fetch a skill from its recorded source")}`);
|
|
82369
|
+
out.push(` ${import_picocolors53.default.cyan("skill remove")} ${import_picocolors53.default.dim("<slug>")} ${import_picocolors53.default.dim("uninstall a skill")}`);
|
|
82370
|
+
out.push(` ${import_picocolors53.default.cyan("skill search")} ${import_picocolors53.default.dim("[query]")} ${import_picocolors53.default.dim("search the brainbase skill registry")}`);
|
|
82371
|
+
out.push(` ${import_picocolors53.default.cyan("skill info")} ${import_picocolors53.default.dim("<creator/slug>")} ${import_picocolors53.default.dim("show registry details for a skill")}`);
|
|
82372
|
+
out.push(` ${import_picocolors53.default.cyan("skill publish")} ${import_picocolors53.default.dim("[dir]")} ${import_picocolors53.default.dim("publish a SKILL.md folder (defaults to .)")}`);
|
|
81980
82373
|
out.push("");
|
|
81981
82374
|
out.push(divider("CLI TOKENS"));
|
|
81982
82375
|
out.push("");
|
|
81983
|
-
out.push(` ${
|
|
81984
|
-
out.push(` ${
|
|
81985
|
-
out.push(` ${
|
|
81986
|
-
out.push(` ${
|
|
82376
|
+
out.push(` ${import_picocolors53.default.cyan("token create")} ${import_picocolors53.default.dim("issue a long-lived CLI key for CI / scripts")}`);
|
|
82377
|
+
out.push(` ${import_picocolors53.default.cyan("token list")} ${import_picocolors53.default.dim("show your tokens")}`);
|
|
82378
|
+
out.push(` ${import_picocolors53.default.cyan("token rename")} ${import_picocolors53.default.dim("<id>")} ${import_picocolors53.default.dim("relabel a token")}`);
|
|
82379
|
+
out.push(` ${import_picocolors53.default.cyan("token revoke")} ${import_picocolors53.default.dim("<id>")} ${import_picocolors53.default.dim("revoke a token")}`);
|
|
81987
82380
|
out.push("");
|
|
81988
82381
|
out.push(divider("MCP"));
|
|
81989
82382
|
out.push("");
|
|
81990
|
-
out.push(` ${
|
|
81991
|
-
out.push(` ${
|
|
82383
|
+
out.push(` ${import_picocolors53.default.cyan("mcp check")} ${import_picocolors53.default.dim("[--json]")} ${import_picocolors53.default.dim("verify MCP server connectivity through the brainbase proxy (runs at sandbox bootstrap)")}`);
|
|
82384
|
+
out.push(` ${import_picocolors53.default.cyan("mcp list")} ${import_picocolors53.default.dim("[--json]")} ${import_picocolors53.default.dim("show configured servers with OAuth state and expiry")}`);
|
|
81992
82385
|
out.push("");
|
|
81993
82386
|
out.push(divider("FLAGS"));
|
|
81994
82387
|
out.push("");
|
|
81995
|
-
out.push(` ${
|
|
81996
|
-
out.push(` ${
|
|
81997
|
-
out.push(` ${
|
|
81998
|
-
out.push(` ${
|
|
81999
|
-
out.push(` ${
|
|
82000
|
-
out.push(` ${
|
|
82001
|
-
out.push(` ${
|
|
82002
|
-
out.push(` ${
|
|
82003
|
-
out.push(` ${
|
|
82004
|
-
out.push(` ${
|
|
82005
|
-
out.push(` ${
|
|
82006
|
-
out.push(` ${
|
|
82007
|
-
out.push(` ${
|
|
82008
|
-
out.push(` ${
|
|
82009
|
-
out.push(` ${
|
|
82010
|
-
out.push(` ${
|
|
82011
|
-
out.push(` ${
|
|
82012
|
-
out.push(` ${
|
|
82388
|
+
out.push(` ${import_picocolors53.default.dim("--harness <id>")} force harness for onboard / sync (e.g. claude-code)`);
|
|
82389
|
+
out.push(` ${import_picocolors53.default.dim("--scope <s>")} force scope: global | project`);
|
|
82390
|
+
out.push(` ${import_picocolors53.default.dim("--yes, -y")} skip confirmations / auto-overwrite`);
|
|
82391
|
+
out.push(` ${import_picocolors53.default.dim("--agent <id>")} for link/task create: use this agent id explicitly`);
|
|
82392
|
+
out.push(` ${import_picocolors53.default.dim("--message <text>")} for task create: required first user message`);
|
|
82393
|
+
out.push(` ${import_picocolors53.default.dim("--title <text>")} for task create: optional task title`);
|
|
82394
|
+
out.push(` ${import_picocolors53.default.dim("--model <id>")} for task create: optional model override`);
|
|
82395
|
+
out.push(` ${import_picocolors53.default.dim("--org <id-or-slug>")} pick the organization (team/agent list, agent create, orchestration create/list)`);
|
|
82396
|
+
out.push(` ${import_picocolors53.default.dim("--team <id>")} pick the team, same commands (works without --org)`);
|
|
82397
|
+
out.push(` ${import_picocolors53.default.dim("--json")} machine-readable output for supported commands`);
|
|
82398
|
+
out.push(` ${import_picocolors53.default.dim("--no-tracking")} for link: skip routing LLM traffic through brainbase`);
|
|
82399
|
+
out.push(` ${import_picocolors53.default.dim("--track")} for agent create: enable tracking non-interactively (off without a TTY)`);
|
|
82400
|
+
out.push(` ${import_picocolors53.default.dim("--shell <sh|fish>")} for agent env: pick output format (auto-detected from $SHELL)`);
|
|
82401
|
+
out.push(` ${import_picocolors53.default.dim("--bot-token <t>")} for agent connect slack (or BRAINBASE_SLACK_BOT_TOKEN, or stdin)`);
|
|
82402
|
+
out.push(` ${import_picocolors53.default.dim("--signing-secret <s>")} for agent connect slack (or BRAINBASE_SLACK_SIGNING_SECRET, or stdin)`);
|
|
82403
|
+
out.push(` ${import_picocolors53.default.dim("--bot-name <name>")} for agent connect meeting: the bot's display name`);
|
|
82404
|
+
out.push(` ${import_picocolors53.default.dim("--full")} for agent init: write a commented template covering every block`);
|
|
82405
|
+
out.push(` ${import_picocolors53.default.dim("--minimal")} for agent init: write the starter manifest (the default)`);
|
|
82406
|
+
out.push(` ${import_picocolors53.default.dim("--all")} for template list: include installs from other folders`);
|
|
82407
|
+
out.push(` ${import_picocolors53.default.dim("--web <url>")} for login: web app URL (default https://app.brainbaselabs.com)`);
|
|
82013
82408
|
out.push("");
|
|
82014
82409
|
out.push(divider("ENV"));
|
|
82015
82410
|
out.push("");
|
|
82016
|
-
out.push(` ${
|
|
82017
|
-
out.push(` ${
|
|
82018
|
-
out.push(` ${
|
|
82019
|
-
out.push(` ${
|
|
82020
|
-
out.push(` ${
|
|
82021
|
-
out.push(` ${
|
|
82022
|
-
out.push(` ${
|
|
82023
|
-
out.push(` ${
|
|
82024
|
-
out.push(` ${
|
|
82025
|
-
out.push(` ${
|
|
82026
|
-
out.push(` ${
|
|
82411
|
+
out.push(` ${import_picocolors53.default.dim("BRAINBASE_HOME")} override the local config dir (default ~/.brainbase)`);
|
|
82412
|
+
out.push(` ${import_picocolors53.default.dim("BRAINBASE_DEBUG")} print full stack traces on error (any value; unset to disable)`);
|
|
82413
|
+
out.push(` ${import_picocolors53.default.dim("BRAINBASE_WEB_URL")} override the web app URL used by login`);
|
|
82414
|
+
out.push(` ${import_picocolors53.default.dim("BRAINBASE_CONTROL_PLANE_URL")} override the MAS host (/v2/cli; task create uses /v2/tasks)`);
|
|
82415
|
+
out.push(` ${import_picocolors53.default.dim("BRAINBASE_API_URL")} legacy KLS host override (uses /api/cli; proxy/registry fallback)`);
|
|
82416
|
+
out.push(` ${import_picocolors53.default.dim("BRAINBASE_PROXY_URL")} override the model-proxy URL used by harness traffic (default https://api.v1.brainbaselabs.com)`);
|
|
82417
|
+
out.push(` ${import_picocolors53.default.dim("BRAINBASE_REGISTRY_URL")} override the registry API URL (default https://api.v1.brainbaselabs.com)`);
|
|
82418
|
+
out.push(` ${import_picocolors53.default.dim("BRAINBASE_TOKEN")} long-lived CLI PAT; the only PAT control-plane commands accept (token.json is not read there)`);
|
|
82419
|
+
out.push(` ${import_picocolors53.default.dim("BRAINBASE_SKIP_AUTH")} bypass the auth gate for development`);
|
|
82420
|
+
out.push(` ${import_picocolors53.default.dim("BRAINBASE_NON_INTERACTIVE")} force non-interactive mode — skip/auto-default prompts (CI & agents)`);
|
|
82421
|
+
out.push(` ${import_picocolors53.default.dim("BRAINBASE_RUN_ENTRYPOINT")} =1 → agent pull executes the agent entrypoint (sandbox boots; or pass --run-entrypoint)`);
|
|
82027
82422
|
out.push("");
|
|
82028
|
-
out.push(` ${
|
|
82029
|
-
out.push(` ${
|
|
82030
|
-
out.push(` ${
|
|
82031
|
-
out.push(` ${
|
|
82032
|
-
out.push(` ${
|
|
82033
|
-
out.push(` ${
|
|
82423
|
+
out.push(` ${import_picocolors53.default.dim("BRAINBASE_MEMORY_MCP_URL")} override the built-in memory MCP host`);
|
|
82424
|
+
out.push(` ${import_picocolors53.default.dim("BRAINBASE_BROWSER_MCP_URL")} override the built-in browser MCP host`);
|
|
82425
|
+
out.push(` ${import_picocolors53.default.dim("BRAINBASE_SLACK_MCP_URL")} override the built-in Slack MCP host`);
|
|
82426
|
+
out.push(` ${import_picocolors53.default.dim("BRAINBASE_MEETING_MCP_URL")} override the built-in meeting MCP host`);
|
|
82427
|
+
out.push(` ${import_picocolors53.default.dim("BRAINBASE_GITHUB_MCP_URL")} override the built-in GitHub MCP host`);
|
|
82428
|
+
out.push(` ${import_picocolors53.default.dim("BRAINBASE_ORCHESTRATION_MCP_URL")} override the built-in orchestration MCP host`);
|
|
82034
82429
|
out.push("");
|
|
82035
82430
|
out.push(divider("HARNESSES"));
|
|
82036
82431
|
out.push("");
|
|
82037
|
-
out.push(` ${
|
|
82038
|
-
out.push(` ${
|
|
82039
|
-
out.push(` ${
|
|
82432
|
+
out.push(` ${import_picocolors53.default.dim("•")} ${import_picocolors53.default.bold("claude-code")} ${import_picocolors53.default.dim("skills, mcps, agents, commands, playbooks, instructions, files")}`);
|
|
82433
|
+
out.push(` ${import_picocolors53.default.dim("•")} ${import_picocolors53.default.bold("codex")} ${import_picocolors53.default.dim("skills, mcps, commands, playbooks, instructions, files")}`);
|
|
82434
|
+
out.push(` ${import_picocolors53.default.dim("•")} ${import_picocolors53.default.bold("kafka")} ${import_picocolors53.default.dim("skills, mcps, agents, commands, playbooks, instructions, files")}`);
|
|
82040
82435
|
out.push("");
|
|
82041
82436
|
console.log(out.join(`
|
|
82042
82437
|
`));
|
|
@@ -82188,13 +82583,13 @@ async function requireAuth(cmd) {
|
|
|
82188
82583
|
if (STORED_PAT_COMMANDS.has(cmd) && readToken())
|
|
82189
82584
|
return;
|
|
82190
82585
|
console.error("");
|
|
82191
|
-
console.error(` ${brandTint("◆")} ${
|
|
82586
|
+
console.error(` ${brandTint("◆")} ${import_picocolors53.default.bold("brainbase")}`);
|
|
82192
82587
|
console.error("");
|
|
82193
|
-
console.error(` ${
|
|
82588
|
+
console.error(` ${import_picocolors53.default.red("✗")} You need to sign in to use ${import_picocolors53.default.bold("brainbase " + cmd)}.`);
|
|
82194
82589
|
if (status.reason)
|
|
82195
|
-
console.error(` ${
|
|
82590
|
+
console.error(` ${import_picocolors53.default.dim(status.reason)}`);
|
|
82196
82591
|
console.error("");
|
|
82197
|
-
console.error(` Run ${
|
|
82592
|
+
console.error(` Run ${import_picocolors53.default.cyan("brainbase login")} to connect this device.`);
|
|
82198
82593
|
console.error("");
|
|
82199
82594
|
process14.exit(1);
|
|
82200
82595
|
}
|
|
@@ -82239,6 +82634,8 @@ async function main() {
|
|
|
82239
82634
|
const noTracking = hasFlag2(sharedArgs, "--no-tracking");
|
|
82240
82635
|
const track = hasFlag2(sharedArgs, "--track");
|
|
82241
82636
|
const forceFlag = hasFlag2(sharedArgs, "--force");
|
|
82637
|
+
const minimalFlag = hasFlag2(sharedArgs, "--minimal");
|
|
82638
|
+
const fullFlag = hasFlag2(sharedArgs, "--full");
|
|
82242
82639
|
const runEntrypointFlag = hasFlag2(sharedArgs, "--run-entrypoint");
|
|
82243
82640
|
const graphOnlyFlag = hasFlag2(sharedArgs, "--graph-only");
|
|
82244
82641
|
const nameFlag = takeFlag("--name");
|
|
@@ -82334,6 +82731,8 @@ async function main() {
|
|
|
82334
82731
|
scope: scopeFlag,
|
|
82335
82732
|
shell: shellFlag,
|
|
82336
82733
|
harness,
|
|
82734
|
+
minimal: minimalFlag,
|
|
82735
|
+
full: fullFlag,
|
|
82337
82736
|
name: nameFlag,
|
|
82338
82737
|
tagline: taglineFlag,
|
|
82339
82738
|
orgId: orgIdFlag,
|
|
@@ -82407,10 +82806,10 @@ async function main() {
|
|
|
82407
82806
|
process14.exit(1);
|
|
82408
82807
|
}
|
|
82409
82808
|
} catch (err) {
|
|
82410
|
-
console.error(
|
|
82809
|
+
console.error(import_picocolors53.default.red(`
|
|
82411
82810
|
${err.message}`));
|
|
82412
82811
|
if (err instanceof ApiError && err.status === 401) {
|
|
82413
|
-
console.error(` Run ${
|
|
82812
|
+
console.error(` Run ${import_picocolors53.default.cyan("brainbase login")} to connect this device.`);
|
|
82414
82813
|
}
|
|
82415
82814
|
if (process14.env.BRAINBASE_DEBUG)
|
|
82416
82815
|
console.error(err.stack);
|