@brainbase-labs/cli 0.25.0 → 0.27.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 +1340 -488
- 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_picocolors54 = __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.27.0",
|
|
36012
36012
|
description: "Pack, share, and install agent templates across harnesses (Claude Code, Codex, ...).",
|
|
36013
36013
|
type: "module",
|
|
36014
36014
|
bin: {
|
|
@@ -54439,6 +54439,21 @@ var api = {
|
|
|
54439
54439
|
body: JSON.stringify(input)
|
|
54440
54440
|
});
|
|
54441
54441
|
},
|
|
54442
|
+
async listAgentEvals(agentId, opts) {
|
|
54443
|
+
const qs = opts?.includeArchived ? "?include_archived=true" : "";
|
|
54444
|
+
const body = await request(`/agents/${encodeURIComponent(agentId)}/evals${qs}`);
|
|
54445
|
+
return Array.isArray(body) ? body : body.items ?? [];
|
|
54446
|
+
},
|
|
54447
|
+
async listAgentEvalRuns(agentId, opts) {
|
|
54448
|
+
const params = new URLSearchParams;
|
|
54449
|
+
if (opts?.taskId)
|
|
54450
|
+
params.set("task_id", opts.taskId);
|
|
54451
|
+
if (opts?.limit !== undefined)
|
|
54452
|
+
params.set("limit", String(opts.limit));
|
|
54453
|
+
const qs = params.toString() ? `?${params.toString()}` : "";
|
|
54454
|
+
const body = await request(`/agents/${encodeURIComponent(agentId)}/eval-runs${qs}`);
|
|
54455
|
+
return Array.isArray(body) ? body : body.items ?? [];
|
|
54456
|
+
},
|
|
54442
54457
|
async getAgentSecrets(agentId) {
|
|
54443
54458
|
const body = await request(`/agents/${encodeURIComponent(agentId)}/secrets`);
|
|
54444
54459
|
const secrets = body && typeof body === "object" ? body.secrets : undefined;
|
|
@@ -61950,6 +61965,7 @@ import fs66 from "node:fs";
|
|
|
61950
61965
|
// src/core/agent-manifest.ts
|
|
61951
61966
|
import path73 from "node:path";
|
|
61952
61967
|
import fs65 from "node:fs";
|
|
61968
|
+
import { randomBytes } from "node:crypto";
|
|
61953
61969
|
var import_yaml2 = __toESM(require_dist(), 1);
|
|
61954
61970
|
var AGENT_MANIFEST_FILE = "brainbase.agent.yaml";
|
|
61955
61971
|
var LEGACY_AGENT_MANIFEST_FILE = "brainbase.yaml";
|
|
@@ -62121,30 +62137,54 @@ function existingManifestPath(cwd2) {
|
|
|
62121
62137
|
function hasManifest(cwd2) {
|
|
62122
62138
|
return existingManifestPath(cwd2) !== null;
|
|
62123
62139
|
}
|
|
62124
|
-
function
|
|
62125
|
-
const p2 = existingManifestPath(cwd2);
|
|
62126
|
-
if (!p2)
|
|
62127
|
-
return null;
|
|
62128
|
-
const raw = fs65.readFileSync(p2, "utf8");
|
|
62140
|
+
function parseManifest(raw, label = AGENT_MANIFEST_FILE) {
|
|
62129
62141
|
let parsed;
|
|
62130
62142
|
try {
|
|
62131
62143
|
parsed = import_yaml2.default.parse(raw);
|
|
62132
62144
|
} catch (err) {
|
|
62133
|
-
throw new Error(`${
|
|
62145
|
+
throw new Error(`${label} is not valid YAML: ${err.message}`);
|
|
62134
62146
|
}
|
|
62135
62147
|
const result2 = AgentManifestSchema.safeParse(parsed);
|
|
62136
62148
|
if (!result2.success) {
|
|
62137
|
-
throw new Error(`${
|
|
62149
|
+
throw new Error(`${label} is invalid: ${result2.error.issues.map((i) => `${i.path.join(".") || "(root)"} — ${i.message}`).join("; ")}`);
|
|
62138
62150
|
}
|
|
62139
62151
|
return result2.data;
|
|
62140
62152
|
}
|
|
62141
|
-
function
|
|
62153
|
+
function readManifest(cwd2) {
|
|
62154
|
+
const p2 = existingManifestPath(cwd2);
|
|
62155
|
+
if (!p2)
|
|
62156
|
+
return null;
|
|
62157
|
+
return parseManifest(fs65.readFileSync(p2, "utf8"), path73.basename(p2));
|
|
62158
|
+
}
|
|
62159
|
+
function renderManifest(manifest) {
|
|
62142
62160
|
const doc = new import_yaml2.default.Document;
|
|
62143
62161
|
doc.contents = manifest;
|
|
62144
62162
|
doc.commentBefore = ` brainbase.agent.yaml — declarative agent manifest.
|
|
62145
62163
|
` + " Committed to source control. Edit by hand, then `brainbase agent push`.";
|
|
62146
|
-
|
|
62147
|
-
|
|
62164
|
+
return String(doc);
|
|
62165
|
+
}
|
|
62166
|
+
function writeManifestText(cwd2, body) {
|
|
62167
|
+
const target = manifestPath(cwd2);
|
|
62168
|
+
const tmp = `${target}.${randomBytes(8).toString("hex")}.tmp`;
|
|
62169
|
+
const fd = fs65.openSync(tmp, "wx");
|
|
62170
|
+
let closed = false;
|
|
62171
|
+
try {
|
|
62172
|
+
fs65.writeFileSync(fd, body, "utf8");
|
|
62173
|
+
fs65.closeSync(fd);
|
|
62174
|
+
closed = true;
|
|
62175
|
+
fs65.renameSync(tmp, target);
|
|
62176
|
+
} catch (err) {
|
|
62177
|
+
if (!closed) {
|
|
62178
|
+
try {
|
|
62179
|
+
fs65.closeSync(fd);
|
|
62180
|
+
} catch {}
|
|
62181
|
+
}
|
|
62182
|
+
fs65.rmSync(tmp, { force: true });
|
|
62183
|
+
throw err;
|
|
62184
|
+
}
|
|
62185
|
+
}
|
|
62186
|
+
function writeManifest(cwd2, manifest) {
|
|
62187
|
+
writeManifestText(cwd2, renderManifest(manifest));
|
|
62148
62188
|
}
|
|
62149
62189
|
function resolveInstructionsPath(cwd2, manifest) {
|
|
62150
62190
|
if (!manifest.instructions?.file)
|
|
@@ -62251,6 +62291,37 @@ function backfillPlaybookIds(playbooks, cloudComponents) {
|
|
|
62251
62291
|
});
|
|
62252
62292
|
return { playbooks: changed ? next : playbooks, changed };
|
|
62253
62293
|
}
|
|
62294
|
+
function backfillEvalIds(evals, cloudComponents) {
|
|
62295
|
+
const bySlug = new Map;
|
|
62296
|
+
for (const c2 of cloudComponents) {
|
|
62297
|
+
if (c2.type !== "eval")
|
|
62298
|
+
continue;
|
|
62299
|
+
const id = c2.meta?.eval_id;
|
|
62300
|
+
const payload = c2.meta?.eval;
|
|
62301
|
+
const judgeAgent = payload?.judge_agent;
|
|
62302
|
+
bySlug.set(c2.slug, {
|
|
62303
|
+
...typeof id === "string" && id ? { id } : {},
|
|
62304
|
+
...typeof judgeAgent === "string" && judgeAgent ? { judgeAgent } : {}
|
|
62305
|
+
});
|
|
62306
|
+
}
|
|
62307
|
+
let changed = false;
|
|
62308
|
+
const next = evals.map((entry) => {
|
|
62309
|
+
const cloud = bySlug.get(entry.slug);
|
|
62310
|
+
if (!cloud)
|
|
62311
|
+
return entry;
|
|
62312
|
+
let updated = entry;
|
|
62313
|
+
if (!updated.id && cloud.id) {
|
|
62314
|
+
updated = { id: cloud.id, ...updated };
|
|
62315
|
+
changed = true;
|
|
62316
|
+
}
|
|
62317
|
+
if (cloud.judgeAgent && updated.judge_agent !== undefined && updated.judge_agent !== cloud.judgeAgent) {
|
|
62318
|
+
updated = { ...updated, judge_agent: cloud.judgeAgent };
|
|
62319
|
+
changed = true;
|
|
62320
|
+
}
|
|
62321
|
+
return updated;
|
|
62322
|
+
});
|
|
62323
|
+
return { evals: changed ? next : evals, changed };
|
|
62324
|
+
}
|
|
62254
62325
|
function stripPlaybookFrontmatter(raw) {
|
|
62255
62326
|
const m3 = /^---\s*\n([\s\S]*?)\n---[ \t]*(?:\n|$)/.exec(raw);
|
|
62256
62327
|
if (!m3)
|
|
@@ -62318,7 +62389,9 @@ var AgentMetaSnapshotSchema = exports_external.object({
|
|
|
62318
62389
|
tagline: exports_external.string().nullish().transform((v3) => v3 ?? undefined),
|
|
62319
62390
|
entrypoint: exports_external.string().optional(),
|
|
62320
62391
|
machine_kind: exports_external.string().min(1).optional(),
|
|
62321
|
-
default_model: exports_external.string().nullable().optional()
|
|
62392
|
+
default_model: exports_external.string().nullable().optional(),
|
|
62393
|
+
memory: exports_external.boolean().nullable().optional(),
|
|
62394
|
+
browser: exports_external.boolean().nullable().optional()
|
|
62322
62395
|
});
|
|
62323
62396
|
var SyncStateSchema = exports_external.object({
|
|
62324
62397
|
schemaVersion: exports_external.literal(1),
|
|
@@ -63518,7 +63591,7 @@ function runHarnessInstall(harnessId, components, opts, agentName) {
|
|
|
63518
63591
|
}
|
|
63519
63592
|
|
|
63520
63593
|
// src/cli/agent.ts
|
|
63521
|
-
var
|
|
63594
|
+
var import_picocolors39 = __toESM(require_picocolors(), 1);
|
|
63522
63595
|
|
|
63523
63596
|
// src/cli/agent-pull.ts
|
|
63524
63597
|
import { spawn as spawn2 } from "node:child_process";
|
|
@@ -63694,6 +63767,21 @@ function hashMcpEntry(entry) {
|
|
|
63694
63767
|
payload.is_enabled = entry.is_enabled ?? true;
|
|
63695
63768
|
return crypto4.createHash("sha256").update(canonicalJson(payload)).digest("hex");
|
|
63696
63769
|
}
|
|
63770
|
+
function evalWirePayload(entry) {
|
|
63771
|
+
return {
|
|
63772
|
+
criteria: entry.criteria,
|
|
63773
|
+
enabled: entry.enabled,
|
|
63774
|
+
icon: entry.icon || null,
|
|
63775
|
+
judge_agent: entry.judge_agent ?? null,
|
|
63776
|
+
judge_model: entry.judge_model,
|
|
63777
|
+
judge_type: entry.judge_type,
|
|
63778
|
+
output_shape: entry.output_shape,
|
|
63779
|
+
classification_values: entry.classification_values && entry.classification_values.length > 0 ? entry.classification_values : null
|
|
63780
|
+
};
|
|
63781
|
+
}
|
|
63782
|
+
function hashEvalEntry(entry) {
|
|
63783
|
+
return crypto4.createHash("sha256").update(canonicalJson(evalWirePayload(entry))).digest("hex");
|
|
63784
|
+
}
|
|
63697
63785
|
function fileHash(p2) {
|
|
63698
63786
|
if (!exists(p2))
|
|
63699
63787
|
return null;
|
|
@@ -63809,6 +63897,13 @@ function readLocalComponents(cwd2, manifest) {
|
|
|
63809
63897
|
hash: componentHashFromFileHashes([hashString(wireBody)])
|
|
63810
63898
|
});
|
|
63811
63899
|
}
|
|
63900
|
+
for (const entry of manifest.evals ?? []) {
|
|
63901
|
+
out.push({
|
|
63902
|
+
type: "eval",
|
|
63903
|
+
slug: entry.slug,
|
|
63904
|
+
hash: hashEvalEntry(entry)
|
|
63905
|
+
});
|
|
63906
|
+
}
|
|
63812
63907
|
return out;
|
|
63813
63908
|
}
|
|
63814
63909
|
function threeWayDiff(input) {
|
|
@@ -63931,9 +64026,44 @@ function diffAgentMeta(manifestMeta, lockMeta, cloudMeta) {
|
|
|
63931
64026
|
cloudChanged: !!cloudMeta && !!lockMeta && !eq(cloudMeta, lockMeta)
|
|
63932
64027
|
};
|
|
63933
64028
|
}
|
|
64029
|
+
var WRITABLE_CAPABILITIES = ["memory", "browser"];
|
|
64030
|
+
var MIRRORED_CAPABILITIES = ["slack", "meeting", "github"];
|
|
64031
|
+
function manifestConfigState(manifest) {
|
|
64032
|
+
return {
|
|
64033
|
+
...manifest.machine_kind !== undefined ? { machine_kind: manifest.machine_kind } : {},
|
|
64034
|
+
...hasOwn(manifest, "default_model") ? { default_model: manifest.default_model ?? null } : {},
|
|
64035
|
+
...manifest.capabilities?.memory !== undefined ? { memory: manifest.capabilities.memory } : {},
|
|
64036
|
+
...manifest.capabilities?.browser !== undefined ? { browser: manifest.capabilities.browser } : {}
|
|
64037
|
+
};
|
|
64038
|
+
}
|
|
64039
|
+
function cloudConfigState(agent) {
|
|
64040
|
+
return {
|
|
64041
|
+
...agent.machine_kind !== undefined ? { machine_kind: agent.machine_kind } : {},
|
|
64042
|
+
...hasOwn(agent, "default_model") ? { default_model: agent.default_model ?? null } : {},
|
|
64043
|
+
...agent.memory_enabled !== undefined ? { memory: agent.memory_enabled } : {},
|
|
64044
|
+
...agent.browser_enabled !== undefined ? { browser: agent.browser_enabled } : {}
|
|
64045
|
+
};
|
|
64046
|
+
}
|
|
63934
64047
|
function hasOwn(value, key2) {
|
|
63935
64048
|
return !!value && Object.prototype.hasOwnProperty.call(value, key2);
|
|
63936
64049
|
}
|
|
64050
|
+
function staleConnectionMirrors(manifest, cloud) {
|
|
64051
|
+
const actualByName = {
|
|
64052
|
+
slack: cloud.slack_connected,
|
|
64053
|
+
meeting: cloud.meeting_connected,
|
|
64054
|
+
github: cloud.github_connected
|
|
64055
|
+
};
|
|
64056
|
+
const stale = [];
|
|
64057
|
+
for (const name of MIRRORED_CAPABILITIES) {
|
|
64058
|
+
const authored = manifest.capabilities?.[name];
|
|
64059
|
+
const actual = actualByName[name];
|
|
64060
|
+
if (authored === undefined || actual === undefined)
|
|
64061
|
+
continue;
|
|
64062
|
+
if (authored !== actual)
|
|
64063
|
+
stale.push({ name, authored, actual });
|
|
64064
|
+
}
|
|
64065
|
+
return stale;
|
|
64066
|
+
}
|
|
63937
64067
|
function diffAgentConfig(manifest, lock, cloud) {
|
|
63938
64068
|
const unsupported = [];
|
|
63939
64069
|
const machineSupported = cloud.machine_kind !== undefined;
|
|
@@ -63948,43 +64078,141 @@ function diffAgentConfig(manifest, lock, cloud) {
|
|
|
63948
64078
|
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
64079
|
const machineCloudChanged = lock?.machine_kind !== undefined && machineSupported && lock.machine_kind !== cloud.machine_kind && manifest.machine_kind !== cloud.machine_kind;
|
|
63950
64080
|
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
|
-
}
|
|
64081
|
+
const defaultModel = threeWayField(defaultModelSupported, manifest.default_model, cloud.default_model, lock, "default_model");
|
|
64082
|
+
const memory = threeWayField(hasOwn(cloud, "memory"), manifest.memory, cloud.memory, lock, "memory");
|
|
64083
|
+
const browser = threeWayField(hasOwn(cloud, "browser"), manifest.browser, cloud.browser, lock, "browser");
|
|
64084
|
+
if (manifest.memory !== undefined && !hasOwn(cloud, "memory")) {
|
|
64085
|
+
unsupported.push("memory");
|
|
64086
|
+
}
|
|
64087
|
+
if (manifest.browser !== undefined && !hasOwn(cloud, "browser")) {
|
|
64088
|
+
unsupported.push("browser");
|
|
63976
64089
|
}
|
|
63977
64090
|
return {
|
|
63978
64091
|
unsupported,
|
|
63979
64092
|
machineMismatch,
|
|
63980
64093
|
machineLocalChanged,
|
|
63981
64094
|
machineCloudChanged,
|
|
63982
|
-
defaultModelLocalChanged,
|
|
63983
|
-
defaultModelCloudChanged,
|
|
63984
|
-
defaultModelConflict,
|
|
63985
|
-
|
|
64095
|
+
defaultModelLocalChanged: defaultModel.localChanged,
|
|
64096
|
+
defaultModelCloudChanged: defaultModel.cloudChanged,
|
|
64097
|
+
defaultModelConflict: defaultModel.conflict,
|
|
64098
|
+
memory,
|
|
64099
|
+
browser,
|
|
64100
|
+
baselineConverged: machineConverged || defaultModel.converged || memory.converged || browser.converged
|
|
63986
64101
|
};
|
|
63987
64102
|
}
|
|
64103
|
+
function threeWayField(supported, authored, cloudRaw, lock, key2) {
|
|
64104
|
+
const result2 = {
|
|
64105
|
+
localChanged: false,
|
|
64106
|
+
cloudChanged: false,
|
|
64107
|
+
conflict: false,
|
|
64108
|
+
converged: false
|
|
64109
|
+
};
|
|
64110
|
+
if (!supported)
|
|
64111
|
+
return result2;
|
|
64112
|
+
const cloudValue = cloudRaw ?? null;
|
|
64113
|
+
const lockSupported = hasOwn(lock, key2);
|
|
64114
|
+
const lockValue = lock?.[key2] ?? null;
|
|
64115
|
+
if (authored === undefined) {
|
|
64116
|
+
if (lockSupported)
|
|
64117
|
+
result2.cloudChanged = cloudValue !== lockValue;
|
|
64118
|
+
return result2;
|
|
64119
|
+
}
|
|
64120
|
+
const localValue = authored ?? null;
|
|
64121
|
+
if (!lockSupported) {
|
|
64122
|
+
result2.localChanged = localValue !== cloudValue;
|
|
64123
|
+
result2.converged = localValue === cloudValue;
|
|
64124
|
+
return result2;
|
|
64125
|
+
}
|
|
64126
|
+
const localMoved = localValue !== lockValue;
|
|
64127
|
+
const cloudMoved = cloudValue !== lockValue;
|
|
64128
|
+
result2.conflict = localMoved && cloudMoved && localValue !== cloudValue;
|
|
64129
|
+
result2.localChanged = localMoved && localValue !== cloudValue;
|
|
64130
|
+
result2.cloudChanged = cloudMoved && localValue !== cloudValue;
|
|
64131
|
+
result2.converged = localMoved && cloudMoved && localValue === cloudValue;
|
|
64132
|
+
return result2;
|
|
64133
|
+
}
|
|
64134
|
+
|
|
64135
|
+
// src/core/eval-merge.ts
|
|
64136
|
+
function evalsFromCloudComponents(components) {
|
|
64137
|
+
return components.filter((c2) => c2.type === "eval").map((c2) => {
|
|
64138
|
+
const meta = c2.meta ?? {};
|
|
64139
|
+
const payload = meta.eval ?? {};
|
|
64140
|
+
const classification = payload.classification_values;
|
|
64141
|
+
return {
|
|
64142
|
+
...typeof meta.eval_id === "string" && meta.eval_id ? { id: meta.eval_id } : {},
|
|
64143
|
+
slug: c2.slug,
|
|
64144
|
+
criteria: typeof payload.criteria === "string" ? payload.criteria : "",
|
|
64145
|
+
...typeof payload.icon === "string" && payload.icon ? { icon: payload.icon } : {},
|
|
64146
|
+
enabled: payload.enabled !== false,
|
|
64147
|
+
judge_model: typeof payload.judge_model === "string" && payload.judge_model ? payload.judge_model : "claude-sonnet-4-6",
|
|
64148
|
+
judge_type: payload.judge_type === "agent" ? "agent" : "model",
|
|
64149
|
+
...typeof payload.judge_agent === "string" && payload.judge_agent ? { judge_agent: payload.judge_agent } : {},
|
|
64150
|
+
output_shape: payload.output_shape === "rating" || payload.output_shape === "classification" ? payload.output_shape : "binary",
|
|
64151
|
+
...Array.isArray(classification) && classification.length > 0 ? { classification_values: classification.map(String) } : {}
|
|
64152
|
+
};
|
|
64153
|
+
});
|
|
64154
|
+
}
|
|
64155
|
+
function mergeEvals(input) {
|
|
64156
|
+
const localBySlug = new Map(input.local.map((e2) => [e2.slug, e2]));
|
|
64157
|
+
const cloudSlugs = new Set(input.cloud.map((e2) => e2.slug));
|
|
64158
|
+
const merged = input.cloud.map((cloudEntry) => {
|
|
64159
|
+
if (!input.keepLocalEvalSlugs.has(cloudEntry.slug))
|
|
64160
|
+
return cloudEntry;
|
|
64161
|
+
return localBySlug.get(cloudEntry.slug) ?? cloudEntry;
|
|
64162
|
+
});
|
|
64163
|
+
const preservedEdits = [];
|
|
64164
|
+
for (const entry of input.local) {
|
|
64165
|
+
if (cloudSlugs.has(entry.slug))
|
|
64166
|
+
continue;
|
|
64167
|
+
const baseline = input.syncedEvalHashes.get(entry.slug);
|
|
64168
|
+
if (baseline !== undefined) {
|
|
64169
|
+
if (baseline === hashEvalEntry(entry))
|
|
64170
|
+
continue;
|
|
64171
|
+
preservedEdits.push(entry.slug);
|
|
64172
|
+
}
|
|
64173
|
+
merged.push(entry);
|
|
64174
|
+
}
|
|
64175
|
+
if (preservedEdits.length && input.onPreservedEdits) {
|
|
64176
|
+
input.onPreservedEdits(preservedEdits);
|
|
64177
|
+
}
|
|
64178
|
+
return merged;
|
|
64179
|
+
}
|
|
64180
|
+
|
|
64181
|
+
// src/core/capability-baseline.ts
|
|
64182
|
+
var CLOUD_KEY = {
|
|
64183
|
+
memory: "memory_enabled",
|
|
64184
|
+
browser: "browser_enabled"
|
|
64185
|
+
};
|
|
64186
|
+
function carryForward(previous, name) {
|
|
64187
|
+
return previous && Object.prototype.hasOwnProperty.call(previous, name) ? { [name]: previous[name] ?? null } : {};
|
|
64188
|
+
}
|
|
64189
|
+
function capabilityBaseline(cloudAgent, previous) {
|
|
64190
|
+
const out = {};
|
|
64191
|
+
for (const name of WRITABLE_CAPABILITIES) {
|
|
64192
|
+
const fromCloud = cloudAgent?.[CLOUD_KEY[name]];
|
|
64193
|
+
if (fromCloud !== undefined) {
|
|
64194
|
+
out[name] = fromCloud;
|
|
64195
|
+
continue;
|
|
64196
|
+
}
|
|
64197
|
+
Object.assign(out, carryForward(previous, name));
|
|
64198
|
+
}
|
|
64199
|
+
return out;
|
|
64200
|
+
}
|
|
64201
|
+
function capabilityBaselineAfterPush(cloudAgent, previous, diff2) {
|
|
64202
|
+
const out = {};
|
|
64203
|
+
for (const name of WRITABLE_CAPABILITIES) {
|
|
64204
|
+
if (diff2[name].cloudChanged && !diff2[name].localChanged) {
|
|
64205
|
+
Object.assign(out, carryForward(previous, name));
|
|
64206
|
+
continue;
|
|
64207
|
+
}
|
|
64208
|
+
const fromCloud = cloudAgent[CLOUD_KEY[name]];
|
|
64209
|
+
if (fromCloud !== undefined)
|
|
64210
|
+
out[name] = fromCloud;
|
|
64211
|
+
else
|
|
64212
|
+
Object.assign(out, carryForward(previous, name));
|
|
64213
|
+
}
|
|
64214
|
+
return out;
|
|
64215
|
+
}
|
|
63988
64216
|
|
|
63989
64217
|
// src/core/secrets-env.ts
|
|
63990
64218
|
import path78 from "node:path";
|
|
@@ -64628,7 +64856,7 @@ async function runAgentPull(cwd2, args) {
|
|
|
64628
64856
|
materializeInstructions(cwd2, cloud, toInstallKeys, keepLocalKeys, existingManifest);
|
|
64629
64857
|
materializeEntrypoint(cwd2, cloudAgent.entrypoint ?? "", existingManifest);
|
|
64630
64858
|
materializePlaybooks(cwd2, cloud, toInstallKeys, keepLocalKeys, existingManifest);
|
|
64631
|
-
const yaml = mergeManifest(cwd2, existingManifest, cloud, cloudAgent, harness, override ? {} : readLocalOnlyContentReporting(cwd2));
|
|
64859
|
+
const yaml = mergeManifest(cwd2, existingManifest, cloud, cloudAgent, harness, override ? {} : readLocalOnlyContentReporting(cwd2), new Map((lock?.components ?? []).filter((c2) => c2.type === "eval").map((c2) => [c2.slug, c2.hash])), new Set([...keepLocalKeys].filter((key2) => key2.startsWith("eval/")).map((key2) => key2.slice("eval/".length))));
|
|
64632
64860
|
writeManifest(cwd2, yaml);
|
|
64633
64861
|
writeLink(cwd2, buildLinkFromAgent(cloudAgent, harness, readLink(cwd2)));
|
|
64634
64862
|
const lockComponents = buildLockComponents({
|
|
@@ -64650,7 +64878,8 @@ async function runAgentPull(cwd2, args) {
|
|
|
64650
64878
|
tagline: cloudAgent.tagline,
|
|
64651
64879
|
...cloudAgent.entrypoint ? { entrypoint: cloudAgent.entrypoint.trim() } : {},
|
|
64652
64880
|
...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 } : {}
|
|
64881
|
+
...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 } : {},
|
|
64882
|
+
...capabilityBaseline(cloudAgent, lock?.agentMeta)
|
|
64654
64883
|
}
|
|
64655
64884
|
};
|
|
64656
64885
|
writeSyncState(cwd2, newState);
|
|
@@ -64789,7 +65018,7 @@ function materializePlaybooks(cwd2, cloud, toInstall, keepLocal, existingManifes
|
|
|
64789
65018
|
fs73.writeFileSync(target, body, "utf8");
|
|
64790
65019
|
}
|
|
64791
65020
|
}
|
|
64792
|
-
function mergeManifest(cwd2, prev, cloud, cloudAgent, harness, localOnly = {}) {
|
|
65021
|
+
function mergeManifest(cwd2, prev, cloud, cloudAgent, harness, localOnly = {}, syncedEvalHashes = new Map, keepLocalEvalSlugs = new Set) {
|
|
64793
65022
|
const skills = cloud.components.filter((c2) => c2.type === "skill").map((c2) => {
|
|
64794
65023
|
const localDecl = prev?.skills.find((s3) => looseSkillComponentSlug(s3.source) === c2.slug);
|
|
64795
65024
|
if (localDecl)
|
|
@@ -64852,6 +65081,7 @@ function mergeManifest(cwd2, prev, cloud, cloudAgent, harness, localOnly = {}) {
|
|
|
64852
65081
|
entry.is_enabled = payload.is_enabled;
|
|
64853
65082
|
return entry;
|
|
64854
65083
|
});
|
|
65084
|
+
const evals = evalsFromCloudComponents(cloud.components);
|
|
64855
65085
|
const caps = capabilitiesFromAgent(cloudAgent);
|
|
64856
65086
|
const machineKind = cloudAgent.machine_kind ?? prev?.machine_kind;
|
|
64857
65087
|
const defaultModelSupported = Object.prototype.hasOwnProperty.call(cloudAgent, "default_model");
|
|
@@ -64870,8 +65100,16 @@ function mergeManifest(cwd2, prev, cloud, cloudAgent, harness, localOnly = {}) {
|
|
|
64870
65100
|
playbooks,
|
|
64871
65101
|
skills,
|
|
64872
65102
|
mcp,
|
|
64873
|
-
evals: [],
|
|
64874
65103
|
...localOnly,
|
|
65104
|
+
evals: mergeEvals({
|
|
65105
|
+
cloud: evals,
|
|
65106
|
+
local: localOnly.evals ?? [],
|
|
65107
|
+
syncedEvalHashes,
|
|
65108
|
+
keepLocalEvalSlugs,
|
|
65109
|
+
onPreservedEdits: (slugs) => {
|
|
65110
|
+
f2.warn(`Kept ${slugs.length} eval${slugs.length === 1 ? "" : "s"} with unpushed edits that ${slugs.length === 1 ? "has" : "have"} been deleted in the cloud: ${slugs.map((s3) => import_picocolors26.default.bold(s3)).join(", ")}. ${import_picocolors26.default.dim("Push to restore, or remove from the manifest to accept the deletion.")}`);
|
|
65111
|
+
}
|
|
65112
|
+
}),
|
|
64875
65113
|
capabilities: {
|
|
64876
65114
|
memory: caps.memory,
|
|
64877
65115
|
browser: caps.browser,
|
|
@@ -64941,7 +65179,8 @@ function buildLockFromCloud(agent_id, cloud, prev, cloudAgent) {
|
|
|
64941
65179
|
tagline: cloudAgent.tagline,
|
|
64942
65180
|
...cloudAgent.entrypoint ? { entrypoint: cloudAgent.entrypoint.trim() } : {},
|
|
64943
65181
|
...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 } : {}
|
|
65182
|
+
...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 } : {},
|
|
65183
|
+
...capabilityBaseline(cloudAgent, prev?.agentMeta)
|
|
64945
65184
|
} : prev?.agentMeta
|
|
64946
65185
|
};
|
|
64947
65186
|
}
|
|
@@ -65056,6 +65295,30 @@ function handleApiError2(err) {
|
|
|
65056
65295
|
// src/cli/agent-push.ts
|
|
65057
65296
|
var import_picocolors28 = __toESM(require_picocolors(), 1);
|
|
65058
65297
|
|
|
65298
|
+
// src/core/eval-reconcile.ts
|
|
65299
|
+
function manifestClaimsEvals(manifest) {
|
|
65300
|
+
return (manifest.evals ?? []).length > 0;
|
|
65301
|
+
}
|
|
65302
|
+
function decideEvalReconcile(input) {
|
|
65303
|
+
const evalRows = input.rows.filter((r2) => r2.type === "eval");
|
|
65304
|
+
const unseen = evalRows.filter((r2) => r2.status === "added-cloud").map((r2) => r2.slug).sort();
|
|
65305
|
+
const cloudModified = evalRows.filter((r2) => r2.status === "modified-cloud" || r2.status === "modified-both" || r2.status === "added-local" && r2.localHash !== undefined && r2.cloudHash !== undefined && r2.localHash !== r2.cloudHash).map((r2) => r2.slug).sort();
|
|
65306
|
+
const archives = evalRows.filter((r2) => r2.status === "removed-local").map((r2) => r2.slug).sort();
|
|
65307
|
+
if (!input.claimsEvals && archives.length === 0) {
|
|
65308
|
+
if (unseen.length > 0 || cloudModified.length > 0) {
|
|
65309
|
+
return { kind: "skip", unseen: [...unseen, ...cloudModified].sort() };
|
|
65310
|
+
}
|
|
65311
|
+
return { kind: "reconcile", archives: [] };
|
|
65312
|
+
}
|
|
65313
|
+
if (input.force) {
|
|
65314
|
+
return { kind: "reconcile", archives: [...archives, ...unseen].sort() };
|
|
65315
|
+
}
|
|
65316
|
+
if (unseen.length === 0 && cloudModified.length === 0) {
|
|
65317
|
+
return { kind: "reconcile", archives };
|
|
65318
|
+
}
|
|
65319
|
+
return { kind: "blocked", unseen, cloudModified, archives };
|
|
65320
|
+
}
|
|
65321
|
+
|
|
65059
65322
|
// src/core/agent-outgoing.ts
|
|
65060
65323
|
var import_picocolors27 = __toESM(require_picocolors(), 1);
|
|
65061
65324
|
async function buildOutgoingComponents(cwd2, manifest, cloud, resolvedVersions) {
|
|
@@ -65158,6 +65421,18 @@ async function buildOutgoingComponents(cwd2, manifest, cloud, resolvedVersions)
|
|
|
65158
65421
|
}
|
|
65159
65422
|
});
|
|
65160
65423
|
}
|
|
65424
|
+
for (const entry of manifest.evals ?? []) {
|
|
65425
|
+
out.push({
|
|
65426
|
+
type: "eval",
|
|
65427
|
+
slug: entry.slug,
|
|
65428
|
+
hash: hashEvalEntry(entry),
|
|
65429
|
+
files: [],
|
|
65430
|
+
meta: {
|
|
65431
|
+
eval: evalWirePayload(entry),
|
|
65432
|
+
...entry.id ? { eval_id: entry.id } : {}
|
|
65433
|
+
}
|
|
65434
|
+
});
|
|
65435
|
+
}
|
|
65161
65436
|
for (const entry of manifest.mcp ?? []) {
|
|
65162
65437
|
if (!entry.url && !entry.command) {
|
|
65163
65438
|
f2.error(`MCP ${import_picocolors27.default.bold(entry.name)} needs either ${import_picocolors27.default.cyan("url")} or ${import_picocolors27.default.cyan("command")}.`);
|
|
@@ -65289,13 +65564,25 @@ async function runAgentPush(cwd2, args) {
|
|
|
65289
65564
|
lock: lock?.components ?? [],
|
|
65290
65565
|
cloud: cloud.components
|
|
65291
65566
|
});
|
|
65292
|
-
const config = diffAgentConfig(manifest, lock?.agentMeta, cloudAgent);
|
|
65567
|
+
const config = diffAgentConfig(manifestConfigState(manifest), lock?.agentMeta, cloudConfigState(cloudAgent));
|
|
65293
65568
|
if (config.unsupported.length > 0) {
|
|
65294
65569
|
f2.error(`This control plane does not support declarative ${config.unsupported.join(" / ")} config.`);
|
|
65295
65570
|
f2.info(`Use the MAS control plane, then run ${import_picocolors28.default.cyan("brainbase agent pull")} before retrying.`);
|
|
65296
65571
|
process.exitCode = 1;
|
|
65297
65572
|
return;
|
|
65298
65573
|
}
|
|
65574
|
+
const staleMirrors = staleConnectionMirrors(manifest, cloudAgent);
|
|
65575
|
+
if (staleMirrors.length > 0) {
|
|
65576
|
+
f2.error(`This manifest's connection state is out of date: ${staleMirrors.map((m3) => `${m3.name} says ${m3.authored}, actually ${m3.actual}`).join("; ")}.`);
|
|
65577
|
+
f2.info(`Run ${import_picocolors28.default.cyan("brainbase agent pull")} to refresh it. These are reported by the cloud, not set from the manifest.`);
|
|
65578
|
+
for (const m3 of staleMirrors) {
|
|
65579
|
+
if (!m3.actual) {
|
|
65580
|
+
f2.info(`To actually connect ${m3.name}, run ${import_picocolors28.default.cyan(`brainbase agent connect ${m3.name}`)}.`);
|
|
65581
|
+
}
|
|
65582
|
+
}
|
|
65583
|
+
process.exitCode = 1;
|
|
65584
|
+
return;
|
|
65585
|
+
}
|
|
65299
65586
|
if (config.machineMismatch) {
|
|
65300
65587
|
if (config.machineCloudChanged && !config.machineLocalChanged) {
|
|
65301
65588
|
f2.error("Cannot push: machine_kind changed on the cloud.");
|
|
@@ -65316,6 +65603,17 @@ async function runAgentPush(cwd2, args) {
|
|
|
65316
65603
|
if (config.defaultModelConflict && args.force) {
|
|
65317
65604
|
f2.warn(`${import_picocolors28.default.yellow("--force")}: overwriting the cloud default_model with the local value.`);
|
|
65318
65605
|
}
|
|
65606
|
+
const conflictedCapabilities = WRITABLE_CAPABILITIES.filter((name) => config[name].conflict);
|
|
65607
|
+
if (conflictedCapabilities.length > 0) {
|
|
65608
|
+
const label = conflictedCapabilities.map((name) => `capabilities.${name}`).join(" and ");
|
|
65609
|
+
if (!args.force) {
|
|
65610
|
+
f2.error(`Cannot push: ${label} changed both locally and on the cloud.`);
|
|
65611
|
+
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.`);
|
|
65612
|
+
process.exitCode = 1;
|
|
65613
|
+
return;
|
|
65614
|
+
}
|
|
65615
|
+
f2.warn(`${import_picocolors28.default.yellow("--force")}: overwriting the cloud ${label} with the local value.`);
|
|
65616
|
+
}
|
|
65319
65617
|
const registryRefs = new Map;
|
|
65320
65618
|
for (const entry of manifest.skills) {
|
|
65321
65619
|
try {
|
|
@@ -65396,12 +65694,33 @@ async function runAgentPush(cwd2, args) {
|
|
|
65396
65694
|
}
|
|
65397
65695
|
const entrypointChanged = resolvedEntrypoint !== undefined && (resolvedEntrypoint ?? "").trim() !== (lock?.agentMeta?.entrypoint ?? "").trim();
|
|
65398
65696
|
for (const r2 of rows) {
|
|
65399
|
-
if (r2.type !== "instruction" && r2.type !== "skill" && r2.type !== "mcp" && r2.type !== "playbook") {
|
|
65400
|
-
f2.error(`Component ${fmtType(r2.type)} ${import_picocolors28.default.bold(r2.slug)} can't be pushed yet — the server accepts instructions, skills, and
|
|
65697
|
+
if (r2.type !== "instruction" && r2.type !== "skill" && r2.type !== "mcp" && r2.type !== "playbook" && r2.type !== "eval") {
|
|
65698
|
+
f2.error(`Component ${fmtType(r2.type)} ${import_picocolors28.default.bold(r2.slug)} can't be pushed yet — the server accepts instructions, skills, mcps, playbooks, and evals in this version.`);
|
|
65401
65699
|
process.exitCode = 1;
|
|
65402
65700
|
return;
|
|
65403
65701
|
}
|
|
65404
65702
|
}
|
|
65703
|
+
const evalDecision = decideEvalReconcile({
|
|
65704
|
+
rows,
|
|
65705
|
+
claimsEvals: manifestClaimsEvals(manifest),
|
|
65706
|
+
force: !!args.force
|
|
65707
|
+
});
|
|
65708
|
+
if (evalDecision.kind === "blocked") {
|
|
65709
|
+
const { unseen, cloudModified } = evalDecision;
|
|
65710
|
+
f2.error(unseen.length > 0 ? "Cannot push: the cloud has eval changes this folder has never seen." : "Cannot push: evals changed both locally and in the cloud.");
|
|
65711
|
+
for (const slug of unseen) {
|
|
65712
|
+
console.error(` ${import_picocolors28.default.red("!")} ${fmtType("eval")} ${import_picocolors28.default.bold(slug)} ${import_picocolors28.default.dim("(only in the cloud — pushing would archive it)")}`);
|
|
65713
|
+
}
|
|
65714
|
+
for (const slug of cloudModified) {
|
|
65715
|
+
console.error(` ${import_picocolors28.default.red("!")} ${fmtType("eval")} ${import_picocolors28.default.bold(slug)} ${import_picocolors28.default.dim("(edited in the cloud — pushing would overwrite that edit)")}`);
|
|
65716
|
+
}
|
|
65717
|
+
f2.info(`Run ${import_picocolors28.default.cyan("brainbase agent pull")} to bring ${unseen.length + cloudModified.length === 1 ? "it" : "them"} into ${import_picocolors28.default.bold("brainbase.agent.yaml")}, then push — or ${import_picocolors28.default.cyan("brainbase agent push --force")} to make your local evals authoritative and archive the rest.`);
|
|
65718
|
+
process.exitCode = 1;
|
|
65719
|
+
return;
|
|
65720
|
+
}
|
|
65721
|
+
if (evalDecision.kind === "skip") {
|
|
65722
|
+
f2.warn(`${evalDecision.unseen.length} cloud eval${evalDecision.unseen.length === 1 ? "" : "s"} (${evalDecision.unseen.map((s3) => import_picocolors28.default.bold(s3)).join(", ")}) ${evalDecision.unseen.length === 1 ? "is" : "are"} not in ${import_picocolors28.default.bold("brainbase.agent.yaml")} and will be left untouched. Run ${import_picocolors28.default.cyan("brainbase agent pull")} to manage ${evalDecision.unseen.length === 1 ? "it" : "them"} from here.`);
|
|
65723
|
+
}
|
|
65405
65724
|
for (const entry of manifest.skills) {
|
|
65406
65725
|
let parsed;
|
|
65407
65726
|
try {
|
|
@@ -65455,7 +65774,7 @@ async function runAgentPush(cwd2, args) {
|
|
|
65455
65774
|
f2.warn(`Cloud runtime config changed since the last sync. Run ${import_picocolors28.default.cyan("brainbase agent pull")} to accept it locally.`);
|
|
65456
65775
|
}
|
|
65457
65776
|
const shouldPushManifest = meta.localChanged || entrypointChanged || toSend.length > 0;
|
|
65458
|
-
const shouldUpdateAgent = meta.localChanged || entrypointChanged || config.defaultModelLocalChanged;
|
|
65777
|
+
const shouldUpdateAgent = meta.localChanged || entrypointChanged || config.defaultModelLocalChanged || config.memory.localChanged || config.browser.localChanged;
|
|
65459
65778
|
const hasAgentChanges = shouldPushManifest || shouldUpdateAgent;
|
|
65460
65779
|
const outgoing = hasAgentChanges ? await buildOutgoingComponents(cwd2, manifest, cloud, resolvedVersions) : null;
|
|
65461
65780
|
if (hasAgentChanges && outgoing === null) {
|
|
@@ -65499,7 +65818,7 @@ async function runAgentPush(cwd2, args) {
|
|
|
65499
65818
|
});
|
|
65500
65819
|
}
|
|
65501
65820
|
if (!hasAgentChanges && !secretPlan) {
|
|
65502
|
-
if (config.defaultModelCloudChanged || config.machineCloudChanged) {
|
|
65821
|
+
if (config.defaultModelCloudChanged || config.machineCloudChanged || config.memory.cloudChanged || config.browser.cloudChanged) {
|
|
65503
65822
|
f2.info("Nothing local to push; cloud runtime config is awaiting pull.");
|
|
65504
65823
|
return;
|
|
65505
65824
|
}
|
|
@@ -65552,14 +65871,28 @@ async function runAgentPush(cwd2, args) {
|
|
|
65552
65871
|
text: secretDiffSummary(secretPlan.diff)
|
|
65553
65872
|
});
|
|
65554
65873
|
}
|
|
65874
|
+
const evalArchives = evalDecision.kind === "reconcile" ? evalDecision.archives : [];
|
|
65875
|
+
if (evalArchives.length) {
|
|
65876
|
+
resultRows.push({
|
|
65877
|
+
type: "rem",
|
|
65878
|
+
label: "archive evals",
|
|
65879
|
+
text: `${evalArchives.length} · ${evalArchives.join(", ")}`
|
|
65880
|
+
});
|
|
65881
|
+
}
|
|
65555
65882
|
await showResultCard({
|
|
65556
65883
|
title: "PUSH",
|
|
65557
65884
|
tone: "info",
|
|
65558
65885
|
subtitle: `${manifest.agent.name} ← local`,
|
|
65559
65886
|
rows: resultRows
|
|
65560
65887
|
});
|
|
65888
|
+
if (evalArchives.length) {
|
|
65889
|
+
f2.warn(`${evalArchives.length} cloud eval${evalArchives.length === 1 ? "" : "s"} ${evalArchives.length === 1 ? "is" : "are"} missing from ${import_picocolors28.default.bold("brainbase.agent.yaml")} and will be archived: ${evalArchives.map((s3) => import_picocolors28.default.bold(s3)).join(", ")}. ${import_picocolors28.default.dim("Archived, not deleted — past verdicts are kept, and re-adding the eval restores it.")}`);
|
|
65890
|
+
}
|
|
65561
65891
|
if (!autoProceed(args.yes)) {
|
|
65562
|
-
const ok = await se({
|
|
65892
|
+
const ok = await se({
|
|
65893
|
+
message: evalArchives.length ? `Send these changes, archiving ${evalArchives.length} eval${evalArchives.length === 1 ? "" : "s"}?` : "Send these changes?",
|
|
65894
|
+
initialValue: evalArchives.length === 0
|
|
65895
|
+
});
|
|
65563
65896
|
if (!ensureNotCancelled(ok)) {
|
|
65564
65897
|
$e("Aborted.");
|
|
65565
65898
|
return;
|
|
@@ -65571,7 +65904,7 @@ async function runAgentPush(cwd2, args) {
|
|
|
65571
65904
|
$e(`Pushed secrets for ${manifest.agent.name}.`);
|
|
65572
65905
|
return;
|
|
65573
65906
|
}
|
|
65574
|
-
if (meta.localChanged || entrypointChanged || config.defaultModelLocalChanged) {
|
|
65907
|
+
if (meta.localChanged || entrypointChanged || config.defaultModelLocalChanged || config.memory.localChanged || config.browser.localChanged) {
|
|
65575
65908
|
const metaSpinner = de();
|
|
65576
65909
|
metaSpinner.start("Updating agent config…");
|
|
65577
65910
|
try {
|
|
@@ -65586,6 +65919,12 @@ async function runAgentPush(cwd2, args) {
|
|
|
65586
65919
|
if (config.defaultModelLocalChanged) {
|
|
65587
65920
|
update2.default_model = manifest.default_model ?? null;
|
|
65588
65921
|
}
|
|
65922
|
+
if (config.memory.localChanged) {
|
|
65923
|
+
update2.memory_enabled = manifest.capabilities?.memory;
|
|
65924
|
+
}
|
|
65925
|
+
if (config.browser.localChanged) {
|
|
65926
|
+
update2.browser_enabled = manifest.capabilities?.browser;
|
|
65927
|
+
}
|
|
65589
65928
|
cloudAgent = await api.updateAgent(agentId, update2);
|
|
65590
65929
|
metaSpinner.stop("Agent config updated.");
|
|
65591
65930
|
} catch (err) {
|
|
@@ -65618,10 +65957,13 @@ async function runAgentPush(cwd2, args) {
|
|
|
65618
65957
|
pushSpinner.start("Pushing…");
|
|
65619
65958
|
let updatedCloud;
|
|
65620
65959
|
try {
|
|
65960
|
+
const reconcileEvals = evalDecision.kind !== "skip";
|
|
65961
|
+
const components = reconcileEvals ? outgoing : outgoing.filter((c2) => c2.type !== "eval");
|
|
65621
65962
|
updatedCloud = await api.pushAgentManifest(agentId, {
|
|
65622
|
-
components
|
|
65963
|
+
components,
|
|
65623
65964
|
base_revision: cloud.revision,
|
|
65624
|
-
reconcile_playbooks: true
|
|
65965
|
+
reconcile_playbooks: true,
|
|
65966
|
+
reconcile_evals: reconcileEvals
|
|
65625
65967
|
});
|
|
65626
65968
|
pushSpinner.stop(`Pushed. New revision ${updatedCloud.revision}.`);
|
|
65627
65969
|
} catch (err) {
|
|
@@ -65635,10 +65977,21 @@ async function runAgentPush(cwd2, args) {
|
|
|
65635
65977
|
return handleApiError3(err);
|
|
65636
65978
|
}
|
|
65637
65979
|
const backfill = backfillPlaybookIds(manifest.playbooks ?? [], updatedCloud.components);
|
|
65980
|
+
let manifestChanged = backfill.changed;
|
|
65638
65981
|
if (backfill.changed) {
|
|
65639
65982
|
manifest.playbooks = backfill.playbooks;
|
|
65983
|
+
}
|
|
65984
|
+
const evalBackfill = backfillEvalIds(manifest.evals ?? [], updatedCloud.components);
|
|
65985
|
+
if (evalBackfill.changed) {
|
|
65986
|
+
manifest.evals = evalBackfill.evals;
|
|
65987
|
+
manifestChanged = true;
|
|
65988
|
+
}
|
|
65989
|
+
if (manifestChanged) {
|
|
65640
65990
|
writeManifest(cwd2, manifest);
|
|
65641
65991
|
}
|
|
65992
|
+
for (const warning of updatedCloud.warnings ?? []) {
|
|
65993
|
+
f2.warn(warning);
|
|
65994
|
+
}
|
|
65642
65995
|
const existing = readLink(cwd2);
|
|
65643
65996
|
if (existing) {
|
|
65644
65997
|
writeLink(cwd2, {
|
|
@@ -65652,12 +66005,27 @@ async function runAgentPush(cwd2, args) {
|
|
|
65652
66005
|
if (lc.hash)
|
|
65653
66006
|
localHashByKey.set(`${lc.type}/${lc.slug}`, lc.hash);
|
|
65654
66007
|
}
|
|
66008
|
+
if (evalBackfill.changed) {
|
|
66009
|
+
for (const entry of manifest.evals ?? []) {
|
|
66010
|
+
localHashByKey.set(`eval/${entry.slug}`, hashEvalEntry(entry));
|
|
66011
|
+
}
|
|
66012
|
+
}
|
|
66013
|
+
const lockSource = evalDecision.kind === "skip" ? [
|
|
66014
|
+
...updatedCloud.components.filter((c2) => c2.type !== "eval"),
|
|
66015
|
+
...(lock?.components ?? []).filter((c2) => c2.type === "eval").map((c2) => ({
|
|
66016
|
+
type: c2.type,
|
|
66017
|
+
slug: c2.slug,
|
|
66018
|
+
hash: c2.hash,
|
|
66019
|
+
files: [],
|
|
66020
|
+
meta: undefined
|
|
66021
|
+
}))
|
|
66022
|
+
] : updatedCloud.components;
|
|
65655
66023
|
const newLock = {
|
|
65656
66024
|
schemaVersion: 1,
|
|
65657
66025
|
agent_id: agentId,
|
|
65658
66026
|
revision: updatedCloud.revision,
|
|
65659
66027
|
synced_at: new Date().toISOString(),
|
|
65660
|
-
components:
|
|
66028
|
+
components: lockSource.map((c2) => {
|
|
65661
66029
|
const decl = manifest.skills.find((s3) => {
|
|
65662
66030
|
try {
|
|
65663
66031
|
const parsed = parseSkillSource2(s3.source);
|
|
@@ -65702,7 +66070,8 @@ function buildAgentMetaAfterPush({
|
|
|
65702
66070
|
tagline: manifest.agent.tagline,
|
|
65703
66071
|
entrypoint: resolvedEntrypoint !== undefined ? resolvedEntrypoint.trim() : lock?.agentMeta?.entrypoint,
|
|
65704
66072
|
...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 } : {}
|
|
66073
|
+
...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 } : {},
|
|
66074
|
+
...capabilityBaselineAfterPush(cloudAgent, lock?.agentMeta, config)
|
|
65706
66075
|
};
|
|
65707
66076
|
}
|
|
65708
66077
|
async function planSecretPush(cwd2, agentId) {
|
|
@@ -65751,6 +66120,9 @@ function handleApiError3(err) {
|
|
|
65751
66120
|
// src/cli/agent-status.ts
|
|
65752
66121
|
import path81 from "node:path";
|
|
65753
66122
|
var import_picocolors29 = __toESM(require_picocolors(), 1);
|
|
66123
|
+
function capabilityDrifted(field) {
|
|
66124
|
+
return field.localChanged || field.cloudChanged || field.conflict;
|
|
66125
|
+
}
|
|
65754
66126
|
async function runAgentStatus(cwd2, args = {}) {
|
|
65755
66127
|
const json = args.json === true;
|
|
65756
66128
|
if (!json)
|
|
@@ -65818,7 +66190,7 @@ async function runAgentStatus(cwd2, args = {}) {
|
|
|
65818
66190
|
cloud: cloud.components
|
|
65819
66191
|
});
|
|
65820
66192
|
const meta = diffAgentMeta(manifest.agent, lock?.agentMeta, cloudAgent);
|
|
65821
|
-
const config = diffAgentConfig(manifest, lock?.agentMeta, cloudAgent);
|
|
66193
|
+
const config = diffAgentConfig(manifestConfigState(manifest), lock?.agentMeta, cloudConfigState(cloudAgent));
|
|
65822
66194
|
const toPush = [];
|
|
65823
66195
|
const toPull = [];
|
|
65824
66196
|
const conflicts = [];
|
|
@@ -65865,10 +66237,21 @@ async function runAgentStatus(cwd2, args = {}) {
|
|
|
65865
66237
|
}
|
|
65866
66238
|
const componentsDrifted = conflicts.length > 0 || toPush.length > 0 || toPull.length > 0;
|
|
65867
66239
|
const metaDrifted = meta.localChanged || meta.cloudChanged;
|
|
65868
|
-
const configDrifted = config.unsupported.length > 0 || config.machineMismatch || config.machineCloudChanged || config.defaultModelLocalChanged || config.defaultModelCloudChanged;
|
|
66240
|
+
const configDrifted = config.unsupported.length > 0 || config.machineMismatch || config.machineCloudChanged || config.defaultModelLocalChanged || config.defaultModelCloudChanged || capabilityDrifted(config.memory) || capabilityDrifted(config.browser);
|
|
65869
66241
|
const secretsDrifted = secretDrift.localOnly.length > 0 || secretDrift.cloudOnly.length > 0 || secretDrift.changed.length > 0;
|
|
65870
66242
|
const everythingInSync = !componentsDrifted && !metaDrifted && !configDrifted && !secretsDrifted;
|
|
65871
66243
|
const unchecked = secretsChecked ? [] : [{ signal: "secrets", reason: secretsUncheckedReason }];
|
|
66244
|
+
const evalPlan = decideEvalReconcile({
|
|
66245
|
+
rows,
|
|
66246
|
+
claimsEvals: manifestClaimsEvals(manifest),
|
|
66247
|
+
force: false
|
|
66248
|
+
});
|
|
66249
|
+
const evalReport = {
|
|
66250
|
+
archive: evalPlan.kind === "reconcile" ? evalPlan.archives : [],
|
|
66251
|
+
unseen: evalPlan.kind === "reconcile" ? [] : evalPlan.unseen,
|
|
66252
|
+
cloudModified: evalPlan.kind === "blocked" ? evalPlan.cloudModified : [],
|
|
66253
|
+
pushBlocked: evalPlan.kind === "blocked"
|
|
66254
|
+
};
|
|
65872
66255
|
if (json) {
|
|
65873
66256
|
emitJson({
|
|
65874
66257
|
linked: true,
|
|
@@ -65883,7 +66266,9 @@ async function runAgentStatus(cwd2, args = {}) {
|
|
|
65883
66266
|
machineCloudChanged: config.machineCloudChanged,
|
|
65884
66267
|
defaultModelLocalChanged: config.defaultModelLocalChanged,
|
|
65885
66268
|
defaultModelCloudChanged: config.defaultModelCloudChanged,
|
|
65886
|
-
defaultModelConflict: config.defaultModelConflict
|
|
66269
|
+
defaultModelConflict: config.defaultModelConflict,
|
|
66270
|
+
memory: config.memory,
|
|
66271
|
+
browser: config.browser
|
|
65887
66272
|
},
|
|
65888
66273
|
secrets: secretsChecked ? {
|
|
65889
66274
|
localOnly: secretDrift.localOnly,
|
|
@@ -65895,6 +66280,7 @@ async function runAgentStatus(cwd2, args = {}) {
|
|
|
65895
66280
|
pull: toPull.map(rowJson),
|
|
65896
66281
|
conflicts: conflicts.map(rowJson)
|
|
65897
66282
|
},
|
|
66283
|
+
evals: evalReport,
|
|
65898
66284
|
inSync: everythingInSync,
|
|
65899
66285
|
unchecked
|
|
65900
66286
|
});
|
|
@@ -65944,6 +66330,19 @@ async function runAgentStatus(cwd2, args = {}) {
|
|
|
65944
66330
|
lines.push(` ${import_picocolors29.default.cyan("← pull")} default_model changed on cloud`);
|
|
65945
66331
|
}
|
|
65946
66332
|
}
|
|
66333
|
+
for (const name of WRITABLE_CAPABILITIES) {
|
|
66334
|
+
const field = config[name];
|
|
66335
|
+
if (field.conflict) {
|
|
66336
|
+
lines.push(` ${import_picocolors29.default.red("! conflict")} capabilities.${name} changed locally and on cloud`);
|
|
66337
|
+
continue;
|
|
66338
|
+
}
|
|
66339
|
+
if (field.localChanged) {
|
|
66340
|
+
lines.push(` ${import_picocolors29.default.yellow("→ push")} capabilities.${name} edited locally`);
|
|
66341
|
+
}
|
|
66342
|
+
if (field.cloudChanged) {
|
|
66343
|
+
lines.push(` ${import_picocolors29.default.cyan("← pull")} capabilities.${name} changed on cloud`);
|
|
66344
|
+
}
|
|
66345
|
+
}
|
|
65947
66346
|
lines.push("");
|
|
65948
66347
|
}
|
|
65949
66348
|
if (secretsDrifted || !secretsChecked) {
|
|
@@ -65985,6 +66384,31 @@ async function runAgentStatus(cwd2, args = {}) {
|
|
|
65985
66384
|
lines.push(` ${import_picocolors29.default.red("!")} ${fmtRow(r2)}`);
|
|
65986
66385
|
lines.push("");
|
|
65987
66386
|
}
|
|
66387
|
+
if (evalReport.archive.length) {
|
|
66388
|
+
lines.push(` ${import_picocolors29.default.bold("evals a push would archive")} ${import_picocolors29.default.dim(`(${evalReport.archive.length})`)}`);
|
|
66389
|
+
for (const slug of evalReport.archive) {
|
|
66390
|
+
lines.push(` ${import_picocolors29.default.yellow("⨯")} ${import_picocolors29.default.bold(slug)} ${import_picocolors29.default.dim("— in the cloud, not in this manifest")}`);
|
|
66391
|
+
}
|
|
66392
|
+
lines.push(` ${import_picocolors29.default.dim("archived, not deleted: past verdicts are kept and re-adding the eval restores it")}`);
|
|
66393
|
+
lines.push("");
|
|
66394
|
+
}
|
|
66395
|
+
if (evalReport.pushBlocked) {
|
|
66396
|
+
lines.push(` ${import_picocolors29.default.bold(import_picocolors29.default.red("evals: push blocked"))}`);
|
|
66397
|
+
for (const slug of evalReport.unseen) {
|
|
66398
|
+
lines.push(` ${import_picocolors29.default.red("!")} ${import_picocolors29.default.bold(slug)} ${import_picocolors29.default.dim("— only in the cloud; pushing would archive it")}`);
|
|
66399
|
+
}
|
|
66400
|
+
for (const slug of evalReport.cloudModified) {
|
|
66401
|
+
lines.push(` ${import_picocolors29.default.red("!")} ${import_picocolors29.default.bold(slug)} ${import_picocolors29.default.dim("— edited in the cloud; pushing would overwrite that edit")}`);
|
|
66402
|
+
}
|
|
66403
|
+
lines.push(` ${import_picocolors29.default.dim("run")} ${import_picocolors29.default.cyan("brainbase agent pull")} ${import_picocolors29.default.dim("first")}`);
|
|
66404
|
+
lines.push("");
|
|
66405
|
+
} else if (evalReport.unseen.length) {
|
|
66406
|
+
lines.push(` ${import_picocolors29.default.bold("evals only in the cloud")} ${import_picocolors29.default.dim(`(${evalReport.unseen.length})`)}`);
|
|
66407
|
+
for (const slug of evalReport.unseen) {
|
|
66408
|
+
lines.push(` ${import_picocolors29.default.cyan("←")} ${import_picocolors29.default.bold(slug)} ${import_picocolors29.default.dim("— left untouched by push; pull to manage it here")}`);
|
|
66409
|
+
}
|
|
66410
|
+
lines.push("");
|
|
66411
|
+
}
|
|
65988
66412
|
lines.push(` ${import_picocolors29.default.dim("run")} ${import_picocolors29.default.cyan("brainbase agent pull")} ${import_picocolors29.default.dim("to apply cloud changes,")} ${import_picocolors29.default.cyan("brainbase agent push")} ${import_picocolors29.default.dim("to send yours")}`);
|
|
65989
66413
|
lines.push("");
|
|
65990
66414
|
console.log(lines.join(`
|
|
@@ -66065,7 +66489,6 @@ function formatExport(shell, key2, value) {
|
|
|
66065
66489
|
}
|
|
66066
66490
|
|
|
66067
66491
|
// src/cli/agent-create.ts
|
|
66068
|
-
import path82 from "node:path";
|
|
66069
66492
|
var import_picocolors32 = __toESM(require_picocolors(), 1);
|
|
66070
66493
|
|
|
66071
66494
|
// src/ui/box.ts
|
|
@@ -66258,6 +66681,153 @@ async function listTeamsPerOrg(orgs) {
|
|
|
66258
66681
|
return { entries, resolved, failures };
|
|
66259
66682
|
}
|
|
66260
66683
|
|
|
66684
|
+
// src/core/agent-scaffold.ts
|
|
66685
|
+
var import_yaml4 = __toESM(require_dist(), 1);
|
|
66686
|
+
import path82 from "node:path";
|
|
66687
|
+
var STARTER_TAGLINE = "A starter agent.";
|
|
66688
|
+
var FALLBACK_NAME = "my-agent";
|
|
66689
|
+
var FALLBACK_HARNESS = "claude-code";
|
|
66690
|
+
function isKnownHarness(id) {
|
|
66691
|
+
return adapters.some((a3) => a3.id === id);
|
|
66692
|
+
}
|
|
66693
|
+
function knownHarnessIds() {
|
|
66694
|
+
return adapters.map((a3) => a3.id);
|
|
66695
|
+
}
|
|
66696
|
+
async function resolveScaffoldHarness(cwd2, flag) {
|
|
66697
|
+
const forced = flag?.trim();
|
|
66698
|
+
if (forced)
|
|
66699
|
+
return { id: normalizeHarnessId(forced), source: "flag" };
|
|
66700
|
+
const detections = await detectHarnesses(cwd2);
|
|
66701
|
+
const inProject = detections.find((d3) => d3.detection.hasProject);
|
|
66702
|
+
if (inProject)
|
|
66703
|
+
return { id: inProject.adapter.id, source: "project" };
|
|
66704
|
+
const installed = detections.find((d3) => d3.detection.detected);
|
|
66705
|
+
if (installed)
|
|
66706
|
+
return { id: installed.adapter.id, source: "installed" };
|
|
66707
|
+
return { id: FALLBACK_HARNESS, source: "default" };
|
|
66708
|
+
}
|
|
66709
|
+
function describeHarnessSource(source) {
|
|
66710
|
+
switch (source) {
|
|
66711
|
+
case "flag":
|
|
66712
|
+
return "from --harness";
|
|
66713
|
+
case "project":
|
|
66714
|
+
return "detected in this folder";
|
|
66715
|
+
case "installed":
|
|
66716
|
+
return "installed on this machine";
|
|
66717
|
+
case "default":
|
|
66718
|
+
return "nothing detected — pass --harness to change it";
|
|
66719
|
+
default: {
|
|
66720
|
+
const never = source;
|
|
66721
|
+
return never;
|
|
66722
|
+
}
|
|
66723
|
+
}
|
|
66724
|
+
}
|
|
66725
|
+
function singleLine(value) {
|
|
66726
|
+
return (value ?? "").replace(/\s+/g, " ").trim();
|
|
66727
|
+
}
|
|
66728
|
+
function resolveScaffoldName(cwd2, flag) {
|
|
66729
|
+
return singleLine(flag) || singleLine(path82.basename(path82.resolve(cwd2))) || FALLBACK_NAME;
|
|
66730
|
+
}
|
|
66731
|
+
function harnessDisplayName(id) {
|
|
66732
|
+
try {
|
|
66733
|
+
return getAdapter(id).displayName;
|
|
66734
|
+
} catch {
|
|
66735
|
+
return id;
|
|
66736
|
+
}
|
|
66737
|
+
}
|
|
66738
|
+
function starterInstructions(harnessId) {
|
|
66739
|
+
return `You are a helpful ${harnessDisplayName(harnessId)} agent.`;
|
|
66740
|
+
}
|
|
66741
|
+
function buildStarterManifest(seed) {
|
|
66742
|
+
return {
|
|
66743
|
+
schema: 1,
|
|
66744
|
+
harness: seed.harness,
|
|
66745
|
+
agent: {
|
|
66746
|
+
name: seed.name,
|
|
66747
|
+
tagline: singleLine(seed.tagline) || STARTER_TAGLINE
|
|
66748
|
+
},
|
|
66749
|
+
instructions: { text: starterInstructions(seed.harness) }
|
|
66750
|
+
};
|
|
66751
|
+
}
|
|
66752
|
+
function scalar(value) {
|
|
66753
|
+
return import_yaml4.default.stringify(value, { lineWidth: 0 }).trimEnd();
|
|
66754
|
+
}
|
|
66755
|
+
function renderFullTemplate(seed) {
|
|
66756
|
+
return `# ${AGENT_MANIFEST_FILE} — declarative agent manifest.
|
|
66757
|
+
# Committed to source control. Edit by hand, then \`brainbase agent push\`.
|
|
66758
|
+
#
|
|
66759
|
+
# Only \`schema\` and \`agent.name\` are required — uncomment the blocks you
|
|
66760
|
+
# need and delete the rest. Full reference:
|
|
66761
|
+
# https://docs.brainbaselabs.com/cli/reference/agent-manifest
|
|
66762
|
+
|
|
66763
|
+
schema: 1
|
|
66764
|
+
|
|
66765
|
+
# Which harness runs this agent locally. One of:
|
|
66766
|
+
# ${knownHarnessIds().join(", ")}.
|
|
66767
|
+
harness: ${scalar(seed.harness)}
|
|
66768
|
+
|
|
66769
|
+
# Sandbox provider, applied when \`brainbase agent create\` claims this file.
|
|
66770
|
+
# Immutable afterwards — recreate the agent to change it.
|
|
66771
|
+
# machine_kind: daytona
|
|
66772
|
+
|
|
66773
|
+
# Agent-level model override. Omit it to leave the cloud value alone, or set
|
|
66774
|
+
# null to clear an override that is already set.
|
|
66775
|
+
# default_model: openai/gpt-5.6-terra
|
|
66776
|
+
|
|
66777
|
+
agent:
|
|
66778
|
+
name: ${scalar(seed.name)}
|
|
66779
|
+
tagline: ${scalar(singleLine(seed.tagline) || STARTER_TAGLINE)}
|
|
66780
|
+
|
|
66781
|
+
# The agent's system prompt. Exactly one of \`text\` or \`file\`.
|
|
66782
|
+
instructions:
|
|
66783
|
+
text: ${scalar(starterInstructions(seed.harness))}
|
|
66784
|
+
# file: ./.brainbase/instructions.md
|
|
66785
|
+
|
|
66786
|
+
# Bash that runs in the sandbox before the agent starts. Exactly one of
|
|
66787
|
+
# \`commands\`, \`file\`, or \`text\`.
|
|
66788
|
+
# entrypoint:
|
|
66789
|
+
# commands:
|
|
66790
|
+
# - npm install
|
|
66791
|
+
|
|
66792
|
+
# Named procedures the agent can follow. Each \`content\` takes exactly one of
|
|
66793
|
+
# \`text\` or \`file\`.
|
|
66794
|
+
# playbooks:
|
|
66795
|
+
# - title: Release checklist
|
|
66796
|
+
# description: Steps to cut a release
|
|
66797
|
+
# content:
|
|
66798
|
+
# file: ./playbooks/release.md
|
|
66799
|
+
|
|
66800
|
+
# Skills to install. A registry ref pins an exact version or omits it to track
|
|
66801
|
+
# the latest; ranges are not supported. Local paths start with \`./\`.
|
|
66802
|
+
# skills:
|
|
66803
|
+
# - source: registry:brainbase/changelog@1.0.0
|
|
66804
|
+
# - source: ./skills/local-linter
|
|
66805
|
+
|
|
66806
|
+
# MCP servers. Each entry needs either \`url\` or \`command\`. Keep tokens out
|
|
66807
|
+
# of this file — put them in the gitignored \`.brainbase/secrets.env\`.
|
|
66808
|
+
# mcp:
|
|
66809
|
+
# - name: github
|
|
66810
|
+
# url: https://api.githubcopilot.com/mcp/
|
|
66811
|
+
# is_enabled: true
|
|
66812
|
+
|
|
66813
|
+
# Criteria a judge scores every completed turn against.
|
|
66814
|
+
# evals:
|
|
66815
|
+
# - slug: answered-the-question
|
|
66816
|
+
# criteria: The reply answers what was asked without inventing facts.
|
|
66817
|
+
|
|
66818
|
+
# Not shown above: \`capabilities\` is written by \`brainbase agent pull\` from
|
|
66819
|
+
# the cloud and never pushed, and \`commands\` / \`hooks\` / \`files\` parse but
|
|
66820
|
+
# no command syncs them yet — \`agent push\` refuses them rather than dropping
|
|
66821
|
+
# them silently.
|
|
66822
|
+
`;
|
|
66823
|
+
}
|
|
66824
|
+
function writeStarterManifest(cwd2, seed, opts = {}) {
|
|
66825
|
+
const body = opts.full ? renderFullTemplate(seed) : renderManifest(buildStarterManifest(seed));
|
|
66826
|
+
const manifest = parseManifest(body);
|
|
66827
|
+
writeManifestText(cwd2, body);
|
|
66828
|
+
return manifest;
|
|
66829
|
+
}
|
|
66830
|
+
|
|
66261
66831
|
// src/cli/agent-create.ts
|
|
66262
66832
|
async function runAgentCreate(cwd2, args) {
|
|
66263
66833
|
banner("agent create — claim a brainbase.agent.yaml and link this folder");
|
|
@@ -66441,7 +67011,7 @@ async function runAgentCreate(cwd2, args) {
|
|
|
66441
67011
|
writeLink(cwd2, link2);
|
|
66442
67012
|
manifest = readManifest(cwd2);
|
|
66443
67013
|
let updatedCloud = null;
|
|
66444
|
-
const hasContent = !!manifest.instructions || manifest.skills.length > 0 || (manifest.mcp ?? []).length > 0 || (manifest.playbooks ?? []).length > 0;
|
|
67014
|
+
const hasContent = !!manifest.instructions || manifest.skills.length > 0 || (manifest.mcp ?? []).length > 0 || (manifest.playbooks ?? []).length > 0 || (manifest.evals ?? []).length > 0;
|
|
66445
67015
|
if (hasContent) {
|
|
66446
67016
|
const outgoing = await buildOutgoingComponents(cwd2, manifest, null);
|
|
66447
67017
|
if (outgoing === null) {
|
|
@@ -66453,7 +67023,8 @@ async function runAgentCreate(cwd2, args) {
|
|
|
66453
67023
|
updatedCloud = await api.pushAgentManifest(agent.id, {
|
|
66454
67024
|
components: outgoing,
|
|
66455
67025
|
base_revision: 0,
|
|
66456
|
-
reconcile_playbooks: true
|
|
67026
|
+
reconcile_playbooks: true,
|
|
67027
|
+
reconcile_evals: true
|
|
66457
67028
|
});
|
|
66458
67029
|
pushSpinner.stop(`Pushed at revision ${updatedCloud.revision}.`);
|
|
66459
67030
|
} catch (err) {
|
|
@@ -66468,8 +67039,16 @@ async function runAgentCreate(cwd2, args) {
|
|
|
66468
67039
|
}
|
|
66469
67040
|
if (updatedCloud) {
|
|
66470
67041
|
const backfill = backfillPlaybookIds(manifest.playbooks ?? [], updatedCloud.components);
|
|
67042
|
+
let manifestChanged = backfill.changed;
|
|
66471
67043
|
if (backfill.changed) {
|
|
66472
67044
|
manifest.playbooks = backfill.playbooks;
|
|
67045
|
+
}
|
|
67046
|
+
const evalBackfill = backfillEvalIds(manifest.evals ?? [], updatedCloud.components);
|
|
67047
|
+
if (evalBackfill.changed) {
|
|
67048
|
+
manifest.evals = evalBackfill.evals;
|
|
67049
|
+
manifestChanged = true;
|
|
67050
|
+
}
|
|
67051
|
+
if (manifestChanged) {
|
|
66473
67052
|
writeManifest(cwd2, manifest);
|
|
66474
67053
|
}
|
|
66475
67054
|
}
|
|
@@ -66495,7 +67074,8 @@ async function runAgentCreate(cwd2, args) {
|
|
|
66495
67074
|
tagline: agent.tagline,
|
|
66496
67075
|
...resolvedEntrypoint ? { entrypoint: resolvedEntrypoint.trim() } : {},
|
|
66497
67076
|
...agent.machine_kind ? { machine_kind: agent.machine_kind } : {},
|
|
66498
|
-
...Object.prototype.hasOwnProperty.call(agent, "default_model") ? { default_model: agent.default_model ?? null } : {}
|
|
67077
|
+
...Object.prototype.hasOwnProperty.call(agent, "default_model") ? { default_model: agent.default_model ?? null } : {},
|
|
67078
|
+
...capabilityBaseline(agent, undefined)
|
|
66499
67079
|
}
|
|
66500
67080
|
};
|
|
66501
67081
|
writeSyncState(cwd2, state);
|
|
@@ -66528,12 +67108,9 @@ async function loadOrScaffoldManifest(cwd2, args) {
|
|
|
66528
67108
|
}
|
|
66529
67109
|
}
|
|
66530
67110
|
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
|
-
}
|
|
67111
|
+
if (!autoProceed(args.yes)) {
|
|
66535
67112
|
const ans = await se({
|
|
66536
|
-
message: `Scaffold a
|
|
67113
|
+
message: `Scaffold a starter ${import_picocolors32.default.bold(AGENT_MANIFEST_FILE)} and continue?`,
|
|
66537
67114
|
initialValue: true
|
|
66538
67115
|
});
|
|
66539
67116
|
if (!ensureNotCancelled(ans)) {
|
|
@@ -66541,25 +67118,21 @@ async function loadOrScaffoldManifest(cwd2, args) {
|
|
|
66541
67118
|
return null;
|
|
66542
67119
|
}
|
|
66543
67120
|
}
|
|
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
|
-
};
|
|
67121
|
+
const harness = await resolveScaffoldHarness(cwd2, args.harness);
|
|
66555
67122
|
try {
|
|
66556
|
-
|
|
67123
|
+
const scaffold = writeStarterManifest(cwd2, {
|
|
67124
|
+
name: resolveScaffoldName(cwd2, args.name),
|
|
67125
|
+
harness: harness.id,
|
|
67126
|
+
tagline: args.tagline
|
|
67127
|
+
});
|
|
67128
|
+
f2.info(`harness ${import_picocolors32.default.bold(harness.id)} ${import_picocolors32.default.dim(`(${describeHarnessSource(harness.source)})`)}`);
|
|
66557
67129
|
f2.info(`Wrote ${import_picocolors32.default.bold(AGENT_MANIFEST_FILE)}.`);
|
|
67130
|
+
return scaffold;
|
|
66558
67131
|
} catch (err) {
|
|
66559
67132
|
f2.error(`Failed to write manifest: ${err.message}`);
|
|
67133
|
+
process.exitCode = 1;
|
|
66560
67134
|
return null;
|
|
66561
67135
|
}
|
|
66562
|
-
return scaffold;
|
|
66563
67136
|
}
|
|
66564
67137
|
async function pickHarness2(cwd2) {
|
|
66565
67138
|
const detections = await detectHarnesses(cwd2);
|
|
@@ -66591,8 +67164,83 @@ function handleApiError4(err) {
|
|
|
66591
67164
|
$e("Aborted.");
|
|
66592
67165
|
}
|
|
66593
67166
|
|
|
66594
|
-
// src/cli/agent-
|
|
67167
|
+
// src/cli/agent-init.ts
|
|
67168
|
+
import path83 from "node:path";
|
|
66595
67169
|
var import_picocolors33 = __toESM(require_picocolors(), 1);
|
|
67170
|
+
function emit(result2) {
|
|
67171
|
+
console.log(JSON.stringify(result2, null, 2));
|
|
67172
|
+
}
|
|
67173
|
+
async function runAgentInit(cwd2, args = {}) {
|
|
67174
|
+
const json = args.json === true;
|
|
67175
|
+
const target = manifestPath(cwd2);
|
|
67176
|
+
if (args.minimal && args.full) {
|
|
67177
|
+
return refuse(json, {
|
|
67178
|
+
path: target,
|
|
67179
|
+
created: false,
|
|
67180
|
+
reason: "conflicting-flags",
|
|
67181
|
+
message: `Pass either ${import_picocolors33.default.cyan("--minimal")} or ${import_picocolors33.default.cyan("--full")}, not both.`
|
|
67182
|
+
});
|
|
67183
|
+
}
|
|
67184
|
+
const existing = existingManifestPath(cwd2);
|
|
67185
|
+
if (existing && !args.force) {
|
|
67186
|
+
return refuse(json, {
|
|
67187
|
+
path: existing,
|
|
67188
|
+
created: false,
|
|
67189
|
+
reason: "manifest-exists",
|
|
67190
|
+
message: `${import_picocolors33.default.bold(path83.basename(existing))} already exists here. Edit it, or pass ${import_picocolors33.default.cyan("--force")} to overwrite it.`
|
|
67191
|
+
});
|
|
67192
|
+
}
|
|
67193
|
+
const harness = await resolveScaffoldHarness(cwd2, args.harness);
|
|
67194
|
+
if (!isKnownHarness(harness.id)) {
|
|
67195
|
+
return refuse(json, {
|
|
67196
|
+
path: target,
|
|
67197
|
+
created: false,
|
|
67198
|
+
reason: "unknown-harness",
|
|
67199
|
+
message: `Unknown harness ${import_picocolors33.default.bold(harness.id)}. Pick one of: ${knownHarnessIds().join(", ")}.`
|
|
67200
|
+
});
|
|
67201
|
+
}
|
|
67202
|
+
const name = resolveScaffoldName(cwd2, args.name);
|
|
67203
|
+
const template2 = args.full ? "full" : "minimal";
|
|
67204
|
+
if (!json)
|
|
67205
|
+
banner("agent init — write a starter brainbase.agent.yaml");
|
|
67206
|
+
try {
|
|
67207
|
+
writeStarterManifest(cwd2, { name, harness: harness.id, tagline: args.tagline }, { full: args.full });
|
|
67208
|
+
} catch (err) {
|
|
67209
|
+
console.error(import_picocolors33.default.red(`Failed to write ${AGENT_MANIFEST_FILE}: ${err.message}`));
|
|
67210
|
+
process.exitCode = 1;
|
|
67211
|
+
return;
|
|
67212
|
+
}
|
|
67213
|
+
if (json) {
|
|
67214
|
+
emit({
|
|
67215
|
+
path: target,
|
|
67216
|
+
created: true,
|
|
67217
|
+
name,
|
|
67218
|
+
harness: harness.id,
|
|
67219
|
+
harness_source: harness.source,
|
|
67220
|
+
template: template2
|
|
67221
|
+
});
|
|
67222
|
+
return;
|
|
67223
|
+
}
|
|
67224
|
+
f2.info(`harness ${import_picocolors33.default.bold(harness.id)} ${import_picocolors33.default.dim(`(${describeHarnessSource(harness.source)})`)}`);
|
|
67225
|
+
f2.success(`Wrote ${import_picocolors33.default.bold(AGENT_MANIFEST_FILE)}${existing ? " (overwritten)" : ""}.`);
|
|
67226
|
+
console.log();
|
|
67227
|
+
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.")}`));
|
|
67228
|
+
console.log();
|
|
67229
|
+
}
|
|
67230
|
+
function refuse(json, outcome) {
|
|
67231
|
+
const { message, ...result2 } = outcome;
|
|
67232
|
+
process.exitCode = 1;
|
|
67233
|
+
if (json) {
|
|
67234
|
+
emit(result2);
|
|
67235
|
+
return;
|
|
67236
|
+
}
|
|
67237
|
+
console.error(`
|
|
67238
|
+
${import_picocolors33.default.red(message)}
|
|
67239
|
+
`);
|
|
67240
|
+
}
|
|
67241
|
+
|
|
67242
|
+
// src/cli/agent-list.ts
|
|
67243
|
+
var import_picocolors34 = __toESM(require_picocolors(), 1);
|
|
66596
67244
|
async function runAgentList(args) {
|
|
66597
67245
|
if (!args.json)
|
|
66598
67246
|
banner("agent list — agents in this team");
|
|
@@ -66612,27 +67260,27 @@ async function runAgentList(args) {
|
|
|
66612
67260
|
function formatAgentList(agents, labels) {
|
|
66613
67261
|
const lines = [""];
|
|
66614
67262
|
if (agents.length === 0) {
|
|
66615
|
-
lines.push(` ${
|
|
67263
|
+
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
67264
|
return lines.join(`
|
|
66617
67265
|
`);
|
|
66618
67266
|
}
|
|
66619
67267
|
for (const agent of agents) {
|
|
66620
|
-
lines.push(` ${
|
|
67268
|
+
lines.push(` ${import_picocolors34.default.bold(agent.name)} ${import_picocolors34.default.dim(agent.slug)}`);
|
|
66621
67269
|
if (agent.tagline)
|
|
66622
|
-
lines.push(` ${
|
|
67270
|
+
lines.push(` ${import_picocolors34.default.dim(agent.tagline)}`);
|
|
66623
67271
|
const meta = [agent.harness, agent.machine_kind, agent.default_model].filter((value) => !!value).join(" · ");
|
|
66624
67272
|
if (meta)
|
|
66625
|
-
lines.push(` ${
|
|
66626
|
-
lines.push(` ${
|
|
67273
|
+
lines.push(` ${import_picocolors34.default.dim(meta)}`);
|
|
67274
|
+
lines.push(` ${import_picocolors34.default.dim(agent.id)}`);
|
|
66627
67275
|
lines.push("");
|
|
66628
67276
|
}
|
|
66629
|
-
lines.push(` ${
|
|
67277
|
+
lines.push(` ${import_picocolors34.default.dim("link this folder to one with")} ${import_picocolors34.default.cyan("brainbase link --agent <id>")}`, "");
|
|
66630
67278
|
return lines.join(`
|
|
66631
67279
|
`);
|
|
66632
67280
|
}
|
|
66633
67281
|
|
|
66634
67282
|
// src/cli/agent-connections.ts
|
|
66635
|
-
var
|
|
67283
|
+
var import_picocolors36 = __toESM(require_picocolors(), 1);
|
|
66636
67284
|
|
|
66637
67285
|
// src/core/integrations.ts
|
|
66638
67286
|
var IMPLEMENTED_INTEGRATIONS = ["slack", "meeting"];
|
|
@@ -66664,7 +67312,7 @@ function explain(state) {
|
|
|
66664
67312
|
}
|
|
66665
67313
|
|
|
66666
67314
|
// src/cli/agent-connect.ts
|
|
66667
|
-
var
|
|
67315
|
+
var import_picocolors35 = __toESM(require_picocolors(), 1);
|
|
66668
67316
|
|
|
66669
67317
|
// src/core/secret-input.ts
|
|
66670
67318
|
import fs74 from "node:fs";
|
|
@@ -66915,9 +67563,9 @@ function report(result2, json) {
|
|
|
66915
67563
|
console.log(JSON.stringify(result2, null, 2));
|
|
66916
67564
|
return;
|
|
66917
67565
|
}
|
|
66918
|
-
const detail = result2.detail ? ` ${
|
|
67566
|
+
const detail = result2.detail ? ` ${import_picocolors35.default.dim(`(${result2.detail})`)}` : "";
|
|
66919
67567
|
f2.success(`${result2.name} connected${detail}`);
|
|
66920
|
-
f2.info(`Run ${
|
|
67568
|
+
f2.info(`Run ${import_picocolors35.default.cyan("brainbase agent pull")} to pick up the built-in ${result2.name} MCP server.`);
|
|
66921
67569
|
}
|
|
66922
67570
|
|
|
66923
67571
|
// src/cli/agent-connections.ts
|
|
@@ -66933,7 +67581,7 @@ async function runAgentConnections(cwd2, args) {
|
|
|
66933
67581
|
return;
|
|
66934
67582
|
}
|
|
66935
67583
|
f2.warn("This folder is not linked to any agent.");
|
|
66936
|
-
f2.info(`Run ${
|
|
67584
|
+
f2.info(`Run ${import_picocolors36.default.cyan("brainbase link")} first.`);
|
|
66937
67585
|
process.exitCode = 1;
|
|
66938
67586
|
return;
|
|
66939
67587
|
}
|
|
@@ -66955,22 +67603,22 @@ async function runAgentConnections(cwd2, args) {
|
|
|
66955
67603
|
function formatConnections(connections) {
|
|
66956
67604
|
const lines = [""];
|
|
66957
67605
|
for (const integration of connections.integrations) {
|
|
66958
|
-
lines.push(` ${statusMark(integration)} ${
|
|
67606
|
+
lines.push(` ${statusMark(integration)} ${import_picocolors36.default.bold(integration.name)}${describe(integration)}`);
|
|
66959
67607
|
const hint = hintFor(integration);
|
|
66960
67608
|
if (hint)
|
|
66961
|
-
lines.push(` ${
|
|
67609
|
+
lines.push(` ${import_picocolors36.default.dim(hint)}`);
|
|
66962
67610
|
}
|
|
66963
67611
|
lines.push("");
|
|
66964
67612
|
return lines.join(`
|
|
66965
67613
|
`);
|
|
66966
67614
|
}
|
|
66967
67615
|
function statusMark(integration) {
|
|
66968
|
-
return integration.connected ?
|
|
67616
|
+
return integration.connected ? import_picocolors36.default.green("✓") : import_picocolors36.default.dim("·");
|
|
66969
67617
|
}
|
|
66970
67618
|
function describe(integration) {
|
|
66971
67619
|
if (!integration.connected)
|
|
66972
|
-
return ` ${
|
|
66973
|
-
return integration.detail ? ` ${
|
|
67620
|
+
return ` ${import_picocolors36.default.dim("not connected")}`;
|
|
67621
|
+
return integration.detail ? ` ${import_picocolors36.default.dim(integration.detail)}` : ` ${import_picocolors36.default.dim("connected")}`;
|
|
66974
67622
|
}
|
|
66975
67623
|
function hintFor(integration) {
|
|
66976
67624
|
const action = actionability(integration);
|
|
@@ -66981,7 +67629,7 @@ function hintFor(integration) {
|
|
|
66981
67629
|
}
|
|
66982
67630
|
|
|
66983
67631
|
// src/cli/agent-disconnect.ts
|
|
66984
|
-
var
|
|
67632
|
+
var import_picocolors37 = __toESM(require_picocolors(), 1);
|
|
66985
67633
|
async function runAgentDisconnect(cwd2, target, args) {
|
|
66986
67634
|
const json = Boolean(args.json);
|
|
66987
67635
|
try {
|
|
@@ -67018,16 +67666,187 @@ async function disconnect(cwd2, target, args, json) {
|
|
|
67018
67666
|
return;
|
|
67019
67667
|
}
|
|
67020
67668
|
f2.success(`${target} disconnected`);
|
|
67021
|
-
f2.info(`Run ${
|
|
67669
|
+
f2.info(`Run ${import_picocolors37.default.cyan("brainbase agent pull")} to drop the built-in ${target} MCP server locally.`);
|
|
67670
|
+
}
|
|
67671
|
+
|
|
67672
|
+
// src/cli/agent-eval.ts
|
|
67673
|
+
var import_picocolors38 = __toESM(require_picocolors(), 1);
|
|
67674
|
+
async function runAgentEval(cwd2, sub, args) {
|
|
67675
|
+
const json = Boolean(args.json);
|
|
67676
|
+
if (sub !== "list" && sub !== "runs") {
|
|
67677
|
+
if (json) {
|
|
67678
|
+
console.log(JSON.stringify({ error: `unknown subcommand: ${sub ?? "(none)"}`, expected: ["list", "runs"] }, null, 2));
|
|
67679
|
+
} else {
|
|
67680
|
+
console.error(`Unknown eval subcommand: ${sub ?? "(none)"}
|
|
67681
|
+
`);
|
|
67682
|
+
printEvalHelp();
|
|
67683
|
+
}
|
|
67684
|
+
process.exitCode = 1;
|
|
67685
|
+
return;
|
|
67686
|
+
}
|
|
67687
|
+
if (!json) {
|
|
67688
|
+
banner(sub === "list" ? "agent eval list — the evals the cloud holds" : "agent eval runs — judge verdicts, newest first");
|
|
67689
|
+
}
|
|
67690
|
+
const link2 = readLink(cwd2);
|
|
67691
|
+
if (!link2) {
|
|
67692
|
+
if (json) {
|
|
67693
|
+
console.log(JSON.stringify({ linked: false, items: [] }, null, 2));
|
|
67694
|
+
} else {
|
|
67695
|
+
f2.warn("This folder is not linked to any agent.");
|
|
67696
|
+
f2.info(`Run ${import_picocolors38.default.cyan("brainbase link")} first.`);
|
|
67697
|
+
}
|
|
67698
|
+
process.exitCode = 1;
|
|
67699
|
+
return;
|
|
67700
|
+
}
|
|
67701
|
+
try {
|
|
67702
|
+
if (sub === "list") {
|
|
67703
|
+
const evals = await api.listAgentEvals(link2.agent_id, {
|
|
67704
|
+
includeArchived: args.archived
|
|
67705
|
+
});
|
|
67706
|
+
if (json) {
|
|
67707
|
+
console.log(JSON.stringify({ linked: true, items: evals }, null, 2));
|
|
67708
|
+
return;
|
|
67709
|
+
}
|
|
67710
|
+
console.log(formatEvals(evals));
|
|
67711
|
+
return;
|
|
67712
|
+
}
|
|
67713
|
+
const runs = await api.listAgentEvalRuns(link2.agent_id, {
|
|
67714
|
+
taskId: args.taskId,
|
|
67715
|
+
limit: args.limit
|
|
67716
|
+
});
|
|
67717
|
+
if (json) {
|
|
67718
|
+
console.log(JSON.stringify({ linked: true, items: runs }, null, 2));
|
|
67719
|
+
return;
|
|
67720
|
+
}
|
|
67721
|
+
console.log(formatRuns(runs));
|
|
67722
|
+
} catch (err) {
|
|
67723
|
+
if (err instanceof ApiError && err.status === 404) {
|
|
67724
|
+
const detail = (err.message || "").trim();
|
|
67725
|
+
const looksLikeAccess = /agent not found/i.test(detail);
|
|
67726
|
+
const message2 = looksLikeAccess ? `${detail} — check that this folder is linked to an agent you can access (${import_picocolors38.default.cyan("brainbase agent status")}).` : `${detail || "Not found"} — this control plane may not expose eval reads yet; upgrade the server, or use the web app.`;
|
|
67727
|
+
if (json) {
|
|
67728
|
+
console.log(JSON.stringify({ linked: true, error: message2, detail, items: [] }, null, 2));
|
|
67729
|
+
} else {
|
|
67730
|
+
f2.error(message2);
|
|
67731
|
+
}
|
|
67732
|
+
process.exitCode = 1;
|
|
67733
|
+
return;
|
|
67734
|
+
}
|
|
67735
|
+
if (!json)
|
|
67736
|
+
throw err;
|
|
67737
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
67738
|
+
console.log(JSON.stringify({ linked: true, error: message, items: [] }, null, 2));
|
|
67739
|
+
process.exitCode = 1;
|
|
67740
|
+
}
|
|
67741
|
+
}
|
|
67742
|
+
function formatEvals(evals) {
|
|
67743
|
+
if (evals.length === 0) {
|
|
67744
|
+
return `
|
|
67745
|
+
${import_picocolors38.default.dim("No evals on this agent.")}
|
|
67746
|
+
${import_picocolors38.default.dim("Add an")} ${import_picocolors38.default.cyan("evals:")} ${import_picocolors38.default.dim("block to brainbase.agent.yaml and run")} ${import_picocolors38.default.cyan("brainbase agent push")}${import_picocolors38.default.dim(".")}
|
|
67747
|
+
`;
|
|
67748
|
+
}
|
|
67749
|
+
const lines = [""];
|
|
67750
|
+
for (const e2 of evals) {
|
|
67751
|
+
const archived = e2.status === "archived";
|
|
67752
|
+
const state = archived ? import_picocolors38.default.dim("⊘") : e2.enabled ? import_picocolors38.default.green("✓") : import_picocolors38.default.dim("·");
|
|
67753
|
+
const judge = e2.judge_type === "agent" ? `agent ${e2.judge_agent ?? import_picocolors38.default.red("(missing)")}` : e2.judge_model;
|
|
67754
|
+
const shape = e2.output_shape === "classification" && e2.classification_values?.length ? `classification (${e2.classification_values.join(" | ")})` : e2.output_shape;
|
|
67755
|
+
lines.push(` ${state} ${import_picocolors38.default.bold(e2.slug)}${archived ? import_picocolors38.default.dim(" (archived)") : ""} ${import_picocolors38.default.dim(shape)} ${import_picocolors38.default.dim("·")} ${import_picocolors38.default.dim(judge)}`);
|
|
67756
|
+
lines.push(` ${e2.criteria}`);
|
|
67757
|
+
if (archived) {
|
|
67758
|
+
lines.push(` ${import_picocolors38.default.dim("archived — not scored; re-add the slug to the manifest and push to restore it")}`);
|
|
67759
|
+
} else if (!e2.enabled) {
|
|
67760
|
+
lines.push(` ${import_picocolors38.default.dim("disabled — not scored")}`);
|
|
67761
|
+
}
|
|
67762
|
+
}
|
|
67763
|
+
lines.push("");
|
|
67764
|
+
return lines.join(`
|
|
67765
|
+
`);
|
|
67766
|
+
}
|
|
67767
|
+
function formatRuns(runs) {
|
|
67768
|
+
if (runs.length === 0) {
|
|
67769
|
+
return `
|
|
67770
|
+
${import_picocolors38.default.dim("No eval runs yet. Evals are scored as the agent finishes a turn.")}
|
|
67771
|
+
`;
|
|
67772
|
+
}
|
|
67773
|
+
const lines = [""];
|
|
67774
|
+
for (const r2 of runs) {
|
|
67775
|
+
lines.push(` ${verdictMark(r2)} ${import_picocolors38.default.bold(r2.eval_slug ?? r2.eval_id)} ${import_picocolors38.default.dim(verdictText(r2))}`);
|
|
67776
|
+
lines.push(` ${import_picocolors38.default.dim("task")} ${r2.task_id}${r2.created_at ? ` ${import_picocolors38.default.dim("·")} ${import_picocolors38.default.dim(r2.created_at)}` : ""}`);
|
|
67777
|
+
if (r2.reasoning)
|
|
67778
|
+
lines.push(` ${r2.reasoning}`);
|
|
67779
|
+
if (r2.error)
|
|
67780
|
+
lines.push(` ${import_picocolors38.default.red(r2.error)}`);
|
|
67781
|
+
if (r2.judge_task_id) {
|
|
67782
|
+
lines.push(` ${import_picocolors38.default.dim(`judge run: ${r2.judge_task_id}`)}`);
|
|
67783
|
+
}
|
|
67784
|
+
}
|
|
67785
|
+
lines.push("");
|
|
67786
|
+
return lines.join(`
|
|
67787
|
+
`);
|
|
67788
|
+
}
|
|
67789
|
+
function verdictMark(r2) {
|
|
67790
|
+
if (r2.status === "errored")
|
|
67791
|
+
return import_picocolors38.default.yellow("!");
|
|
67792
|
+
if (r2.passed === true)
|
|
67793
|
+
return import_picocolors38.default.green("✓");
|
|
67794
|
+
if (r2.passed === false)
|
|
67795
|
+
return import_picocolors38.default.red("✗");
|
|
67796
|
+
if (typeof r2.rating === "number")
|
|
67797
|
+
return r2.rating >= 4 ? import_picocolors38.default.green("✓") : import_picocolors38.default.yellow("~");
|
|
67798
|
+
if (r2.category)
|
|
67799
|
+
return import_picocolors38.default.cyan("•");
|
|
67800
|
+
return import_picocolors38.default.dim("·");
|
|
67801
|
+
}
|
|
67802
|
+
function verdictText(r2) {
|
|
67803
|
+
if (r2.status === "errored")
|
|
67804
|
+
return "judge errored";
|
|
67805
|
+
if (r2.passed === true)
|
|
67806
|
+
return "passed";
|
|
67807
|
+
if (r2.passed === false)
|
|
67808
|
+
return "failed";
|
|
67809
|
+
if (typeof r2.rating === "number")
|
|
67810
|
+
return `${r2.rating}/5`;
|
|
67811
|
+
if (r2.category)
|
|
67812
|
+
return r2.category;
|
|
67813
|
+
return r2.status;
|
|
67814
|
+
}
|
|
67815
|
+
function printEvalHelp() {
|
|
67816
|
+
const out = [""];
|
|
67817
|
+
out.push(` ${import_picocolors38.default.bold("brainbase agent eval")} ${import_picocolors38.default.dim("<sub> [options]")}`);
|
|
67818
|
+
out.push("");
|
|
67819
|
+
out.push(` ${import_picocolors38.default.cyan("list")} ${import_picocolors38.default.dim("the evals the cloud holds for this agent (--archived to include archived, --json for scripts)")}`);
|
|
67820
|
+
out.push(` ${import_picocolors38.default.cyan("runs")} ${import_picocolors38.default.dim("judge verdicts, newest first (--task-id <id>, --limit <n>, --json for scripts)")}`);
|
|
67821
|
+
out.push("");
|
|
67822
|
+
out.push(` ${import_picocolors38.default.dim("Eval definitions are declarative: edit the")} ${import_picocolors38.default.cyan("evals:")} ${import_picocolors38.default.dim("block in brainbase.agent.yaml")}`);
|
|
67823
|
+
out.push(` ${import_picocolors38.default.dim("and run")} ${import_picocolors38.default.cyan("brainbase agent push")}${import_picocolors38.default.dim(". These commands read; they do not write.")}`);
|
|
67824
|
+
out.push("");
|
|
67825
|
+
console.log(out.join(`
|
|
67826
|
+
`));
|
|
67022
67827
|
}
|
|
67023
67828
|
|
|
67024
67829
|
// src/cli/agent.ts
|
|
67025
67830
|
async function runAgent(cwd2, sub, args, opts) {
|
|
67026
67831
|
if (args.some((arg) => arg === "--help" || arg === "-h")) {
|
|
67027
|
-
|
|
67832
|
+
if (sub === "eval")
|
|
67833
|
+
printEvalHelp();
|
|
67834
|
+
else
|
|
67835
|
+
printHelp();
|
|
67028
67836
|
return;
|
|
67029
67837
|
}
|
|
67030
67838
|
switch (sub) {
|
|
67839
|
+
case "init":
|
|
67840
|
+
await runAgentInit(cwd2, {
|
|
67841
|
+
name: opts.name,
|
|
67842
|
+
tagline: opts.tagline,
|
|
67843
|
+
harness: opts.harness,
|
|
67844
|
+
minimal: opts.minimal,
|
|
67845
|
+
full: opts.full,
|
|
67846
|
+
force: opts.force,
|
|
67847
|
+
json: opts.json
|
|
67848
|
+
});
|
|
67849
|
+
return;
|
|
67031
67850
|
case "create":
|
|
67032
67851
|
await runAgentCreate(cwd2, {
|
|
67033
67852
|
yes: opts.yes,
|
|
@@ -67088,6 +67907,14 @@ async function runAgent(cwd2, sub, args, opts) {
|
|
|
67088
67907
|
case "disconnect":
|
|
67089
67908
|
await runAgentDisconnect(cwd2, args[0], { yes: opts.yes, json: opts.json });
|
|
67090
67909
|
return;
|
|
67910
|
+
case "eval":
|
|
67911
|
+
await runAgentEval(cwd2, args[0], {
|
|
67912
|
+
json: opts.json,
|
|
67913
|
+
taskId: opts.taskId,
|
|
67914
|
+
limit: opts.limit,
|
|
67915
|
+
archived: opts.archived
|
|
67916
|
+
});
|
|
67917
|
+
return;
|
|
67091
67918
|
case "env":
|
|
67092
67919
|
await runAgentEnv(cwd2, { shell: opts.shell });
|
|
67093
67920
|
return;
|
|
@@ -67107,31 +67934,33 @@ async function runAgent(cwd2, sub, args, opts) {
|
|
|
67107
67934
|
function printHelp() {
|
|
67108
67935
|
const out = [];
|
|
67109
67936
|
out.push("");
|
|
67110
|
-
out.push(` ${
|
|
67937
|
+
out.push(` ${import_picocolors39.default.bold("brainbase agent")} ${import_picocolors39.default.dim("<sub> [options]")}`);
|
|
67111
67938
|
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(` ${
|
|
67939
|
+
out.push(` ${import_picocolors39.default.cyan("list")} ${import_picocolors39.default.dim("show the agents in a team, with the ids `brainbase link` takes (--json for scripts)")}`);
|
|
67940
|
+
out.push(` ${import_picocolors39.default.cyan("init")} ${import_picocolors39.default.dim("write a starter brainbase.agent.yaml here — offline, no login (--full for a commented template, --force to overwrite)")}`);
|
|
67941
|
+
out.push(` ${import_picocolors39.default.cyan("create")} ${import_picocolors39.default.dim("claim an unclaimed brainbase.agent.yaml and create the cloud agent (scaffolds one if the folder has none)")}`);
|
|
67942
|
+
out.push(` ${import_picocolors39.default.cyan("pull")} ${import_picocolors39.default.dim("[<id>]")} ${import_picocolors39.default.dim("apply cloud changes into this folder — pass <id> to switch (--force to override); --run-entrypoint to also execute the agent entrypoint")}`);
|
|
67943
|
+
out.push(` ${import_picocolors39.default.cyan("push")} ${import_picocolors39.default.dim("send local changes to the cloud — instructions, playbooks, skills, MCPs, evals, entrypoint (--force to overwrite cloud-side conflicts with local)")}`);
|
|
67944
|
+
out.push(` ${import_picocolors39.default.cyan("unpack")} ${import_picocolors39.default.dim("install the claimed agent into a harness layout (--harness to override)")}`);
|
|
67945
|
+
out.push(` ${import_picocolors39.default.cyan("status")} ${import_picocolors39.default.dim("show what would push, what would pull, and which manifest blocks are ignored (--json for scripts)")}`);
|
|
67946
|
+
out.push(` ${import_picocolors39.default.cyan("connections")} ${import_picocolors39.default.dim("show which integrations this agent is wired to (--json for scripts)")}`);
|
|
67947
|
+
out.push(` ${import_picocolors39.default.cyan("connect")} ${import_picocolors39.default.dim("<name>")} ${import_picocolors39.default.dim("connect slack or meeting — credentials come from flags, env, or stdin")}`);
|
|
67948
|
+
out.push(` ${import_picocolors39.default.cyan("disconnect")} ${import_picocolors39.default.dim("<name>")} ${import_picocolors39.default.dim("revoke a slack or meeting install")}`);
|
|
67949
|
+
out.push(` ${import_picocolors39.default.cyan("eval")} ${import_picocolors39.default.dim("<list|runs>")} ${import_picocolors39.default.dim("read eval definitions and judge verdicts — definitions are edited in the manifest and pushed (--json for scripts)")}`);
|
|
67950
|
+
out.push(` ${import_picocolors39.default.cyan("env")} ${import_picocolors39.default.dim('print export statements — use with `eval "$(brainbase agent env)"`')}`);
|
|
67122
67951
|
out.push("");
|
|
67123
|
-
out.push(` ${
|
|
67124
|
-
out.push(` ${
|
|
67952
|
+
out.push(` ${import_picocolors39.default.dim("Slack credentials:")} ${import_picocolors39.default.dim("--bot-token / BRAINBASE_SLACK_BOT_TOKEN, --signing-secret / BRAINBASE_SLACK_SIGNING_SECRET,")}`);
|
|
67953
|
+
out.push(` ${import_picocolors39.default.dim('or pipe {"bot_token":"…","signing_secret":"…"} on stdin to keep them out of argv.')}`);
|
|
67125
67954
|
out.push("");
|
|
67126
67955
|
console.log(out.join(`
|
|
67127
67956
|
`));
|
|
67128
67957
|
}
|
|
67129
67958
|
|
|
67130
67959
|
// src/cli/team.ts
|
|
67131
|
-
var
|
|
67960
|
+
var import_picocolors41 = __toESM(require_picocolors(), 1);
|
|
67132
67961
|
|
|
67133
67962
|
// src/cli/team-list.ts
|
|
67134
|
-
var
|
|
67963
|
+
var import_picocolors40 = __toESM(require_picocolors(), 1);
|
|
67135
67964
|
async function runTeamList(args) {
|
|
67136
67965
|
if (!args.json)
|
|
67137
67966
|
banner("team list — teams you can put agents in");
|
|
@@ -67151,25 +67980,25 @@ async function runTeamList(args) {
|
|
|
67151
67980
|
function formatTeamList(grouped) {
|
|
67152
67981
|
const lines = [""];
|
|
67153
67982
|
if (grouped.length === 0) {
|
|
67154
|
-
lines.push(` ${
|
|
67983
|
+
lines.push(` ${import_picocolors40.default.dim("You are not a member of any organization.")}`, "");
|
|
67155
67984
|
return lines.join(`
|
|
67156
67985
|
`);
|
|
67157
67986
|
}
|
|
67158
67987
|
const nameWidth = Math.max(...grouped.flatMap(({ teams }) => teams.map((t) => t.name.length)), 0);
|
|
67159
67988
|
for (const { org, teams, error } of grouped) {
|
|
67160
|
-
const slug = org.slug ? ` ${
|
|
67161
|
-
lines.push(` ${
|
|
67989
|
+
const slug = org.slug ? ` ${import_picocolors40.default.dim(org.slug)}` : "";
|
|
67990
|
+
lines.push(` ${import_picocolors40.default.bold(org.name)}${slug}`);
|
|
67162
67991
|
if (error) {
|
|
67163
|
-
lines.push(` ${
|
|
67992
|
+
lines.push(` ${import_picocolors40.default.red(`could not load teams: ${error}`)}`);
|
|
67164
67993
|
} else if (teams.length === 0) {
|
|
67165
|
-
lines.push(` ${
|
|
67994
|
+
lines.push(` ${import_picocolors40.default.dim("no teams yet — create one in the web app")}`);
|
|
67166
67995
|
}
|
|
67167
67996
|
for (const team of teams) {
|
|
67168
|
-
lines.push(` ${team.name.padEnd(nameWidth)} ${
|
|
67997
|
+
lines.push(` ${team.name.padEnd(nameWidth)} ${import_picocolors40.default.dim(team.id)}`);
|
|
67169
67998
|
}
|
|
67170
67999
|
lines.push("");
|
|
67171
68000
|
}
|
|
67172
|
-
lines.push(` ${
|
|
68001
|
+
lines.push(` ${import_picocolors40.default.dim("list a team’s agents with")} ${import_picocolors40.default.cyan("brainbase agent list --team <id>")}`, "");
|
|
67173
68002
|
return lines.join(`
|
|
67174
68003
|
`);
|
|
67175
68004
|
}
|
|
@@ -67200,29 +68029,29 @@ async function runTeam(sub, args, opts) {
|
|
|
67200
68029
|
function printHelp2() {
|
|
67201
68030
|
const out = [];
|
|
67202
68031
|
out.push("");
|
|
67203
|
-
out.push(` ${
|
|
68032
|
+
out.push(` ${import_picocolors41.default.bold("brainbase team")} ${import_picocolors41.default.dim("<sub> [options]")}`);
|
|
67204
68033
|
out.push("");
|
|
67205
|
-
out.push(` ${
|
|
68034
|
+
out.push(` ${import_picocolors41.default.cyan("list")} ${import_picocolors41.default.dim("show the teams you can create agents in, grouped by organization")}`);
|
|
67206
68035
|
out.push("");
|
|
67207
|
-
out.push(` ${
|
|
67208
|
-
out.push(` ${
|
|
68036
|
+
out.push(` ${import_picocolors41.default.dim("--org <id-or-slug>")} ${import_picocolors41.default.dim("limit to one organization")}`);
|
|
68037
|
+
out.push(` ${import_picocolors41.default.dim("--json")} ${import_picocolors41.default.dim("machine-readable output")}`);
|
|
67209
68038
|
out.push("");
|
|
67210
68039
|
console.log(out.join(`
|
|
67211
68040
|
`));
|
|
67212
68041
|
}
|
|
67213
68042
|
|
|
67214
68043
|
// src/cli/orchestration.ts
|
|
67215
|
-
var
|
|
68044
|
+
var import_picocolors48 = __toESM(require_picocolors(), 1);
|
|
67216
68045
|
|
|
67217
68046
|
// src/cli/orchestration-pull.ts
|
|
67218
|
-
import
|
|
68047
|
+
import path87 from "node:path";
|
|
67219
68048
|
import fs78 from "node:fs";
|
|
67220
|
-
var
|
|
68049
|
+
var import_picocolors42 = __toESM(require_picocolors(), 1);
|
|
67221
68050
|
|
|
67222
68051
|
// src/core/orchestration-manifest.ts
|
|
67223
|
-
import
|
|
68052
|
+
import path84 from "node:path";
|
|
67224
68053
|
import fs75 from "node:fs";
|
|
67225
|
-
var
|
|
68054
|
+
var import_yaml5 = __toESM(require_dist(), 1);
|
|
67226
68055
|
var ORCH_MANIFEST_FILE = "brainbase-orchestration.yaml";
|
|
67227
68056
|
var ORCH_MEMBERS_DIR = "agents";
|
|
67228
68057
|
var OrchMetaSchema = exports_external.object({
|
|
@@ -67274,7 +68103,7 @@ var OrchestrationManifestSchema = exports_external.object({
|
|
|
67274
68103
|
triggers: exports_external.array(TriggerSchema).optional()
|
|
67275
68104
|
});
|
|
67276
68105
|
function orchManifestPath(cwd2) {
|
|
67277
|
-
return
|
|
68106
|
+
return path84.join(cwd2, ORCH_MANIFEST_FILE);
|
|
67278
68107
|
}
|
|
67279
68108
|
function hasOrchManifest(cwd2) {
|
|
67280
68109
|
return fs75.existsSync(orchManifestPath(cwd2));
|
|
@@ -67286,7 +68115,7 @@ function readOrchManifest(cwd2) {
|
|
|
67286
68115
|
const raw = fs75.readFileSync(p2, "utf8");
|
|
67287
68116
|
let parsed;
|
|
67288
68117
|
try {
|
|
67289
|
-
parsed =
|
|
68118
|
+
parsed = import_yaml5.default.parse(raw);
|
|
67290
68119
|
} catch (err) {
|
|
67291
68120
|
throw new Error(`${ORCH_MANIFEST_FILE} is not valid YAML: ${err.message}`);
|
|
67292
68121
|
}
|
|
@@ -67297,7 +68126,7 @@ function readOrchManifest(cwd2) {
|
|
|
67297
68126
|
return result2.data;
|
|
67298
68127
|
}
|
|
67299
68128
|
function writeOrchManifest(cwd2, manifest) {
|
|
67300
|
-
const doc = new
|
|
68129
|
+
const doc = new import_yaml5.default.Document;
|
|
67301
68130
|
doc.contents = manifest;
|
|
67302
68131
|
doc.commentBefore = ` brainbase-orchestration.yaml — declarative orchestration manifest.
|
|
67303
68132
|
` + ` Committed to source control. Edit by hand, then
|
|
@@ -67307,7 +68136,7 @@ function writeOrchManifest(cwd2, manifest) {
|
|
|
67307
68136
|
fs75.writeFileSync(orchManifestPath(cwd2), String(doc), "utf8");
|
|
67308
68137
|
}
|
|
67309
68138
|
function memberDir(cwd2, slug) {
|
|
67310
|
-
return
|
|
68139
|
+
return path84.join(cwd2, ORCH_MEMBERS_DIR, slug);
|
|
67311
68140
|
}
|
|
67312
68141
|
var MEMBER_SLUG_MAX = 50;
|
|
67313
68142
|
function slugifyRaw(raw) {
|
|
@@ -67341,7 +68170,7 @@ function resolveMemberSlugs(members) {
|
|
|
67341
68170
|
}
|
|
67342
68171
|
|
|
67343
68172
|
// src/core/orchestration-link.ts
|
|
67344
|
-
import
|
|
68173
|
+
import path85 from "node:path";
|
|
67345
68174
|
import fs76 from "node:fs";
|
|
67346
68175
|
var ORCH_LINK_FILE = "orchestration-link.json";
|
|
67347
68176
|
var ORCH_SYNC_STATE_FILE = "orchestration-sync-state.json";
|
|
@@ -67376,10 +68205,10 @@ var OrchestrationSyncStateSchema = exports_external.object({
|
|
|
67376
68205
|
edges: exports_external.array(SyncedEdgeSchema)
|
|
67377
68206
|
});
|
|
67378
68207
|
function orchLinkPath(cwd2) {
|
|
67379
|
-
return
|
|
68208
|
+
return path85.join(cwd2, LINK_DIR, ORCH_LINK_FILE);
|
|
67380
68209
|
}
|
|
67381
68210
|
function orchSyncStatePath(cwd2) {
|
|
67382
|
-
return
|
|
68211
|
+
return path85.join(cwd2, LINK_DIR, ORCH_SYNC_STATE_FILE);
|
|
67383
68212
|
}
|
|
67384
68213
|
function readOrchLink(cwd2) {
|
|
67385
68214
|
const p2 = orchLinkPath(cwd2);
|
|
@@ -67392,7 +68221,7 @@ function readOrchLink(cwd2) {
|
|
|
67392
68221
|
}
|
|
67393
68222
|
}
|
|
67394
68223
|
function writeOrchLink(cwd2, link2) {
|
|
67395
|
-
ensureDir(
|
|
68224
|
+
ensureDir(path85.join(cwd2, LINK_DIR));
|
|
67396
68225
|
const clean2 = {};
|
|
67397
68226
|
for (const [k3, v3] of Object.entries(link2)) {
|
|
67398
68227
|
if (v3 !== null && v3 !== undefined)
|
|
@@ -67412,12 +68241,12 @@ function readOrchSyncState(cwd2) {
|
|
|
67412
68241
|
}
|
|
67413
68242
|
}
|
|
67414
68243
|
function writeOrchSyncState(cwd2, state) {
|
|
67415
|
-
ensureDir(
|
|
68244
|
+
ensureDir(path85.join(cwd2, LINK_DIR));
|
|
67416
68245
|
writeJson(orchSyncStatePath(cwd2), state);
|
|
67417
68246
|
ensureGitignore2(cwd2);
|
|
67418
68247
|
}
|
|
67419
68248
|
function ensureGitignore2(cwd2) {
|
|
67420
|
-
const ignorePath =
|
|
68249
|
+
const ignorePath = path85.join(cwd2, LINK_DIR, ".gitignore");
|
|
67421
68250
|
const desired = `${ORCH_SYNC_STATE_FILE}
|
|
67422
68251
|
`;
|
|
67423
68252
|
try {
|
|
@@ -67435,7 +68264,7 @@ function ensureGitignore2(cwd2) {
|
|
|
67435
68264
|
}
|
|
67436
68265
|
|
|
67437
68266
|
// src/core/agent-fresh-install.ts
|
|
67438
|
-
import
|
|
68267
|
+
import path86 from "node:path";
|
|
67439
68268
|
import fs77 from "node:fs";
|
|
67440
68269
|
import os15 from "node:os";
|
|
67441
68270
|
async function installAgentFresh(input) {
|
|
@@ -67458,7 +68287,7 @@ async function installAgentFresh(input) {
|
|
|
67458
68287
|
type: c2.type,
|
|
67459
68288
|
slug: c2.slug,
|
|
67460
68289
|
scope,
|
|
67461
|
-
rootDir:
|
|
68290
|
+
rootDir: path86.join(stageRoot, c2.type, c2.slug),
|
|
67462
68291
|
description: c2.description,
|
|
67463
68292
|
meta: c2.meta,
|
|
67464
68293
|
payload: proxifyMcpPayload(structuredClone(c2.meta?.mcp)),
|
|
@@ -67483,7 +68312,7 @@ async function installAgentFresh(input) {
|
|
|
67483
68312
|
const claimedByOther = folderClaimedByOtherAgent(cwd2, agent.id);
|
|
67484
68313
|
const localOnly = input.preserveManifest || claimedByOther ? {} : readLocalOnlyContentReporting(cwd2);
|
|
67485
68314
|
if (claimedByOther) {
|
|
67486
|
-
f2.warn(`${
|
|
68315
|
+
f2.warn(`${path86.basename(cwd2)} was linked to a different agent; its local-only blocks were left out of the rebuilt manifest.`);
|
|
67487
68316
|
}
|
|
67488
68317
|
const manifest = input.preserveManifest ? null : buildManifestFromCloud(cloud, agent, localOnly);
|
|
67489
68318
|
if (manifest)
|
|
@@ -67516,7 +68345,8 @@ async function installAgentFresh(input) {
|
|
|
67516
68345
|
name: agent.name,
|
|
67517
68346
|
tagline: agent.tagline,
|
|
67518
68347
|
...agent.machine_kind ? { machine_kind: agent.machine_kind } : {},
|
|
67519
|
-
...Object.prototype.hasOwnProperty.call(agent, "default_model") ? { default_model: agent.default_model ?? null } : {}
|
|
68348
|
+
...Object.prototype.hasOwnProperty.call(agent, "default_model") ? { default_model: agent.default_model ?? null } : {},
|
|
68349
|
+
...capabilityBaseline(agent, undefined)
|
|
67520
68350
|
}
|
|
67521
68351
|
});
|
|
67522
68352
|
const returnedManifest = manifest ?? buildManifestFromCloud(cloud, agent, localOnly);
|
|
@@ -67532,13 +68362,13 @@ async function installAgentFresh(input) {
|
|
|
67532
68362
|
}
|
|
67533
68363
|
}
|
|
67534
68364
|
function stageManifestComponents2(components) {
|
|
67535
|
-
const root = fs77.mkdtempSync(
|
|
68365
|
+
const root = fs77.mkdtempSync(path86.join(os15.tmpdir(), "brainbase-orch-pull-"));
|
|
67536
68366
|
for (const c2 of components) {
|
|
67537
|
-
const compDir =
|
|
68367
|
+
const compDir = path86.join(root, c2.type, c2.slug);
|
|
67538
68368
|
ensureDir(compDir);
|
|
67539
68369
|
for (const f4 of c2.files) {
|
|
67540
|
-
const target =
|
|
67541
|
-
ensureDir(
|
|
68370
|
+
const target = path86.join(compDir, f4.path);
|
|
68371
|
+
ensureDir(path86.dirname(target));
|
|
67542
68372
|
fs77.writeFileSync(target, f4.content);
|
|
67543
68373
|
}
|
|
67544
68374
|
}
|
|
@@ -67572,8 +68402,8 @@ function materializeInstructions2(cwd2, cloud) {
|
|
|
67572
68402
|
const body = c2.files[0]?.content ?? "";
|
|
67573
68403
|
if (!body.trim())
|
|
67574
68404
|
continue;
|
|
67575
|
-
const target =
|
|
67576
|
-
ensureDir(
|
|
68405
|
+
const target = path86.join(cwd2, DEFAULT_INSTRUCTIONS_FILE);
|
|
68406
|
+
ensureDir(path86.dirname(target));
|
|
67577
68407
|
fs77.writeFileSync(target, normalizeInstructionBody(body), "utf8");
|
|
67578
68408
|
return;
|
|
67579
68409
|
}
|
|
@@ -67586,8 +68416,8 @@ function materializePlaybooks2(cwd2, cloud) {
|
|
|
67586
68416
|
if (!raw.trim())
|
|
67587
68417
|
continue;
|
|
67588
68418
|
const { body } = stripPlaybookFrontmatter(raw);
|
|
67589
|
-
const target =
|
|
67590
|
-
ensureDir(
|
|
68419
|
+
const target = path86.join(cwd2, DEFAULT_PLAYBOOKS_DIR, `${c2.slug}.md`);
|
|
68420
|
+
ensureDir(path86.dirname(target));
|
|
67591
68421
|
fs77.writeFileSync(target, body, "utf8");
|
|
67592
68422
|
}
|
|
67593
68423
|
}
|
|
@@ -67630,7 +68460,7 @@ function buildManifestFromCloud(cloud, agent, localOnly = {}) {
|
|
|
67630
68460
|
title,
|
|
67631
68461
|
...description ? { description } : {},
|
|
67632
68462
|
...typeof pbMeta.icon === "string" && pbMeta.icon ? { icon: pbMeta.icon } : {},
|
|
67633
|
-
content: { file:
|
|
68463
|
+
content: { file: path86.join(DEFAULT_PLAYBOOKS_DIR, `${c2.slug}.md`) }
|
|
67634
68464
|
};
|
|
67635
68465
|
});
|
|
67636
68466
|
const caps = capabilitiesFromAgent(agent);
|
|
@@ -67644,8 +68474,13 @@ function buildManifestFromCloud(cloud, agent, localOnly = {}) {
|
|
|
67644
68474
|
},
|
|
67645
68475
|
...hasInstructions ? { instructions: { file: DEFAULT_INSTRUCTIONS_FILE } } : {},
|
|
67646
68476
|
playbooks,
|
|
67647
|
-
evals: localOnly.evals ?? [],
|
|
67648
68477
|
...localOnly,
|
|
68478
|
+
evals: mergeEvals({
|
|
68479
|
+
cloud: evalsFromCloudComponents(cloud.components),
|
|
68480
|
+
local: localOnly.evals ?? [],
|
|
68481
|
+
syncedEvalHashes: new Map,
|
|
68482
|
+
keepLocalEvalSlugs: new Set
|
|
68483
|
+
}),
|
|
67649
68484
|
skills,
|
|
67650
68485
|
mcp,
|
|
67651
68486
|
capabilities: {
|
|
@@ -67737,8 +68572,8 @@ async function runOrchestrationPull(cwd2, args) {
|
|
|
67737
68572
|
orchId = args.orchestrationId;
|
|
67738
68573
|
} else {
|
|
67739
68574
|
f2.warn("This folder is not linked to any orchestration.");
|
|
67740
|
-
f2.info(`Run ${
|
|
67741
|
-
or ${
|
|
68575
|
+
f2.info(`Run ${import_picocolors42.default.cyan("brainbase orchestration pull <id>")} with an orchestration id,
|
|
68576
|
+
or ${import_picocolors42.default.cyan("brainbase orchestration list")} to find one.`);
|
|
67742
68577
|
return;
|
|
67743
68578
|
}
|
|
67744
68579
|
const sp = de();
|
|
@@ -67757,24 +68592,24 @@ async function runOrchestrationPull(cwd2, args) {
|
|
|
67757
68592
|
const slugFor = (agentId) => slugByAgent.get(agentId) ?? agentId;
|
|
67758
68593
|
const planLines = [];
|
|
67759
68594
|
planLines.push("");
|
|
67760
|
-
planLines.push(` ${
|
|
68595
|
+
planLines.push(` ${import_picocolors42.default.bold(cloud.name)} ${import_picocolors42.default.dim(`(${cloud.id})`)}`);
|
|
67761
68596
|
if (cloud.description)
|
|
67762
|
-
planLines.push(` ${
|
|
68597
|
+
planLines.push(` ${import_picocolors42.default.dim(cloud.description)}`);
|
|
67763
68598
|
planLines.push("");
|
|
67764
|
-
planLines.push(` ${
|
|
68599
|
+
planLines.push(` ${import_picocolors42.default.dim("members:")}`);
|
|
67765
68600
|
for (const m3 of cloud.members) {
|
|
67766
68601
|
const skipped = !m3.manifest;
|
|
67767
|
-
const tail2 = skipped ?
|
|
67768
|
-
planLines.push(` ${
|
|
68602
|
+
const tail2 = skipped ? import_picocolors42.default.red(" (manifest unavailable — skipped)") : "";
|
|
68603
|
+
planLines.push(` ${import_picocolors42.default.cyan("•")} ${import_picocolors42.default.bold(slugFor(m3.agent_id))} ${import_picocolors42.default.dim(`(${m3.name})`)}${tail2}`);
|
|
67769
68604
|
}
|
|
67770
68605
|
if (cloud.edges.length) {
|
|
67771
68606
|
planLines.push("");
|
|
67772
|
-
planLines.push(` ${
|
|
68607
|
+
planLines.push(` ${import_picocolors42.default.dim("edges:")}`);
|
|
67773
68608
|
for (const e2 of cloud.edges) {
|
|
67774
68609
|
const from = slugFor(e2.from_agent_id);
|
|
67775
68610
|
const to2 = slugFor(e2.to_agent_id);
|
|
67776
|
-
const desc = e2.description ? ` ${
|
|
67777
|
-
planLines.push(` ${
|
|
68611
|
+
const desc = e2.description ? ` ${import_picocolors42.default.dim("— " + e2.description)}` : "";
|
|
68612
|
+
planLines.push(` ${import_picocolors42.default.cyan(from)} ${import_picocolors42.default.dim("→")} ${import_picocolors42.default.cyan(to2)}${desc}`);
|
|
67778
68613
|
}
|
|
67779
68614
|
}
|
|
67780
68615
|
planLines.push("");
|
|
@@ -67783,7 +68618,7 @@ async function runOrchestrationPull(cwd2, args) {
|
|
|
67783
68618
|
const isRefresh = !!existingLink;
|
|
67784
68619
|
if (!autoProceed(args.yes) && !isRefresh) {
|
|
67785
68620
|
const ok = await se({
|
|
67786
|
-
message: `Pull into ${
|
|
68621
|
+
message: `Pull into ${import_picocolors42.default.bold(cwd2)}?`,
|
|
67787
68622
|
initialValue: true
|
|
67788
68623
|
});
|
|
67789
68624
|
if (!ensureNotCancelled(ok)) {
|
|
@@ -67827,7 +68662,7 @@ async function runOrchestrationPull(cwd2, args) {
|
|
|
67827
68662
|
scope: "project",
|
|
67828
68663
|
pullSecrets: true
|
|
67829
68664
|
});
|
|
67830
|
-
memberSp.stop(`Installed ${
|
|
68665
|
+
memberSp.stop(`Installed ${import_picocolors42.default.bold(slug)} ${import_picocolors42.default.dim(`(${m3.manifest.components.length} components)`)}.`);
|
|
67831
68666
|
installedMembers.push({
|
|
67832
68667
|
agent_id: m3.agent_id,
|
|
67833
68668
|
slug,
|
|
@@ -67888,7 +68723,7 @@ async function runOrchestrationPull(cwd2, args) {
|
|
|
67888
68723
|
payload_schema: e2.payload_schema ?? {}
|
|
67889
68724
|
}))
|
|
67890
68725
|
});
|
|
67891
|
-
$e(`Pulled ${cloud.name} at revision ${cloud.revision} into ${
|
|
68726
|
+
$e(`Pulled ${cloud.name} at revision ${cloud.revision} into ${path87.basename(cwd2)}/ ${import_picocolors42.default.dim(`(${installedMembers.length}/${cloud.members.length} members)`)}.`);
|
|
67892
68727
|
}
|
|
67893
68728
|
function handleApiError5(err) {
|
|
67894
68729
|
if (err instanceof ApiError) {
|
|
@@ -67905,7 +68740,7 @@ function handleApiError5(err) {
|
|
|
67905
68740
|
}
|
|
67906
68741
|
|
|
67907
68742
|
// src/cli/orchestration-push.ts
|
|
67908
|
-
var
|
|
68743
|
+
var import_picocolors43 = __toESM(require_picocolors(), 1);
|
|
67909
68744
|
|
|
67910
68745
|
// src/core/orchestration-outgoing.ts
|
|
67911
68746
|
function buildOrchestrationGraphPayload(manifest, slugToAgentId) {
|
|
@@ -67988,7 +68823,7 @@ function findUnpushableMembers(cwd2, members) {
|
|
|
67988
68823
|
continue;
|
|
67989
68824
|
}
|
|
67990
68825
|
if (!memberManifest.id) {
|
|
67991
|
-
f2.error(`${m3.slug}: ${AGENT_MANIFEST_FILE} is unclaimed (no ${
|
|
68826
|
+
f2.error(`${m3.slug}: ${AGENT_MANIFEST_FILE} is unclaimed (no ${import_picocolors43.default.cyan("id")}), so there is nothing to push to.`);
|
|
67992
68827
|
blocked.push(m3.slug);
|
|
67993
68828
|
continue;
|
|
67994
68829
|
}
|
|
@@ -68003,12 +68838,12 @@ async function runOrchestrationPush(cwd2, args) {
|
|
|
68003
68838
|
const link2 = readOrchLink(cwd2);
|
|
68004
68839
|
if (!link2) {
|
|
68005
68840
|
f2.warn("This folder is not linked to any orchestration.");
|
|
68006
|
-
f2.info(`Run ${
|
|
68841
|
+
f2.info(`Run ${import_picocolors43.default.cyan("brainbase orchestration pull <id>")} first.`);
|
|
68007
68842
|
return;
|
|
68008
68843
|
}
|
|
68009
68844
|
if (!hasOrchManifest(cwd2)) {
|
|
68010
|
-
f2.warn(`No ${
|
|
68011
|
-
f2.info(`Run ${
|
|
68845
|
+
f2.warn(`No ${import_picocolors43.default.bold(ORCH_MANIFEST_FILE)} here.`);
|
|
68846
|
+
f2.info(`Run ${import_picocolors43.default.cyan("brainbase orchestration pull")} to materialise the manifest before pushing.`);
|
|
68012
68847
|
return;
|
|
68013
68848
|
}
|
|
68014
68849
|
let manifest;
|
|
@@ -68032,7 +68867,7 @@ async function runOrchestrationPush(cwd2, args) {
|
|
|
68032
68867
|
}
|
|
68033
68868
|
if (missing.length) {
|
|
68034
68869
|
f2.error(`Missing local checkouts for: ${missing.join(", ")}.`);
|
|
68035
|
-
f2.info(`Run ${
|
|
68870
|
+
f2.info(`Run ${import_picocolors43.default.cyan("brainbase orchestration pull")} to materialise the missing folders.`);
|
|
68036
68871
|
process.exitCode = 1;
|
|
68037
68872
|
return;
|
|
68038
68873
|
}
|
|
@@ -68053,13 +68888,13 @@ async function runOrchestrationPush(cwd2, args) {
|
|
|
68053
68888
|
}
|
|
68054
68889
|
}
|
|
68055
68890
|
const plan = [""];
|
|
68056
|
-
plan.push(` ${
|
|
68057
|
-
plan.push(` ${
|
|
68891
|
+
plan.push(` ${import_picocolors43.default.bold(link2.name)} ${import_picocolors43.default.dim(`(${link2.orchestration_id})`)}`);
|
|
68892
|
+
plan.push(` ${import_picocolors43.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
68893
|
plan.push("");
|
|
68059
68894
|
if (!args.graphOnly) {
|
|
68060
|
-
plan.push(` ${
|
|
68895
|
+
plan.push(` ${import_picocolors43.default.dim("per-member agent push:")}`);
|
|
68061
68896
|
for (const m3 of manifest.members) {
|
|
68062
|
-
plan.push(` ${
|
|
68897
|
+
plan.push(` ${import_picocolors43.default.cyan("•")} ${import_picocolors43.default.bold(m3.slug)}`);
|
|
68063
68898
|
}
|
|
68064
68899
|
plan.push("");
|
|
68065
68900
|
}
|
|
@@ -68079,7 +68914,7 @@ async function runOrchestrationPush(cwd2, args) {
|
|
|
68079
68914
|
for (const m3 of manifest.members) {
|
|
68080
68915
|
const dir = memberDir(cwd2, m3.slug);
|
|
68081
68916
|
console.log("");
|
|
68082
|
-
console.log(`${
|
|
68917
|
+
console.log(`${import_picocolors43.default.dim("───")} ${import_picocolors43.default.bold(m3.slug)} ${import_picocolors43.default.dim("───")}`);
|
|
68083
68918
|
const exitCodeBeforePush = process.exitCode;
|
|
68084
68919
|
try {
|
|
68085
68920
|
await runAgentPush(dir, { yes: true });
|
|
@@ -68143,7 +68978,7 @@ function handleApiError6(err) {
|
|
|
68143
68978
|
f2.error("You do not have access to this orchestration.");
|
|
68144
68979
|
} else if (err.status === 409) {
|
|
68145
68980
|
f2.error(err.message);
|
|
68146
|
-
f2.info(`Run ${
|
|
68981
|
+
f2.info(`Run ${import_picocolors43.default.cyan("brainbase orchestration pull")} to reconcile, then push again.`);
|
|
68147
68982
|
} else {
|
|
68148
68983
|
f2.error(err.message);
|
|
68149
68984
|
}
|
|
@@ -68153,13 +68988,13 @@ function handleApiError6(err) {
|
|
|
68153
68988
|
}
|
|
68154
68989
|
|
|
68155
68990
|
// src/cli/orchestration-status.ts
|
|
68156
|
-
var
|
|
68991
|
+
var import_picocolors44 = __toESM(require_picocolors(), 1);
|
|
68157
68992
|
async function runOrchestrationStatus(cwd2) {
|
|
68158
68993
|
banner("orchestration status — what changed locally, remotely, both");
|
|
68159
68994
|
const link2 = readOrchLink(cwd2);
|
|
68160
68995
|
if (!link2) {
|
|
68161
68996
|
f2.warn("This folder is not linked to any orchestration.");
|
|
68162
|
-
f2.info(`Run ${
|
|
68997
|
+
f2.info(`Run ${import_picocolors44.default.cyan("brainbase orchestration pull <id>")} first.`);
|
|
68163
68998
|
return;
|
|
68164
68999
|
}
|
|
68165
69000
|
const localManifest = hasOrchManifest(cwd2) ? readOrchManifest(cwd2) : null;
|
|
@@ -68182,8 +69017,8 @@ async function runOrchestrationStatus(cwd2) {
|
|
|
68182
69017
|
}
|
|
68183
69018
|
const lines = [];
|
|
68184
69019
|
lines.push("");
|
|
68185
|
-
lines.push(` ${
|
|
68186
|
-
lines.push(` ${
|
|
69020
|
+
lines.push(` ${import_picocolors44.default.bold(link2.name)} ${import_picocolors44.default.dim(`(${link2.orchestration_id})`)}`);
|
|
69021
|
+
lines.push(` ${import_picocolors44.default.dim("revision")} cloud ${cloud.revision}${lock ? ` · lock ${lock.revision}` : " · never pulled"}`);
|
|
68187
69022
|
lines.push("");
|
|
68188
69023
|
const localSlugByAgentId = new Map;
|
|
68189
69024
|
for (const m3 of localManifest?.members ?? []) {
|
|
@@ -68197,12 +69032,12 @@ async function runOrchestrationStatus(cwd2) {
|
|
|
68197
69032
|
const membersAdded = [...localMemberSet].filter((s3) => !cloudMemberSet.has(s3));
|
|
68198
69033
|
const membersRemoved = [...cloudMemberSet].filter((s3) => !localMemberSet.has(s3));
|
|
68199
69034
|
if (membersAdded.length || membersRemoved.length) {
|
|
68200
|
-
lines.push(` ${
|
|
69035
|
+
lines.push(` ${import_picocolors44.default.bold("members")}`);
|
|
68201
69036
|
for (const slug of membersAdded) {
|
|
68202
|
-
lines.push(` ${
|
|
69037
|
+
lines.push(` ${import_picocolors44.default.yellow("→ push")} added in yaml: ${import_picocolors44.default.bold(slug)}`);
|
|
68203
69038
|
}
|
|
68204
69039
|
for (const slug of membersRemoved) {
|
|
68205
|
-
lines.push(` ${
|
|
69040
|
+
lines.push(` ${import_picocolors44.default.cyan("← pull")} added on cloud: ${import_picocolors44.default.bold(slug)}`);
|
|
68206
69041
|
}
|
|
68207
69042
|
lines.push("");
|
|
68208
69043
|
}
|
|
@@ -68217,11 +69052,11 @@ async function runOrchestrationStatus(cwd2) {
|
|
|
68217
69052
|
const edgesAdded = [...localEdges.keys()].filter((k3) => !cloudEdges.has(k3));
|
|
68218
69053
|
const edgesRemoved = [...cloudEdges.keys()].filter((k3) => !localEdges.has(k3));
|
|
68219
69054
|
if (edgesAdded.length || edgesRemoved.length) {
|
|
68220
|
-
lines.push(` ${
|
|
69055
|
+
lines.push(` ${import_picocolors44.default.bold("edges")}`);
|
|
68221
69056
|
for (const k3 of edgesAdded)
|
|
68222
|
-
lines.push(` ${
|
|
69057
|
+
lines.push(` ${import_picocolors44.default.yellow("→ push")} added in yaml: ${k3}`);
|
|
68223
69058
|
for (const k3 of edgesRemoved)
|
|
68224
|
-
lines.push(` ${
|
|
69059
|
+
lines.push(` ${import_picocolors44.default.cyan("← pull")} added on cloud: ${k3}`);
|
|
68225
69060
|
lines.push("");
|
|
68226
69061
|
}
|
|
68227
69062
|
const cloudTriggerKey = (t) => {
|
|
@@ -68259,11 +69094,11 @@ async function runOrchestrationStatus(cwd2) {
|
|
|
68259
69094
|
const triggersAdded = [...localTriggers.keys()].filter((k3) => !cloudTriggers.has(k3));
|
|
68260
69095
|
const triggersRemoved = [...cloudTriggers.keys()].filter((k3) => !localTriggers.has(k3));
|
|
68261
69096
|
if (triggersAdded.length || triggersRemoved.length) {
|
|
68262
|
-
lines.push(` ${
|
|
69097
|
+
lines.push(` ${import_picocolors44.default.bold("schedule triggers")}`);
|
|
68263
69098
|
for (const k3 of triggersAdded)
|
|
68264
|
-
lines.push(` ${
|
|
69099
|
+
lines.push(` ${import_picocolors44.default.yellow("→ push")} added/changed in yaml: ${localTriggers.get(k3) ?? k3}`);
|
|
68265
69100
|
for (const k3 of triggersRemoved)
|
|
68266
|
-
lines.push(` ${
|
|
69101
|
+
lines.push(` ${import_picocolors44.default.cyan("← pull")} added/changed on cloud: ${cloudTriggers.get(k3) ?? k3}`);
|
|
68267
69102
|
lines.push("");
|
|
68268
69103
|
}
|
|
68269
69104
|
const lockByAgentId = new Map((lock?.members ?? []).map((m3) => [m3.agent_id, m3]));
|
|
@@ -68286,27 +69121,27 @@ async function runOrchestrationStatus(cwd2) {
|
|
|
68286
69121
|
}
|
|
68287
69122
|
}
|
|
68288
69123
|
if (memberDrift.length) {
|
|
68289
|
-
lines.push(` ${
|
|
69124
|
+
lines.push(` ${import_picocolors44.default.bold("member content drift")}`);
|
|
68290
69125
|
for (const d3 of memberDrift) {
|
|
68291
|
-
lines.push(` ${
|
|
69126
|
+
lines.push(` ${import_picocolors44.default.cyan("?")} ${import_picocolors44.default.bold(d3.slug)} ${import_picocolors44.default.dim("— " + d3.reason)}`);
|
|
68292
69127
|
}
|
|
68293
|
-
lines.push(` ${
|
|
69128
|
+
lines.push(` ${import_picocolors44.default.dim("cd into each member folder and run")} ${import_picocolors44.default.cyan("brainbase agent status")}`);
|
|
68294
69129
|
lines.push("");
|
|
68295
69130
|
}
|
|
68296
69131
|
const revisionDrift = lock?.revision != null && cloud.revision !== lock.revision;
|
|
68297
69132
|
if (revisionDrift) {
|
|
68298
|
-
lines.push(` ${
|
|
68299
|
-
lines.push(` ${
|
|
69133
|
+
lines.push(` ${import_picocolors44.default.bold("cloud revision")}`);
|
|
69134
|
+
lines.push(` ${import_picocolors44.default.cyan("← pull")} cloud changed since last pull: ${import_picocolors44.default.dim(`lock ${lock.revision} → cloud ${cloud.revision}`)}`);
|
|
68300
69135
|
lines.push("");
|
|
68301
69136
|
}
|
|
68302
69137
|
if (!membersAdded.length && !membersRemoved.length && !edgesAdded.length && !edgesRemoved.length && !triggersAdded.length && !triggersRemoved.length && !memberDrift.length && !revisionDrift) {
|
|
68303
|
-
lines.push(` ${
|
|
69138
|
+
lines.push(` ${import_picocolors44.default.green("✓")} everything is in sync`);
|
|
68304
69139
|
lines.push("");
|
|
68305
69140
|
console.log(lines.join(`
|
|
68306
69141
|
`));
|
|
68307
69142
|
return;
|
|
68308
69143
|
}
|
|
68309
|
-
lines.push(` ${
|
|
69144
|
+
lines.push(` ${import_picocolors44.default.dim("run")} ${import_picocolors44.default.cyan("brainbase orchestration pull")} ${import_picocolors44.default.dim("to apply cloud changes,")} ${import_picocolors44.default.cyan("brainbase orchestration push")} ${import_picocolors44.default.dim("to send yours")}`);
|
|
68310
69145
|
lines.push("");
|
|
68311
69146
|
console.log(lines.join(`
|
|
68312
69147
|
`));
|
|
@@ -68321,7 +69156,7 @@ function stableJson(value) {
|
|
|
68321
69156
|
}
|
|
68322
69157
|
|
|
68323
69158
|
// src/cli/orchestration-list.ts
|
|
68324
|
-
var
|
|
69159
|
+
var import_picocolors45 = __toESM(require_picocolors(), 1);
|
|
68325
69160
|
async function runOrchestrationList(args) {
|
|
68326
69161
|
banner("orchestration list — orchestrations under a team");
|
|
68327
69162
|
const { org, team } = await resolveOrgAndTeam({
|
|
@@ -68345,13 +69180,13 @@ async function runOrchestrationList(args) {
|
|
|
68345
69180
|
}
|
|
68346
69181
|
const lines = [""];
|
|
68347
69182
|
for (const o2 of items) {
|
|
68348
|
-
lines.push(` ${
|
|
69183
|
+
lines.push(` ${import_picocolors45.default.bold(o2.name)} ${import_picocolors45.default.dim(o2.id)}`);
|
|
68349
69184
|
if (o2.description)
|
|
68350
|
-
lines.push(` ${
|
|
68351
|
-
lines.push(` ${
|
|
69185
|
+
lines.push(` ${import_picocolors45.default.dim(o2.description)}`);
|
|
69186
|
+
lines.push(` ${import_picocolors45.default.dim(`${o2.member_count} member${o2.member_count === 1 ? "" : "s"} · ${o2.edge_count} edge${o2.edge_count === 1 ? "" : "s"}`)}`);
|
|
68352
69187
|
lines.push("");
|
|
68353
69188
|
}
|
|
68354
|
-
lines.push(` ${
|
|
69189
|
+
lines.push(` ${import_picocolors45.default.dim("pull one with")} ${import_picocolors45.default.cyan("brainbase orchestration pull <id>")}`);
|
|
68355
69190
|
lines.push("");
|
|
68356
69191
|
console.log(lines.join(`
|
|
68357
69192
|
`));
|
|
@@ -68359,7 +69194,7 @@ async function runOrchestrationList(args) {
|
|
|
68359
69194
|
|
|
68360
69195
|
// src/cli/orchestration-add-agent.ts
|
|
68361
69196
|
import fs79 from "node:fs";
|
|
68362
|
-
var
|
|
69197
|
+
var import_picocolors46 = __toESM(require_picocolors(), 1);
|
|
68363
69198
|
|
|
68364
69199
|
// src/core/orchestration-add.ts
|
|
68365
69200
|
function resolveOrgIdForGroup(groupId, orgsWithTeams) {
|
|
@@ -68424,7 +69259,7 @@ async function runOrchestrationAddAgent(cwd2, args) {
|
|
|
68424
69259
|
const link2 = readOrchLink(cwd2);
|
|
68425
69260
|
if (!link2 || !hasOrchManifest(cwd2)) {
|
|
68426
69261
|
f2.warn("This folder is not a linked orchestration.");
|
|
68427
|
-
f2.info(`Run ${
|
|
69262
|
+
f2.info(`Run ${import_picocolors46.default.cyan("brainbase orchestration pull <id>")} first.`);
|
|
68428
69263
|
return;
|
|
68429
69264
|
}
|
|
68430
69265
|
let manifest;
|
|
@@ -68450,7 +69285,7 @@ async function runOrchestrationAddAgent(cwd2, args) {
|
|
|
68450
69285
|
while (manifest.members.some((m3) => m3.slug === candidate) || fs79.existsSync(memberDir(cwd2, candidate))) {
|
|
68451
69286
|
candidate = `${slug}-${++n}`;
|
|
68452
69287
|
}
|
|
68453
|
-
f2.info(`Slug ${
|
|
69288
|
+
f2.info(`Slug ${import_picocolors46.default.bold(slug)} is taken — using ${import_picocolors46.default.bold(candidate)}.`);
|
|
68454
69289
|
slug = candidate;
|
|
68455
69290
|
}
|
|
68456
69291
|
let payloadSchema;
|
|
@@ -68474,7 +69309,7 @@ async function runOrchestrationAddAgent(cwd2, args) {
|
|
|
68474
69309
|
const resolved = resolveOrgIdForGroup(link2.group_id, orgsWithTeams);
|
|
68475
69310
|
if (!resolved) {
|
|
68476
69311
|
sp.stop("Failed.");
|
|
68477
|
-
f2.error(`Could not find an org that owns group ${
|
|
69312
|
+
f2.error(`Could not find an org that owns group ${import_picocolors46.default.bold(link2.group_id)}. ` + `Pass ${import_picocolors46.default.cyan("--org <id>")} explicitly.`);
|
|
68478
69313
|
return;
|
|
68479
69314
|
}
|
|
68480
69315
|
orgId = resolved;
|
|
@@ -68491,14 +69326,14 @@ async function runOrchestrationAddAgent(cwd2, args) {
|
|
|
68491
69326
|
if (from.length === 0 && to2.length === 0 && isInteractive() && manifest.members.length > 0) {
|
|
68492
69327
|
const memberOptions = manifest.members.map((m3) => ({ value: m3.slug, label: m3.slug }));
|
|
68493
69328
|
const pickedFrom = await ae({
|
|
68494
|
-
message: `Connect ${
|
|
69329
|
+
message: `Connect ${import_picocolors46.default.bold(slug)} FROM which member(s)? — edges INTO ${slug} (space to select, enter to skip)`,
|
|
68495
69330
|
options: memberOptions,
|
|
68496
69331
|
required: false
|
|
68497
69332
|
});
|
|
68498
69333
|
if (Array.isArray(pickedFrom))
|
|
68499
69334
|
from = pickedFrom;
|
|
68500
69335
|
const pickedTo = await ae({
|
|
68501
|
-
message: `Connect ${
|
|
69336
|
+
message: `Connect ${import_picocolors46.default.bold(slug)} TO which member(s)? — edges OUT of ${slug} (space to select, enter to skip)`,
|
|
68502
69337
|
options: memberOptions,
|
|
68503
69338
|
required: false
|
|
68504
69339
|
});
|
|
@@ -68537,23 +69372,23 @@ async function runOrchestrationAddAgent(cwd2, args) {
|
|
|
68537
69372
|
}
|
|
68538
69373
|
writeOrchManifest(cwd2, updated);
|
|
68539
69374
|
if (args.noPush) {
|
|
68540
|
-
f2.info(`Manifest updated. Run ${
|
|
69375
|
+
f2.info(`Manifest updated. Run ${import_picocolors46.default.cyan("brainbase orchestration push")} to apply.`);
|
|
68541
69376
|
return;
|
|
68542
69377
|
}
|
|
68543
69378
|
await runOrchestrationPush(cwd2, { yes: true, graphOnly: true });
|
|
68544
69379
|
}
|
|
68545
69380
|
|
|
68546
69381
|
// src/cli/orchestration-create.ts
|
|
68547
|
-
var
|
|
69382
|
+
var import_picocolors47 = __toESM(require_picocolors(), 1);
|
|
68548
69383
|
async function runOrchestrationCreate(cwd2, args) {
|
|
68549
69384
|
banner("orchestration create — claim a brainbase-orchestration.yaml");
|
|
68550
69385
|
if (readOrchLink(cwd2)) {
|
|
68551
69386
|
f2.warn("This folder is already linked to an orchestration.");
|
|
68552
|
-
f2.info(`Run ${
|
|
69387
|
+
f2.info(`Run ${import_picocolors47.default.cyan("brainbase orchestration push")} to update it.`);
|
|
68553
69388
|
return;
|
|
68554
69389
|
}
|
|
68555
69390
|
if (!hasOrchManifest(cwd2)) {
|
|
68556
|
-
f2.warn(`No ${
|
|
69391
|
+
f2.warn(`No ${import_picocolors47.default.bold(ORCH_MANIFEST_FILE)} here.`);
|
|
68557
69392
|
f2.info(`Create one, or pull an existing orchestration first.`);
|
|
68558
69393
|
return;
|
|
68559
69394
|
}
|
|
@@ -68586,10 +69421,10 @@ async function runOrchestrationCreate(cwd2, args) {
|
|
|
68586
69421
|
});
|
|
68587
69422
|
const plan = [
|
|
68588
69423
|
"",
|
|
68589
|
-
` ${
|
|
68590
|
-
` ${
|
|
68591
|
-
` ${
|
|
68592
|
-
` ${
|
|
69424
|
+
` ${import_picocolors47.default.bold(manifest.orchestration.name)}`,
|
|
69425
|
+
` ${import_picocolors47.default.dim("org")} ${import_picocolors47.default.bold(target.org.name)}`,
|
|
69426
|
+
` ${import_picocolors47.default.dim("team")} ${import_picocolors47.default.bold(target.team.name)}`,
|
|
69427
|
+
` ${import_picocolors47.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
69428
|
""
|
|
68594
69429
|
];
|
|
68595
69430
|
console.log(plan.join(`
|
|
@@ -68619,7 +69454,7 @@ async function runOrchestrationCreate(cwd2, args) {
|
|
|
68619
69454
|
edges: graph.edges,
|
|
68620
69455
|
triggers: graph.triggers
|
|
68621
69456
|
});
|
|
68622
|
-
sp.stop(`Created ${
|
|
69457
|
+
sp.stop(`Created ${import_picocolors47.default.bold(created.name)}.`);
|
|
68623
69458
|
writeOrchLink(cwd2, {
|
|
68624
69459
|
schemaVersion: 1,
|
|
68625
69460
|
orchestration_id: created.id,
|
|
@@ -68732,21 +69567,21 @@ async function runOrchestration(cwd2, sub, args, opts) {
|
|
|
68732
69567
|
function printHelp3() {
|
|
68733
69568
|
const out = [];
|
|
68734
69569
|
out.push("");
|
|
68735
|
-
out.push(` ${
|
|
69570
|
+
out.push(` ${import_picocolors48.default.bold("brainbase orchestration")} ${import_picocolors48.default.dim("<sub> [options]")}`);
|
|
68736
69571
|
out.push("");
|
|
68737
|
-
out.push(` ${
|
|
68738
|
-
out.push(` ${
|
|
68739
|
-
out.push(` ${
|
|
68740
|
-
out.push(` ${
|
|
68741
|
-
out.push(` ${
|
|
68742
|
-
out.push(` ${
|
|
69572
|
+
out.push(` ${import_picocolors48.default.cyan("create")} ${import_picocolors48.default.dim("claim a local orchestration manifest and create it in the cloud")}`);
|
|
69573
|
+
out.push(` ${import_picocolors48.default.cyan("pull")} ${import_picocolors48.default.dim("<id>")} ${import_picocolors48.default.dim("fetch orchestration + every member agent into this folder")}`);
|
|
69574
|
+
out.push(` ${import_picocolors48.default.cyan("push")} ${import_picocolors48.default.dim("push each member, then update the orchestration graph")}`);
|
|
69575
|
+
out.push(` ${import_picocolors48.default.cyan("add-agent")} ${import_picocolors48.default.dim("<name>")} ${import_picocolors48.default.dim("create a member agent, wire edges (--from/--to), and push")}`);
|
|
69576
|
+
out.push(` ${import_picocolors48.default.cyan("status")} ${import_picocolors48.default.dim("show what would push and what would pull")}`);
|
|
69577
|
+
out.push(` ${import_picocolors48.default.cyan("list")} ${import_picocolors48.default.dim("list orchestrations under a team")}`);
|
|
68743
69578
|
out.push("");
|
|
68744
|
-
out.push(` ${
|
|
68745
|
-
out.push(` ${
|
|
68746
|
-
out.push(` ${
|
|
68747
|
-
out.push(` ${
|
|
68748
|
-
out.push(` ${
|
|
68749
|
-
out.push(` ${
|
|
69579
|
+
out.push(` ${import_picocolors48.default.bold("Flags")}`);
|
|
69580
|
+
out.push(` ${import_picocolors48.default.dim("--yes, -y")} skip confirmations`);
|
|
69581
|
+
out.push(` ${import_picocolors48.default.dim("--harness <id>")} harness for newly-created member folders (default claude-code)`);
|
|
69582
|
+
out.push(` ${import_picocolors48.default.dim("--graph-only")} for push: only update members + edges, skip per-member push`);
|
|
69583
|
+
out.push(` ${import_picocolors48.default.dim("--org <id>")} for create/list: org id or slug (CLI vocab — DB teams.id)`);
|
|
69584
|
+
out.push(` ${import_picocolors48.default.dim("--team <id>")} for create/list: team id (CLI vocab — DB groups.id)`);
|
|
68750
69585
|
out.push("");
|
|
68751
69586
|
console.log(out.join(`
|
|
68752
69587
|
`));
|
|
@@ -68791,11 +69626,11 @@ async function runRun(cwd2, args) {
|
|
|
68791
69626
|
}
|
|
68792
69627
|
|
|
68793
69628
|
// src/cli/publish.ts
|
|
68794
|
-
var
|
|
69629
|
+
var import_picocolors49 = __toESM(require_picocolors(), 1);
|
|
68795
69630
|
function runPublish() {
|
|
68796
69631
|
banner("publish — moved");
|
|
68797
|
-
f2.error(`${
|
|
68798
|
-
f2.info(`Use ${
|
|
69632
|
+
f2.error(`${import_picocolors49.default.bold("brainbase publish")} does not exist.`);
|
|
69633
|
+
f2.info(`Use ${import_picocolors49.default.cyan("brainbase agent push")} to send your local changes to the cloud.`);
|
|
68799
69634
|
process.exit(1);
|
|
68800
69635
|
}
|
|
68801
69636
|
|
|
@@ -69094,7 +69929,7 @@ async function runStatus(cwd2) {
|
|
|
69094
69929
|
}
|
|
69095
69930
|
|
|
69096
69931
|
// src/cli/token.ts
|
|
69097
|
-
var
|
|
69932
|
+
var import_picocolors50 = __toESM(require_picocolors(), 1);
|
|
69098
69933
|
|
|
69099
69934
|
// src/ui/ink/TokenCards.tsx
|
|
69100
69935
|
var jsx_dev_runtime17 = __toESM(require_jsx_dev_runtime(), 1);
|
|
@@ -69516,7 +70351,7 @@ async function runTokenRename(args) {
|
|
|
69516
70351
|
}
|
|
69517
70352
|
}
|
|
69518
70353
|
if (name === target.name.trim()) {
|
|
69519
|
-
console.log(`${sym.ok} ${
|
|
70354
|
+
console.log(`${sym.ok} ${import_picocolors50.default.bold(target.name.trim())} already has that label; nothing to do.`);
|
|
69520
70355
|
return;
|
|
69521
70356
|
}
|
|
69522
70357
|
try {
|
|
@@ -69524,7 +70359,7 @@ async function runTokenRename(args) {
|
|
|
69524
70359
|
} catch (error) {
|
|
69525
70360
|
throw withLoginHint(error);
|
|
69526
70361
|
}
|
|
69527
|
-
console.log(`${sym.ok} Renamed ${
|
|
70362
|
+
console.log(`${sym.ok} Renamed ${import_picocolors50.default.dim(target.name)} → ${import_picocolors50.default.bold(name)}`);
|
|
69528
70363
|
}
|
|
69529
70364
|
async function runTokenRevoke(args) {
|
|
69530
70365
|
if (!args.id) {
|
|
@@ -69542,14 +70377,14 @@ async function runTokenRevoke(args) {
|
|
|
69542
70377
|
throw new Error(`No token with id ${args.id}. Run \`brainbase token list\` to see yours.`);
|
|
69543
70378
|
}
|
|
69544
70379
|
if (target.revoked_at) {
|
|
69545
|
-
reconcileDeadToken(target, `${
|
|
70380
|
+
reconcileDeadToken(target, `${import_picocolors50.default.bold(target.name)} is already revoked.`);
|
|
69546
70381
|
return;
|
|
69547
70382
|
}
|
|
69548
70383
|
const stored = readToken();
|
|
69549
70384
|
const isLocalToken = Boolean(stored && stored.token.startsWith(target.prefix));
|
|
69550
70385
|
if (!autoProceed(args.yes)) {
|
|
69551
70386
|
const ok = await se({
|
|
69552
|
-
message: isLocalToken ? `Revoke ${
|
|
70387
|
+
message: isLocalToken ? `Revoke ${import_picocolors50.default.bold(target.name)} (${args.id})? This is the token this CLI is using, so it will stop working here too.` : `Revoke ${import_picocolors50.default.bold(target.name)} (${args.id})? CIs and machines using it will stop working.`,
|
|
69553
70388
|
initialValue: false
|
|
69554
70389
|
});
|
|
69555
70390
|
if (!ensureNotCancelled(ok))
|
|
@@ -69560,14 +70395,14 @@ async function runTokenRevoke(args) {
|
|
|
69560
70395
|
} catch (error) {
|
|
69561
70396
|
if (error instanceof ApiError && error.status === 404) {
|
|
69562
70397
|
if (isExpired2(target)) {
|
|
69563
|
-
reconcileDeadToken(target, `${
|
|
70398
|
+
reconcileDeadToken(target, `${import_picocolors50.default.bold(target.name)} had already expired.`);
|
|
69564
70399
|
return;
|
|
69565
70400
|
}
|
|
69566
70401
|
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
70402
|
}
|
|
69568
70403
|
throw withLoginHint(error);
|
|
69569
70404
|
}
|
|
69570
|
-
reconcileDeadToken(target, `Revoked ${
|
|
70405
|
+
reconcileDeadToken(target, `Revoked ${import_picocolors50.default.bold(target.name)}.`);
|
|
69571
70406
|
}
|
|
69572
70407
|
function reconcileDeadToken(target, headline) {
|
|
69573
70408
|
let outcome;
|
|
@@ -69601,7 +70436,7 @@ function reportLocalToken(headline, outcome) {
|
|
|
69601
70436
|
}
|
|
69602
70437
|
async function runTokenClear() {
|
|
69603
70438
|
if (!readToken()) {
|
|
69604
|
-
console.log(
|
|
70439
|
+
console.log(import_picocolors50.default.dim("No local token stored."));
|
|
69605
70440
|
return;
|
|
69606
70441
|
}
|
|
69607
70442
|
clearToken();
|
|
@@ -69701,31 +70536,31 @@ async function runToken(sub, rest2, args) {
|
|
|
69701
70536
|
function printTokenHelp() {
|
|
69702
70537
|
const out = [];
|
|
69703
70538
|
out.push("");
|
|
69704
|
-
out.push(` ${
|
|
70539
|
+
out.push(` ${import_picocolors50.default.bold("brainbase token")} ${import_picocolors50.default.dim("<command>")}`);
|
|
69705
70540
|
out.push("");
|
|
69706
|
-
out.push(` ${
|
|
69707
|
-
out.push(` ${
|
|
69708
|
-
out.push(` ${
|
|
69709
|
-
out.push(` ${
|
|
69710
|
-
out.push(` ${
|
|
70541
|
+
out.push(` ${import_picocolors50.default.cyan("create")} ${import_picocolors50.default.dim("issue a new long-lived CLI key (PAT)")}`);
|
|
70542
|
+
out.push(` ${import_picocolors50.default.cyan("list")} ${import_picocolors50.default.dim("show your tokens")}`);
|
|
70543
|
+
out.push(` ${import_picocolors50.default.cyan("rename")} ${import_picocolors50.default.dim("<id>")} ${import_picocolors50.default.dim("relabel a token by id")}`);
|
|
70544
|
+
out.push(` ${import_picocolors50.default.cyan("revoke")} ${import_picocolors50.default.dim("<id>")} ${import_picocolors50.default.dim("revoke a token by id")}`);
|
|
70545
|
+
out.push(` ${import_picocolors50.default.cyan("clear")} ${import_picocolors50.default.dim("forget the local token (does not revoke)")}`);
|
|
69711
70546
|
out.push("");
|
|
69712
|
-
out.push(` ${
|
|
69713
|
-
out.push(` ${
|
|
69714
|
-
out.push(` ${
|
|
69715
|
-
out.push(` ${
|
|
70547
|
+
out.push(` ${import_picocolors50.default.bold("create flags")}`);
|
|
70548
|
+
out.push(` ${import_picocolors50.default.cyan("--name, -n")} ${import_picocolors50.default.dim("<label>")} ${import_picocolors50.default.dim("token label (prompted if omitted)")}`);
|
|
70549
|
+
out.push(` ${import_picocolors50.default.cyan("--scopes")} ${import_picocolors50.default.dim("<list>")} ${import_picocolors50.default.dim("comma-separated; allowed: read, publish, admin")}`);
|
|
70550
|
+
out.push(` ${import_picocolors50.default.dim("default: read,publish")}`);
|
|
69716
70551
|
out.push("");
|
|
69717
|
-
out.push(` ${
|
|
69718
|
-
out.push(` ${
|
|
70552
|
+
out.push(` ${import_picocolors50.default.bold("rename flags")}`);
|
|
70553
|
+
out.push(` ${import_picocolors50.default.cyan("--name, -n")} ${import_picocolors50.default.dim("<label>")} ${import_picocolors50.default.dim("new label (prompted if omitted)")}`);
|
|
69719
70554
|
out.push("");
|
|
69720
70555
|
console.log(out.join(`
|
|
69721
70556
|
`));
|
|
69722
70557
|
}
|
|
69723
70558
|
|
|
69724
70559
|
// src/cli/mcp.ts
|
|
69725
|
-
var
|
|
70560
|
+
var import_picocolors51 = __toESM(require_picocolors(), 1);
|
|
69726
70561
|
|
|
69727
70562
|
// src/core/mcp-check/collect-servers.ts
|
|
69728
|
-
import
|
|
70563
|
+
import path88 from "node:path";
|
|
69729
70564
|
import fs80 from "node:fs";
|
|
69730
70565
|
function collectServers(cwd2, env3 = process.env) {
|
|
69731
70566
|
const out = [];
|
|
@@ -69777,7 +70612,7 @@ function pushResolved(out, seen, name, entry, env3) {
|
|
|
69777
70612
|
out.push({ name, url: finalUrl, headers });
|
|
69778
70613
|
}
|
|
69779
70614
|
function* readResolvedMcps(cwd2) {
|
|
69780
|
-
const p2 =
|
|
70615
|
+
const p2 = path88.join(cwd2, ".brainbase", "resolved-mcps.json");
|
|
69781
70616
|
let raw;
|
|
69782
70617
|
try {
|
|
69783
70618
|
raw = fs80.readFileSync(p2, "utf-8");
|
|
@@ -69804,12 +70639,12 @@ function* readResolvedMcps(cwd2) {
|
|
|
69804
70639
|
}
|
|
69805
70640
|
}
|
|
69806
70641
|
function readClaudeCode(cwd2) {
|
|
69807
|
-
const file =
|
|
70642
|
+
const file = path88.join(cwd2, ".mcp.json");
|
|
69808
70643
|
const map2 = listMcpServersFromMcpJson(file);
|
|
69809
70644
|
return Object.entries(map2);
|
|
69810
70645
|
}
|
|
69811
70646
|
function readCodex(cwd2) {
|
|
69812
|
-
const file =
|
|
70647
|
+
const file = path88.join(cwd2, ".codex", "config.toml");
|
|
69813
70648
|
try {
|
|
69814
70649
|
return Object.entries(listMcpServers2(file));
|
|
69815
70650
|
} catch {
|
|
@@ -69817,7 +70652,7 @@ function readCodex(cwd2) {
|
|
|
69817
70652
|
}
|
|
69818
70653
|
}
|
|
69819
70654
|
function readKafka(cwd2) {
|
|
69820
|
-
const file =
|
|
70655
|
+
const file = path88.join(cwd2, ".kafka", "kafka.json");
|
|
69821
70656
|
try {
|
|
69822
70657
|
return Object.entries(listMcpServers3(file));
|
|
69823
70658
|
} catch {
|
|
@@ -70105,10 +70940,10 @@ function assignProp(target, prop, value) {
|
|
|
70105
70940
|
configurable: true
|
|
70106
70941
|
});
|
|
70107
70942
|
}
|
|
70108
|
-
function getElementAtPath(obj,
|
|
70109
|
-
if (!
|
|
70943
|
+
function getElementAtPath(obj, path89) {
|
|
70944
|
+
if (!path89)
|
|
70110
70945
|
return obj;
|
|
70111
|
-
return
|
|
70946
|
+
return path89.reduce((acc, key2) => acc?.[key2], obj);
|
|
70112
70947
|
}
|
|
70113
70948
|
function promiseAllObject(promisesObj) {
|
|
70114
70949
|
const keys2 = Object.keys(promisesObj);
|
|
@@ -70424,11 +71259,11 @@ function aborted(x3, startIndex = 0) {
|
|
|
70424
71259
|
}
|
|
70425
71260
|
return false;
|
|
70426
71261
|
}
|
|
70427
|
-
function prefixIssues(
|
|
71262
|
+
function prefixIssues(path89, issues) {
|
|
70428
71263
|
return issues.map((iss) => {
|
|
70429
71264
|
var _a;
|
|
70430
71265
|
(_a = iss).path ?? (_a.path = []);
|
|
70431
|
-
iss.path.unshift(
|
|
71266
|
+
iss.path.unshift(path89);
|
|
70432
71267
|
return iss;
|
|
70433
71268
|
});
|
|
70434
71269
|
}
|
|
@@ -76194,8 +77029,8 @@ async function random2(size2) {
|
|
|
76194
77029
|
const evenDistCutoff = Math.pow(2, 8) - Math.pow(2, 8) % mask.length;
|
|
76195
77030
|
let result2 = "";
|
|
76196
77031
|
while (result2.length < size2) {
|
|
76197
|
-
const
|
|
76198
|
-
for (const randomByte of
|
|
77032
|
+
const randomBytes2 = await getRandomValues(size2 - result2.length);
|
|
77033
|
+
for (const randomByte of randomBytes2) {
|
|
76199
77034
|
if (randomByte < evenDistCutoff) {
|
|
76200
77035
|
result2 += mask[randomByte % mask.length];
|
|
76201
77036
|
}
|
|
@@ -78079,17 +78914,17 @@ async function runMcpCheck(cwd2, options) {
|
|
|
78079
78914
|
function renderHuman(report2) {
|
|
78080
78915
|
const lines = [];
|
|
78081
78916
|
if (report2.check_status === "skipped") {
|
|
78082
|
-
lines.push(
|
|
78917
|
+
lines.push(import_picocolors51.default.dim("No MCP servers configured — nothing to check."));
|
|
78083
78918
|
return lines.join(`
|
|
78084
78919
|
`) + `
|
|
78085
78920
|
`;
|
|
78086
78921
|
}
|
|
78087
78922
|
for (const s3 of report2.servers) {
|
|
78088
|
-
const mark = s3.status === "ok" ?
|
|
78089
|
-
const detail = s3.status === "ok" ?
|
|
78923
|
+
const mark = s3.status === "ok" ? import_picocolors51.default.green("✓") : s3.status === "auth_failed" ? import_picocolors51.default.red("✗") : import_picocolors51.default.yellow("⚠");
|
|
78924
|
+
const detail = s3.status === "ok" ? import_picocolors51.default.dim(`${s3.tool_count} tool${s3.tool_count === 1 ? "" : "s"}`) : import_picocolors51.default.dim(s3.status + (s3.error ? ` — ${s3.error}` : ""));
|
|
78090
78925
|
lines.push(` ${mark} ${s3.name} ${detail}`);
|
|
78091
78926
|
}
|
|
78092
|
-
const summary = report2.check_status === "ok" ?
|
|
78927
|
+
const summary = report2.check_status === "ok" ? import_picocolors51.default.green("All MCP servers connected.") : import_picocolors51.default.yellow("Some MCP servers are unhealthy.");
|
|
78093
78928
|
lines.push("", summary);
|
|
78094
78929
|
return lines.join(`
|
|
78095
78930
|
`) + `
|
|
@@ -78185,12 +79020,12 @@ function isUnhealthy(server) {
|
|
|
78185
79020
|
}
|
|
78186
79021
|
function renderServerList(servers) {
|
|
78187
79022
|
if (servers.length === 0) {
|
|
78188
|
-
return
|
|
79023
|
+
return import_picocolors51.default.dim("No MCP servers configured for this agent.") + `
|
|
78189
79024
|
`;
|
|
78190
79025
|
}
|
|
78191
79026
|
const lines = [""];
|
|
78192
79027
|
for (const s3 of servers) {
|
|
78193
|
-
const mark = s3.auth === "oauth_expired" ?
|
|
79028
|
+
const mark = s3.auth === "oauth_expired" ? import_picocolors51.default.red("✗") : s3.auth === "oauth_required" || isUnhealthy(s3) ? import_picocolors51.default.yellow("!") : !s3.is_enabled ? import_picocolors51.default.dim("·") : import_picocolors51.default.green("✓");
|
|
78194
79029
|
const bits = [s3.transport];
|
|
78195
79030
|
if (!s3.is_enabled)
|
|
78196
79031
|
bits.push("disabled");
|
|
@@ -78203,10 +79038,10 @@ function renderServerList(servers) {
|
|
|
78203
79038
|
const expiry = describeExpiry(s3);
|
|
78204
79039
|
if (expiry)
|
|
78205
79040
|
bits.push(expiry);
|
|
78206
|
-
lines.push(` ${mark} ${
|
|
79041
|
+
lines.push(` ${mark} ${import_picocolors51.default.bold(s3.name)} ${import_picocolors51.default.dim(bits.join(" · "))}`);
|
|
78207
79042
|
}
|
|
78208
79043
|
if (servers.some((s3) => s3.auth === "oauth_required" || s3.auth === "oauth_expired")) {
|
|
78209
|
-
lines.push("",
|
|
79044
|
+
lines.push("", import_picocolors51.default.dim("Authorize OAuth-backed servers in the web app; the CLI cannot run that flow yet."));
|
|
78210
79045
|
}
|
|
78211
79046
|
lines.push("");
|
|
78212
79047
|
return lines.join(`
|
|
@@ -78249,7 +79084,7 @@ async function runMcp(cwd2, sub, _argv, options) {
|
|
|
78249
79084
|
}
|
|
78250
79085
|
|
|
78251
79086
|
// src/cli/task.ts
|
|
78252
|
-
var
|
|
79087
|
+
var import_picocolors52 = __toESM(require_picocolors(), 1);
|
|
78253
79088
|
|
|
78254
79089
|
// src/cli/task-create.ts
|
|
78255
79090
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
@@ -78435,25 +79270,25 @@ async function runTask(cwd2, sub, args) {
|
|
|
78435
79270
|
function printHelp4() {
|
|
78436
79271
|
const out = [];
|
|
78437
79272
|
out.push("");
|
|
78438
|
-
out.push(` ${
|
|
79273
|
+
out.push(` ${import_picocolors52.default.bold("brainbase task")} ${import_picocolors52.default.dim("<sub> [options]")}`);
|
|
78439
79274
|
out.push("");
|
|
78440
|
-
out.push(` ${
|
|
79275
|
+
out.push(` ${import_picocolors52.default.cyan("create")} ${import_picocolors52.default.dim("--message <text>")} ${import_picocolors52.default.dim("create a task and start its first run")}`);
|
|
78441
79276
|
out.push("");
|
|
78442
|
-
out.push(` ${
|
|
78443
|
-
out.push(` ${
|
|
78444
|
-
out.push(` ${
|
|
78445
|
-
out.push(` ${
|
|
78446
|
-
out.push(` ${
|
|
78447
|
-
out.push(` ${
|
|
79277
|
+
out.push(` ${import_picocolors52.default.bold("create flags")}`);
|
|
79278
|
+
out.push(` ${import_picocolors52.default.dim("--message <text>")} required first user message`);
|
|
79279
|
+
out.push(` ${import_picocolors52.default.dim("--agent <id>")} override the claimed agent in brainbase.agent.yaml`);
|
|
79280
|
+
out.push(` ${import_picocolors52.default.dim("--title <text>")} optional task title`);
|
|
79281
|
+
out.push(` ${import_picocolors52.default.dim("--model <id>")} optional model override`);
|
|
79282
|
+
out.push(` ${import_picocolors52.default.dim("--json")} print task_id, agent_id, and status as JSON`);
|
|
78448
79283
|
out.push("");
|
|
78449
|
-
out.push(` ${
|
|
79284
|
+
out.push(` ${import_picocolors52.default.dim("Flag-like values:")} use ${import_picocolors52.default.cyan("--flag=value")} or ${import_picocolors52.default.cyan("--flag -- <value>")}`);
|
|
78450
79285
|
out.push("");
|
|
78451
79286
|
console.log(out.join(`
|
|
78452
79287
|
`));
|
|
78453
79288
|
}
|
|
78454
79289
|
|
|
78455
79290
|
// src/cli/benchmark.ts
|
|
78456
|
-
var
|
|
79291
|
+
var import_picocolors53 = __toESM(require_picocolors(), 1);
|
|
78457
79292
|
import {
|
|
78458
79293
|
execFileSync as execFileSync3,
|
|
78459
79294
|
spawn as spawn5
|
|
@@ -78461,7 +79296,7 @@ import {
|
|
|
78461
79296
|
import crypto7 from "node:crypto";
|
|
78462
79297
|
import fs82 from "node:fs";
|
|
78463
79298
|
import os17 from "node:os";
|
|
78464
|
-
import
|
|
79299
|
+
import path90 from "node:path";
|
|
78465
79300
|
|
|
78466
79301
|
// src/core/benchmark-phase.ts
|
|
78467
79302
|
import {
|
|
@@ -78471,7 +79306,7 @@ import {
|
|
|
78471
79306
|
import crypto6 from "node:crypto";
|
|
78472
79307
|
import fs81 from "node:fs";
|
|
78473
79308
|
import os16 from "node:os";
|
|
78474
|
-
import
|
|
79309
|
+
import path89 from "node:path";
|
|
78475
79310
|
import { Readable, Transform as Transform2 } from "node:stream";
|
|
78476
79311
|
import { pipeline as pipeline2 } from "node:stream/promises";
|
|
78477
79312
|
import { createGunzip, createInflateRaw } from "node:zlib";
|
|
@@ -78515,7 +79350,7 @@ var BASE_ENV_NAMES = [
|
|
|
78515
79350
|
"USER"
|
|
78516
79351
|
];
|
|
78517
79352
|
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(
|
|
79353
|
+
var AbsolutePathSchema = exports_external.string().min(1).refine(path89.isAbsolute, {
|
|
78519
79354
|
message: "must be an absolute path"
|
|
78520
79355
|
});
|
|
78521
79356
|
var Sha256Schema = exports_external.string().regex(SHA256_RE).transform((value) => value.toLowerCase());
|
|
@@ -78933,35 +79768,35 @@ function normalizedRootRelative(input) {
|
|
|
78933
79768
|
return safeRelPath(input);
|
|
78934
79769
|
}
|
|
78935
79770
|
function isWithin(root, candidate) {
|
|
78936
|
-
const relative =
|
|
78937
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
79771
|
+
const relative = path89.relative(path89.resolve(root), path89.resolve(candidate));
|
|
79772
|
+
return relative === "" || !relative.startsWith("..") && !path89.isAbsolute(relative);
|
|
78938
79773
|
}
|
|
78939
79774
|
function canonicalFuturePath(input) {
|
|
78940
|
-
const resolved =
|
|
79775
|
+
const resolved = path89.resolve(input);
|
|
78941
79776
|
const suffix = [];
|
|
78942
79777
|
let current = resolved;
|
|
78943
79778
|
while (!fs81.existsSync(current)) {
|
|
78944
|
-
const parent =
|
|
79779
|
+
const parent = path89.dirname(current);
|
|
78945
79780
|
if (parent === current)
|
|
78946
79781
|
break;
|
|
78947
|
-
suffix.unshift(
|
|
79782
|
+
suffix.unshift(path89.basename(current));
|
|
78948
79783
|
current = parent;
|
|
78949
79784
|
}
|
|
78950
79785
|
const canonicalBase = fs81.realpathSync(current);
|
|
78951
|
-
return
|
|
79786
|
+
return path89.join(canonicalBase, ...suffix);
|
|
78952
79787
|
}
|
|
78953
79788
|
function validateRoots(spec) {
|
|
78954
|
-
const workspace =
|
|
79789
|
+
const workspace = path89.resolve(spec.workspace_root);
|
|
78955
79790
|
if (!fs81.existsSync(workspace) || fs81.lstatSync(workspace).isSymbolicLink() || !fs81.lstatSync(workspace).isDirectory()) {
|
|
78956
79791
|
throw new BenchmarkPhaseError("invalid_workspace_root", "workspace_root must be an existing real directory");
|
|
78957
79792
|
}
|
|
78958
79793
|
const canonicalWorkspace = canonicalFuturePath(workspace);
|
|
78959
|
-
const staging =
|
|
78960
|
-
const expectedStaging =
|
|
79794
|
+
const staging = path89.resolve(spec.staging_root);
|
|
79795
|
+
const expectedStaging = path89.join(workspace, ".brainbase", "benchmark", spec.attempt_id, "incoming");
|
|
78961
79796
|
if (staging !== expectedStaging) {
|
|
78962
79797
|
throw new BenchmarkPhaseError("invalid_staging_root", `staging_root must be ${expectedStaging}`);
|
|
78963
79798
|
}
|
|
78964
|
-
if (!fs81.existsSync(staging) || fs81.lstatSync(staging).isSymbolicLink() || !fs81.lstatSync(staging).isDirectory() || fs81.realpathSync(staging) !==
|
|
79799
|
+
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
79800
|
throw new BenchmarkPhaseError("invalid_staging_root", "staging_root must be a real directory under workspace_root");
|
|
78966
79801
|
}
|
|
78967
79802
|
const canonicalLogs = validateExternalRoot("logs_root", spec.logs_root, canonicalWorkspace);
|
|
@@ -78973,8 +79808,8 @@ function validateRoots(spec) {
|
|
|
78973
79808
|
}
|
|
78974
79809
|
}
|
|
78975
79810
|
function validateExternalRoot(label, input, canonicalWorkspace) {
|
|
78976
|
-
const candidate =
|
|
78977
|
-
if (candidate ===
|
|
79811
|
+
const candidate = path89.resolve(input);
|
|
79812
|
+
if (candidate === path89.parse(candidate).root) {
|
|
78978
79813
|
throw new BenchmarkPhaseError(`invalid_${label}`, `${label} cannot be a filesystem root`);
|
|
78979
79814
|
}
|
|
78980
79815
|
if (fs81.existsSync(candidate) && fs81.lstatSync(candidate).isSymbolicLink()) {
|
|
@@ -79004,9 +79839,9 @@ function assertNoSymlinkTraversal(root, relative) {
|
|
|
79004
79839
|
const rel = normalizedRootRelative(relative);
|
|
79005
79840
|
if (rel === ".")
|
|
79006
79841
|
return;
|
|
79007
|
-
let current =
|
|
79842
|
+
let current = path89.resolve(root);
|
|
79008
79843
|
for (const segment of rel.split("/").slice(0, -1)) {
|
|
79009
|
-
current =
|
|
79844
|
+
current = path89.join(current, segment);
|
|
79010
79845
|
if (!fs81.existsSync(current))
|
|
79011
79846
|
continue;
|
|
79012
79847
|
if (fs81.lstatSync(current).isSymbolicLink()) {
|
|
@@ -79075,10 +79910,10 @@ function assertWritableDestination(root, relative) {
|
|
|
79075
79910
|
const rel = normalizedRootRelative(relative);
|
|
79076
79911
|
if (rel === ".")
|
|
79077
79912
|
return;
|
|
79078
|
-
let current =
|
|
79913
|
+
let current = path89.resolve(root);
|
|
79079
79914
|
const segments = rel.split("/");
|
|
79080
79915
|
for (const segment of segments.slice(0, -1)) {
|
|
79081
|
-
current =
|
|
79916
|
+
current = path89.join(current, segment);
|
|
79082
79917
|
if (!fs81.existsSync(current))
|
|
79083
79918
|
continue;
|
|
79084
79919
|
const stat = fs81.lstatSync(current);
|
|
@@ -79089,7 +79924,7 @@ function assertWritableDestination(root, relative) {
|
|
|
79089
79924
|
throw new BenchmarkPhaseError("destination_conflict", `destination parent is not a directory: ${relative}`);
|
|
79090
79925
|
}
|
|
79091
79926
|
}
|
|
79092
|
-
const destination =
|
|
79927
|
+
const destination = path89.resolve(root, rel);
|
|
79093
79928
|
if (fs81.existsSync(destination) && fs81.lstatSync(destination).isDirectory()) {
|
|
79094
79929
|
throw new BenchmarkPhaseError("destination_conflict", `file destination is an existing directory: ${relative}`);
|
|
79095
79930
|
}
|
|
@@ -79115,7 +79950,7 @@ function validateDestinationGraph(paths) {
|
|
|
79115
79950
|
}
|
|
79116
79951
|
function sourcePath(stagingRoot, relative) {
|
|
79117
79952
|
const rel = safeRelPath(relative);
|
|
79118
|
-
const source =
|
|
79953
|
+
const source = path89.resolve(stagingRoot, rel);
|
|
79119
79954
|
if (!isWithin(stagingRoot, source)) {
|
|
79120
79955
|
throw new BenchmarkPhaseError("unsafe_path", `source escapes staging root: ${relative}`);
|
|
79121
79956
|
}
|
|
@@ -79150,7 +79985,7 @@ async function verifyRecordsUnchanged(records, spec) {
|
|
|
79150
79985
|
}
|
|
79151
79986
|
const relative = safeRelPath(record3.path);
|
|
79152
79987
|
assertNoSymlinkTraversal(root, relative);
|
|
79153
|
-
const candidate =
|
|
79988
|
+
const candidate = path89.resolve(root, relative);
|
|
79154
79989
|
if (!isWithin(root, candidate)) {
|
|
79155
79990
|
throw new BenchmarkPhaseError("evidence_tampered", `evidence was removed during evaluation: ${record3.root}:${record3.path}`);
|
|
79156
79991
|
}
|
|
@@ -79220,7 +80055,7 @@ async function cachedVerifiedInput(stagingRoot, input, context) {
|
|
|
79220
80055
|
function stagedInputRecord(stagingRoot, verified) {
|
|
79221
80056
|
return {
|
|
79222
80057
|
root: "staging",
|
|
79223
|
-
path:
|
|
80058
|
+
path: path89.relative(stagingRoot, verified.source).replace(/\\/g, "/"),
|
|
79224
80059
|
sha256: verified.sha256,
|
|
79225
80060
|
size: verified.size,
|
|
79226
80061
|
mode: verified.mode,
|
|
@@ -79241,7 +80076,7 @@ function removeRemoteHydrationInputs(spec) {
|
|
|
79241
80076
|
if (!material.download_url_env || removedSources.has(material.source))
|
|
79242
80077
|
continue;
|
|
79243
80078
|
const relative = safeRelPath(material.source);
|
|
79244
|
-
const source =
|
|
80079
|
+
const source = path89.resolve(spec.staging_root, relative);
|
|
79245
80080
|
if (!isWithin(spec.staging_root, source)) {
|
|
79246
80081
|
throw new BenchmarkPhaseError("unsafe_path", `source escapes staging root: ${material.source}`);
|
|
79247
80082
|
}
|
|
@@ -79273,7 +80108,7 @@ async function downloadInputReference(stagingRoot, input, context) {
|
|
|
79273
80108
|
return await cachedVerifiedInput(stagingRoot, input, context);
|
|
79274
80109
|
}
|
|
79275
80110
|
const relative = safeRelPath(input.source);
|
|
79276
|
-
const destination =
|
|
80111
|
+
const destination = path89.resolve(stagingRoot, relative);
|
|
79277
80112
|
if (!isWithin(stagingRoot, destination)) {
|
|
79278
80113
|
throw new BenchmarkPhaseError("unsafe_path", `source escapes staging root: ${input.source}`);
|
|
79279
80114
|
}
|
|
@@ -79302,7 +80137,7 @@ async function downloadInputReference(stagingRoot, input, context) {
|
|
|
79302
80137
|
if (remainingMs <= 0) {
|
|
79303
80138
|
throw new BenchmarkPhaseError("phase_timeout", "phase budget expired");
|
|
79304
80139
|
}
|
|
79305
|
-
fs81.mkdirSync(
|
|
80140
|
+
fs81.mkdirSync(path89.dirname(destination), { recursive: true, mode: 448 });
|
|
79306
80141
|
assertNoSymlinkTraversal(stagingRoot, relative);
|
|
79307
80142
|
assertWritableDestination(stagingRoot, relative);
|
|
79308
80143
|
const temporary = `${destination}.${process.pid}.${crypto6.randomBytes(6).toString("hex")}.download`;
|
|
@@ -79521,7 +80356,7 @@ function findZipMembers(archivePath, requested, context) {
|
|
|
79521
80356
|
}
|
|
79522
80357
|
}
|
|
79523
80358
|
async function writeVerifiedArchiveMember(source, destination, material, context) {
|
|
79524
|
-
fs81.mkdirSync(
|
|
80359
|
+
fs81.mkdirSync(path89.dirname(destination), { recursive: true, mode: 448 });
|
|
79525
80360
|
const temporary = `${destination}.${process.pid}.${crypto6.randomBytes(6).toString("hex")}.tmp`;
|
|
79526
80361
|
const descriptor = fs81.openSync(temporary, "wx", 384);
|
|
79527
80362
|
const hash = crypto6.createHash("sha256");
|
|
@@ -79636,7 +80471,7 @@ async function extractArchiveMembers(archivePath, outputRoot, materials, context
|
|
|
79636
80471
|
const indexed = findZipMembers(archivePath, requested, context);
|
|
79637
80472
|
for (const [memberPath, material] of requested) {
|
|
79638
80473
|
assertBudget(context);
|
|
79639
|
-
const destination =
|
|
80474
|
+
const destination = path89.resolve(outputRoot, memberPath);
|
|
79640
80475
|
if (!isWithin(outputRoot, destination)) {
|
|
79641
80476
|
throw new BenchmarkPhaseError("unsafe_path", `archive member escapes output root: ${memberPath}`);
|
|
79642
80477
|
}
|
|
@@ -79712,7 +80547,7 @@ async function extractArchiveMembers(archivePath, outputRoot, materials, context
|
|
|
79712
80547
|
return extracted;
|
|
79713
80548
|
}
|
|
79714
80549
|
async function atomicCopy(source, destination, mode, sourceRoot) {
|
|
79715
|
-
fs81.mkdirSync(
|
|
80550
|
+
fs81.mkdirSync(path89.dirname(destination), { recursive: true });
|
|
79716
80551
|
const temporary = `${destination}.${process.pid}.${crypto6.randomBytes(6).toString("hex")}.tmp`;
|
|
79717
80552
|
const opened = openRegularFileNoFollow(source, `copy source ${source}`, sourceRoot);
|
|
79718
80553
|
try {
|
|
@@ -79732,7 +80567,7 @@ async function atomicCopy(source, destination, mode, sourceRoot) {
|
|
|
79732
80567
|
}
|
|
79733
80568
|
}
|
|
79734
80569
|
async function recordFile(root, filePath, rootName, kind = "file") {
|
|
79735
|
-
const relative =
|
|
80570
|
+
const relative = path89.relative(root, filePath).replace(/\\/g, "/");
|
|
79736
80571
|
if (kind === "symlink") {
|
|
79737
80572
|
const stat = fs81.lstatSync(filePath);
|
|
79738
80573
|
const target = fs81.readlinkSync(filePath);
|
|
@@ -79773,11 +80608,11 @@ async function copyMaterial(material, sourceRoot, destinationRoot, destinationRo
|
|
|
79773
80608
|
throw new BenchmarkPhaseError("unsafe_path", "file destination cannot be a directory root");
|
|
79774
80609
|
}
|
|
79775
80610
|
assertWritableDestination(destinationRoot, destinationRel);
|
|
79776
|
-
const destination =
|
|
80611
|
+
const destination = path89.resolve(destinationRoot, destinationRel);
|
|
79777
80612
|
if (material.kind === "file") {
|
|
79778
80613
|
await atomicCopy(source, destination, material.mode ?? verifiedSource?.mode, sourceRoot);
|
|
79779
80614
|
} else {
|
|
79780
|
-
await atomicCopy(source, destination, material.mode,
|
|
80615
|
+
await atomicCopy(source, destination, material.mode, path89.dirname(source));
|
|
79781
80616
|
}
|
|
79782
80617
|
const record3 = await recordFile(destinationRoot, destination, destinationRootName);
|
|
79783
80618
|
const expectedSha256 = material.kind === "archive_file" ? material.file_sha256 : material.sha256;
|
|
@@ -79787,15 +80622,15 @@ async function copyMaterial(material, sourceRoot, destinationRoot, destinationRo
|
|
|
79787
80622
|
}
|
|
79788
80623
|
return [record3];
|
|
79789
80624
|
}
|
|
79790
|
-
const temporary = fs81.mkdtempSync(
|
|
80625
|
+
const temporary = fs81.mkdtempSync(path89.join(os16.tmpdir(), "brainbase-benchmark-"));
|
|
79791
80626
|
try {
|
|
79792
|
-
const verifiedArchive =
|
|
80627
|
+
const verifiedArchive = path89.join(temporary, "material.tar.gz");
|
|
79793
80628
|
await atomicCopy(source, verifiedArchive, 384, sourceRoot);
|
|
79794
80629
|
const archiveRecord = await recordFile(temporary, verifiedArchive, "staging");
|
|
79795
80630
|
if (archiveRecord.sha256 !== material.sha256 || archiveRecord.size !== material.size_bytes) {
|
|
79796
80631
|
throw new BenchmarkPhaseError("evidence_tampered", `material changed while it was copied: ${material.source}`);
|
|
79797
80632
|
}
|
|
79798
|
-
const extractedRoot =
|
|
80633
|
+
const extractedRoot = path89.join(temporary, "extracted");
|
|
79799
80634
|
const extracted = await extract({
|
|
79800
80635
|
tarFile: verifiedArchive,
|
|
79801
80636
|
outDir: extractedRoot,
|
|
@@ -79804,17 +80639,17 @@ async function copyMaterial(material, sourceRoot, destinationRoot, destinationRo
|
|
|
79804
80639
|
});
|
|
79805
80640
|
const outputs = [];
|
|
79806
80641
|
for (const extractedRel of extracted.sort()) {
|
|
79807
|
-
const sourceFile =
|
|
80642
|
+
const sourceFile = path89.resolve(extractedRoot, safeRelPath(extractedRel));
|
|
79808
80643
|
const stat = fs81.lstatSync(sourceFile);
|
|
79809
80644
|
if (!stat.isFile())
|
|
79810
80645
|
continue;
|
|
79811
|
-
const combined = destinationRel === "." ? safeRelPath(extractedRel) : safeRelPath(
|
|
80646
|
+
const combined = destinationRel === "." ? safeRelPath(extractedRel) : safeRelPath(path89.posix.join(destinationRel, extractedRel));
|
|
79812
80647
|
const checked = protectWorkspace ? workspaceRel(combined) : combined;
|
|
79813
80648
|
if (!protectWorkspace && checked.toLowerCase() === ".brainbase-benchmark-owner.json") {
|
|
79814
80649
|
throw new BenchmarkPhaseError("reserved_path", "benchmark input cannot replace the phase ownership marker");
|
|
79815
80650
|
}
|
|
79816
80651
|
assertWritableDestination(destinationRoot, checked);
|
|
79817
|
-
const destination =
|
|
80652
|
+
const destination = path89.resolve(destinationRoot, checked);
|
|
79818
80653
|
await atomicCopy(sourceFile, destination, material.mode, extractedRoot);
|
|
79819
80654
|
outputs.push(await recordFile(destinationRoot, destination, destinationRootName));
|
|
79820
80655
|
}
|
|
@@ -79838,7 +80673,7 @@ async function preflightMaterial(material, materials, sourceRoot, destinationRoo
|
|
|
79838
80673
|
const cacheKey = archiveMemberCacheKey(material);
|
|
79839
80674
|
let extracted = context.preparedArchiveFiles.get(cacheKey);
|
|
79840
80675
|
if (!extracted) {
|
|
79841
|
-
const temporary2 = fs81.mkdtempSync(
|
|
80676
|
+
const temporary2 = fs81.mkdtempSync(path89.join(os16.tmpdir(), "brainbase-benchmark-member-"));
|
|
79842
80677
|
context.temporaryRoots.add(temporary2);
|
|
79843
80678
|
const archiveKey = archiveSourceCacheKey(material);
|
|
79844
80679
|
const related = materials.filter((candidate) => candidate.kind === "archive_file" && archiveSourceCacheKey(candidate) === archiveKey);
|
|
@@ -79858,15 +80693,15 @@ async function preflightMaterial(material, materials, sourceRoot, destinationRoo
|
|
|
79858
80693
|
}
|
|
79859
80694
|
return [destinationRel];
|
|
79860
80695
|
}
|
|
79861
|
-
const temporary = fs81.mkdtempSync(
|
|
80696
|
+
const temporary = fs81.mkdtempSync(path89.join(os16.tmpdir(), "brainbase-benchmark-preflight-"));
|
|
79862
80697
|
try {
|
|
79863
|
-
const verifiedArchive =
|
|
80698
|
+
const verifiedArchive = path89.join(temporary, "material.tar.gz");
|
|
79864
80699
|
await atomicCopy(source, verifiedArchive, 384, sourceRoot);
|
|
79865
80700
|
const archiveRecord = await recordFile(temporary, verifiedArchive, "staging");
|
|
79866
80701
|
if (archiveRecord.sha256 !== material.sha256 || archiveRecord.size !== material.size_bytes) {
|
|
79867
80702
|
throw new BenchmarkPhaseError("evidence_tampered", `material changed while it was copied: ${material.source}`);
|
|
79868
80703
|
}
|
|
79869
|
-
const extractedRoot =
|
|
80704
|
+
const extractedRoot = path89.join(temporary, "extracted");
|
|
79870
80705
|
const extracted = await extract({
|
|
79871
80706
|
tarFile: verifiedArchive,
|
|
79872
80707
|
outDir: extractedRoot,
|
|
@@ -79875,7 +80710,7 @@ async function preflightMaterial(material, materials, sourceRoot, destinationRoo
|
|
|
79875
80710
|
});
|
|
79876
80711
|
const planned = [];
|
|
79877
80712
|
for (const extractedRel of extracted) {
|
|
79878
|
-
const combined = destinationRel === "." ? safeRelPath(extractedRel) : safeRelPath(
|
|
80713
|
+
const combined = destinationRel === "." ? safeRelPath(extractedRel) : safeRelPath(path89.posix.join(destinationRel, extractedRel));
|
|
79879
80714
|
const checked = protectWorkspace ? workspaceRel(combined) : combined;
|
|
79880
80715
|
if (!protectWorkspace && checked.toLowerCase() === ".brainbase-benchmark-owner.json") {
|
|
79881
80716
|
throw new BenchmarkPhaseError("reserved_path", "benchmark input cannot replace the phase ownership marker");
|
|
@@ -79889,7 +80724,7 @@ async function preflightMaterial(material, materials, sourceRoot, destinationRoo
|
|
|
79889
80724
|
}
|
|
79890
80725
|
}
|
|
79891
80726
|
function ownerMarker(root) {
|
|
79892
|
-
return
|
|
80727
|
+
return path89.join(root, ".brainbase-benchmark-owner.json");
|
|
79893
80728
|
}
|
|
79894
80729
|
function verifyOwnedDirectory(root, role, spec) {
|
|
79895
80730
|
if (!fs81.existsSync(root) || fs81.lstatSync(root).isSymbolicLink())
|
|
@@ -80027,7 +80862,7 @@ function markedProcessPids(marker) {
|
|
|
80027
80862
|
if (pid === process.pid)
|
|
80028
80863
|
continue;
|
|
80029
80864
|
try {
|
|
80030
|
-
const environment = fs81.readFileSync(
|
|
80865
|
+
const environment = fs81.readFileSync(path89.join("/proc", entry, "environ"), "utf8");
|
|
80031
80866
|
if (environment.split("\x00").includes(assignment))
|
|
80032
80867
|
matches2.push(pid);
|
|
80033
80868
|
} catch {}
|
|
@@ -80061,7 +80896,7 @@ function markedProcessPids(marker) {
|
|
|
80061
80896
|
function processExists(pid) {
|
|
80062
80897
|
if (process.platform === "linux") {
|
|
80063
80898
|
try {
|
|
80064
|
-
const stat = fs81.readFileSync(
|
|
80899
|
+
const stat = fs81.readFileSync(path89.join("/proc", String(pid), "stat"), "utf8");
|
|
80065
80900
|
const commandEnd = stat.lastIndexOf(")");
|
|
80066
80901
|
const state = commandEnd >= 0 ? stat.slice(commandEnd + 2, commandEnd + 3) : "";
|
|
80067
80902
|
if (state === "Z" || state === "X")
|
|
@@ -80105,7 +80940,7 @@ async function terminateCommandProcesses(child, marker, observedDescendants) {
|
|
|
80105
80940
|
async function runCommand(command, root, spec, context, options = {}) {
|
|
80106
80941
|
const cwdRel = normalizedRootRelative(command.cwd);
|
|
80107
80942
|
assertNoSymlinkTraversal(root, cwdRel);
|
|
80108
|
-
const cwd2 =
|
|
80943
|
+
const cwd2 = path89.resolve(root, cwdRel);
|
|
80109
80944
|
let cwdStat;
|
|
80110
80945
|
try {
|
|
80111
80946
|
cwdStat = fs81.lstatSync(cwd2);
|
|
@@ -80228,8 +81063,8 @@ async function runCommand(command, root, spec, context, options = {}) {
|
|
|
80228
81063
|
});
|
|
80229
81064
|
}
|
|
80230
81065
|
async function writeLog(root, name, data, spec) {
|
|
80231
|
-
const destination =
|
|
80232
|
-
fs81.mkdirSync(
|
|
81066
|
+
const destination = path89.join(root, name);
|
|
81067
|
+
fs81.mkdirSync(path89.dirname(destination), { recursive: true });
|
|
80233
81068
|
const temporary = `${destination}.${process.pid}.${crypto6.randomBytes(6).toString("hex")}.tmp`;
|
|
80234
81069
|
try {
|
|
80235
81070
|
fs81.writeFileSync(temporary, redactCommandOutput(data, spec), {
|
|
@@ -80243,7 +81078,7 @@ async function writeLog(root, name, data, spec) {
|
|
|
80243
81078
|
return await recordFile(root, destination, "logs");
|
|
80244
81079
|
}
|
|
80245
81080
|
function writeBufferAtomic(destination, data) {
|
|
80246
|
-
fs81.mkdirSync(
|
|
81081
|
+
fs81.mkdirSync(path89.dirname(destination), { recursive: true });
|
|
80247
81082
|
const temporary = `${destination}.${process.pid}.${crypto6.randomBytes(6).toString("hex")}.tmp`;
|
|
80248
81083
|
try {
|
|
80249
81084
|
fs81.writeFileSync(temporary, data, { flag: "wx", mode: 384 });
|
|
@@ -80343,7 +81178,7 @@ async function executeHydrate(spec, context) {
|
|
|
80343
81178
|
finalOutputs.push(output);
|
|
80344
81179
|
continue;
|
|
80345
81180
|
}
|
|
80346
|
-
const candidate =
|
|
81181
|
+
const candidate = path89.resolve(spec.workspace_root, safeRelPath(output.path));
|
|
80347
81182
|
assertNoSymlinkTraversal(spec.workspace_root, output.path);
|
|
80348
81183
|
if (!fs81.existsSync(candidate))
|
|
80349
81184
|
continue;
|
|
@@ -80374,7 +81209,7 @@ async function readEvidence(stagingRoot, evidence) {
|
|
|
80374
81209
|
buffer,
|
|
80375
81210
|
record: {
|
|
80376
81211
|
root: "staging",
|
|
80377
|
-
path:
|
|
81212
|
+
path: path89.relative(stagingRoot, filePath).replace(/\\/g, "/"),
|
|
80378
81213
|
sha256: evidence.sha256,
|
|
80379
81214
|
size: opened.stat.size,
|
|
80380
81215
|
mode: opened.stat.mode & 511
|
|
@@ -80387,14 +81222,14 @@ async function readEvidence(stagingRoot, evidence) {
|
|
|
80387
81222
|
async function workspaceManifest(spec, context) {
|
|
80388
81223
|
const records = [];
|
|
80389
81224
|
let totalBytes = 0;
|
|
80390
|
-
const stack = [
|
|
81225
|
+
const stack = [path89.resolve(spec.workspace_root)];
|
|
80391
81226
|
while (stack.length > 0) {
|
|
80392
81227
|
const directory = stack.pop();
|
|
80393
81228
|
const entries = fs81.readdirSync(directory, { withFileTypes: true }).sort((a3, b4) => a3.name.localeCompare(b4.name));
|
|
80394
81229
|
for (const entry of entries) {
|
|
80395
81230
|
assertBudget(context);
|
|
80396
|
-
const full =
|
|
80397
|
-
const relative =
|
|
81231
|
+
const full = path89.join(directory, entry.name);
|
|
81232
|
+
const relative = path89.relative(spec.workspace_root, full).replace(/\\/g, "/");
|
|
80398
81233
|
if (relative === ".brainbase" || relative.startsWith(".brainbase/"))
|
|
80399
81234
|
continue;
|
|
80400
81235
|
if (relative === ".git" || relative.startsWith(".git/"))
|
|
@@ -80427,13 +81262,13 @@ async function verifyWorkspaceManifestUnchanged(expected, spec, context) {
|
|
|
80427
81262
|
}
|
|
80428
81263
|
function treeBytes(root, context) {
|
|
80429
81264
|
let totalBytes = 0;
|
|
80430
|
-
const stack = [
|
|
81265
|
+
const stack = [path89.resolve(root)];
|
|
80431
81266
|
while (stack.length > 0) {
|
|
80432
81267
|
const directory = stack.pop();
|
|
80433
81268
|
const entries = fs81.readdirSync(directory, { withFileTypes: true });
|
|
80434
81269
|
for (const entry of entries) {
|
|
80435
81270
|
assertBudget(context);
|
|
80436
|
-
const candidate =
|
|
81271
|
+
const candidate = path89.join(directory, entry.name);
|
|
80437
81272
|
const stat = fs81.lstatSync(candidate);
|
|
80438
81273
|
if (stat.isDirectory()) {
|
|
80439
81274
|
stack.push(candidate);
|
|
@@ -80447,7 +81282,7 @@ function treeBytes(root, context) {
|
|
|
80447
81282
|
totalBytes += Buffer.byteLength(fs81.readlinkSync(candidate));
|
|
80448
81283
|
continue;
|
|
80449
81284
|
}
|
|
80450
|
-
throw new BenchmarkPhaseError("unsafe_path", `evaluate output contains an unsupported filesystem entry: ${
|
|
81285
|
+
throw new BenchmarkPhaseError("unsafe_path", `evaluate output contains an unsupported filesystem entry: ${path89.relative(root, candidate)}`);
|
|
80451
81286
|
}
|
|
80452
81287
|
}
|
|
80453
81288
|
return totalBytes;
|
|
@@ -80493,11 +81328,11 @@ function manifestDirectories(manifest, context) {
|
|
|
80493
81328
|
assertBudget(context);
|
|
80494
81329
|
if (entry.kind === "symlink")
|
|
80495
81330
|
continue;
|
|
80496
|
-
let current =
|
|
81331
|
+
let current = path89.posix.dirname(entry.path);
|
|
80497
81332
|
while (current !== ".") {
|
|
80498
81333
|
assertBudget(context);
|
|
80499
81334
|
directories.add(current);
|
|
80500
|
-
current =
|
|
81335
|
+
current = path89.posix.dirname(current);
|
|
80501
81336
|
}
|
|
80502
81337
|
}
|
|
80503
81338
|
return [...directories].sort();
|
|
@@ -80566,8 +81401,8 @@ async function copyCandidateOutput(output, manifest, spec, context) {
|
|
|
80566
81401
|
const copied = [];
|
|
80567
81402
|
for (const frozenFile of selected.files) {
|
|
80568
81403
|
assertBudget(context);
|
|
80569
|
-
const source =
|
|
80570
|
-
const destination =
|
|
81404
|
+
const source = path89.resolve(spec.workspace_root, safeRelPath(frozenFile.path));
|
|
81405
|
+
const destination = path89.resolve(spec.logs_root, "candidate-outputs", output.id, safeRelPath(frozenFile.path));
|
|
80571
81406
|
if (fs81.existsSync(destination)) {
|
|
80572
81407
|
throw new BenchmarkPhaseError("destination_conflict", `candidate output destination already exists: ${output.id}/${frozenFile.path}`);
|
|
80573
81408
|
}
|
|
@@ -80581,24 +81416,24 @@ async function copyCandidateOutput(output, manifest, spec, context) {
|
|
|
80581
81416
|
return copied;
|
|
80582
81417
|
}
|
|
80583
81418
|
async function copyFrozenWorkspace(manifest, spec, context, sourceRoot = spec.workspace_root, symlinkPolicy = "preserve") {
|
|
80584
|
-
const destinationRoot = fs81.mkdtempSync(
|
|
81419
|
+
const destinationRoot = fs81.mkdtempSync(path89.join(os16.tmpdir(), "brainbase-benchmark-workspace-"));
|
|
80585
81420
|
fs81.chmodSync(destinationRoot, 448);
|
|
80586
81421
|
context.temporaryRoots.add(destinationRoot);
|
|
80587
81422
|
for (const frozenFile of manifest) {
|
|
80588
81423
|
assertBudget(context);
|
|
80589
|
-
const source =
|
|
80590
|
-
const destination =
|
|
81424
|
+
const source = path89.resolve(sourceRoot, safeRelPath(frozenFile.path));
|
|
81425
|
+
const destination = path89.resolve(destinationRoot, safeRelPath(frozenFile.path));
|
|
80591
81426
|
if (frozenFile.kind === "symlink") {
|
|
80592
81427
|
const stat = fs81.lstatSync(source);
|
|
80593
81428
|
const target = stat.isSymbolicLink() ? fs81.readlinkSync(source) : null;
|
|
80594
81429
|
if (target === null || Buffer.byteLength(target) !== frozenFile.size || sha256(target) !== frozenFile.sha256) {
|
|
80595
81430
|
throw new BenchmarkPhaseError("evidence_tampered", `workspace changed after it was frozen: ${frozenFile.path}`);
|
|
80596
81431
|
}
|
|
80597
|
-
const resolvedTarget =
|
|
80598
|
-
if (symlinkPolicy === "contained_relative_only" && (
|
|
81432
|
+
const resolvedTarget = path89.resolve(path89.dirname(source), target);
|
|
81433
|
+
if (symlinkPolicy === "contained_relative_only" && (path89.isAbsolute(target) || !isWithin(sourceRoot, resolvedTarget))) {
|
|
80599
81434
|
continue;
|
|
80600
81435
|
}
|
|
80601
|
-
fs81.mkdirSync(
|
|
81436
|
+
fs81.mkdirSync(path89.dirname(destination), { recursive: true, mode: 448 });
|
|
80602
81437
|
fs81.symlinkSync(target, destination);
|
|
80603
81438
|
continue;
|
|
80604
81439
|
}
|
|
@@ -80611,12 +81446,12 @@ async function copyFrozenWorkspace(manifest, spec, context, sourceRoot = spec.wo
|
|
|
80611
81446
|
return destinationRoot;
|
|
80612
81447
|
}
|
|
80613
81448
|
async function copyEvaluatorTests(spec, evaluator, context) {
|
|
80614
|
-
const destinationRoot = fs81.mkdtempSync(
|
|
81449
|
+
const destinationRoot = fs81.mkdtempSync(path89.join(os16.tmpdir(), "brainbase-benchmark-tests-"));
|
|
80615
81450
|
fs81.chmodSync(destinationRoot, 448);
|
|
80616
81451
|
context.temporaryRoots.add(destinationRoot);
|
|
80617
81452
|
const sourceRoot = evaluatorTestsPath(evaluator, spec.tests_root);
|
|
80618
81453
|
const relativeRoot = evaluator.tests_path ? normalizedRootRelative(evaluator.tests_path) : ".";
|
|
80619
|
-
const destinationStart = relativeRoot === "." ? destinationRoot :
|
|
81454
|
+
const destinationStart = relativeRoot === "." ? destinationRoot : path89.resolve(destinationRoot, relativeRoot);
|
|
80620
81455
|
fs81.mkdirSync(destinationStart, { recursive: true, mode: 448 });
|
|
80621
81456
|
const stack = [{ source: sourceRoot, destination: destinationStart }];
|
|
80622
81457
|
while (stack.length > 0) {
|
|
@@ -80625,11 +81460,11 @@ async function copyEvaluatorTests(spec, evaluator, context) {
|
|
|
80625
81460
|
const entries = fs81.readdirSync(current.source, { withFileTypes: true }).sort((left, right) => left.name.localeCompare(right.name));
|
|
80626
81461
|
for (const entry of entries) {
|
|
80627
81462
|
assertBudget(context);
|
|
80628
|
-
const source =
|
|
80629
|
-
const destination =
|
|
81463
|
+
const source = path89.join(current.source, entry.name);
|
|
81464
|
+
const destination = path89.join(current.destination, entry.name);
|
|
80630
81465
|
const stat = fs81.lstatSync(source);
|
|
80631
81466
|
if (stat.isSymbolicLink()) {
|
|
80632
|
-
throw new BenchmarkPhaseError("unsafe_path", `evaluator reference tree contains a symlink: ${
|
|
81467
|
+
throw new BenchmarkPhaseError("unsafe_path", `evaluator reference tree contains a symlink: ${path89.relative(spec.tests_root, source)}`);
|
|
80633
81468
|
}
|
|
80634
81469
|
if (stat.isDirectory()) {
|
|
80635
81470
|
fs81.mkdirSync(destination, { recursive: true, mode: stat.mode & 511 });
|
|
@@ -80637,7 +81472,7 @@ async function copyEvaluatorTests(spec, evaluator, context) {
|
|
|
80637
81472
|
continue;
|
|
80638
81473
|
}
|
|
80639
81474
|
if (!stat.isFile()) {
|
|
80640
|
-
throw new BenchmarkPhaseError("unsafe_path", `evaluator reference tree contains an unsupported filesystem entry: ${
|
|
81475
|
+
throw new BenchmarkPhaseError("unsafe_path", `evaluator reference tree contains an unsupported filesystem entry: ${path89.relative(spec.tests_root, source)}`);
|
|
80641
81476
|
}
|
|
80642
81477
|
await atomicCopy(source, destination, stat.mode & 511, spec.tests_root);
|
|
80643
81478
|
const sourceRecord = await recordFile(spec.tests_root, source, "tests");
|
|
@@ -80654,7 +81489,7 @@ function evaluatorTestsPath(evaluator, testsRoot) {
|
|
|
80654
81489
|
return testsRoot;
|
|
80655
81490
|
const relative = normalizedRootRelative(evaluator.tests_path);
|
|
80656
81491
|
assertNoSymlinkTraversal(testsRoot, relative);
|
|
80657
|
-
const candidate =
|
|
81492
|
+
const candidate = path89.resolve(testsRoot, relative);
|
|
80658
81493
|
if (!isWithin(testsRoot, candidate) || !fs81.existsSync(candidate)) {
|
|
80659
81494
|
throw new BenchmarkPhaseError("invalid_tests_path", `evaluator tests_path does not exist: ${evaluator.tests_path}`);
|
|
80660
81495
|
}
|
|
@@ -80715,7 +81550,7 @@ function structuredJudgeError(stderr) {
|
|
|
80715
81550
|
function readCriterionResults(resultPath, criterionKeys, allowedEvidenceIds, spec, additionalSecrets = []) {
|
|
80716
81551
|
let opened;
|
|
80717
81552
|
try {
|
|
80718
|
-
opened = openRegularFileNoFollow(resultPath, "criterion result",
|
|
81553
|
+
opened = openRegularFileNoFollow(resultPath, "criterion result", path89.dirname(resultPath));
|
|
80719
81554
|
} catch (error2) {
|
|
80720
81555
|
if (error2.code === "ENOENT") {
|
|
80721
81556
|
throw new BenchmarkPhaseError("missing_criterion_result", "sandbox evaluator did not write its criterion result");
|
|
@@ -80862,7 +81697,7 @@ async function evaluateOne(evaluator, spec, manifest, frozenWorkspaceRoot, final
|
|
|
80862
81697
|
if (evaluator.type === "workspace_assertion") {
|
|
80863
81698
|
const relative = workspaceRel(evaluator.path);
|
|
80864
81699
|
assertNoSymlinkTraversal(frozenWorkspaceRoot, relative);
|
|
80865
|
-
const candidate =
|
|
81700
|
+
const candidate = path89.resolve(frozenWorkspaceRoot, relative);
|
|
80866
81701
|
let stat = null;
|
|
80867
81702
|
try {
|
|
80868
81703
|
stat = fs81.lstatSync(candidate);
|
|
@@ -80942,10 +81777,10 @@ async function evaluateOne(evaluator, spec, manifest, frozenWorkspaceRoot, final
|
|
|
80942
81777
|
};
|
|
80943
81778
|
let criterionResultPath;
|
|
80944
81779
|
if (evaluator.criterion_keys) {
|
|
80945
|
-
privateResultRoot = fs81.mkdtempSync(
|
|
81780
|
+
privateResultRoot = fs81.mkdtempSync(path89.join(os16.tmpdir(), "brainbase-benchmark-criteria-"));
|
|
80946
81781
|
fs81.chmodSync(privateResultRoot, 448);
|
|
80947
81782
|
context.temporaryRoots.add(privateResultRoot);
|
|
80948
|
-
criterionResultPath =
|
|
81783
|
+
criterionResultPath = path89.join(privateResultRoot, "result.json");
|
|
80949
81784
|
environment.BRAINBASE_BENCHMARK_CRITERIA_RESULT = criterionResultPath;
|
|
80950
81785
|
}
|
|
80951
81786
|
const result2 = await runCommand(command, commandRoot, spec, context, {
|
|
@@ -81036,8 +81871,8 @@ async function executeEvaluate(spec, context) {
|
|
|
81036
81871
|
context.logsOwned = true;
|
|
81037
81872
|
validateRoots(spec);
|
|
81038
81873
|
const outputs = [];
|
|
81039
|
-
const finalOutputPath =
|
|
81040
|
-
const trajectoryPath =
|
|
81874
|
+
const finalOutputPath = path89.join(spec.logs_root, "candidate-evidence", "final-output");
|
|
81875
|
+
const trajectoryPath = path89.join(spec.logs_root, "candidate-evidence", "trajectory.json");
|
|
81041
81876
|
writeBufferAtomic(finalOutputPath, finalOutput.buffer);
|
|
81042
81877
|
writeBufferAtomic(trajectoryPath, trajectoryEvidence.buffer);
|
|
81043
81878
|
const frozenEvidenceRecords = [
|
|
@@ -81049,7 +81884,7 @@ async function executeEvaluate(spec, context) {
|
|
|
81049
81884
|
assertEvaluateOutputBudget(spec, context);
|
|
81050
81885
|
assertBudget(context);
|
|
81051
81886
|
const manifest = await workspaceManifest(spec, context);
|
|
81052
|
-
const manifestPath2 =
|
|
81887
|
+
const manifestPath2 = path89.join(spec.logs_root, "candidate-workspace-manifest.json");
|
|
81053
81888
|
writeJsonAtomic(manifestPath2, {
|
|
81054
81889
|
schema_version: SCHEMA_VERSION,
|
|
81055
81890
|
attempt_id: spec.attempt_id,
|
|
@@ -81063,12 +81898,12 @@ async function executeEvaluate(spec, context) {
|
|
|
81063
81898
|
for (const artifactRelInput of spec.candidate_artifacts) {
|
|
81064
81899
|
const artifactRel = workspaceRel(artifactRelInput);
|
|
81065
81900
|
assertNoSymlinkTraversal(spec.workspace_root, artifactRel);
|
|
81066
|
-
const source =
|
|
81901
|
+
const source = path89.resolve(spec.workspace_root, artifactRel);
|
|
81067
81902
|
const frozenArtifact = manifest.find((entry) => entry.path === artifactRel && entry.kind !== "symlink");
|
|
81068
81903
|
if (!frozenArtifact || !fs81.existsSync(source) || !fs81.lstatSync(source).isFile()) {
|
|
81069
81904
|
throw new BenchmarkPhaseError("missing_artifact", `candidate artifact is missing: ${artifactRel}`);
|
|
81070
81905
|
}
|
|
81071
|
-
const destination =
|
|
81906
|
+
const destination = path89.resolve(spec.logs_root, "candidate-artifacts", artifactRel);
|
|
81072
81907
|
await atomicCopy(source, destination, undefined, spec.workspace_root);
|
|
81073
81908
|
const artifact = await recordFile(spec.logs_root, destination, "logs");
|
|
81074
81909
|
if (artifact.sha256 !== frozenArtifact.sha256 || artifact.size !== frozenArtifact.size || artifact.mode !== frozenArtifact.mode) {
|
|
@@ -81086,7 +81921,7 @@ async function executeEvaluate(spec, context) {
|
|
|
81086
81921
|
assertEvaluateOutputBudget(spec, context);
|
|
81087
81922
|
if (spec.capture_workspace_archive) {
|
|
81088
81923
|
const regularFiles = manifest.filter((entry) => entry.kind !== "symlink").map((entry) => entry.path);
|
|
81089
|
-
const archive =
|
|
81924
|
+
const archive = path89.join(spec.logs_root, "candidate-workspace.tar.gz");
|
|
81090
81925
|
const temporary = `${archive}.${process.pid}.${crypto6.randomBytes(6).toString("hex")}.tmp`;
|
|
81091
81926
|
try {
|
|
81092
81927
|
await pack({ rootDir: spec.workspace_root, outFile: temporary, files: regularFiles });
|
|
@@ -81273,7 +82108,7 @@ function rawIdentity(value) {
|
|
|
81273
82108
|
};
|
|
81274
82109
|
}
|
|
81275
82110
|
function readSpecBytes(specPathInput) {
|
|
81276
|
-
const specPath =
|
|
82111
|
+
const specPath = path89.resolve(specPathInput);
|
|
81277
82112
|
const noFollow = typeof fs81.constants.O_NOFOLLOW === "number" ? fs81.constants.O_NOFOLLOW : 0;
|
|
81278
82113
|
let fd;
|
|
81279
82114
|
try {
|
|
@@ -81304,8 +82139,8 @@ function validateBenchmarkInvocationBytes(bytes, resultPathInput, expectedPhase)
|
|
|
81304
82139
|
throw new BenchmarkPhaseError("phase_mismatch", `the ${expectedPhase} command cannot execute a ${spec.phase} spec`);
|
|
81305
82140
|
}
|
|
81306
82141
|
validateRoots(spec);
|
|
81307
|
-
const resultPath =
|
|
81308
|
-
const expectedResultPath =
|
|
82142
|
+
const resultPath = path89.resolve(resultPathInput);
|
|
82143
|
+
const expectedResultPath = path89.join(path89.resolve(spec.logs_root), "result.json");
|
|
81309
82144
|
if (resultPath !== expectedResultPath) {
|
|
81310
82145
|
throw new BenchmarkPhaseError("invalid_result_path", `result path must be ${expectedResultPath}`);
|
|
81311
82146
|
}
|
|
@@ -81405,7 +82240,7 @@ function writeBenchmarkPhaseTimeoutResult(specBytes, resultPathInput, expectedPh
|
|
|
81405
82240
|
async function runBenchmarkPhase(specPathInput, resultPathInput, expectedPhase, immutableSpecBytes) {
|
|
81406
82241
|
const startedAt = nowIso();
|
|
81407
82242
|
const started = Date.now();
|
|
81408
|
-
const resultPath =
|
|
82243
|
+
const resultPath = path89.resolve(resultPathInput);
|
|
81409
82244
|
let raw = undefined;
|
|
81410
82245
|
let digest = null;
|
|
81411
82246
|
let identity2 = rawIdentity(raw);
|
|
@@ -81441,7 +82276,7 @@ async function runBenchmarkPhase(specPathInput, resultPathInput, expectedPhase,
|
|
|
81441
82276
|
throw new BenchmarkPhaseError("phase_mismatch", `the ${expectedPhase} command cannot execute a ${spec.phase} spec`);
|
|
81442
82277
|
}
|
|
81443
82278
|
validateRoots(spec);
|
|
81444
|
-
const expectedResultPath =
|
|
82279
|
+
const expectedResultPath = path89.join(path89.resolve(spec.logs_root), "result.json");
|
|
81445
82280
|
if (resultPath !== expectedResultPath) {
|
|
81446
82281
|
throw new BenchmarkPhaseError("invalid_result_path", `result path must be ${expectedResultPath}`);
|
|
81447
82282
|
}
|
|
@@ -81669,7 +82504,7 @@ function terminatePhase(child) {
|
|
|
81669
82504
|
}
|
|
81670
82505
|
}
|
|
81671
82506
|
function createAnonymousSpecFd(bytes) {
|
|
81672
|
-
const temporary =
|
|
82507
|
+
const temporary = path90.join(os17.tmpdir(), `brainbase-benchmark-spec-${process.pid}-${crypto7.randomBytes(12).toString("hex")}`);
|
|
81673
82508
|
fs82.writeFileSync(temporary, bytes, { flag: "wx", mode: 384 });
|
|
81674
82509
|
try {
|
|
81675
82510
|
const fd = fs82.openSync(temporary, "r");
|
|
@@ -81873,13 +82708,13 @@ async function runBenchmark(sub, args, write = (value) => process.stdout.write(v
|
|
|
81873
82708
|
function printHelp5() {
|
|
81874
82709
|
const out = [];
|
|
81875
82710
|
out.push("");
|
|
81876
|
-
out.push(` ${
|
|
82711
|
+
out.push(` ${import_picocolors53.default.bold("brainbase benchmark")} ${import_picocolors53.default.dim("<sub> [options]")}`);
|
|
81877
82712
|
out.push("");
|
|
81878
|
-
out.push(` ${
|
|
81879
|
-
out.push(` ${
|
|
81880
|
-
out.push(` ${
|
|
82713
|
+
out.push(` ${import_picocolors53.default.cyan("hydrate")} ${import_picocolors53.default.dim("--spec <path> --result <path> --json")}`);
|
|
82714
|
+
out.push(` ${import_picocolors53.default.cyan("evaluate")} ${import_picocolors53.default.dim("--spec <path> --result <path> --json")}`);
|
|
82715
|
+
out.push(` ${import_picocolors53.default.cyan("capabilities")} ${import_picocolors53.default.dim("--json")}`);
|
|
81881
82716
|
out.push("");
|
|
81882
|
-
out.push(` ${
|
|
82717
|
+
out.push(` ${import_picocolors53.default.dim("These machine-only commands execute versioned benchmark phase specs inside a task sandbox.")}`);
|
|
81883
82718
|
out.push("");
|
|
81884
82719
|
console.log(out.join(`
|
|
81885
82720
|
`));
|
|
@@ -81906,137 +82741,140 @@ var SUBCOMMAND_OWNED_FLAGS = {
|
|
|
81906
82741
|
function help() {
|
|
81907
82742
|
const out = [];
|
|
81908
82743
|
out.push("");
|
|
81909
|
-
out.push(` ${brandTint("◆")} ${
|
|
81910
|
-
out.push(` ${
|
|
82744
|
+
out.push(` ${brandTint("◆")} ${import_picocolors54.default.bold("brainbase")} ${import_picocolors54.default.dim(`v${VERSION}`)}`);
|
|
82745
|
+
out.push(` ${import_picocolors54.default.dim("connect your local agent to the brainbase platform")}`);
|
|
81911
82746
|
out.push("");
|
|
81912
82747
|
out.push(divider("USAGE"));
|
|
81913
82748
|
out.push("");
|
|
81914
|
-
out.push(` ${
|
|
82749
|
+
out.push(` ${import_picocolors54.default.bold("brainbase")} ${import_picocolors54.default.dim("<command> [options]")}`);
|
|
81915
82750
|
out.push("");
|
|
81916
82751
|
out.push(divider("AUTH"));
|
|
81917
82752
|
out.push("");
|
|
81918
|
-
out.push(` ${
|
|
81919
|
-
out.push(` ${
|
|
81920
|
-
out.push(` ${
|
|
82753
|
+
out.push(` ${import_picocolors54.default.cyan("login")} ${import_picocolors54.default.dim(" open the web app and connect this device")}`);
|
|
82754
|
+
out.push(` ${import_picocolors54.default.cyan("logout")} ${import_picocolors54.default.dim(" clear the local session")}`);
|
|
82755
|
+
out.push(` ${import_picocolors54.default.cyan("whoami")} ${import_picocolors54.default.dim("[--json]")} ${import_picocolors54.default.dim(" show which credential is in use and what it covers")}`);
|
|
81921
82756
|
out.push("");
|
|
81922
82757
|
out.push(divider("DISCOVERY"));
|
|
81923
82758
|
out.push("");
|
|
81924
|
-
out.push(` ${
|
|
81925
|
-
out.push(` ${
|
|
82759
|
+
out.push(` ${import_picocolors54.default.cyan("team list")} ${import_picocolors54.default.dim("show the teams you can create agents in")}`);
|
|
82760
|
+
out.push(` ${import_picocolors54.default.cyan("agent list")} ${import_picocolors54.default.dim("show a team's agents and their ids")}`);
|
|
81926
82761
|
out.push("");
|
|
81927
82762
|
out.push(divider("LINKED AGENT"));
|
|
81928
82763
|
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(` ${
|
|
82764
|
+
out.push(` ${import_picocolors54.default.cyan("agent init")} ${import_picocolors54.default.dim("write a starter brainbase.agent.yaml here — offline, no login needed")}`);
|
|
82765
|
+
out.push(` ${import_picocolors54.default.cyan("agent create")} ${import_picocolors54.default.dim("claim an unclaimed brainbase.agent.yaml and create the cloud agent")}`);
|
|
82766
|
+
out.push(` ${import_picocolors54.default.cyan("agent pull")} ${import_picocolors54.default.dim("[<id>]")} ${import_picocolors54.default.dim("bring cloud changes into this folder (--force to override; --run-entrypoint to also execute the agent entrypoint)")}`);
|
|
82767
|
+
out.push(` ${import_picocolors54.default.cyan("agent push")} ${import_picocolors54.default.dim("send local changes to the cloud (--force to overwrite cloud-side conflicts with local)")}`);
|
|
82768
|
+
out.push(` ${import_picocolors54.default.cyan("agent unpack")} ${import_picocolors54.default.dim("install the claimed agent into a harness layout")}`);
|
|
82769
|
+
out.push(` ${import_picocolors54.default.cyan("link")} ${import_picocolors54.default.dim("attach this folder to an existing agent")}`);
|
|
82770
|
+
out.push(` ${import_picocolors54.default.cyan("agent status")} ${import_picocolors54.default.dim("show what would pull and what would push")}`);
|
|
82771
|
+
out.push(` ${import_picocolors54.default.cyan("agent connections")} ${import_picocolors54.default.dim("show which integrations this agent is wired to (--json for CI)")}`);
|
|
82772
|
+
out.push(` ${import_picocolors54.default.cyan("agent connect")} ${import_picocolors54.default.dim("<name>")} ${import_picocolors54.default.dim("connect slack or meeting from the terminal")}`);
|
|
82773
|
+
out.push(` ${import_picocolors54.default.cyan("agent disconnect")} ${import_picocolors54.default.dim("<name>")} ${import_picocolors54.default.dim("revoke a slack or meeting install")}`);
|
|
82774
|
+
out.push(` ${import_picocolors54.default.cyan("agent env")} ${import_picocolors54.default.dim("print export lines for `eval $(brainbase agent env)`")}`);
|
|
82775
|
+
out.push(` ${import_picocolors54.default.cyan("run")} ${import_picocolors54.default.dim("<cmd> [args...]")} ${import_picocolors54.default.dim("run <cmd> with secrets.env loaded into env")}`);
|
|
82776
|
+
out.push(` ${import_picocolors54.default.cyan("status")} ${import_picocolors54.default.dim("show what this folder is linked to")}`);
|
|
82777
|
+
out.push(` ${import_picocolors54.default.cyan("unlink")} ${import_picocolors54.default.dim("disconnect this folder")}`);
|
|
81942
82778
|
out.push("");
|
|
81943
82779
|
out.push(divider("TASKS"));
|
|
81944
82780
|
out.push("");
|
|
81945
|
-
out.push(` ${
|
|
82781
|
+
out.push(` ${import_picocolors54.default.cyan("task create")} ${import_picocolors54.default.dim("--message <text>")} ${import_picocolors54.default.dim("create a managed task and start its first run")}`);
|
|
81946
82782
|
out.push("");
|
|
81947
82783
|
out.push(divider("BENCHMARK RUNTIME"));
|
|
81948
82784
|
out.push("");
|
|
81949
|
-
out.push(` ${
|
|
81950
|
-
out.push(` ${
|
|
81951
|
-
out.push(` ${
|
|
82785
|
+
out.push(` ${import_picocolors54.default.cyan("benchmark hydrate")} ${import_picocolors54.default.dim("--spec <path> --result <path> --json")}`);
|
|
82786
|
+
out.push(` ${import_picocolors54.default.cyan("benchmark evaluate")} ${import_picocolors54.default.dim("--spec <path> --result <path> --json")}`);
|
|
82787
|
+
out.push(` ${import_picocolors54.default.cyan("benchmark capabilities")} ${import_picocolors54.default.dim("--json")}`);
|
|
81952
82788
|
out.push("");
|
|
81953
82789
|
out.push(divider("ORCHESTRATIONS"));
|
|
81954
82790
|
out.push("");
|
|
81955
|
-
out.push(` ${
|
|
81956
|
-
out.push(` ${
|
|
81957
|
-
out.push(` ${
|
|
81958
|
-
out.push(` ${
|
|
81959
|
-
out.push(` ${
|
|
82791
|
+
out.push(` ${import_picocolors54.default.cyan("orchestration create")} ${import_picocolors54.default.dim("claim a local orchestration manifest and create it in the cloud")}`);
|
|
82792
|
+
out.push(` ${import_picocolors54.default.cyan("orchestration list")} ${import_picocolors54.default.dim("list orchestrations under a team")}`);
|
|
82793
|
+
out.push(` ${import_picocolors54.default.cyan("orchestration pull")} ${import_picocolors54.default.dim("<id>")} ${import_picocolors54.default.dim("recursively fetch an orchestration + every member agent")}`);
|
|
82794
|
+
out.push(` ${import_picocolors54.default.cyan("orchestration push")} ${import_picocolors54.default.dim("recursively push each member, then update the graph")}`);
|
|
82795
|
+
out.push(` ${import_picocolors54.default.cyan("orchestration status")} ${import_picocolors54.default.dim("show what would push and what would pull")}`);
|
|
81960
82796
|
out.push("");
|
|
81961
82797
|
out.push(divider("TEMPLATES"));
|
|
81962
82798
|
out.push("");
|
|
81963
|
-
out.push(` ${
|
|
81964
|
-
out.push(` ${
|
|
81965
|
-
out.push(` ${
|
|
81966
|
-
out.push(` ${
|
|
81967
|
-
out.push(` ${
|
|
81968
|
-
out.push(` ${
|
|
81969
|
-
out.push(` ${
|
|
82799
|
+
out.push(` ${import_picocolors54.default.cyan("template pack")} ${import_picocolors54.default.dim("bundle the current agent into a template")}`);
|
|
82800
|
+
out.push(` ${import_picocolors54.default.cyan("template publish")} ${import_picocolors54.default.dim("upload a template to the registry")}`);
|
|
82801
|
+
out.push(` ${import_picocolors54.default.cyan("template search")} ${import_picocolors54.default.dim("[query]")} ${import_picocolors54.default.dim("search the registry")}`);
|
|
82802
|
+
out.push(` ${import_picocolors54.default.cyan("template info")} ${import_picocolors54.default.dim("<creator/slug>")} ${import_picocolors54.default.dim("show registry details for a template")}`);
|
|
82803
|
+
out.push(` ${import_picocolors54.default.cyan("template onboard")} ${import_picocolors54.default.dim("<creator/slug>")} ${import_picocolors54.default.dim("install (or refresh) a template")}`);
|
|
82804
|
+
out.push(` ${import_picocolors54.default.cyan("template list")} ${import_picocolors54.default.dim("show installed templates")}`);
|
|
82805
|
+
out.push(` ${import_picocolors54.default.cyan("template remove")} ${import_picocolors54.default.dim("<creator/slug>")} ${import_picocolors54.default.dim("uninstall a template")}`);
|
|
81970
82806
|
out.push("");
|
|
81971
82807
|
out.push(divider("SKILLS"));
|
|
81972
82808
|
out.push("");
|
|
81973
|
-
out.push(` ${
|
|
81974
|
-
out.push(` ${
|
|
81975
|
-
out.push(` ${
|
|
81976
|
-
out.push(` ${
|
|
81977
|
-
out.push(` ${
|
|
81978
|
-
out.push(` ${
|
|
81979
|
-
out.push(` ${
|
|
82809
|
+
out.push(` ${import_picocolors54.default.cyan("skill add")} ${import_picocolors54.default.dim("<source>")} ${import_picocolors54.default.dim("install a skill (github / git / brainbase)")}`);
|
|
82810
|
+
out.push(` ${import_picocolors54.default.cyan("skill list")} ${import_picocolors54.default.dim("show locally installed skills + their source")}`);
|
|
82811
|
+
out.push(` ${import_picocolors54.default.cyan("skill update")} ${import_picocolors54.default.dim("<slug>")} ${import_picocolors54.default.dim("re-fetch a skill from its recorded source")}`);
|
|
82812
|
+
out.push(` ${import_picocolors54.default.cyan("skill remove")} ${import_picocolors54.default.dim("<slug>")} ${import_picocolors54.default.dim("uninstall a skill")}`);
|
|
82813
|
+
out.push(` ${import_picocolors54.default.cyan("skill search")} ${import_picocolors54.default.dim("[query]")} ${import_picocolors54.default.dim("search the brainbase skill registry")}`);
|
|
82814
|
+
out.push(` ${import_picocolors54.default.cyan("skill info")} ${import_picocolors54.default.dim("<creator/slug>")} ${import_picocolors54.default.dim("show registry details for a skill")}`);
|
|
82815
|
+
out.push(` ${import_picocolors54.default.cyan("skill publish")} ${import_picocolors54.default.dim("[dir]")} ${import_picocolors54.default.dim("publish a SKILL.md folder (defaults to .)")}`);
|
|
81980
82816
|
out.push("");
|
|
81981
82817
|
out.push(divider("CLI TOKENS"));
|
|
81982
82818
|
out.push("");
|
|
81983
|
-
out.push(` ${
|
|
81984
|
-
out.push(` ${
|
|
81985
|
-
out.push(` ${
|
|
81986
|
-
out.push(` ${
|
|
82819
|
+
out.push(` ${import_picocolors54.default.cyan("token create")} ${import_picocolors54.default.dim("issue a long-lived CLI key for CI / scripts")}`);
|
|
82820
|
+
out.push(` ${import_picocolors54.default.cyan("token list")} ${import_picocolors54.default.dim("show your tokens")}`);
|
|
82821
|
+
out.push(` ${import_picocolors54.default.cyan("token rename")} ${import_picocolors54.default.dim("<id>")} ${import_picocolors54.default.dim("relabel a token")}`);
|
|
82822
|
+
out.push(` ${import_picocolors54.default.cyan("token revoke")} ${import_picocolors54.default.dim("<id>")} ${import_picocolors54.default.dim("revoke a token")}`);
|
|
81987
82823
|
out.push("");
|
|
81988
82824
|
out.push(divider("MCP"));
|
|
81989
82825
|
out.push("");
|
|
81990
|
-
out.push(` ${
|
|
81991
|
-
out.push(` ${
|
|
82826
|
+
out.push(` ${import_picocolors54.default.cyan("mcp check")} ${import_picocolors54.default.dim("[--json]")} ${import_picocolors54.default.dim("verify MCP server connectivity through the brainbase proxy (runs at sandbox bootstrap)")}`);
|
|
82827
|
+
out.push(` ${import_picocolors54.default.cyan("mcp list")} ${import_picocolors54.default.dim("[--json]")} ${import_picocolors54.default.dim("show configured servers with OAuth state and expiry")}`);
|
|
81992
82828
|
out.push("");
|
|
81993
82829
|
out.push(divider("FLAGS"));
|
|
81994
82830
|
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(` ${
|
|
82831
|
+
out.push(` ${import_picocolors54.default.dim("--harness <id>")} force harness for onboard / sync (e.g. claude-code)`);
|
|
82832
|
+
out.push(` ${import_picocolors54.default.dim("--scope <s>")} force scope: global | project`);
|
|
82833
|
+
out.push(` ${import_picocolors54.default.dim("--yes, -y")} skip confirmations / auto-overwrite`);
|
|
82834
|
+
out.push(` ${import_picocolors54.default.dim("--agent <id>")} for link/task create: use this agent id explicitly`);
|
|
82835
|
+
out.push(` ${import_picocolors54.default.dim("--message <text>")} for task create: required first user message`);
|
|
82836
|
+
out.push(` ${import_picocolors54.default.dim("--title <text>")} for task create: optional task title`);
|
|
82837
|
+
out.push(` ${import_picocolors54.default.dim("--model <id>")} for task create: optional model override`);
|
|
82838
|
+
out.push(` ${import_picocolors54.default.dim("--org <id-or-slug>")} pick the organization (team/agent list, agent create, orchestration create/list)`);
|
|
82839
|
+
out.push(` ${import_picocolors54.default.dim("--team <id>")} pick the team, same commands (works without --org)`);
|
|
82840
|
+
out.push(` ${import_picocolors54.default.dim("--json")} machine-readable output for supported commands`);
|
|
82841
|
+
out.push(` ${import_picocolors54.default.dim("--no-tracking")} for link: skip routing LLM traffic through brainbase`);
|
|
82842
|
+
out.push(` ${import_picocolors54.default.dim("--track")} for agent create: enable tracking non-interactively (off without a TTY)`);
|
|
82843
|
+
out.push(` ${import_picocolors54.default.dim("--shell <sh|fish>")} for agent env: pick output format (auto-detected from $SHELL)`);
|
|
82844
|
+
out.push(` ${import_picocolors54.default.dim("--bot-token <t>")} for agent connect slack (or BRAINBASE_SLACK_BOT_TOKEN, or stdin)`);
|
|
82845
|
+
out.push(` ${import_picocolors54.default.dim("--signing-secret <s>")} for agent connect slack (or BRAINBASE_SLACK_SIGNING_SECRET, or stdin)`);
|
|
82846
|
+
out.push(` ${import_picocolors54.default.dim("--bot-name <name>")} for agent connect meeting: the bot's display name`);
|
|
82847
|
+
out.push(` ${import_picocolors54.default.dim("--full")} for agent init: write a commented template covering every block`);
|
|
82848
|
+
out.push(` ${import_picocolors54.default.dim("--minimal")} for agent init: write the starter manifest (the default)`);
|
|
82849
|
+
out.push(` ${import_picocolors54.default.dim("--all")} for template list: include installs from other folders`);
|
|
82850
|
+
out.push(` ${import_picocolors54.default.dim("--web <url>")} for login: web app URL (default https://app.brainbaselabs.com)`);
|
|
82013
82851
|
out.push("");
|
|
82014
82852
|
out.push(divider("ENV"));
|
|
82015
82853
|
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(` ${
|
|
82854
|
+
out.push(` ${import_picocolors54.default.dim("BRAINBASE_HOME")} override the local config dir (default ~/.brainbase)`);
|
|
82855
|
+
out.push(` ${import_picocolors54.default.dim("BRAINBASE_DEBUG")} print full stack traces on error (any value; unset to disable)`);
|
|
82856
|
+
out.push(` ${import_picocolors54.default.dim("BRAINBASE_WEB_URL")} override the web app URL used by login`);
|
|
82857
|
+
out.push(` ${import_picocolors54.default.dim("BRAINBASE_CONTROL_PLANE_URL")} override the MAS host (/v2/cli; task create uses /v2/tasks)`);
|
|
82858
|
+
out.push(` ${import_picocolors54.default.dim("BRAINBASE_API_URL")} legacy KLS host override (uses /api/cli; proxy/registry fallback)`);
|
|
82859
|
+
out.push(` ${import_picocolors54.default.dim("BRAINBASE_PROXY_URL")} override the model-proxy URL used by harness traffic (default https://api.v1.brainbaselabs.com)`);
|
|
82860
|
+
out.push(` ${import_picocolors54.default.dim("BRAINBASE_REGISTRY_URL")} override the registry API URL (default https://api.v1.brainbaselabs.com)`);
|
|
82861
|
+
out.push(` ${import_picocolors54.default.dim("BRAINBASE_TOKEN")} long-lived CLI PAT; the only PAT control-plane commands accept (token.json is not read there)`);
|
|
82862
|
+
out.push(` ${import_picocolors54.default.dim("BRAINBASE_SKIP_AUTH")} bypass the auth gate for development`);
|
|
82863
|
+
out.push(` ${import_picocolors54.default.dim("BRAINBASE_NON_INTERACTIVE")} force non-interactive mode — skip/auto-default prompts (CI & agents)`);
|
|
82864
|
+
out.push(` ${import_picocolors54.default.dim("BRAINBASE_RUN_ENTRYPOINT")} =1 → agent pull executes the agent entrypoint (sandbox boots; or pass --run-entrypoint)`);
|
|
82027
82865
|
out.push("");
|
|
82028
|
-
out.push(` ${
|
|
82029
|
-
out.push(` ${
|
|
82030
|
-
out.push(` ${
|
|
82031
|
-
out.push(` ${
|
|
82032
|
-
out.push(` ${
|
|
82033
|
-
out.push(` ${
|
|
82866
|
+
out.push(` ${import_picocolors54.default.dim("BRAINBASE_MEMORY_MCP_URL")} override the built-in memory MCP host`);
|
|
82867
|
+
out.push(` ${import_picocolors54.default.dim("BRAINBASE_BROWSER_MCP_URL")} override the built-in browser MCP host`);
|
|
82868
|
+
out.push(` ${import_picocolors54.default.dim("BRAINBASE_SLACK_MCP_URL")} override the built-in Slack MCP host`);
|
|
82869
|
+
out.push(` ${import_picocolors54.default.dim("BRAINBASE_MEETING_MCP_URL")} override the built-in meeting MCP host`);
|
|
82870
|
+
out.push(` ${import_picocolors54.default.dim("BRAINBASE_GITHUB_MCP_URL")} override the built-in GitHub MCP host`);
|
|
82871
|
+
out.push(` ${import_picocolors54.default.dim("BRAINBASE_ORCHESTRATION_MCP_URL")} override the built-in orchestration MCP host`);
|
|
82034
82872
|
out.push("");
|
|
82035
82873
|
out.push(divider("HARNESSES"));
|
|
82036
82874
|
out.push("");
|
|
82037
|
-
out.push(` ${
|
|
82038
|
-
out.push(` ${
|
|
82039
|
-
out.push(` ${
|
|
82875
|
+
out.push(` ${import_picocolors54.default.dim("•")} ${import_picocolors54.default.bold("claude-code")} ${import_picocolors54.default.dim("skills, mcps, agents, commands, playbooks, instructions, files")}`);
|
|
82876
|
+
out.push(` ${import_picocolors54.default.dim("•")} ${import_picocolors54.default.bold("codex")} ${import_picocolors54.default.dim("skills, mcps, commands, playbooks, instructions, files")}`);
|
|
82877
|
+
out.push(` ${import_picocolors54.default.dim("•")} ${import_picocolors54.default.bold("kafka")} ${import_picocolors54.default.dim("skills, mcps, agents, commands, playbooks, instructions, files")}`);
|
|
82040
82878
|
out.push("");
|
|
82041
82879
|
console.log(out.join(`
|
|
82042
82880
|
`));
|
|
@@ -82067,7 +82905,9 @@ var VALUE_TAKING_FLAGS = new Set([
|
|
|
82067
82905
|
"--app-id",
|
|
82068
82906
|
"--app-name",
|
|
82069
82907
|
"--bot-name",
|
|
82070
|
-
"--bot-image-url"
|
|
82908
|
+
"--bot-image-url",
|
|
82909
|
+
"--task-id",
|
|
82910
|
+
"--limit"
|
|
82071
82911
|
]);
|
|
82072
82912
|
function isValueOfPriorFlag2(args, index) {
|
|
82073
82913
|
return index > 0 && VALUE_TAKING_FLAGS.has(args[index - 1]);
|
|
@@ -82188,13 +83028,13 @@ async function requireAuth(cmd) {
|
|
|
82188
83028
|
if (STORED_PAT_COMMANDS.has(cmd) && readToken())
|
|
82189
83029
|
return;
|
|
82190
83030
|
console.error("");
|
|
82191
|
-
console.error(` ${brandTint("◆")} ${
|
|
83031
|
+
console.error(` ${brandTint("◆")} ${import_picocolors54.default.bold("brainbase")}`);
|
|
82192
83032
|
console.error("");
|
|
82193
|
-
console.error(` ${
|
|
83033
|
+
console.error(` ${import_picocolors54.default.red("✗")} You need to sign in to use ${import_picocolors54.default.bold("brainbase " + cmd)}.`);
|
|
82194
83034
|
if (status.reason)
|
|
82195
|
-
console.error(` ${
|
|
83035
|
+
console.error(` ${import_picocolors54.default.dim(status.reason)}`);
|
|
82196
83036
|
console.error("");
|
|
82197
|
-
console.error(` Run ${
|
|
83037
|
+
console.error(` Run ${import_picocolors54.default.cyan("brainbase login")} to connect this device.`);
|
|
82198
83038
|
console.error("");
|
|
82199
83039
|
process14.exit(1);
|
|
82200
83040
|
}
|
|
@@ -82239,6 +83079,8 @@ async function main() {
|
|
|
82239
83079
|
const noTracking = hasFlag2(sharedArgs, "--no-tracking");
|
|
82240
83080
|
const track = hasFlag2(sharedArgs, "--track");
|
|
82241
83081
|
const forceFlag = hasFlag2(sharedArgs, "--force");
|
|
83082
|
+
const minimalFlag = hasFlag2(sharedArgs, "--minimal");
|
|
83083
|
+
const fullFlag = hasFlag2(sharedArgs, "--full");
|
|
82242
83084
|
const runEntrypointFlag = hasFlag2(sharedArgs, "--run-entrypoint");
|
|
82243
83085
|
const graphOnlyFlag = hasFlag2(sharedArgs, "--graph-only");
|
|
82244
83086
|
const nameFlag = takeFlag("--name");
|
|
@@ -82259,6 +83101,11 @@ async function main() {
|
|
|
82259
83101
|
const appNameFlag = getFlag(sharedArgs, "--app-name");
|
|
82260
83102
|
const botNameFlag = getFlag(sharedArgs, "--bot-name");
|
|
82261
83103
|
const botImageUrlFlag = getFlag(sharedArgs, "--bot-image-url");
|
|
83104
|
+
const taskIdFlag = getFlag(sharedArgs, "--task-id");
|
|
83105
|
+
const limitRaw = getFlag(sharedArgs, "--limit");
|
|
83106
|
+
const limitParsed = limitRaw === undefined ? NaN : Number(limitRaw);
|
|
83107
|
+
const limitFlag = Number.isInteger(limitParsed) && limitParsed >= 1 && limitParsed <= 200 ? limitParsed : undefined;
|
|
83108
|
+
const archivedFlag = hasFlag2(sharedArgs, "--archived");
|
|
82262
83109
|
ensureSkillResolversRegistered();
|
|
82263
83110
|
await requireAuth(cmd);
|
|
82264
83111
|
try {
|
|
@@ -82334,6 +83181,8 @@ async function main() {
|
|
|
82334
83181
|
scope: scopeFlag,
|
|
82335
83182
|
shell: shellFlag,
|
|
82336
83183
|
harness,
|
|
83184
|
+
minimal: minimalFlag,
|
|
83185
|
+
full: fullFlag,
|
|
82337
83186
|
name: nameFlag,
|
|
82338
83187
|
tagline: taglineFlag,
|
|
82339
83188
|
orgId: orgIdFlag,
|
|
@@ -82348,7 +83197,10 @@ async function main() {
|
|
|
82348
83197
|
appId: appIdFlag,
|
|
82349
83198
|
appName: appNameFlag,
|
|
82350
83199
|
botName: botNameFlag,
|
|
82351
|
-
botImageUrl: botImageUrlFlag
|
|
83200
|
+
botImageUrl: botImageUrlFlag,
|
|
83201
|
+
taskId: taskIdFlag,
|
|
83202
|
+
limit: limitFlag,
|
|
83203
|
+
archived: archivedFlag
|
|
82352
83204
|
});
|
|
82353
83205
|
break;
|
|
82354
83206
|
}
|
|
@@ -82407,10 +83259,10 @@ async function main() {
|
|
|
82407
83259
|
process14.exit(1);
|
|
82408
83260
|
}
|
|
82409
83261
|
} catch (err) {
|
|
82410
|
-
console.error(
|
|
83262
|
+
console.error(import_picocolors54.default.red(`
|
|
82411
83263
|
${err.message}`));
|
|
82412
83264
|
if (err instanceof ApiError && err.status === 401) {
|
|
82413
|
-
console.error(` Run ${
|
|
83265
|
+
console.error(` Run ${import_picocolors54.default.cyan("brainbase login")} to connect this device.`);
|
|
82414
83266
|
}
|
|
82415
83267
|
if (process14.env.BRAINBASE_DEBUG)
|
|
82416
83268
|
console.error(err.stack);
|