@brainbase-labs/cli 0.15.0 → 0.16.0-rc.1
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/README.md +29 -3
- package/dist/index.js +1083 -290
- package/package.json +4 -2
package/dist/index.js
CHANGED
|
@@ -35141,7 +35141,7 @@ var require_dist2 = __commonJS((exports, module) => {
|
|
|
35141
35141
|
});
|
|
35142
35142
|
|
|
35143
35143
|
// src/index.ts
|
|
35144
|
-
var
|
|
35144
|
+
var import_picocolors43 = __toESM(require_picocolors(), 1);
|
|
35145
35145
|
import process14 from "node:process";
|
|
35146
35146
|
import fs76 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.16.0-rc.1",
|
|
36012
36012
|
description: "Pack, share, and install agent templates across harnesses (Claude Code, Codex, ...).",
|
|
36013
36013
|
type: "module",
|
|
36014
36014
|
bin: {
|
|
@@ -36022,8 +36022,10 @@ var package_default = {
|
|
|
36022
36022
|
scripts: {
|
|
36023
36023
|
dev: "bun run src/index.ts",
|
|
36024
36024
|
build: "bun run scripts/build.ts",
|
|
36025
|
+
test: "bun test",
|
|
36025
36026
|
typecheck: "tsc --noEmit",
|
|
36026
|
-
|
|
36027
|
+
verify: "bun run typecheck && bun test && bun run build",
|
|
36028
|
+
prepublishOnly: "bun run verify"
|
|
36027
36029
|
},
|
|
36028
36030
|
repository: {
|
|
36029
36031
|
type: "git",
|
|
@@ -53348,7 +53350,8 @@ function apiErrorMessage(body, status) {
|
|
|
53348
53350
|
}
|
|
53349
53351
|
|
|
53350
53352
|
// src/core/api.ts
|
|
53351
|
-
var
|
|
53353
|
+
var DEFAULT_CONTROL_PLANE_BASE = "https://api.brainbaselabs.com";
|
|
53354
|
+
var DEFAULT_PROXY_BASE = "https://api.v1.brainbaselabs.com";
|
|
53352
53355
|
|
|
53353
53356
|
class ApiError extends Error {
|
|
53354
53357
|
status;
|
|
@@ -53360,13 +53363,25 @@ class ApiError extends Error {
|
|
|
53360
53363
|
this.name = "ApiError";
|
|
53361
53364
|
}
|
|
53362
53365
|
}
|
|
53363
|
-
function apiBase(
|
|
53364
|
-
const
|
|
53365
|
-
if (
|
|
53366
|
-
return
|
|
53367
|
-
|
|
53368
|
-
|
|
53369
|
-
|
|
53366
|
+
function apiBase(_session) {
|
|
53367
|
+
const controlPlane = process.env.BRAINBASE_CONTROL_PLANE_URL;
|
|
53368
|
+
if (controlPlane) {
|
|
53369
|
+
return `${controlPlane.replace(/\/+$/, "")}/v2/cli`;
|
|
53370
|
+
}
|
|
53371
|
+
const legacyApi = process.env.BRAINBASE_API_URL;
|
|
53372
|
+
if (legacyApi) {
|
|
53373
|
+
return `${legacyApi.replace(/\/+$/, "")}/api/cli`;
|
|
53374
|
+
}
|
|
53375
|
+
return `${DEFAULT_CONTROL_PLANE_BASE}/v2/cli`;
|
|
53376
|
+
}
|
|
53377
|
+
function usesLegacyControlPlane() {
|
|
53378
|
+
return !process.env.BRAINBASE_CONTROL_PLANE_URL && !!process.env.BRAINBASE_API_URL;
|
|
53379
|
+
}
|
|
53380
|
+
function legacyScheduleError() {
|
|
53381
|
+
return new ApiError("Schedule-trigger writes require the MAS control plane. Set BRAINBASE_CONTROL_PLANE_URL or unset the legacy BRAINBASE_API_URL override.", 400);
|
|
53382
|
+
}
|
|
53383
|
+
function legacyAgentConfigError() {
|
|
53384
|
+
return new ApiError("Declarative machine/model config requires the MAS control plane. Set BRAINBASE_CONTROL_PLANE_URL or unset the legacy BRAINBASE_API_URL override.", 400);
|
|
53370
53385
|
}
|
|
53371
53386
|
function requireSession() {
|
|
53372
53387
|
const status = authStatus();
|
|
@@ -53412,87 +53427,113 @@ async function request(pathname, init = {}) {
|
|
|
53412
53427
|
}
|
|
53413
53428
|
var api = {
|
|
53414
53429
|
listOrgs() {
|
|
53415
|
-
return request("/
|
|
53430
|
+
return request("/orgs");
|
|
53416
53431
|
},
|
|
53417
53432
|
listTeams(orgId) {
|
|
53418
|
-
return request(`/
|
|
53433
|
+
return request(`/orgs/${encodeURIComponent(orgId)}/teams`);
|
|
53419
53434
|
},
|
|
53420
53435
|
createTeam(orgId, name) {
|
|
53421
|
-
return request(`/
|
|
53436
|
+
return request(`/orgs/${encodeURIComponent(orgId)}/teams`, {
|
|
53422
53437
|
method: "POST",
|
|
53423
53438
|
body: JSON.stringify({ name })
|
|
53424
53439
|
});
|
|
53425
53440
|
},
|
|
53426
53441
|
createAgent(input) {
|
|
53427
|
-
|
|
53442
|
+
if (usesLegacyControlPlane() && (input.machine_kind !== undefined || input.default_model !== undefined)) {
|
|
53443
|
+
return Promise.reject(legacyAgentConfigError());
|
|
53444
|
+
}
|
|
53445
|
+
return request("/agents", {
|
|
53428
53446
|
method: "POST",
|
|
53429
53447
|
body: JSON.stringify(input)
|
|
53430
53448
|
});
|
|
53431
53449
|
},
|
|
53432
53450
|
getAgent(agentId) {
|
|
53433
|
-
return request(`/
|
|
53451
|
+
return request(`/agents/${encodeURIComponent(agentId)}`);
|
|
53434
53452
|
},
|
|
53435
53453
|
getAgentRevision(agentId) {
|
|
53436
|
-
return request(`/
|
|
53454
|
+
return request(`/agents/${encodeURIComponent(agentId)}/revision`);
|
|
53437
53455
|
},
|
|
53438
53456
|
getAgentManifest(agentId) {
|
|
53439
|
-
return request(`/
|
|
53457
|
+
return request(`/agents/${encodeURIComponent(agentId)}/manifest`);
|
|
53440
53458
|
},
|
|
53441
53459
|
updateAgent(agentId, input) {
|
|
53442
|
-
|
|
53460
|
+
if (usesLegacyControlPlane() && (input.machine_kind !== undefined || input.default_model !== undefined)) {
|
|
53461
|
+
return Promise.reject(legacyAgentConfigError());
|
|
53462
|
+
}
|
|
53463
|
+
return request(`/agents/${encodeURIComponent(agentId)}`, {
|
|
53443
53464
|
method: "PUT",
|
|
53444
53465
|
body: JSON.stringify(input)
|
|
53445
53466
|
});
|
|
53446
53467
|
},
|
|
53447
53468
|
pushAgentManifest(agentId, input) {
|
|
53448
|
-
return request(`/
|
|
53469
|
+
return request(`/agents/${encodeURIComponent(agentId)}/manifest`, {
|
|
53449
53470
|
method: "PUT",
|
|
53450
53471
|
body: JSON.stringify(input)
|
|
53451
53472
|
});
|
|
53452
53473
|
},
|
|
53453
53474
|
getAgentSecrets(agentId) {
|
|
53454
|
-
return request(`/
|
|
53475
|
+
return request(`/agents/${encodeURIComponent(agentId)}/secrets`);
|
|
53455
53476
|
},
|
|
53456
53477
|
putAgentSecrets(agentId, secrets) {
|
|
53457
|
-
return request(`/
|
|
53478
|
+
return request(`/agents/${encodeURIComponent(agentId)}/secrets`, {
|
|
53458
53479
|
method: "PUT",
|
|
53459
53480
|
body: JSON.stringify({ secrets })
|
|
53460
53481
|
});
|
|
53461
53482
|
},
|
|
53462
53483
|
createCliKey(agentId, input) {
|
|
53463
|
-
return request(`/
|
|
53484
|
+
return request(`/agents/${encodeURIComponent(agentId)}/keys`, {
|
|
53464
53485
|
method: "POST",
|
|
53465
53486
|
body: JSON.stringify(input)
|
|
53466
53487
|
});
|
|
53467
53488
|
},
|
|
53468
53489
|
revokeCliKey(keyId) {
|
|
53469
|
-
return request(`/
|
|
53490
|
+
return request(`/keys/${encodeURIComponent(keyId)}`, {
|
|
53470
53491
|
method: "DELETE"
|
|
53471
53492
|
});
|
|
53472
53493
|
},
|
|
53473
53494
|
listOrchestrations(orgId, teamId) {
|
|
53474
|
-
return request(`/
|
|
53495
|
+
return request(`/orgs/${encodeURIComponent(orgId)}/teams/${encodeURIComponent(teamId)}/orchestrations`);
|
|
53496
|
+
},
|
|
53497
|
+
createOrchestration(input) {
|
|
53498
|
+
if (usesLegacyControlPlane()) {
|
|
53499
|
+
return Promise.reject(new ApiError("Orchestration creation requires the MAS control plane. Set BRAINBASE_CONTROL_PLANE_URL or unset the legacy BRAINBASE_API_URL override.", 400));
|
|
53500
|
+
}
|
|
53501
|
+
return request("/orchestrations", {
|
|
53502
|
+
method: "POST",
|
|
53503
|
+
body: JSON.stringify(input)
|
|
53504
|
+
});
|
|
53475
53505
|
},
|
|
53476
53506
|
getOrchestration(orchId) {
|
|
53477
|
-
return request(`/
|
|
53507
|
+
return request(`/orchestrations/${encodeURIComponent(orchId)}`);
|
|
53478
53508
|
},
|
|
53479
53509
|
getOrchestrationManifest(orchId) {
|
|
53480
|
-
return request(`/
|
|
53510
|
+
return request(`/orchestrations/${encodeURIComponent(orchId)}/manifest`);
|
|
53481
53511
|
},
|
|
53482
|
-
updateOrchestration(orchId, input) {
|
|
53483
|
-
|
|
53512
|
+
async updateOrchestration(orchId, input) {
|
|
53513
|
+
let payload = input;
|
|
53514
|
+
if (usesLegacyControlPlane() && input.triggers !== undefined) {
|
|
53515
|
+
if (input.triggers.length > 0)
|
|
53516
|
+
throw legacyScheduleError();
|
|
53517
|
+
const current = await request(`/orchestrations/${encodeURIComponent(orchId)}`);
|
|
53518
|
+
if ((current.triggers ?? []).some((trigger) => trigger.trigger_type === "schedule")) {
|
|
53519
|
+
throw legacyScheduleError();
|
|
53520
|
+
}
|
|
53521
|
+
const { triggers: _unsupported, ...legacyPayload } = input;
|
|
53522
|
+
payload = legacyPayload;
|
|
53523
|
+
}
|
|
53524
|
+
return request(`/orchestrations/${encodeURIComponent(orchId)}`, {
|
|
53484
53525
|
method: "PUT",
|
|
53485
|
-
body: JSON.stringify(
|
|
53526
|
+
body: JSON.stringify(payload)
|
|
53486
53527
|
});
|
|
53487
53528
|
}
|
|
53488
53529
|
};
|
|
53489
53530
|
function proxyBaseUrl(session) {
|
|
53490
|
-
const envOverride = process.env.BRAINBASE_API_URL;
|
|
53531
|
+
const envOverride = process.env.BRAINBASE_PROXY_URL || process.env.BRAINBASE_API_URL;
|
|
53491
53532
|
if (envOverride)
|
|
53492
53533
|
return envOverride.replace(/\/+$/, "");
|
|
53493
53534
|
if (session?.server)
|
|
53494
53535
|
return session.server.replace(/\/+$/, "");
|
|
53495
|
-
return
|
|
53536
|
+
return DEFAULT_PROXY_BASE.replace(/\/+$/, "");
|
|
53496
53537
|
}
|
|
53497
53538
|
|
|
53498
53539
|
// src/core/token.ts
|
|
@@ -53554,9 +53595,9 @@ function clearToken() {
|
|
|
53554
53595
|
}
|
|
53555
53596
|
|
|
53556
53597
|
// src/core/registry-client.ts
|
|
53557
|
-
var DEFAULT_BASE = "https://
|
|
53598
|
+
var DEFAULT_BASE = "https://api.v1.brainbaselabs.com";
|
|
53558
53599
|
function baseUrl(session) {
|
|
53559
|
-
const env3 = process.env.BRAINBASE_REGISTRY_URL
|
|
53600
|
+
const env3 = process.env.BRAINBASE_REGISTRY_URL || process.env.BRAINBASE_API_URL;
|
|
53560
53601
|
if (env3)
|
|
53561
53602
|
return env3.replace(/\/+$/, "");
|
|
53562
53603
|
if (session?.server)
|
|
@@ -53564,7 +53605,7 @@ function baseUrl(session) {
|
|
|
53564
53605
|
return DEFAULT_BASE.replace(/\/+$/, "");
|
|
53565
53606
|
}
|
|
53566
53607
|
function registryHost() {
|
|
53567
|
-
const env3 = process.env.BRAINBASE_REGISTRY_URL
|
|
53608
|
+
const env3 = process.env.BRAINBASE_REGISTRY_URL || process.env.BRAINBASE_API_URL;
|
|
53568
53609
|
if (env3)
|
|
53569
53610
|
return env3.replace(/\/+$/, "");
|
|
53570
53611
|
const s = readAuth();
|
|
@@ -60799,10 +60840,13 @@ var EvalSchema = exports_external.object({
|
|
|
60799
60840
|
message: "classification_values must not contain duplicate labels",
|
|
60800
60841
|
path: ["classification_values"]
|
|
60801
60842
|
});
|
|
60843
|
+
var MODEL_ID_RE = /^[A-Za-z0-9._:/-]{1,128}$/;
|
|
60802
60844
|
var AgentManifestSchema = exports_external.object({
|
|
60803
60845
|
schema: exports_external.literal(1),
|
|
60804
60846
|
id: exports_external.string().min(1).optional(),
|
|
60805
60847
|
harness: exports_external.string().min(1).optional(),
|
|
60848
|
+
machine_kind: exports_external.string().trim().min(1).optional(),
|
|
60849
|
+
default_model: exports_external.string().trim().regex(MODEL_ID_RE, "default_model must use letters, digits, and . _ - : / only (max 128)").nullable().optional(),
|
|
60806
60850
|
agent: AgentMetaSchema,
|
|
60807
60851
|
instructions: InstructionsSchema.optional(),
|
|
60808
60852
|
entrypoint: EntrypointSchema.optional(),
|
|
@@ -61037,7 +61081,9 @@ var SyncedComponentSchema = exports_external.object({
|
|
|
61037
61081
|
var AgentMetaSnapshotSchema = exports_external.object({
|
|
61038
61082
|
name: exports_external.string(),
|
|
61039
61083
|
tagline: exports_external.string().nullish().transform((v3) => v3 ?? undefined),
|
|
61040
|
-
entrypoint: exports_external.string().optional()
|
|
61084
|
+
entrypoint: exports_external.string().optional(),
|
|
61085
|
+
machine_kind: exports_external.string().min(1).optional(),
|
|
61086
|
+
default_model: exports_external.string().nullable().optional()
|
|
61041
61087
|
});
|
|
61042
61088
|
var SyncStateSchema = exports_external.object({
|
|
61043
61089
|
schemaVersion: exports_external.literal(1),
|
|
@@ -61933,7 +61979,8 @@ async function runSync(cwd2, args) {
|
|
|
61933
61979
|
agent_id: link2.agent_id,
|
|
61934
61980
|
revision: manifest.revision,
|
|
61935
61981
|
synced_at: new Date().toISOString(),
|
|
61936
|
-
components: prevState?.components ?? []
|
|
61982
|
+
components: prevState?.components ?? [],
|
|
61983
|
+
agentMeta: prevState?.agentMeta
|
|
61937
61984
|
});
|
|
61938
61985
|
return;
|
|
61939
61986
|
}
|
|
@@ -62102,7 +62149,8 @@ async function runSync(cwd2, args) {
|
|
|
62102
62149
|
agent_id: link2.agent_id,
|
|
62103
62150
|
revision: manifest.revision,
|
|
62104
62151
|
synced_at: new Date().toISOString(),
|
|
62105
|
-
components: nextComponents
|
|
62152
|
+
components: nextComponents,
|
|
62153
|
+
agentMeta: prevState?.agentMeta
|
|
62106
62154
|
};
|
|
62107
62155
|
writeSyncState(cwd2, newState);
|
|
62108
62156
|
$e(`Synced ${link2.name} to revision ${manifest.revision}.`);
|
|
@@ -62241,17 +62289,15 @@ function canonicalJson(value) {
|
|
|
62241
62289
|
throw new Error(`Unsupported value in canonicalJson: ${typeof value}`);
|
|
62242
62290
|
}
|
|
62243
62291
|
function hashMcpEntry(entry) {
|
|
62244
|
-
const payload = {
|
|
62292
|
+
const payload = {
|
|
62293
|
+
args: entry.args ?? [],
|
|
62294
|
+
env: entry.env ?? {},
|
|
62295
|
+
headers: entry.headers ?? {}
|
|
62296
|
+
};
|
|
62245
62297
|
if (entry.url !== undefined)
|
|
62246
62298
|
payload.url = entry.url;
|
|
62247
62299
|
if (entry.command !== undefined)
|
|
62248
62300
|
payload.command = entry.command;
|
|
62249
|
-
if (entry.args !== undefined)
|
|
62250
|
-
payload.args = entry.args;
|
|
62251
|
-
if (entry.env !== undefined)
|
|
62252
|
-
payload.env = entry.env;
|
|
62253
|
-
if (entry.headers !== undefined)
|
|
62254
|
-
payload.headers = entry.headers;
|
|
62255
62301
|
payload.is_enabled = entry.is_enabled ?? true;
|
|
62256
62302
|
return crypto4.createHash("sha256").update(canonicalJson(payload)).digest("hex");
|
|
62257
62303
|
}
|
|
@@ -62422,7 +62468,10 @@ function threeWayDiff(input) {
|
|
|
62422
62468
|
const sourceChanged = !!local && local.hash === null && !!local.declaredSource && lock?.source !== undefined && lock.source !== local.declaredSource;
|
|
62423
62469
|
const localChanged = sourceChanged || localHash !== null && lockHash !== undefined && localHash !== lockHash;
|
|
62424
62470
|
const cloudChanged = cloudHash !== undefined && lockHash !== undefined && cloudHash !== lockHash;
|
|
62425
|
-
|
|
62471
|
+
const converged = !sourceChanged && localHash !== null && cloudHash !== undefined && localHash === cloudHash;
|
|
62472
|
+
if (converged)
|
|
62473
|
+
status = "in-sync";
|
|
62474
|
+
else if (localChanged && cloudChanged)
|
|
62426
62475
|
status = "modified-both";
|
|
62427
62476
|
else if (localChanged)
|
|
62428
62477
|
status = "modified-local";
|
|
@@ -62489,6 +62538,60 @@ function diffAgentMeta(manifestMeta, lockMeta, cloudMeta) {
|
|
|
62489
62538
|
cloudChanged: !!cloudMeta && !!lockMeta && !eq(cloudMeta, lockMeta)
|
|
62490
62539
|
};
|
|
62491
62540
|
}
|
|
62541
|
+
function hasOwn(value, key2) {
|
|
62542
|
+
return !!value && Object.prototype.hasOwnProperty.call(value, key2);
|
|
62543
|
+
}
|
|
62544
|
+
function diffAgentConfig(manifest, lock, cloud) {
|
|
62545
|
+
const unsupported = [];
|
|
62546
|
+
const machineSupported = cloud.machine_kind !== undefined;
|
|
62547
|
+
const defaultModelSupported = hasOwn(cloud, "default_model");
|
|
62548
|
+
if (manifest.machine_kind !== undefined && !machineSupported) {
|
|
62549
|
+
unsupported.push("machine_kind");
|
|
62550
|
+
}
|
|
62551
|
+
if (manifest.default_model !== undefined && !defaultModelSupported) {
|
|
62552
|
+
unsupported.push("default_model");
|
|
62553
|
+
}
|
|
62554
|
+
const machineMismatch = manifest.machine_kind !== undefined && machineSupported && manifest.machine_kind !== cloud.machine_kind;
|
|
62555
|
+
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);
|
|
62556
|
+
const machineCloudChanged = lock?.machine_kind !== undefined && machineSupported && lock.machine_kind !== cloud.machine_kind && manifest.machine_kind !== cloud.machine_kind;
|
|
62557
|
+
const machineConverged = manifest.machine_kind !== undefined && machineSupported && manifest.machine_kind === cloud.machine_kind && (lock?.machine_kind === undefined || lock.machine_kind !== cloud.machine_kind);
|
|
62558
|
+
let defaultModelLocalChanged = false;
|
|
62559
|
+
let defaultModelCloudChanged = false;
|
|
62560
|
+
let defaultModelConflict = false;
|
|
62561
|
+
let defaultModelConverged = false;
|
|
62562
|
+
if (defaultModelSupported) {
|
|
62563
|
+
const cloudValue = cloud.default_model ?? null;
|
|
62564
|
+
const localAuthored = manifest.default_model !== undefined;
|
|
62565
|
+
const lockSupported = hasOwn(lock, "default_model");
|
|
62566
|
+
if (localAuthored) {
|
|
62567
|
+
const localValue = manifest.default_model ?? null;
|
|
62568
|
+
if (lockSupported) {
|
|
62569
|
+
const lockValue = lock?.default_model ?? null;
|
|
62570
|
+
const localMoved = localValue !== lockValue;
|
|
62571
|
+
const cloudMoved = cloudValue !== lockValue;
|
|
62572
|
+
defaultModelConflict = localMoved && cloudMoved && localValue !== cloudValue;
|
|
62573
|
+
defaultModelLocalChanged = localMoved && localValue !== cloudValue;
|
|
62574
|
+
defaultModelCloudChanged = cloudMoved && localValue !== cloudValue;
|
|
62575
|
+
defaultModelConverged = localMoved && cloudMoved && localValue === cloudValue;
|
|
62576
|
+
} else {
|
|
62577
|
+
defaultModelLocalChanged = localValue !== cloudValue;
|
|
62578
|
+
defaultModelConverged = localValue === cloudValue;
|
|
62579
|
+
}
|
|
62580
|
+
} else if (lockSupported) {
|
|
62581
|
+
defaultModelCloudChanged = cloudValue !== (lock?.default_model ?? null);
|
|
62582
|
+
}
|
|
62583
|
+
}
|
|
62584
|
+
return {
|
|
62585
|
+
unsupported,
|
|
62586
|
+
machineMismatch,
|
|
62587
|
+
machineLocalChanged,
|
|
62588
|
+
machineCloudChanged,
|
|
62589
|
+
defaultModelLocalChanged,
|
|
62590
|
+
defaultModelCloudChanged,
|
|
62591
|
+
defaultModelConflict,
|
|
62592
|
+
baselineConverged: machineConverged || defaultModelConverged
|
|
62593
|
+
};
|
|
62594
|
+
}
|
|
62492
62595
|
|
|
62493
62596
|
// src/core/secrets-env.ts
|
|
62494
62597
|
import path75 from "node:path";
|
|
@@ -62714,7 +62817,7 @@ async function runAgentUnpack(cwd2, args) {
|
|
|
62714
62817
|
cwd: cwd2,
|
|
62715
62818
|
scope,
|
|
62716
62819
|
resolveConflict: async (_c) => "overwrite",
|
|
62717
|
-
resolveSecret:
|
|
62820
|
+
resolveSecret: makeLocalSecretResolver(cwd2)
|
|
62718
62821
|
};
|
|
62719
62822
|
const sp = de();
|
|
62720
62823
|
sp.start("Installing harness layout…");
|
|
@@ -62799,10 +62902,10 @@ function stageLocalSkill(source, cwd2, stageRoot, scope, toInstall) {
|
|
|
62799
62902
|
return null;
|
|
62800
62903
|
}
|
|
62801
62904
|
try {
|
|
62802
|
-
const parsed =
|
|
62905
|
+
const parsed = resolveSkillSourceForUnpack(source);
|
|
62803
62906
|
if (parsed.type === "local" || parsed.type === "inline")
|
|
62804
62907
|
return null;
|
|
62805
|
-
const slug =
|
|
62908
|
+
const slug = skillComponentSlugForUnpack(source);
|
|
62806
62909
|
const compDir = path76.join(stageRoot, "skill", slug);
|
|
62807
62910
|
ensureDir(compDir);
|
|
62808
62911
|
toInstall.push({
|
|
@@ -62818,10 +62921,35 @@ function stageLocalSkill(source, cwd2, stageRoot, scope, toInstall) {
|
|
|
62818
62921
|
return `Skill ${source}: ${err.message} — skipped.`;
|
|
62819
62922
|
}
|
|
62820
62923
|
}
|
|
62924
|
+
function resolveSkillSourceForUnpack(source) {
|
|
62925
|
+
if (source.startsWith("registry:")) {
|
|
62926
|
+
const parsed = parseSkillSource2(source);
|
|
62927
|
+
if (parsed.kind !== "registry" || !parsed.creator) {
|
|
62928
|
+
throw new Error(`Registry skill source must include a creator: ${source}`);
|
|
62929
|
+
}
|
|
62930
|
+
return {
|
|
62931
|
+
type: "brainbase",
|
|
62932
|
+
creator: parsed.creator,
|
|
62933
|
+
slug: parsed.slug,
|
|
62934
|
+
version: parsed.version
|
|
62935
|
+
};
|
|
62936
|
+
}
|
|
62937
|
+
return parseSkillSource(source);
|
|
62938
|
+
}
|
|
62939
|
+
function makeLocalSecretResolver(cwd2) {
|
|
62940
|
+
const secrets = readLocalSecrets(cwd2);
|
|
62941
|
+
return async (key2) => secrets[key2] ?? null;
|
|
62942
|
+
}
|
|
62943
|
+
function skillComponentSlugForUnpack(source) {
|
|
62944
|
+
if (source.startsWith("registry:")) {
|
|
62945
|
+
const parsed = parseSkillSource2(source);
|
|
62946
|
+
if (parsed.kind === "registry") {
|
|
62947
|
+
return registrySkillComponentSlug(parsed);
|
|
62948
|
+
}
|
|
62949
|
+
}
|
|
62950
|
+
return defaultSlugForSource(source);
|
|
62951
|
+
}
|
|
62821
62952
|
function defaultSlugForSource(source) {
|
|
62822
|
-
const reg = /^registry:(?:[a-z0-9_-]+\/)?([a-z0-9_-]+)/i.exec(source);
|
|
62823
|
-
if (reg)
|
|
62824
|
-
return reg[1].toLowerCase();
|
|
62825
62953
|
const gh = /^(?:github|git):[^/]*\/?([a-z0-9_-]+)/i.exec(source);
|
|
62826
62954
|
if (gh)
|
|
62827
62955
|
return gh[1].toLowerCase();
|
|
@@ -62915,6 +63043,23 @@ async function runAgentPull(cwd2, args) {
|
|
|
62915
63043
|
lock: lock?.components ?? [],
|
|
62916
63044
|
cloud: cloud.components
|
|
62917
63045
|
});
|
|
63046
|
+
const config = diffAgentConfig(existingManifest ?? {}, lock?.agentMeta, cloudAgent);
|
|
63047
|
+
const localRuntimeConfigChanged = config.machineLocalChanged || config.defaultModelLocalChanged;
|
|
63048
|
+
if (localRuntimeConfigChanged && !args.force) {
|
|
63049
|
+
f2.error(`Runtime config has local edits that pull would overwrite: ${[
|
|
63050
|
+
...config.machineLocalChanged ? ["machine_kind"] : [],
|
|
63051
|
+
...config.defaultModelLocalChanged ? ["default_model"] : []
|
|
63052
|
+
].join(", ")}.`);
|
|
63053
|
+
if (config.machineLocalChanged) {
|
|
63054
|
+
f2.info(`machine_kind cannot change on an existing agent. Run ${import_picocolors26.default.cyan("brainbase agent pull --force")} to discard the edit, or create a new agent for that provider.`);
|
|
63055
|
+
}
|
|
63056
|
+
if (config.defaultModelLocalChanged) {
|
|
63057
|
+
f2.info(`Push the default_model edit first, or run ${import_picocolors26.default.cyan("brainbase agent pull --force")} to discard it.`);
|
|
63058
|
+
}
|
|
63059
|
+
process.exitCode = 1;
|
|
63060
|
+
return;
|
|
63061
|
+
}
|
|
63062
|
+
const runtimeConfigChanged = config.machineCloudChanged || config.defaultModelCloudChanged || !!args.force && localRuntimeConfigChanged;
|
|
62918
63063
|
const toInstallKeys = new Set;
|
|
62919
63064
|
const toRemoveKeys = new Set;
|
|
62920
63065
|
const conflicts = [];
|
|
@@ -62968,7 +63113,7 @@ async function runAgentPull(cwd2, args) {
|
|
|
62968
63113
|
declaredSlugs: declaredMcpSlugs,
|
|
62969
63114
|
scope: args.scope ?? "project"
|
|
62970
63115
|
});
|
|
62971
|
-
if (toInstallKeys.size === 0 && toRemoveKeys.size === 0 && builtinInstall.length === 0 && builtinRemoveSlugs.length === 0 && !override) {
|
|
63116
|
+
if (toInstallKeys.size === 0 && toRemoveKeys.size === 0 && builtinInstall.length === 0 && builtinRemoveSlugs.length === 0 && !runtimeConfigChanged && !override) {
|
|
62972
63117
|
f2.info(`You're up to date.`);
|
|
62973
63118
|
writeLink(cwd2, buildLinkFromAgent(cloudAgent, harness, readLink(cwd2)));
|
|
62974
63119
|
writeSyncState(cwd2, buildLockFromCloud(agentId, cloud, lock, cloudAgent));
|
|
@@ -63002,6 +63147,13 @@ async function runAgentPull(cwd2, args) {
|
|
|
63002
63147
|
text: String(keepLocalKeys.size)
|
|
63003
63148
|
});
|
|
63004
63149
|
}
|
|
63150
|
+
if (runtimeConfigChanged) {
|
|
63151
|
+
resultRows.push({
|
|
63152
|
+
type: "upd",
|
|
63153
|
+
label: "runtime config",
|
|
63154
|
+
text: "machine/model from cloud"
|
|
63155
|
+
});
|
|
63156
|
+
}
|
|
63005
63157
|
await showResultCard({
|
|
63006
63158
|
title: override ? "PULL (FORCE)" : "PULL",
|
|
63007
63159
|
tone: override ? "warn" : "info",
|
|
@@ -63022,6 +63174,7 @@ async function runAgentPull(cwd2, args) {
|
|
|
63022
63174
|
const stageRoot = stageManifestComponents(installComponents);
|
|
63023
63175
|
const justInstalledPaths = new Map;
|
|
63024
63176
|
try {
|
|
63177
|
+
const availableSecrets = await pullSecrets(cwd2, agentId);
|
|
63025
63178
|
if (installComponents.length > 0 || builtinInstall.length > 0) {
|
|
63026
63179
|
const installSpinner = de();
|
|
63027
63180
|
installSpinner.start("Applying updates…");
|
|
@@ -63032,7 +63185,7 @@ async function runAgentPull(cwd2, args) {
|
|
|
63032
63185
|
rootDir: path77.join(stageRoot, c2.type, c2.slug),
|
|
63033
63186
|
description: c2.description,
|
|
63034
63187
|
meta: c2.meta,
|
|
63035
|
-
payload: proxifyMcpPayload(c2.meta?.mcp),
|
|
63188
|
+
payload: proxifyMcpPayload(structuredClone(c2.meta?.mcp)),
|
|
63036
63189
|
checksum: c2.hash,
|
|
63037
63190
|
source: skillSourceFromMeta(c2)
|
|
63038
63191
|
}));
|
|
@@ -63041,7 +63194,7 @@ async function runAgentPull(cwd2, args) {
|
|
|
63041
63194
|
cwd: cwd2,
|
|
63042
63195
|
scope,
|
|
63043
63196
|
resolveConflict: async (_c) => "overwrite",
|
|
63044
|
-
resolveSecret: async () => null
|
|
63197
|
+
resolveSecret: async (name) => availableSecrets[name] ?? null
|
|
63045
63198
|
};
|
|
63046
63199
|
const result2 = await runHarnessInstall3(adapter.id, componentsForNativeInstall(toInstall, !!args.acp), opts, cloudAgent.name);
|
|
63047
63200
|
installSpinner.stop("Applied.");
|
|
@@ -63096,11 +63249,12 @@ async function runAgentPull(cwd2, args) {
|
|
|
63096
63249
|
agentMeta: {
|
|
63097
63250
|
name: cloudAgent.name,
|
|
63098
63251
|
tagline: cloudAgent.tagline,
|
|
63099
|
-
...cloudAgent.entrypoint ? { entrypoint: cloudAgent.entrypoint.trim() } : {}
|
|
63252
|
+
...cloudAgent.entrypoint ? { entrypoint: cloudAgent.entrypoint.trim() } : {},
|
|
63253
|
+
...cloudAgent.machine_kind ? { machine_kind: cloudAgent.machine_kind } : lock?.agentMeta?.machine_kind ? { machine_kind: lock.agentMeta.machine_kind } : {},
|
|
63254
|
+
...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 } : {}
|
|
63100
63255
|
}
|
|
63101
63256
|
};
|
|
63102
63257
|
writeSyncState(cwd2, newState);
|
|
63103
|
-
await pullSecrets(cwd2, agentId);
|
|
63104
63258
|
await runEntrypointIfPresent(cwd2, yaml, entrypointExecutionAllowed({ flag: args.runEntrypoint, env: process.env }));
|
|
63105
63259
|
$e(`Pulled ${cloudAgent.name} at revision ${cloud.revision}.`);
|
|
63106
63260
|
} finally {
|
|
@@ -63299,10 +63453,14 @@ function mergeManifest(cwd2, prev, cloud, cloudAgent, harness) {
|
|
|
63299
63453
|
return entry;
|
|
63300
63454
|
});
|
|
63301
63455
|
const caps = capabilitiesFromAgent(cloudAgent);
|
|
63456
|
+
const machineKind = cloudAgent.machine_kind ?? prev?.machine_kind;
|
|
63457
|
+
const defaultModelSupported = Object.prototype.hasOwnProperty.call(cloudAgent, "default_model");
|
|
63302
63458
|
return {
|
|
63303
63459
|
schema: 1,
|
|
63304
63460
|
id: cloudAgent.id,
|
|
63305
63461
|
harness,
|
|
63462
|
+
...machineKind ? { machine_kind: machineKind } : {},
|
|
63463
|
+
...defaultModelSupported ? cloudAgent.default_model ? { default_model: cloudAgent.default_model } : prev?.default_model === null ? { default_model: null } : {} : prev?.default_model !== undefined ? { default_model: prev.default_model } : {},
|
|
63306
63464
|
agent: {
|
|
63307
63465
|
name: cloudAgent.name,
|
|
63308
63466
|
...cloudAgent.tagline ? { tagline: cloudAgent.tagline } : {}
|
|
@@ -63379,7 +63537,9 @@ function buildLockFromCloud(agent_id, cloud, prev, cloudAgent) {
|
|
|
63379
63537
|
agentMeta: cloudAgent ? {
|
|
63380
63538
|
name: cloudAgent.name,
|
|
63381
63539
|
tagline: cloudAgent.tagline,
|
|
63382
|
-
...cloudAgent.entrypoint ? { entrypoint: cloudAgent.entrypoint.trim() } : {}
|
|
63540
|
+
...cloudAgent.entrypoint ? { entrypoint: cloudAgent.entrypoint.trim() } : {},
|
|
63541
|
+
...cloudAgent.machine_kind ? { machine_kind: cloudAgent.machine_kind } : prev?.agentMeta?.machine_kind ? { machine_kind: prev.agentMeta.machine_kind } : {},
|
|
63542
|
+
...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 } : {}
|
|
63383
63543
|
} : prev?.agentMeta
|
|
63384
63544
|
};
|
|
63385
63545
|
}
|
|
@@ -63449,6 +63609,7 @@ async function runEntrypointIfPresent(cwd2, manifest, execute) {
|
|
|
63449
63609
|
}
|
|
63450
63610
|
}
|
|
63451
63611
|
async function pullSecrets(cwd2, agentId) {
|
|
63612
|
+
const localSecrets = readLocalSecrets(cwd2);
|
|
63452
63613
|
let cloudSecrets;
|
|
63453
63614
|
const sp = de();
|
|
63454
63615
|
sp.start("Fetching secrets…");
|
|
@@ -63461,9 +63622,8 @@ async function pullSecrets(cwd2, agentId) {
|
|
|
63461
63622
|
if (err instanceof ApiError && err.status !== 404) {
|
|
63462
63623
|
f2.warn(`Skipped secrets: ${err.message}`);
|
|
63463
63624
|
}
|
|
63464
|
-
return;
|
|
63625
|
+
return localSecrets;
|
|
63465
63626
|
}
|
|
63466
|
-
const localSecrets = readLocalSecrets(cwd2);
|
|
63467
63627
|
const diff2 = diffSecrets(localSecrets, cloudSecrets);
|
|
63468
63628
|
if (diff2.localOnly.length > 0 || diff2.changed.length > 0) {
|
|
63469
63629
|
if (diff2.localOnly.length) {
|
|
@@ -63475,6 +63635,7 @@ async function pullSecrets(cwd2, agentId) {
|
|
|
63475
63635
|
}
|
|
63476
63636
|
const merged = { ...cloudSecrets, ...localSecrets };
|
|
63477
63637
|
writeLocalSecrets(cwd2, merged);
|
|
63638
|
+
return merged;
|
|
63478
63639
|
}
|
|
63479
63640
|
function handleApiError2(err) {
|
|
63480
63641
|
if (err instanceof ApiError) {
|
|
@@ -63703,8 +63864,12 @@ async function runAgentPush(cwd2, args) {
|
|
|
63703
63864
|
const sp = de();
|
|
63704
63865
|
sp.start(`Fetching cloud state…`);
|
|
63705
63866
|
let cloud;
|
|
63867
|
+
let cloudAgent;
|
|
63706
63868
|
try {
|
|
63707
|
-
cloud = await
|
|
63869
|
+
[cloud, cloudAgent] = await Promise.all([
|
|
63870
|
+
api.getAgentManifest(agentId),
|
|
63871
|
+
api.getAgent(agentId)
|
|
63872
|
+
]);
|
|
63708
63873
|
sp.stop(`Cloud revision ${cloud.revision}.`);
|
|
63709
63874
|
} catch (err) {
|
|
63710
63875
|
sp.stop("Failed.");
|
|
@@ -63717,6 +63882,33 @@ async function runAgentPush(cwd2, args) {
|
|
|
63717
63882
|
lock: lock?.components ?? [],
|
|
63718
63883
|
cloud: cloud.components
|
|
63719
63884
|
});
|
|
63885
|
+
const config = diffAgentConfig(manifest, lock?.agentMeta, cloudAgent);
|
|
63886
|
+
if (config.unsupported.length > 0) {
|
|
63887
|
+
f2.error(`This control plane does not support declarative ${config.unsupported.join(" / ")} config.`);
|
|
63888
|
+
f2.info(`Use the MAS control plane, then run ${import_picocolors28.default.cyan("brainbase agent pull")} before retrying.`);
|
|
63889
|
+
process.exitCode = 1;
|
|
63890
|
+
return;
|
|
63891
|
+
}
|
|
63892
|
+
if (config.machineMismatch) {
|
|
63893
|
+
if (config.machineCloudChanged && !config.machineLocalChanged) {
|
|
63894
|
+
f2.error("Cannot push: machine_kind changed on the cloud.");
|
|
63895
|
+
f2.info(`Run ${import_picocolors28.default.cyan("brainbase agent pull")} to accept the cloud provider.`);
|
|
63896
|
+
} else {
|
|
63897
|
+
f2.error(`Cannot change machine_kind on an existing agent (${import_picocolors28.default.dim(cloudAgent.machine_kind ?? "unknown")} → ${import_picocolors28.default.bold(manifest.machine_kind)}).`);
|
|
63898
|
+
f2.info("machine_kind applies when the agent is created; create a new agent to use a different provider.");
|
|
63899
|
+
}
|
|
63900
|
+
process.exitCode = 1;
|
|
63901
|
+
return;
|
|
63902
|
+
}
|
|
63903
|
+
if (config.defaultModelConflict && !args.force) {
|
|
63904
|
+
f2.error("Cannot push: default_model changed both locally and on the cloud.");
|
|
63905
|
+
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 model.`);
|
|
63906
|
+
process.exitCode = 1;
|
|
63907
|
+
return;
|
|
63908
|
+
}
|
|
63909
|
+
if (config.defaultModelConflict && args.force) {
|
|
63910
|
+
f2.warn(`${import_picocolors28.default.yellow("--force")}: overwriting the cloud default_model with the local value.`);
|
|
63911
|
+
}
|
|
63720
63912
|
const registryRefs = new Map;
|
|
63721
63913
|
for (const entry of manifest.skills) {
|
|
63722
63914
|
try {
|
|
@@ -63775,14 +63967,7 @@ async function runAgentPush(cwd2, args) {
|
|
|
63775
63967
|
row.status = "modified-local";
|
|
63776
63968
|
}
|
|
63777
63969
|
}
|
|
63778
|
-
|
|
63779
|
-
if (!cloudMeta) {
|
|
63780
|
-
try {
|
|
63781
|
-
const a3 = await api.getAgent(agentId);
|
|
63782
|
-
cloudMeta = { name: a3.name, tagline: a3.tagline, entrypoint: a3.entrypoint };
|
|
63783
|
-
} catch {}
|
|
63784
|
-
}
|
|
63785
|
-
const meta = diffAgentMeta(manifest.agent, lock?.agentMeta, cloudMeta);
|
|
63970
|
+
const meta = diffAgentMeta(manifest.agent, lock?.agentMeta, cloudAgent);
|
|
63786
63971
|
let resolvedEntrypoint;
|
|
63787
63972
|
if (manifest.entrypoint) {
|
|
63788
63973
|
const body = resolveEntrypoint(cwd2, manifest);
|
|
@@ -63832,10 +64017,6 @@ async function runAgentPush(cwd2, args) {
|
|
|
63832
64017
|
}
|
|
63833
64018
|
const { toSend, conflicts, upstreamOnly } = partitionPushRows(rows, !!args.force);
|
|
63834
64019
|
const forcedOverrides = args.force ? rows.filter((r2) => r2.status === "modified-both") : [];
|
|
63835
|
-
if (!meta.localChanged && !entrypointChanged && toSend.length === 0 && conflicts.length === 0) {
|
|
63836
|
-
f2.info("Nothing to push — local is in sync with the cloud.");
|
|
63837
|
-
return;
|
|
63838
|
-
}
|
|
63839
64020
|
if (conflicts.length > 0) {
|
|
63840
64021
|
f2.error(`Cannot push: ${conflicts.length} component${conflicts.length === 1 ? "" : "s"} changed both locally and on the cloud:`);
|
|
63841
64022
|
for (const r2 of conflicts) {
|
|
@@ -63857,6 +64038,61 @@ async function runAgentPush(cwd2, args) {
|
|
|
63857
64038
|
}
|
|
63858
64039
|
f2.info(`If you push now, your push targets revision ${cloud.revision} and may race. Consider \`brainbase agent pull\` first.`);
|
|
63859
64040
|
}
|
|
64041
|
+
if (config.defaultModelCloudChanged || config.machineCloudChanged) {
|
|
64042
|
+
f2.warn(`Cloud runtime config changed since the last sync. Run ${import_picocolors28.default.cyan("brainbase agent pull")} to accept it locally.`);
|
|
64043
|
+
}
|
|
64044
|
+
const shouldPushManifest = meta.localChanged || entrypointChanged || toSend.length > 0;
|
|
64045
|
+
const shouldUpdateAgent = meta.localChanged || entrypointChanged || config.defaultModelLocalChanged;
|
|
64046
|
+
const hasAgentChanges = shouldPushManifest || shouldUpdateAgent;
|
|
64047
|
+
const outgoing = hasAgentChanges ? await buildOutgoingComponents(cwd2, manifest, cloud, resolvedVersions) : null;
|
|
64048
|
+
if (hasAgentChanges && outgoing === null) {
|
|
64049
|
+
process.exitCode = 1;
|
|
64050
|
+
return;
|
|
64051
|
+
}
|
|
64052
|
+
let secretPlan = null;
|
|
64053
|
+
try {
|
|
64054
|
+
secretPlan = await planSecretPush(cwd2, agentId);
|
|
64055
|
+
} catch (err) {
|
|
64056
|
+
if (!hasAgentChanges) {
|
|
64057
|
+
handleApiError3(err);
|
|
64058
|
+
return;
|
|
64059
|
+
}
|
|
64060
|
+
f2.warn(`Couldn't read cloud secrets to diff: ${err.message}. Skipping secret push.`);
|
|
64061
|
+
}
|
|
64062
|
+
if (!hasAgentChanges && config.baselineConverged) {
|
|
64063
|
+
writeSyncState(cwd2, lock ? {
|
|
64064
|
+
...lock,
|
|
64065
|
+
synced_at: new Date().toISOString(),
|
|
64066
|
+
agentMeta: buildAgentMetaAfterPush({
|
|
64067
|
+
manifest,
|
|
64068
|
+
lock,
|
|
64069
|
+
cloudAgent,
|
|
64070
|
+
resolvedEntrypoint,
|
|
64071
|
+
config
|
|
64072
|
+
})
|
|
64073
|
+
} : {
|
|
64074
|
+
schemaVersion: 1,
|
|
64075
|
+
agent_id: agentId,
|
|
64076
|
+
revision: cloud.revision,
|
|
64077
|
+
synced_at: new Date().toISOString(),
|
|
64078
|
+
components: [],
|
|
64079
|
+
agentMeta: buildAgentMetaAfterPush({
|
|
64080
|
+
manifest,
|
|
64081
|
+
lock,
|
|
64082
|
+
cloudAgent,
|
|
64083
|
+
resolvedEntrypoint,
|
|
64084
|
+
config
|
|
64085
|
+
})
|
|
64086
|
+
});
|
|
64087
|
+
}
|
|
64088
|
+
if (!hasAgentChanges && !secretPlan) {
|
|
64089
|
+
if (config.defaultModelCloudChanged || config.machineCloudChanged) {
|
|
64090
|
+
f2.info("Nothing local to push; cloud runtime config is awaiting pull.");
|
|
64091
|
+
return;
|
|
64092
|
+
}
|
|
64093
|
+
f2.info("Nothing to push — local is in sync with the cloud.");
|
|
64094
|
+
return;
|
|
64095
|
+
}
|
|
63860
64096
|
const sendKeys = new Set(toSend.map((r2) => r2.key));
|
|
63861
64097
|
for (const u2 of skillUpdates) {
|
|
63862
64098
|
if (!sendKeys.has(compKey("skill", u2.componentSlug)))
|
|
@@ -63882,6 +64118,13 @@ async function runAgentPush(cwd2, args) {
|
|
|
63882
64118
|
text: resolvedEntrypoint === "" ? "cleared" : "updated"
|
|
63883
64119
|
});
|
|
63884
64120
|
}
|
|
64121
|
+
if (config.defaultModelLocalChanged) {
|
|
64122
|
+
resultRows.push({
|
|
64123
|
+
type: "upd",
|
|
64124
|
+
label: "default model",
|
|
64125
|
+
text: manifest.default_model === null ? "cleared" : manifest.default_model
|
|
64126
|
+
});
|
|
64127
|
+
}
|
|
63885
64128
|
if (toSend.length) {
|
|
63886
64129
|
resultRows.push({
|
|
63887
64130
|
type: "add",
|
|
@@ -63889,6 +64132,13 @@ async function runAgentPush(cwd2, args) {
|
|
|
63889
64132
|
text: `${toSend.length} · ${toSend.map((r2) => `${r2.type}/${r2.slug}`).join(", ")}`
|
|
63890
64133
|
});
|
|
63891
64134
|
}
|
|
64135
|
+
if (secretPlan) {
|
|
64136
|
+
resultRows.push({
|
|
64137
|
+
type: "upd",
|
|
64138
|
+
label: "secrets",
|
|
64139
|
+
text: secretDiffSummary(secretPlan.diff)
|
|
64140
|
+
});
|
|
64141
|
+
}
|
|
63892
64142
|
await showResultCard({
|
|
63893
64143
|
title: "PUSH",
|
|
63894
64144
|
tone: "info",
|
|
@@ -63902,9 +64152,15 @@ async function runAgentPush(cwd2, args) {
|
|
|
63902
64152
|
return;
|
|
63903
64153
|
}
|
|
63904
64154
|
}
|
|
63905
|
-
if (
|
|
64155
|
+
if (!hasAgentChanges) {
|
|
64156
|
+
if (!secretPlan || !await pushSecrets(agentId, secretPlan))
|
|
64157
|
+
return;
|
|
64158
|
+
$e(`Pushed secrets for ${manifest.agent.name}.`);
|
|
64159
|
+
return;
|
|
64160
|
+
}
|
|
64161
|
+
if (meta.localChanged || entrypointChanged || config.defaultModelLocalChanged) {
|
|
63906
64162
|
const metaSpinner = de();
|
|
63907
|
-
metaSpinner.start("Updating agent
|
|
64163
|
+
metaSpinner.start("Updating agent config…");
|
|
63908
64164
|
try {
|
|
63909
64165
|
const update2 = {};
|
|
63910
64166
|
if (meta.localChanged) {
|
|
@@ -63914,16 +64170,37 @@ async function runAgentPush(cwd2, args) {
|
|
|
63914
64170
|
if (entrypointChanged) {
|
|
63915
64171
|
update2.entrypoint = resolvedEntrypoint;
|
|
63916
64172
|
}
|
|
63917
|
-
|
|
63918
|
-
|
|
64173
|
+
if (config.defaultModelLocalChanged) {
|
|
64174
|
+
update2.default_model = manifest.default_model ?? null;
|
|
64175
|
+
}
|
|
64176
|
+
cloudAgent = await api.updateAgent(agentId, update2);
|
|
64177
|
+
metaSpinner.stop("Agent config updated.");
|
|
63919
64178
|
} catch (err) {
|
|
63920
64179
|
metaSpinner.stop("Failed.");
|
|
63921
64180
|
return handleApiError3(err);
|
|
63922
64181
|
}
|
|
63923
64182
|
}
|
|
63924
|
-
|
|
63925
|
-
|
|
64183
|
+
if (!shouldPushManifest) {
|
|
64184
|
+
const state = {
|
|
64185
|
+
schemaVersion: 1,
|
|
64186
|
+
agent_id: agentId,
|
|
64187
|
+
revision: cloud.revision,
|
|
64188
|
+
synced_at: new Date().toISOString(),
|
|
64189
|
+
components: lock?.components ?? [],
|
|
64190
|
+
agentMeta: buildAgentMetaAfterPush({
|
|
64191
|
+
manifest,
|
|
64192
|
+
lock,
|
|
64193
|
+
cloudAgent,
|
|
64194
|
+
resolvedEntrypoint,
|
|
64195
|
+
config
|
|
64196
|
+
})
|
|
64197
|
+
};
|
|
64198
|
+
writeSyncState(cwd2, state);
|
|
64199
|
+
if (secretPlan && !await pushSecrets(agentId, secretPlan))
|
|
64200
|
+
return;
|
|
64201
|
+
$e(`Pushed agent config for ${manifest.agent.name}.`);
|
|
63926
64202
|
return;
|
|
64203
|
+
}
|
|
63927
64204
|
const pushSpinner = de();
|
|
63928
64205
|
pushSpinner.start("Pushing…");
|
|
63929
64206
|
let updatedCloud;
|
|
@@ -63939,6 +64216,7 @@ async function runAgentPush(cwd2, args) {
|
|
|
63939
64216
|
if (err instanceof ApiError && err.status === 409) {
|
|
63940
64217
|
f2.error(err.message);
|
|
63941
64218
|
f2.info(`Run ${import_picocolors28.default.cyan("brainbase agent pull")} and try again.`);
|
|
64219
|
+
process.exitCode = 1;
|
|
63942
64220
|
return;
|
|
63943
64221
|
}
|
|
63944
64222
|
return handleApiError3(err);
|
|
@@ -63985,43 +64263,67 @@ async function runAgentPush(cwd2, args) {
|
|
|
63985
64263
|
...decl ? { source: decl } : {}
|
|
63986
64264
|
};
|
|
63987
64265
|
}),
|
|
63988
|
-
agentMeta: {
|
|
63989
|
-
|
|
63990
|
-
|
|
63991
|
-
|
|
63992
|
-
|
|
64266
|
+
agentMeta: buildAgentMetaAfterPush({
|
|
64267
|
+
manifest,
|
|
64268
|
+
lock,
|
|
64269
|
+
cloudAgent,
|
|
64270
|
+
resolvedEntrypoint,
|
|
64271
|
+
config
|
|
64272
|
+
})
|
|
63993
64273
|
};
|
|
63994
64274
|
writeSyncState(cwd2, newLock);
|
|
63995
|
-
await pushSecrets(
|
|
64275
|
+
if (secretPlan && !await pushSecrets(agentId, secretPlan)) {
|
|
64276
|
+
return;
|
|
64277
|
+
}
|
|
63996
64278
|
$e(`Pushed ${manifest.agent.name} at revision ${updatedCloud.revision}.`);
|
|
63997
64279
|
}
|
|
63998
|
-
|
|
64280
|
+
function buildAgentMetaAfterPush({
|
|
64281
|
+
manifest,
|
|
64282
|
+
lock,
|
|
64283
|
+
cloudAgent,
|
|
64284
|
+
resolvedEntrypoint,
|
|
64285
|
+
config
|
|
64286
|
+
}) {
|
|
64287
|
+
return {
|
|
64288
|
+
name: manifest.agent.name,
|
|
64289
|
+
tagline: manifest.agent.tagline,
|
|
64290
|
+
entrypoint: resolvedEntrypoint !== undefined ? resolvedEntrypoint.trim() : lock?.agentMeta?.entrypoint,
|
|
64291
|
+
...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 } : {},
|
|
64292
|
+
...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 } : {}
|
|
64293
|
+
};
|
|
64294
|
+
}
|
|
64295
|
+
async function planSecretPush(cwd2, agentId) {
|
|
64296
|
+
if (!exists(secretsPath(cwd2)))
|
|
64297
|
+
return null;
|
|
63999
64298
|
const localSecrets = readLocalSecrets(cwd2);
|
|
64000
64299
|
if (Object.keys(localSecrets).length === 0)
|
|
64001
|
-
return;
|
|
64002
|
-
|
|
64003
|
-
|
|
64004
|
-
const res = await api.getAgentSecrets(agentId);
|
|
64005
|
-
cloudSecrets = res.secrets ?? {};
|
|
64006
|
-
} catch (err) {
|
|
64007
|
-
f2.warn(`Couldn't read cloud secrets to diff: ${err.message}. Skipping secret push.`);
|
|
64008
|
-
return;
|
|
64009
|
-
}
|
|
64300
|
+
return null;
|
|
64301
|
+
const res = await api.getAgentSecrets(agentId);
|
|
64302
|
+
const cloudSecrets = res.secrets ?? {};
|
|
64010
64303
|
const diff2 = diffSecrets(localSecrets, cloudSecrets);
|
|
64011
64304
|
if (diff2.localOnly.length === 0 && diff2.changed.length === 0 && diff2.cloudOnly.length === 0) {
|
|
64012
|
-
return;
|
|
64305
|
+
return null;
|
|
64013
64306
|
}
|
|
64307
|
+
return { secrets: localSecrets, diff: diff2 };
|
|
64308
|
+
}
|
|
64309
|
+
async function pushSecrets(agentId, plan) {
|
|
64014
64310
|
const sp = de();
|
|
64015
64311
|
sp.start("Pushing secrets…");
|
|
64016
64312
|
try {
|
|
64017
|
-
await api.putAgentSecrets(agentId,
|
|
64018
|
-
sp.stop(`Secrets pushed (${
|
|
64313
|
+
await api.putAgentSecrets(agentId, plan.secrets);
|
|
64314
|
+
sp.stop(`Secrets pushed (${secretDiffSummary(plan.diff)}).`);
|
|
64315
|
+
return true;
|
|
64019
64316
|
} catch (err) {
|
|
64020
64317
|
sp.stop("Failed.");
|
|
64021
64318
|
handleApiError3(err);
|
|
64319
|
+
return false;
|
|
64022
64320
|
}
|
|
64023
64321
|
}
|
|
64322
|
+
function secretDiffSummary(diff2) {
|
|
64323
|
+
return `${diff2.localOnly.length} added, ${diff2.changed.length} updated, ${diff2.cloudOnly.length} removed`;
|
|
64324
|
+
}
|
|
64024
64325
|
function handleApiError3(err) {
|
|
64326
|
+
process.exitCode = 1;
|
|
64025
64327
|
if (err instanceof ApiError) {
|
|
64026
64328
|
if (err.status === 401) {
|
|
64027
64329
|
f2.error("Your session is invalid. Run `brainbase login` and try again.");
|
|
@@ -64046,10 +64348,14 @@ async function runAgentStatus(cwd2) {
|
|
|
64046
64348
|
const manifest = hasManifest(cwd2) ? readManifest(cwd2) : null;
|
|
64047
64349
|
const lock = readSyncState(cwd2);
|
|
64048
64350
|
let cloud = null;
|
|
64351
|
+
let cloudAgent = null;
|
|
64049
64352
|
const sp = de();
|
|
64050
64353
|
sp.start(`Fetching ${link2.name}…`);
|
|
64051
64354
|
try {
|
|
64052
|
-
cloud = await
|
|
64355
|
+
[cloud, cloudAgent] = await Promise.all([
|
|
64356
|
+
api.getAgentManifest(link2.agent_id),
|
|
64357
|
+
api.getAgent(link2.agent_id)
|
|
64358
|
+
]);
|
|
64053
64359
|
sp.stop(`Cloud revision ${cloud.revision}.`);
|
|
64054
64360
|
} catch (err) {
|
|
64055
64361
|
sp.stop("Failed to reach brainbase.");
|
|
@@ -64071,7 +64377,8 @@ async function runAgentStatus(cwd2) {
|
|
|
64071
64377
|
lock: lock?.components ?? [],
|
|
64072
64378
|
cloud: cloud.components
|
|
64073
64379
|
});
|
|
64074
|
-
const meta = diffAgentMeta(manifest.agent, lock?.agentMeta,
|
|
64380
|
+
const meta = diffAgentMeta(manifest.agent, lock?.agentMeta, cloudAgent);
|
|
64381
|
+
const config = diffAgentConfig(manifest, lock?.agentMeta, cloudAgent);
|
|
64075
64382
|
const toPush = [];
|
|
64076
64383
|
const toPull = [];
|
|
64077
64384
|
const conflicts = [];
|
|
@@ -64115,6 +64422,29 @@ async function runAgentStatus(cwd2) {
|
|
|
64115
64422
|
}
|
|
64116
64423
|
lines.push("");
|
|
64117
64424
|
}
|
|
64425
|
+
if (config.unsupported.length > 0 || config.machineMismatch || config.machineCloudChanged || config.defaultModelLocalChanged || config.defaultModelCloudChanged) {
|
|
64426
|
+
lines.push(` ${import_picocolors29.default.bold("runtime config")}`);
|
|
64427
|
+
if (config.unsupported.length > 0) {
|
|
64428
|
+
lines.push(` ${import_picocolors29.default.red("! unsupported")} ${config.unsupported.join(", ")} not exposed by this control plane`);
|
|
64429
|
+
}
|
|
64430
|
+
if (config.machineMismatch && !(config.machineCloudChanged && !config.machineLocalChanged)) {
|
|
64431
|
+
lines.push(` ${import_picocolors29.default.red("! blocked")} machine_kind differs; provider changes require a new agent`);
|
|
64432
|
+
}
|
|
64433
|
+
if (config.machineCloudChanged && !config.machineLocalChanged) {
|
|
64434
|
+
lines.push(` ${import_picocolors29.default.cyan("← pull")} machine_kind changed on cloud`);
|
|
64435
|
+
}
|
|
64436
|
+
if (config.defaultModelConflict) {
|
|
64437
|
+
lines.push(` ${import_picocolors29.default.red("! conflict")} default_model changed locally and on cloud`);
|
|
64438
|
+
} else {
|
|
64439
|
+
if (config.defaultModelLocalChanged) {
|
|
64440
|
+
lines.push(` ${import_picocolors29.default.yellow("→ push")} default_model edited locally`);
|
|
64441
|
+
}
|
|
64442
|
+
if (config.defaultModelCloudChanged) {
|
|
64443
|
+
lines.push(` ${import_picocolors29.default.cyan("← pull")} default_model changed on cloud`);
|
|
64444
|
+
}
|
|
64445
|
+
}
|
|
64446
|
+
lines.push("");
|
|
64447
|
+
}
|
|
64118
64448
|
try {
|
|
64119
64449
|
const localSecrets = readLocalSecrets(cwd2);
|
|
64120
64450
|
const cloudRes = await api.getAgentSecrets(link2.agent_id);
|
|
@@ -64131,7 +64461,7 @@ async function runAgentStatus(cwd2) {
|
|
|
64131
64461
|
lines.push("");
|
|
64132
64462
|
}
|
|
64133
64463
|
} catch {}
|
|
64134
|
-
if (conflicts.length === 0 && toPush.length === 0 && toPull.length === 0) {
|
|
64464
|
+
if (conflicts.length === 0 && toPush.length === 0 && toPull.length === 0 && !meta.localChanged && !meta.cloudChanged && config.unsupported.length === 0 && !config.machineMismatch && !config.machineCloudChanged && !config.defaultModelLocalChanged && !config.defaultModelCloudChanged) {
|
|
64135
64465
|
lines.push(` ${import_picocolors29.default.green("✓")} everything is in sync`);
|
|
64136
64466
|
lines.push("");
|
|
64137
64467
|
console.log(lines.join(`
|
|
@@ -64272,7 +64602,7 @@ async function runAgentCreate(cwd2, args) {
|
|
|
64272
64602
|
}
|
|
64273
64603
|
let org;
|
|
64274
64604
|
if (args.orgId) {
|
|
64275
|
-
const found = orgs.find((o2) => o2.id === args.orgId);
|
|
64605
|
+
const found = orgs.find((o2) => o2.id === args.orgId || o2.slug === args.orgId);
|
|
64276
64606
|
if (!found) {
|
|
64277
64607
|
f2.error(`Org ${args.orgId} not found or you're not a member.`);
|
|
64278
64608
|
return;
|
|
@@ -64285,7 +64615,7 @@ async function runAgentCreate(cwd2, args) {
|
|
|
64285
64615
|
const orgId = await select({
|
|
64286
64616
|
message: "Pick an organization",
|
|
64287
64617
|
options: orgs.map((o2) => ({ value: o2.id, label: o2.name, hint: o2.role })),
|
|
64288
|
-
flagHint: "Pass --org <id> to choose non-interactively."
|
|
64618
|
+
flagHint: "Pass --org <id-or-slug> to choose non-interactively."
|
|
64289
64619
|
});
|
|
64290
64620
|
org = orgs.find((o2) => o2.id === orgId);
|
|
64291
64621
|
}
|
|
@@ -64405,7 +64735,9 @@ async function runAgentCreate(cwd2, args) {
|
|
|
64405
64735
|
name: agentName,
|
|
64406
64736
|
tagline,
|
|
64407
64737
|
harness,
|
|
64408
|
-
...resolvedEntrypoint !== undefined ? { entrypoint: resolvedEntrypoint } : {}
|
|
64738
|
+
...resolvedEntrypoint !== undefined ? { entrypoint: resolvedEntrypoint } : {},
|
|
64739
|
+
...manifest.machine_kind !== undefined ? { machine_kind: manifest.machine_kind } : {},
|
|
64740
|
+
...manifest.default_model !== undefined ? { default_model: manifest.default_model } : {}
|
|
64409
64741
|
});
|
|
64410
64742
|
createSpinner.stop(`Created ${import_picocolors31.default.bold(agent.name)}.`);
|
|
64411
64743
|
} catch (err) {
|
|
@@ -64413,6 +64745,29 @@ async function runAgentCreate(cwd2, args) {
|
|
|
64413
64745
|
handleApiError4(err);
|
|
64414
64746
|
return;
|
|
64415
64747
|
}
|
|
64748
|
+
const machineConfigMissing = manifest.machine_kind !== undefined && agent.machine_kind !== manifest.machine_kind;
|
|
64749
|
+
const modelConfigMissing = manifest.default_model !== undefined && (!Object.prototype.hasOwnProperty.call(agent, "default_model") || (agent.default_model ?? null) !== (manifest.default_model ?? null));
|
|
64750
|
+
if (machineConfigMissing || modelConfigMissing) {
|
|
64751
|
+
manifest.id = agent.id;
|
|
64752
|
+
manifest.harness = harness;
|
|
64753
|
+
writeManifest(cwd2, manifest);
|
|
64754
|
+
const fields = [
|
|
64755
|
+
...machineConfigMissing ? ["machine_kind"] : [],
|
|
64756
|
+
...modelConfigMissing ? ["default_model"] : []
|
|
64757
|
+
];
|
|
64758
|
+
f2.error(`Agent ${import_picocolors31.default.bold(agent.id)} was created, but this control plane did not apply ${fields.join(" / ")}.`);
|
|
64759
|
+
if (machineConfigMissing) {
|
|
64760
|
+
if (agent.machine_kind) {
|
|
64761
|
+
f2.info(`machine_kind is immutable. Run ${import_picocolors31.default.cyan("brainbase agent pull --force")} to accept ${agent.machine_kind}, or delete this agent and recreate it after upgrading the control plane.`);
|
|
64762
|
+
} else {
|
|
64763
|
+
f2.info("machine_kind is immutable and this server did not report the provider it created. Upgrade the control plane, delete this agent, and recreate it.");
|
|
64764
|
+
}
|
|
64765
|
+
} else {
|
|
64766
|
+
f2.info(`Upgrade the control plane, then run ${import_picocolors31.default.cyan("brainbase agent push")} to apply default_model.`);
|
|
64767
|
+
}
|
|
64768
|
+
process.exitCode = 1;
|
|
64769
|
+
return;
|
|
64770
|
+
}
|
|
64416
64771
|
const session = authStatus().session;
|
|
64417
64772
|
let tracking;
|
|
64418
64773
|
const adapter = getRouteAdapter(harness);
|
|
@@ -64514,31 +64869,33 @@ async function runAgentCreate(cwd2, args) {
|
|
|
64514
64869
|
manifest.playbooks = backfill.playbooks;
|
|
64515
64870
|
writeManifest(cwd2, manifest);
|
|
64516
64871
|
}
|
|
64517
|
-
const localHashByKey = new Map;
|
|
64518
|
-
for (const lc of readLocalComponents(cwd2, manifest)) {
|
|
64519
|
-
if (lc.hash)
|
|
64520
|
-
localHashByKey.set(`${lc.type}/${lc.slug}`, lc.hash);
|
|
64521
|
-
}
|
|
64522
|
-
const syncedComponents = updatedCloud.components.map((c2) => ({
|
|
64523
|
-
type: c2.type,
|
|
64524
|
-
slug: c2.slug,
|
|
64525
|
-
hash: localHashByKey.get(`${c2.type}/${c2.slug}`) ?? c2.hash,
|
|
64526
|
-
installedPaths: []
|
|
64527
|
-
}));
|
|
64528
|
-
const state = {
|
|
64529
|
-
schemaVersion: 1,
|
|
64530
|
-
agent_id: agent.id,
|
|
64531
|
-
revision: updatedCloud.revision,
|
|
64532
|
-
synced_at: new Date().toISOString(),
|
|
64533
|
-
components: syncedComponents,
|
|
64534
|
-
agentMeta: {
|
|
64535
|
-
name: agent.name,
|
|
64536
|
-
tagline: agent.tagline,
|
|
64537
|
-
...resolvedEntrypoint ? { entrypoint: resolvedEntrypoint.trim() } : {}
|
|
64538
|
-
}
|
|
64539
|
-
};
|
|
64540
|
-
writeSyncState(cwd2, state);
|
|
64541
64872
|
}
|
|
64873
|
+
const localHashByKey = new Map;
|
|
64874
|
+
for (const lc of readLocalComponents(cwd2, manifest)) {
|
|
64875
|
+
if (lc.hash)
|
|
64876
|
+
localHashByKey.set(`${lc.type}/${lc.slug}`, lc.hash);
|
|
64877
|
+
}
|
|
64878
|
+
const syncedComponents = (updatedCloud?.components ?? []).map((c2) => ({
|
|
64879
|
+
type: c2.type,
|
|
64880
|
+
slug: c2.slug,
|
|
64881
|
+
hash: localHashByKey.get(`${c2.type}/${c2.slug}`) ?? c2.hash,
|
|
64882
|
+
installedPaths: []
|
|
64883
|
+
}));
|
|
64884
|
+
const state = {
|
|
64885
|
+
schemaVersion: 1,
|
|
64886
|
+
agent_id: agent.id,
|
|
64887
|
+
revision: updatedCloud?.revision ?? agent.revision ?? 0,
|
|
64888
|
+
synced_at: new Date().toISOString(),
|
|
64889
|
+
components: syncedComponents,
|
|
64890
|
+
agentMeta: {
|
|
64891
|
+
name: agent.name,
|
|
64892
|
+
tagline: agent.tagline,
|
|
64893
|
+
...resolvedEntrypoint ? { entrypoint: resolvedEntrypoint.trim() } : {},
|
|
64894
|
+
...agent.machine_kind ? { machine_kind: agent.machine_kind } : {},
|
|
64895
|
+
...Object.prototype.hasOwnProperty.call(agent, "default_model") ? { default_model: agent.default_model ?? null } : {}
|
|
64896
|
+
}
|
|
64897
|
+
};
|
|
64898
|
+
writeSyncState(cwd2, state);
|
|
64542
64899
|
$e(`Created ${import_picocolors31.default.bold(agent.name)} and linked this folder.`);
|
|
64543
64900
|
await showResultCard({
|
|
64544
64901
|
title: "CREATED",
|
|
@@ -64632,6 +64989,10 @@ function handleApiError4(err) {
|
|
|
64632
64989
|
|
|
64633
64990
|
// src/cli/agent.ts
|
|
64634
64991
|
async function runAgent(cwd2, sub, args, opts) {
|
|
64992
|
+
if (args.some((arg) => arg === "--help" || arg === "-h")) {
|
|
64993
|
+
printHelp();
|
|
64994
|
+
return;
|
|
64995
|
+
}
|
|
64635
64996
|
switch (sub) {
|
|
64636
64997
|
case "create":
|
|
64637
64998
|
await runAgentCreate(cwd2, {
|
|
@@ -64702,7 +65063,7 @@ function printHelp() {
|
|
|
64702
65063
|
}
|
|
64703
65064
|
|
|
64704
65065
|
// src/cli/orchestration.ts
|
|
64705
|
-
var
|
|
65066
|
+
var import_picocolors39 = __toESM(require_picocolors(), 1);
|
|
64706
65067
|
|
|
64707
65068
|
// src/cli/orchestration-pull.ts
|
|
64708
65069
|
import path82 from "node:path";
|
|
@@ -64730,20 +65091,32 @@ var EdgeSchema = exports_external.object({
|
|
|
64730
65091
|
from: exports_external.string().min(1),
|
|
64731
65092
|
to: exports_external.string().min(1),
|
|
64732
65093
|
description: exports_external.string().optional(),
|
|
64733
|
-
payload_schema: exports_external.record(exports_external.unknown()).optional()
|
|
65094
|
+
payload_schema: exports_external.record(exports_external.unknown()).optional(),
|
|
65095
|
+
settings: exports_external.record(exports_external.unknown()).optional()
|
|
64734
65096
|
});
|
|
64735
65097
|
var TriggerEdgeSchema = exports_external.object({
|
|
64736
65098
|
agent: exports_external.string(),
|
|
64737
65099
|
description: exports_external.string().optional(),
|
|
64738
65100
|
payload_schema: exports_external.record(exports_external.unknown()).optional()
|
|
64739
65101
|
});
|
|
64740
|
-
var
|
|
64741
|
-
|
|
64742
|
-
|
|
65102
|
+
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
65103
|
+
var ScheduleTriggerSchema = exports_external.object({
|
|
65104
|
+
type: exports_external.literal("schedule"),
|
|
65105
|
+
node_id: exports_external.string().regex(UUID_RE, "must be a UUID"),
|
|
65106
|
+
is_active: exports_external.boolean().optional(),
|
|
65107
|
+
config: exports_external.record(exports_external.unknown()).optional(),
|
|
65108
|
+
to: exports_external.array(TriggerEdgeSchema).default([])
|
|
65109
|
+
});
|
|
65110
|
+
var ReadOnlyTriggerSchema = exports_external.object({
|
|
65111
|
+
type: exports_external.string().refine((value) => value !== "schedule", {
|
|
65112
|
+
message: "schedule triggers must use a UUID node_id"
|
|
65113
|
+
}),
|
|
65114
|
+
node_id: exports_external.string().min(1),
|
|
64743
65115
|
is_active: exports_external.boolean().optional(),
|
|
64744
65116
|
config: exports_external.record(exports_external.unknown()).optional(),
|
|
64745
65117
|
to: exports_external.array(TriggerEdgeSchema).default([])
|
|
64746
65118
|
});
|
|
65119
|
+
var TriggerSchema = exports_external.union([ScheduleTriggerSchema, ReadOnlyTriggerSchema]);
|
|
64747
65120
|
var OrchestrationManifestSchema = exports_external.object({
|
|
64748
65121
|
schema: exports_external.literal(1),
|
|
64749
65122
|
orchestration: OrchMetaSchema,
|
|
@@ -64779,7 +65152,9 @@ function writeOrchManifest(cwd2, manifest) {
|
|
|
64779
65152
|
doc.contents = manifest;
|
|
64780
65153
|
doc.commentBefore = ` brainbase-orchestration.yaml — declarative orchestration manifest.
|
|
64781
65154
|
` + ` Committed to source control. Edit by hand, then
|
|
64782
|
-
` + " `brainbase orchestration push`. Member agents live under ./agents/." +
|
|
65155
|
+
` + " `brainbase orchestration push`. Member agents live under ./agents/." + `
|
|
65156
|
+
Schedule triggers are writable. App/Pipedream triggers are preserved
|
|
65157
|
+
` + " as read-only context and ignored by `orchestration push`.";
|
|
64783
65158
|
fs70.writeFileSync(orchManifestPath(cwd2), String(doc), "utf8");
|
|
64784
65159
|
}
|
|
64785
65160
|
function memberDir(cwd2, slug) {
|
|
@@ -64918,6 +65293,7 @@ async function installAgentFresh(input) {
|
|
|
64918
65293
|
const { cwd: cwd2, agent, cloud, harness } = input;
|
|
64919
65294
|
const scope = input.scope ?? "project";
|
|
64920
65295
|
ensureDir(cwd2);
|
|
65296
|
+
const availableSecrets = input.pullSecrets === false ? {} : await pullAgentSecrets(cwd2, agent.id);
|
|
64921
65297
|
const stageRoot = stageManifestComponents2(cloud.components);
|
|
64922
65298
|
const justInstalledPaths = new Map;
|
|
64923
65299
|
const caps = capabilitiesFromAgent(agent);
|
|
@@ -64936,7 +65312,7 @@ async function installAgentFresh(input) {
|
|
|
64936
65312
|
rootDir: path81.join(stageRoot, c2.type, c2.slug),
|
|
64937
65313
|
description: c2.description,
|
|
64938
65314
|
meta: c2.meta,
|
|
64939
|
-
payload: proxifyMcpPayload(c2.meta?.mcp),
|
|
65315
|
+
payload: proxifyMcpPayload(structuredClone(c2.meta?.mcp)),
|
|
64940
65316
|
checksum: c2.hash
|
|
64941
65317
|
}));
|
|
64942
65318
|
toInstall.push(...builtinInstall);
|
|
@@ -64944,7 +65320,7 @@ async function installAgentFresh(input) {
|
|
|
64944
65320
|
cwd: cwd2,
|
|
64945
65321
|
scope,
|
|
64946
65322
|
resolveConflict: async (_c) => "overwrite",
|
|
64947
|
-
resolveSecret: async () => null
|
|
65323
|
+
resolveSecret: async (name) => availableSecrets[name] ?? null
|
|
64948
65324
|
};
|
|
64949
65325
|
const result2 = await runHarnessInstall4(harness, toInstall, installOpts, agent.name);
|
|
64950
65326
|
for (const o2 of result2.installed) {
|
|
@@ -64952,6 +65328,7 @@ async function installAgentFresh(input) {
|
|
|
64952
65328
|
}
|
|
64953
65329
|
}
|
|
64954
65330
|
materializeInstructions2(cwd2, cloud);
|
|
65331
|
+
materializePlaybooks2(cwd2, cloud);
|
|
64955
65332
|
const manifest = input.preserveManifest ? null : buildManifestFromCloud(cloud, agent);
|
|
64956
65333
|
if (manifest)
|
|
64957
65334
|
writeManifest(cwd2, manifest);
|
|
@@ -64979,11 +65356,13 @@ async function installAgentFresh(input) {
|
|
|
64979
65356
|
revision: cloud.revision,
|
|
64980
65357
|
synced_at: new Date().toISOString(),
|
|
64981
65358
|
components: syncedComponents,
|
|
64982
|
-
agentMeta: {
|
|
65359
|
+
agentMeta: {
|
|
65360
|
+
name: agent.name,
|
|
65361
|
+
tagline: agent.tagline,
|
|
65362
|
+
...agent.machine_kind ? { machine_kind: agent.machine_kind } : {},
|
|
65363
|
+
...Object.prototype.hasOwnProperty.call(agent, "default_model") ? { default_model: agent.default_model ?? null } : {}
|
|
65364
|
+
}
|
|
64983
65365
|
});
|
|
64984
|
-
if (input.pullSecrets !== false) {
|
|
64985
|
-
await pullAgentSecrets(cwd2, agent.id);
|
|
64986
|
-
}
|
|
64987
65366
|
const returnedManifest = manifest ?? buildManifestFromCloud(cloud, agent);
|
|
64988
65367
|
return {
|
|
64989
65368
|
installedPaths: justInstalledPaths,
|
|
@@ -65043,6 +65422,19 @@ function materializeInstructions2(cwd2, cloud) {
|
|
|
65043
65422
|
return;
|
|
65044
65423
|
}
|
|
65045
65424
|
}
|
|
65425
|
+
function materializePlaybooks2(cwd2, cloud) {
|
|
65426
|
+
for (const c2 of cloud.components) {
|
|
65427
|
+
if (c2.type !== "playbook")
|
|
65428
|
+
continue;
|
|
65429
|
+
const raw = c2.files[0]?.content ?? "";
|
|
65430
|
+
if (!raw.trim())
|
|
65431
|
+
continue;
|
|
65432
|
+
const { body } = stripPlaybookFrontmatter(raw);
|
|
65433
|
+
const target = path81.join(cwd2, DEFAULT_PLAYBOOKS_DIR, `${c2.slug}.md`);
|
|
65434
|
+
ensureDir(path81.dirname(target));
|
|
65435
|
+
fs72.writeFileSync(target, body, "utf8");
|
|
65436
|
+
}
|
|
65437
|
+
}
|
|
65046
65438
|
function buildManifestFromCloud(cloud, agent) {
|
|
65047
65439
|
const skills = cloud.components.filter((c2) => c2.type === "skill").map((c2) => {
|
|
65048
65440
|
const meta = c2.meta ?? {};
|
|
@@ -65071,15 +65463,31 @@ function buildManifestFromCloud(cloud, agent) {
|
|
|
65071
65463
|
entry.is_enabled = payload.is_enabled;
|
|
65072
65464
|
return entry;
|
|
65073
65465
|
});
|
|
65466
|
+
const playbooks = cloud.components.filter((c2) => c2.type === "playbook").map((c2) => {
|
|
65467
|
+
const raw = c2.files[0]?.content ?? "";
|
|
65468
|
+
const { frontmatter } = stripPlaybookFrontmatter(raw);
|
|
65469
|
+
const pbMeta = c2.meta ?? {};
|
|
65470
|
+
const title = typeof frontmatter.title === "string" && frontmatter.title || c2.slug;
|
|
65471
|
+
const description = typeof frontmatter.description === "string" ? frontmatter.description : undefined;
|
|
65472
|
+
return {
|
|
65473
|
+
...typeof pbMeta.playbook_id === "string" && pbMeta.playbook_id ? { id: pbMeta.playbook_id } : {},
|
|
65474
|
+
title,
|
|
65475
|
+
...description ? { description } : {},
|
|
65476
|
+
...typeof pbMeta.icon === "string" && pbMeta.icon ? { icon: pbMeta.icon } : {},
|
|
65477
|
+
content: { file: path81.join(DEFAULT_PLAYBOOKS_DIR, `${c2.slug}.md`) }
|
|
65478
|
+
};
|
|
65479
|
+
});
|
|
65074
65480
|
const caps = capabilitiesFromAgent(agent);
|
|
65075
65481
|
return {
|
|
65076
65482
|
schema: 1,
|
|
65483
|
+
...agent.machine_kind ? { machine_kind: agent.machine_kind } : {},
|
|
65484
|
+
...agent.default_model ? { default_model: agent.default_model } : {},
|
|
65077
65485
|
agent: {
|
|
65078
65486
|
name: agent.name,
|
|
65079
65487
|
...agent.tagline ? { tagline: agent.tagline } : {}
|
|
65080
65488
|
},
|
|
65081
65489
|
...hasInstructions ? { instructions: { file: DEFAULT_INSTRUCTIONS_FILE } } : {},
|
|
65082
|
-
playbooks
|
|
65490
|
+
playbooks,
|
|
65083
65491
|
evals: [],
|
|
65084
65492
|
skills,
|
|
65085
65493
|
mcp,
|
|
@@ -65098,14 +65506,58 @@ async function pullAgentSecrets(cwd2, agentId) {
|
|
|
65098
65506
|
if (Object.keys(secrets).length > 0) {
|
|
65099
65507
|
writeLocalSecrets(cwd2, secrets);
|
|
65100
65508
|
}
|
|
65509
|
+
return secrets;
|
|
65101
65510
|
} catch (err) {
|
|
65102
65511
|
if (err instanceof ApiError && err.status !== 404) {
|
|
65103
65512
|
f2.warn(`Skipped secrets for agent ${agentId}: ${err.message}`);
|
|
65104
65513
|
}
|
|
65514
|
+
return {};
|
|
65105
65515
|
}
|
|
65106
65516
|
}
|
|
65107
65517
|
|
|
65518
|
+
// src/core/orchestration-trigger-config.ts
|
|
65519
|
+
function normalizeScheduleTriggerConfig(config) {
|
|
65520
|
+
const cron = config?.cron_expression;
|
|
65521
|
+
const result2 = {};
|
|
65522
|
+
if (typeof cron === "string" && cron.trim()) {
|
|
65523
|
+
result2.cron_expression = cron.trim();
|
|
65524
|
+
}
|
|
65525
|
+
const configuredProps = config?.configured_props;
|
|
65526
|
+
if (configuredProps && typeof configuredProps === "object" && !Array.isArray(configuredProps) && Object.keys(configuredProps).length > 0) {
|
|
65527
|
+
result2.configured_props = configuredProps;
|
|
65528
|
+
}
|
|
65529
|
+
return result2;
|
|
65530
|
+
}
|
|
65531
|
+
function scheduleTriggerConfigForManifest(config) {
|
|
65532
|
+
const normalized = normalizeScheduleTriggerConfig(config);
|
|
65533
|
+
return Object.keys(normalized).length ? normalized : undefined;
|
|
65534
|
+
}
|
|
65535
|
+
function formatScheduleTriggerLabel(input) {
|
|
65536
|
+
const config = normalizeScheduleTriggerConfig(input.config);
|
|
65537
|
+
const cron = typeof config.cron_expression === "string" ? config.cron_expression : "missing cron";
|
|
65538
|
+
const state = input.isActive ?? false ? "active" : "inactive";
|
|
65539
|
+
const targetText = input.targets.length ? ` -> ${input.targets.join(", ")}` : "";
|
|
65540
|
+
return `schedule ${input.nodeId} (${cron}, ${state})${targetText}`;
|
|
65541
|
+
}
|
|
65542
|
+
|
|
65108
65543
|
// src/cli/orchestration-pull.ts
|
|
65544
|
+
function triggersForManifest(triggers, slugFor) {
|
|
65545
|
+
return triggers.map((trigger) => {
|
|
65546
|
+
const schedule = trigger.trigger_type === "schedule";
|
|
65547
|
+
const config = schedule ? scheduleTriggerConfigForManifest(trigger.config) : trigger.config;
|
|
65548
|
+
return {
|
|
65549
|
+
type: trigger.trigger_type,
|
|
65550
|
+
node_id: trigger.node_id,
|
|
65551
|
+
is_active: trigger.is_active,
|
|
65552
|
+
...config && Object.keys(config).length ? { config } : {},
|
|
65553
|
+
to: trigger.edges.map((edge) => ({
|
|
65554
|
+
agent: slugFor(edge.to_agent_id),
|
|
65555
|
+
...edge.description ? { description: edge.description } : {},
|
|
65556
|
+
...edge.payload_schema && Object.keys(edge.payload_schema).length ? { payload_schema: edge.payload_schema } : {}
|
|
65557
|
+
}))
|
|
65558
|
+
};
|
|
65559
|
+
});
|
|
65560
|
+
}
|
|
65109
65561
|
async function runOrchestrationPull(cwd2, args) {
|
|
65110
65562
|
banner("orchestration pull — fetch orchestration + all member agents");
|
|
65111
65563
|
let orchId = null;
|
|
@@ -65129,6 +65581,7 @@ async function runOrchestrationPull(cwd2, args) {
|
|
|
65129
65581
|
} catch (err) {
|
|
65130
65582
|
sp.stop("Failed.");
|
|
65131
65583
|
handleApiError5(err);
|
|
65584
|
+
process.exitCode = 1;
|
|
65132
65585
|
return;
|
|
65133
65586
|
}
|
|
65134
65587
|
const slugByAgent = resolveMemberSlugs(cloud.members);
|
|
@@ -65196,7 +65649,9 @@ async function runOrchestrationPull(cwd2, args) {
|
|
|
65196
65649
|
org_id: cloud.group_id,
|
|
65197
65650
|
team_id: cloud.group_id,
|
|
65198
65651
|
url: undefined,
|
|
65199
|
-
harness: fallbackHarness
|
|
65652
|
+
harness: fallbackHarness,
|
|
65653
|
+
machine_kind: m3.machine_kind,
|
|
65654
|
+
default_model: m3.default_model
|
|
65200
65655
|
},
|
|
65201
65656
|
cloud: m3.manifest,
|
|
65202
65657
|
harness: fallbackHarness,
|
|
@@ -65214,6 +65669,7 @@ async function runOrchestrationPull(cwd2, args) {
|
|
|
65214
65669
|
f2.error(err.message);
|
|
65215
65670
|
}
|
|
65216
65671
|
}
|
|
65672
|
+
const manifestTriggers = triggersForManifest(cloud.triggers ?? [], slugFor);
|
|
65217
65673
|
const manifest = {
|
|
65218
65674
|
schema: 1,
|
|
65219
65675
|
orchestration: {
|
|
@@ -65234,21 +65690,10 @@ async function runOrchestrationPull(cwd2, args) {
|
|
|
65234
65690
|
from: slugFor(e2.from_agent_id),
|
|
65235
65691
|
to: slugFor(e2.to_agent_id),
|
|
65236
65692
|
...e2.description ? { description: e2.description } : {},
|
|
65237
|
-
...e2.payload_schema && Object.keys(e2.payload_schema).length ? { payload_schema: e2.payload_schema } : {}
|
|
65693
|
+
...e2.payload_schema && Object.keys(e2.payload_schema).length ? { payload_schema: e2.payload_schema } : {},
|
|
65694
|
+
...e2.settings && Object.keys(e2.settings).length ? { settings: e2.settings } : {}
|
|
65238
65695
|
})),
|
|
65239
|
-
...
|
|
65240
|
-
triggers: cloud.triggers.map((t) => ({
|
|
65241
|
-
type: t.trigger_type,
|
|
65242
|
-
node_id: t.node_id,
|
|
65243
|
-
is_active: t.is_active,
|
|
65244
|
-
...t.config && Object.keys(t.config).length ? { config: t.config } : {},
|
|
65245
|
-
to: t.edges.map((e2) => ({
|
|
65246
|
-
agent: slugFor(e2.to_agent_id),
|
|
65247
|
-
...e2.description ? { description: e2.description } : {},
|
|
65248
|
-
...e2.payload_schema && Object.keys(e2.payload_schema).length ? { payload_schema: e2.payload_schema } : {}
|
|
65249
|
-
}))
|
|
65250
|
-
}))
|
|
65251
|
-
} : {}
|
|
65696
|
+
...manifestTriggers.length ? { triggers: manifestTriggers } : {}
|
|
65252
65697
|
};
|
|
65253
65698
|
writeOrchManifest(cwd2, manifest);
|
|
65254
65699
|
writeOrchLink(cwd2, {
|
|
@@ -65292,6 +65737,70 @@ function handleApiError5(err) {
|
|
|
65292
65737
|
|
|
65293
65738
|
// src/cli/orchestration-push.ts
|
|
65294
65739
|
var import_picocolors34 = __toESM(require_picocolors(), 1);
|
|
65740
|
+
|
|
65741
|
+
// src/core/orchestration-outgoing.ts
|
|
65742
|
+
function buildOrchestrationGraphPayload(manifest, slugToAgentId) {
|
|
65743
|
+
const memberSlugs = new Set(manifest.members.map((m3) => m3.slug));
|
|
65744
|
+
for (const e2 of manifest.edges) {
|
|
65745
|
+
if (!memberSlugs.has(e2.from)) {
|
|
65746
|
+
throw new Error(`Edge from "${e2.from}" references a slug that isn't in members.`);
|
|
65747
|
+
}
|
|
65748
|
+
if (!memberSlugs.has(e2.to)) {
|
|
65749
|
+
throw new Error(`Edge to "${e2.to}" references a slug that isn't in members.`);
|
|
65750
|
+
}
|
|
65751
|
+
if (e2.from === e2.to) {
|
|
65752
|
+
throw new Error(`Edge ${e2.from} -> ${e2.to}: self-loops are not allowed.`);
|
|
65753
|
+
}
|
|
65754
|
+
}
|
|
65755
|
+
const scheduleTriggers = (manifest.triggers ?? []).filter((t) => t.type === "schedule");
|
|
65756
|
+
const seenTriggerNodeIds = new Set;
|
|
65757
|
+
for (const t of scheduleTriggers) {
|
|
65758
|
+
if (seenTriggerNodeIds.has(t.node_id)) {
|
|
65759
|
+
throw new Error(`Schedule trigger ${t.node_id} is duplicated.`);
|
|
65760
|
+
}
|
|
65761
|
+
seenTriggerNodeIds.add(t.node_id);
|
|
65762
|
+
const config = normalizeScheduleTriggerConfig(t.config);
|
|
65763
|
+
const cron = config.cron_expression;
|
|
65764
|
+
if (typeof cron !== "string" || !cron.trim()) {
|
|
65765
|
+
throw new Error(`Schedule trigger ${t.node_id} is missing cron_expression.`);
|
|
65766
|
+
}
|
|
65767
|
+
if (cron.trim().split(/\s+/).length !== 5) {
|
|
65768
|
+
throw new Error(`Schedule trigger ${t.node_id} cron_expression must use standard 5-field cron syntax.`);
|
|
65769
|
+
}
|
|
65770
|
+
for (const e2 of t.to) {
|
|
65771
|
+
if (!memberSlugs.has(e2.agent)) {
|
|
65772
|
+
throw new Error(`Trigger ${t.node_id} points to "${e2.agent}", which isn't in members.`);
|
|
65773
|
+
}
|
|
65774
|
+
}
|
|
65775
|
+
}
|
|
65776
|
+
const missing = manifest.members.map((m3) => m3.slug).filter((slug) => !slugToAgentId.has(slug));
|
|
65777
|
+
if (missing.length) {
|
|
65778
|
+
throw new Error(`These members have no local checkout (expected at agents/<slug>/brainbase.agent.yaml): ${missing.join(", ")}.`);
|
|
65779
|
+
}
|
|
65780
|
+
return {
|
|
65781
|
+
memberIds: manifest.members.map((m3) => slugToAgentId.get(m3.slug)),
|
|
65782
|
+
edges: manifest.edges.map((e2) => ({
|
|
65783
|
+
from_agent_id: slugToAgentId.get(e2.from),
|
|
65784
|
+
to_agent_id: slugToAgentId.get(e2.to),
|
|
65785
|
+
description: e2.description ?? "",
|
|
65786
|
+
payload_schema: e2.payload_schema ?? {},
|
|
65787
|
+
settings: e2.settings ?? {}
|
|
65788
|
+
})),
|
|
65789
|
+
triggers: scheduleTriggers.map((t) => ({
|
|
65790
|
+
node_id: t.node_id,
|
|
65791
|
+
type: "schedule",
|
|
65792
|
+
is_active: t.is_active ?? false,
|
|
65793
|
+
config: normalizeScheduleTriggerConfig(t.config),
|
|
65794
|
+
edges: t.to.map((e2) => ({
|
|
65795
|
+
to_agent_id: slugToAgentId.get(e2.agent),
|
|
65796
|
+
description: e2.description ?? "",
|
|
65797
|
+
payload_schema: e2.payload_schema ?? {}
|
|
65798
|
+
}))
|
|
65799
|
+
}))
|
|
65800
|
+
};
|
|
65801
|
+
}
|
|
65802
|
+
|
|
65803
|
+
// src/cli/orchestration-push.ts
|
|
65295
65804
|
async function runOrchestrationPush(cwd2, args) {
|
|
65296
65805
|
banner("orchestration push — recursively push each member, then update the graph");
|
|
65297
65806
|
const link2 = readOrchLink(cwd2);
|
|
@@ -65310,23 +65819,9 @@ async function runOrchestrationPush(cwd2, args) {
|
|
|
65310
65819
|
manifest = readOrchManifest(cwd2);
|
|
65311
65820
|
} catch (err) {
|
|
65312
65821
|
f2.error(err.message);
|
|
65822
|
+
process.exitCode = 1;
|
|
65313
65823
|
return;
|
|
65314
65824
|
}
|
|
65315
|
-
const memberSlugs = new Set(manifest.members.map((m3) => m3.slug));
|
|
65316
|
-
for (const e2 of manifest.edges) {
|
|
65317
|
-
if (!memberSlugs.has(e2.from)) {
|
|
65318
|
-
f2.error(`Edge from "${import_picocolors34.default.bold(e2.from)}" references a slug that isn't in members.`);
|
|
65319
|
-
return;
|
|
65320
|
-
}
|
|
65321
|
-
if (!memberSlugs.has(e2.to)) {
|
|
65322
|
-
f2.error(`Edge to "${import_picocolors34.default.bold(e2.to)}" references a slug that isn't in members.`);
|
|
65323
|
-
return;
|
|
65324
|
-
}
|
|
65325
|
-
if (e2.from === e2.to) {
|
|
65326
|
-
f2.error(`Edge ${import_picocolors34.default.bold(e2.from)} → ${import_picocolors34.default.bold(e2.to)}: self-loops are not allowed.`);
|
|
65327
|
-
return;
|
|
65328
|
-
}
|
|
65329
|
-
}
|
|
65330
65825
|
const slugToAgentId = new Map;
|
|
65331
65826
|
const missing = [];
|
|
65332
65827
|
for (const m3 of manifest.members) {
|
|
@@ -65339,13 +65834,21 @@ async function runOrchestrationPush(cwd2, args) {
|
|
|
65339
65834
|
slugToAgentId.set(m3.slug, memberLink.agent_id);
|
|
65340
65835
|
}
|
|
65341
65836
|
if (missing.length) {
|
|
65342
|
-
f2.error(`
|
|
65837
|
+
f2.error(`Missing local checkouts for: ${missing.join(", ")}.`);
|
|
65343
65838
|
f2.info(`Run ${import_picocolors34.default.cyan("brainbase orchestration pull")} to materialise the missing folders.`);
|
|
65344
65839
|
return;
|
|
65345
65840
|
}
|
|
65841
|
+
let graph;
|
|
65842
|
+
try {
|
|
65843
|
+
graph = buildOrchestrationGraphPayload(manifest, slugToAgentId);
|
|
65844
|
+
} catch (err) {
|
|
65845
|
+
f2.error(err.message);
|
|
65846
|
+
process.exitCode = 1;
|
|
65847
|
+
return;
|
|
65848
|
+
}
|
|
65346
65849
|
const plan = [""];
|
|
65347
65850
|
plan.push(` ${import_picocolors34.default.bold(link2.name)} ${import_picocolors34.default.dim(`(${link2.orchestration_id})`)}`);
|
|
65348
|
-
plan.push(` ${import_picocolors34.default.dim(`${manifest.members.length} member${manifest.members.length === 1 ? "" : "s"}, ${manifest.edges.length} edge${manifest.edges.length === 1 ? "" : "s"}`)}`);
|
|
65851
|
+
plan.push(` ${import_picocolors34.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"}`)}`);
|
|
65349
65852
|
plan.push("");
|
|
65350
65853
|
if (!args.graphOnly) {
|
|
65351
65854
|
plan.push(` ${import_picocolors34.default.dim("per-member agent push:")}`);
|
|
@@ -65358,7 +65861,7 @@ async function runOrchestrationPush(cwd2, args) {
|
|
|
65358
65861
|
`));
|
|
65359
65862
|
if (!autoProceed(args.yes)) {
|
|
65360
65863
|
const ok = await se({
|
|
65361
|
-
message: args.graphOnly ? "Push graph (members +
|
|
65864
|
+
message: args.graphOnly ? "Push graph (members, edges + triggers) only?" : "Push each member, then update the graph?",
|
|
65362
65865
|
initialValue: true
|
|
65363
65866
|
});
|
|
65364
65867
|
if (!ensureNotCancelled(ok)) {
|
|
@@ -65375,17 +65878,11 @@ async function runOrchestrationPush(cwd2, args) {
|
|
|
65375
65878
|
await runAgentPush(dir, { yes: true });
|
|
65376
65879
|
} catch (err) {
|
|
65377
65880
|
f2.error(`Failed to push ${m3.slug}: ${err.message}`);
|
|
65881
|
+
process.exitCode = 1;
|
|
65378
65882
|
return;
|
|
65379
65883
|
}
|
|
65380
65884
|
}
|
|
65381
65885
|
}
|
|
65382
|
-
const memberIds = manifest.members.map((m3) => slugToAgentId.get(m3.slug));
|
|
65383
|
-
const edges = manifest.edges.map((e2) => ({
|
|
65384
|
-
from_agent_id: slugToAgentId.get(e2.from),
|
|
65385
|
-
to_agent_id: slugToAgentId.get(e2.to),
|
|
65386
|
-
description: e2.description ?? "",
|
|
65387
|
-
payload_schema: e2.payload_schema ?? {}
|
|
65388
|
-
}));
|
|
65389
65886
|
const sp = de();
|
|
65390
65887
|
sp.start("Updating orchestration graph…");
|
|
65391
65888
|
const lock = readOrchSyncState(cwd2);
|
|
@@ -65396,8 +65893,9 @@ async function runOrchestrationPush(cwd2, args) {
|
|
|
65396
65893
|
icon: manifest.orchestration.icon,
|
|
65397
65894
|
icon_color: manifest.orchestration.icon_color,
|
|
65398
65895
|
credit_limit: manifest.orchestration.credit_limit,
|
|
65399
|
-
members: memberIds,
|
|
65400
|
-
edges,
|
|
65896
|
+
members: graph.memberIds,
|
|
65897
|
+
edges: graph.edges,
|
|
65898
|
+
triggers: graph.triggers,
|
|
65401
65899
|
...lock?.revision != null ? { base_revision: lock.revision } : {}
|
|
65402
65900
|
});
|
|
65403
65901
|
sp.stop(`Graph updated. New cloud revision ${updated.revision}.`);
|
|
@@ -65408,7 +65906,7 @@ async function runOrchestrationPush(cwd2, args) {
|
|
|
65408
65906
|
synced_at: new Date().toISOString(),
|
|
65409
65907
|
members: updated.members.map((m3) => ({
|
|
65410
65908
|
agent_id: m3.agent_id,
|
|
65411
|
-
slug: m3.slug,
|
|
65909
|
+
slug: manifest.members.find((member) => slugToAgentId.get(member.slug) === m3.agent_id)?.slug ?? m3.slug,
|
|
65412
65910
|
revision: m3.revision ?? 0
|
|
65413
65911
|
})),
|
|
65414
65912
|
edges: updated.edges.map((e2) => ({
|
|
@@ -65422,6 +65920,7 @@ async function runOrchestrationPush(cwd2, args) {
|
|
|
65422
65920
|
} catch (err) {
|
|
65423
65921
|
sp.stop("Failed.");
|
|
65424
65922
|
handleApiError6(err);
|
|
65923
|
+
process.exitCode = 1;
|
|
65425
65924
|
}
|
|
65426
65925
|
}
|
|
65427
65926
|
function handleApiError6(err) {
|
|
@@ -65466,6 +65965,7 @@ async function runOrchestrationStatus(cwd2) {
|
|
|
65466
65965
|
} else {
|
|
65467
65966
|
f2.error(err.message);
|
|
65468
65967
|
}
|
|
65968
|
+
process.exitCode = 1;
|
|
65469
65969
|
return;
|
|
65470
65970
|
}
|
|
65471
65971
|
const lines = [];
|
|
@@ -65473,7 +65973,14 @@ async function runOrchestrationStatus(cwd2) {
|
|
|
65473
65973
|
lines.push(` ${import_picocolors35.default.bold(link2.name)} ${import_picocolors35.default.dim(`(${link2.orchestration_id})`)}`);
|
|
65474
65974
|
lines.push(` ${import_picocolors35.default.dim("revision")} cloud ${cloud.revision}${lock ? ` · lock ${lock.revision}` : " · never pulled"}`);
|
|
65475
65975
|
lines.push("");
|
|
65476
|
-
const
|
|
65976
|
+
const localSlugByAgentId = new Map;
|
|
65977
|
+
for (const m3 of localManifest?.members ?? []) {
|
|
65978
|
+
const link3 = readLink(memberDir(cwd2, m3.slug));
|
|
65979
|
+
if (link3)
|
|
65980
|
+
localSlugByAgentId.set(link3.agent_id, m3.slug);
|
|
65981
|
+
}
|
|
65982
|
+
const slugForAgent = (agentId, fallback) => localSlugByAgentId.get(agentId) ?? fallback;
|
|
65983
|
+
const cloudMemberSet = new Set(cloud.members.map((m3) => slugForAgent(m3.agent_id, m3.slug)));
|
|
65477
65984
|
const localMemberSet = new Set((localManifest?.members ?? []).map((m3) => m3.slug));
|
|
65478
65985
|
const membersAdded = [...localMemberSet].filter((s3) => !cloudMemberSet.has(s3));
|
|
65479
65986
|
const membersRemoved = [...cloudMemberSet].filter((s3) => !localMemberSet.has(s3));
|
|
@@ -65487,8 +65994,8 @@ async function runOrchestrationStatus(cwd2) {
|
|
|
65487
65994
|
}
|
|
65488
65995
|
lines.push("");
|
|
65489
65996
|
}
|
|
65490
|
-
const cloudEdgeKey = (e2) => `${e2.from_slug ?? e2.from_agent_id}->${e2.to_slug ?? e2.to_agent_id}|${e2.description ?? ""}`;
|
|
65491
|
-
const localEdgeKey = (e2) => `${e2.from}->${e2.to}|${e2.description ?? ""}`;
|
|
65997
|
+
const cloudEdgeKey = (e2) => `${slugForAgent(e2.from_agent_id, e2.from_slug ?? e2.from_agent_id)}->${slugForAgent(e2.to_agent_id, e2.to_slug ?? e2.to_agent_id)}|${e2.description ?? ""}|${stableJson(e2.payload_schema ?? {})}|${stableJson(e2.settings ?? {})}`;
|
|
65998
|
+
const localEdgeKey = (e2) => `${e2.from}->${e2.to}|${e2.description ?? ""}|${stableJson(e2.payload_schema ?? {})}|${stableJson(e2.settings ?? {})}`;
|
|
65492
65999
|
const cloudEdges = new Map;
|
|
65493
66000
|
for (const e2 of cloud.edges)
|
|
65494
66001
|
cloudEdges.set(cloudEdgeKey(e2), true);
|
|
@@ -65505,20 +66012,63 @@ async function runOrchestrationStatus(cwd2) {
|
|
|
65505
66012
|
lines.push(` ${import_picocolors35.default.cyan("← pull")} added on cloud: ${k3}`);
|
|
65506
66013
|
lines.push("");
|
|
65507
66014
|
}
|
|
66015
|
+
const cloudTriggerKey = (t) => {
|
|
66016
|
+
const edges = t.edges.map((e2) => `${slugForAgent(e2.to_agent_id, e2.to_slug ?? e2.to_agent_id)}|${e2.description ?? ""}|${stableJson(e2.payload_schema ?? {})}`).sort().join(",");
|
|
66017
|
+
return `${t.node_id}|${t.is_active ?? false}|${stableJson(normalizeScheduleTriggerConfig(t.config))}|${edges}`;
|
|
66018
|
+
};
|
|
66019
|
+
const cloudTriggerLabel = (t) => formatScheduleTriggerLabel({
|
|
66020
|
+
nodeId: t.node_id,
|
|
66021
|
+
isActive: t.is_active ?? false,
|
|
66022
|
+
config: t.config,
|
|
66023
|
+
targets: t.edges.map((e2) => slugForAgent(e2.to_agent_id, e2.to_slug ?? e2.to_agent_id))
|
|
66024
|
+
});
|
|
66025
|
+
const localTriggerKey = (t) => {
|
|
66026
|
+
const edges = t.to.map((e2) => `${e2.agent}|${e2.description ?? ""}|${stableJson(e2.payload_schema ?? {})}`).sort().join(",");
|
|
66027
|
+
return `${t.node_id}|${t.is_active ?? false}|${stableJson(normalizeScheduleTriggerConfig(t.config))}|${edges}`;
|
|
66028
|
+
};
|
|
66029
|
+
const localTriggerLabel = (t) => formatScheduleTriggerLabel({
|
|
66030
|
+
nodeId: t.node_id,
|
|
66031
|
+
isActive: t.is_active ?? false,
|
|
66032
|
+
config: t.config,
|
|
66033
|
+
targets: t.to.map((e2) => e2.agent)
|
|
66034
|
+
});
|
|
66035
|
+
const cloudTriggers = new Map;
|
|
66036
|
+
for (const t of cloud.triggers ?? []) {
|
|
66037
|
+
if (t.trigger_type === "schedule") {
|
|
66038
|
+
cloudTriggers.set(cloudTriggerKey(t), cloudTriggerLabel(t));
|
|
66039
|
+
}
|
|
66040
|
+
}
|
|
66041
|
+
const localTriggers = new Map;
|
|
66042
|
+
for (const t of localManifest?.triggers ?? []) {
|
|
66043
|
+
if (t.type === "schedule") {
|
|
66044
|
+
localTriggers.set(localTriggerKey(t), localTriggerLabel(t));
|
|
66045
|
+
}
|
|
66046
|
+
}
|
|
66047
|
+
const triggersAdded = [...localTriggers.keys()].filter((k3) => !cloudTriggers.has(k3));
|
|
66048
|
+
const triggersRemoved = [...cloudTriggers.keys()].filter((k3) => !localTriggers.has(k3));
|
|
66049
|
+
if (triggersAdded.length || triggersRemoved.length) {
|
|
66050
|
+
lines.push(` ${import_picocolors35.default.bold("schedule triggers")}`);
|
|
66051
|
+
for (const k3 of triggersAdded)
|
|
66052
|
+
lines.push(` ${import_picocolors35.default.yellow("→ push")} added/changed in yaml: ${localTriggers.get(k3) ?? k3}`);
|
|
66053
|
+
for (const k3 of triggersRemoved)
|
|
66054
|
+
lines.push(` ${import_picocolors35.default.cyan("← pull")} added/changed on cloud: ${cloudTriggers.get(k3) ?? k3}`);
|
|
66055
|
+
lines.push("");
|
|
66056
|
+
}
|
|
65508
66057
|
const lockByAgentId = new Map((lock?.members ?? []).map((m3) => [m3.agent_id, m3]));
|
|
65509
66058
|
const memberDrift = [];
|
|
65510
66059
|
for (const m3 of cloud.members) {
|
|
65511
|
-
const
|
|
66060
|
+
const slug = slugForAgent(m3.agent_id, m3.slug);
|
|
66061
|
+
const dir = memberDir(cwd2, slug);
|
|
65512
66062
|
const memberSync = readSyncState(dir);
|
|
65513
66063
|
if (!memberSync) {
|
|
65514
|
-
memberDrift.push({ slug
|
|
66064
|
+
memberDrift.push({ slug, reason: "no local checkout" });
|
|
65515
66065
|
continue;
|
|
65516
66066
|
}
|
|
65517
66067
|
const lockEntry = lockByAgentId.get(m3.agent_id);
|
|
65518
66068
|
const lockedRev = lockEntry?.revision;
|
|
65519
66069
|
if (m3.revision != null && lockedRev != null && m3.revision !== lockedRev) {
|
|
65520
66070
|
memberDrift.push({
|
|
65521
|
-
slug
|
|
66071
|
+
slug,
|
|
65522
66072
|
reason: `cloud rev ${m3.revision} ≠ lock ${lockedRev}`
|
|
65523
66073
|
});
|
|
65524
66074
|
}
|
|
@@ -65531,7 +66081,13 @@ async function runOrchestrationStatus(cwd2) {
|
|
|
65531
66081
|
lines.push(` ${import_picocolors35.default.dim("cd into each member folder and run")} ${import_picocolors35.default.cyan("brainbase agent status")}`);
|
|
65532
66082
|
lines.push("");
|
|
65533
66083
|
}
|
|
65534
|
-
|
|
66084
|
+
const revisionDrift = lock?.revision != null && cloud.revision !== lock.revision;
|
|
66085
|
+
if (revisionDrift) {
|
|
66086
|
+
lines.push(` ${import_picocolors35.default.bold("cloud revision")}`);
|
|
66087
|
+
lines.push(` ${import_picocolors35.default.cyan("← pull")} cloud changed since last pull: ${import_picocolors35.default.dim(`lock ${lock.revision} → cloud ${cloud.revision}`)}`);
|
|
66088
|
+
lines.push("");
|
|
66089
|
+
}
|
|
66090
|
+
if (!membersAdded.length && !membersRemoved.length && !edgesAdded.length && !edgesRemoved.length && !triggersAdded.length && !triggersRemoved.length && !memberDrift.length && !revisionDrift) {
|
|
65535
66091
|
lines.push(` ${import_picocolors35.default.green("✓")} everything is in sync`);
|
|
65536
66092
|
lines.push("");
|
|
65537
66093
|
console.log(lines.join(`
|
|
@@ -65543,6 +66099,14 @@ async function runOrchestrationStatus(cwd2) {
|
|
|
65543
66099
|
console.log(lines.join(`
|
|
65544
66100
|
`));
|
|
65545
66101
|
}
|
|
66102
|
+
function stableJson(value) {
|
|
66103
|
+
if (value == null || typeof value !== "object")
|
|
66104
|
+
return JSON.stringify(value);
|
|
66105
|
+
if (Array.isArray(value))
|
|
66106
|
+
return `[${value.map(stableJson).join(",")}]`;
|
|
66107
|
+
const obj = value;
|
|
66108
|
+
return `{${Object.keys(obj).sort().map((key2) => `${JSON.stringify(key2)}:${stableJson(obj[key2])}`).join(",")}}`;
|
|
66109
|
+
}
|
|
65546
66110
|
|
|
65547
66111
|
// src/cli/orchestration-list.ts
|
|
65548
66112
|
var import_picocolors36 = __toESM(require_picocolors(), 1);
|
|
@@ -65550,7 +66114,7 @@ async function runOrchestrationList(args) {
|
|
|
65550
66114
|
banner("orchestration list — orchestrations under a team");
|
|
65551
66115
|
let orgId = args.orgId;
|
|
65552
66116
|
let teamId = args.teamId;
|
|
65553
|
-
if (!orgId) {
|
|
66117
|
+
if (!orgId || !isUuid(orgId)) {
|
|
65554
66118
|
let orgs;
|
|
65555
66119
|
try {
|
|
65556
66120
|
orgs = await api.listOrgs();
|
|
@@ -65562,13 +66126,20 @@ async function runOrchestrationList(args) {
|
|
|
65562
66126
|
f2.warn("You are not a member of any organization.");
|
|
65563
66127
|
return;
|
|
65564
66128
|
}
|
|
65565
|
-
if (
|
|
66129
|
+
if (orgId) {
|
|
66130
|
+
const found = orgs.find((o2) => o2.id === orgId || o2.slug === orgId);
|
|
66131
|
+
if (!found) {
|
|
66132
|
+
f2.error(`Org ${orgId} not found or you're not a member.`);
|
|
66133
|
+
return;
|
|
66134
|
+
}
|
|
66135
|
+
orgId = found.id;
|
|
66136
|
+
} else if (orgs.length === 1) {
|
|
65566
66137
|
orgId = orgs[0].id;
|
|
65567
66138
|
} else {
|
|
65568
66139
|
orgId = await select({
|
|
65569
66140
|
message: "Which organization?",
|
|
65570
|
-
options: orgs.map((o2) => ({ value: o2.id, label: o2.name })),
|
|
65571
|
-
flagHint: "Pass --org <id>."
|
|
66141
|
+
options: orgs.map((o2) => ({ value: o2.id, label: o2.name, hint: o2.role })),
|
|
66142
|
+
flagHint: "Pass --org <id-or-slug>."
|
|
65572
66143
|
});
|
|
65573
66144
|
}
|
|
65574
66145
|
}
|
|
@@ -65622,6 +66193,9 @@ async function runOrchestrationList(args) {
|
|
|
65622
66193
|
console.log(lines.join(`
|
|
65623
66194
|
`));
|
|
65624
66195
|
}
|
|
66196
|
+
function isUuid(value) {
|
|
66197
|
+
return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-9a-f][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);
|
|
66198
|
+
}
|
|
65625
66199
|
function handleApiError7(err) {
|
|
65626
66200
|
if (err instanceof ApiError) {
|
|
65627
66201
|
if (err.status === 401) {
|
|
@@ -65820,9 +66394,224 @@ async function runOrchestrationAddAgent(cwd2, args) {
|
|
|
65820
66394
|
await runOrchestrationPush(cwd2, { yes: true, graphOnly: true });
|
|
65821
66395
|
}
|
|
65822
66396
|
|
|
66397
|
+
// src/cli/orchestration-create.ts
|
|
66398
|
+
var import_picocolors38 = __toESM(require_picocolors(), 1);
|
|
66399
|
+
async function runOrchestrationCreate(cwd2, args) {
|
|
66400
|
+
banner("orchestration create — claim a brainbase-orchestration.yaml");
|
|
66401
|
+
if (readOrchLink(cwd2)) {
|
|
66402
|
+
f2.warn("This folder is already linked to an orchestration.");
|
|
66403
|
+
f2.info(`Run ${import_picocolors38.default.cyan("brainbase orchestration push")} to update it.`);
|
|
66404
|
+
return;
|
|
66405
|
+
}
|
|
66406
|
+
if (!hasOrchManifest(cwd2)) {
|
|
66407
|
+
f2.warn(`No ${import_picocolors38.default.bold(ORCH_MANIFEST_FILE)} here.`);
|
|
66408
|
+
f2.info(`Create one, or pull an existing orchestration first.`);
|
|
66409
|
+
return;
|
|
66410
|
+
}
|
|
66411
|
+
let manifest;
|
|
66412
|
+
try {
|
|
66413
|
+
manifest = readOrchManifest(cwd2);
|
|
66414
|
+
} catch (err) {
|
|
66415
|
+
f2.error(err.message);
|
|
66416
|
+
process.exitCode = 1;
|
|
66417
|
+
return;
|
|
66418
|
+
}
|
|
66419
|
+
const slugToAgentId = new Map;
|
|
66420
|
+
for (const m3 of manifest.members) {
|
|
66421
|
+
const link2 = readLink(memberDir(cwd2, m3.slug));
|
|
66422
|
+
if (link2)
|
|
66423
|
+
slugToAgentId.set(m3.slug, link2.agent_id);
|
|
66424
|
+
}
|
|
66425
|
+
let graph;
|
|
66426
|
+
try {
|
|
66427
|
+
graph = buildOrchestrationGraphPayload(manifest, slugToAgentId);
|
|
66428
|
+
} catch (err) {
|
|
66429
|
+
f2.error(err.message);
|
|
66430
|
+
process.exitCode = 1;
|
|
66431
|
+
return;
|
|
66432
|
+
}
|
|
66433
|
+
const target = await resolveOrgAndTeam(args);
|
|
66434
|
+
if (!target)
|
|
66435
|
+
return;
|
|
66436
|
+
const plan = [
|
|
66437
|
+
"",
|
|
66438
|
+
` ${import_picocolors38.default.bold(manifest.orchestration.name)}`,
|
|
66439
|
+
` ${import_picocolors38.default.dim("org")} ${import_picocolors38.default.bold(target.org.name)}`,
|
|
66440
|
+
` ${import_picocolors38.default.dim("team")} ${import_picocolors38.default.bold(target.team.name)}`,
|
|
66441
|
+
` ${import_picocolors38.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"}`,
|
|
66442
|
+
""
|
|
66443
|
+
];
|
|
66444
|
+
console.log(plan.join(`
|
|
66445
|
+
`));
|
|
66446
|
+
if (!autoProceed(args.yes)) {
|
|
66447
|
+
const ok = await se({
|
|
66448
|
+
message: "Create this orchestration?",
|
|
66449
|
+
initialValue: true
|
|
66450
|
+
});
|
|
66451
|
+
if (!ensureNotCancelled(ok)) {
|
|
66452
|
+
$e("Aborted.");
|
|
66453
|
+
return;
|
|
66454
|
+
}
|
|
66455
|
+
}
|
|
66456
|
+
const sp = de();
|
|
66457
|
+
sp.start("Creating orchestration…");
|
|
66458
|
+
try {
|
|
66459
|
+
const created = await api.createOrchestration({
|
|
66460
|
+
org_id: target.org.id,
|
|
66461
|
+
team_id: target.team.id,
|
|
66462
|
+
name: manifest.orchestration.name,
|
|
66463
|
+
description: manifest.orchestration.description ?? "",
|
|
66464
|
+
icon: manifest.orchestration.icon,
|
|
66465
|
+
icon_color: manifest.orchestration.icon_color,
|
|
66466
|
+
credit_limit: manifest.orchestration.credit_limit,
|
|
66467
|
+
members: graph.memberIds,
|
|
66468
|
+
edges: graph.edges,
|
|
66469
|
+
triggers: graph.triggers
|
|
66470
|
+
});
|
|
66471
|
+
sp.stop(`Created ${import_picocolors38.default.bold(created.name)}.`);
|
|
66472
|
+
writeOrchLink(cwd2, {
|
|
66473
|
+
schemaVersion: 1,
|
|
66474
|
+
orchestration_id: created.id,
|
|
66475
|
+
group_id: created.group_id,
|
|
66476
|
+
org_id: target.org.id,
|
|
66477
|
+
team_id: target.team.id,
|
|
66478
|
+
name: created.name,
|
|
66479
|
+
description: created.description || undefined,
|
|
66480
|
+
linked_at: new Date().toISOString()
|
|
66481
|
+
});
|
|
66482
|
+
writeOrchSyncState(cwd2, {
|
|
66483
|
+
schemaVersion: 1,
|
|
66484
|
+
orchestration_id: created.id,
|
|
66485
|
+
revision: created.revision,
|
|
66486
|
+
synced_at: new Date().toISOString(),
|
|
66487
|
+
members: created.members.map((m3) => ({
|
|
66488
|
+
agent_id: m3.agent_id,
|
|
66489
|
+
slug: manifest.members.find((member) => slugToAgentId.get(member.slug) === m3.agent_id)?.slug ?? m3.slug,
|
|
66490
|
+
revision: m3.revision ?? 0
|
|
66491
|
+
})),
|
|
66492
|
+
edges: created.edges.map((e2) => ({
|
|
66493
|
+
from_slug: e2.from_slug ?? e2.from_agent_id,
|
|
66494
|
+
to_slug: e2.to_slug ?? e2.to_agent_id,
|
|
66495
|
+
description: e2.description ?? "",
|
|
66496
|
+
payload_schema: e2.payload_schema ?? {}
|
|
66497
|
+
}))
|
|
66498
|
+
});
|
|
66499
|
+
$e(`Created ${created.name} at revision ${created.revision}.`);
|
|
66500
|
+
} catch (err) {
|
|
66501
|
+
sp.stop("Failed.");
|
|
66502
|
+
handleApiError8(err);
|
|
66503
|
+
process.exitCode = 1;
|
|
66504
|
+
}
|
|
66505
|
+
}
|
|
66506
|
+
async function resolveOrgAndTeam(args) {
|
|
66507
|
+
const orgsSpinner = de();
|
|
66508
|
+
orgsSpinner.start("Loading your organizations…");
|
|
66509
|
+
let orgs;
|
|
66510
|
+
try {
|
|
66511
|
+
orgs = await api.listOrgs();
|
|
66512
|
+
} catch (err) {
|
|
66513
|
+
orgsSpinner.stop("Failed.");
|
|
66514
|
+
handleApiError8(err);
|
|
66515
|
+
process.exitCode = 1;
|
|
66516
|
+
return null;
|
|
66517
|
+
}
|
|
66518
|
+
orgsSpinner.stop(`Found ${orgs.length} organization${orgs.length === 1 ? "" : "s"}.`);
|
|
66519
|
+
if (orgs.length === 0) {
|
|
66520
|
+
f2.warn("You are not in any organizations yet.");
|
|
66521
|
+
process.exitCode = 1;
|
|
66522
|
+
return null;
|
|
66523
|
+
}
|
|
66524
|
+
let org;
|
|
66525
|
+
if (args.orgId) {
|
|
66526
|
+
const found = orgs.find((o2) => o2.id === args.orgId || o2.slug === args.orgId);
|
|
66527
|
+
if (!found) {
|
|
66528
|
+
f2.error(`Org ${args.orgId} not found or you're not a member.`);
|
|
66529
|
+
process.exitCode = 1;
|
|
66530
|
+
return null;
|
|
66531
|
+
}
|
|
66532
|
+
org = found;
|
|
66533
|
+
} else if (orgs.length === 1) {
|
|
66534
|
+
org = orgs[0];
|
|
66535
|
+
f2.info(`Using organization ${import_picocolors38.default.bold(org.name)}.`);
|
|
66536
|
+
} else if (!isInteractive()) {
|
|
66537
|
+
throw new NonInteractiveError("Multiple organizations. Pass --org <id-or-slug> to choose non-interactively.");
|
|
66538
|
+
} else {
|
|
66539
|
+
const orgId = await select({
|
|
66540
|
+
message: "Pick an organization",
|
|
66541
|
+
options: orgs.map((o2) => ({ value: o2.id, label: o2.name, hint: o2.role })),
|
|
66542
|
+
flagHint: "Pass --org <id-or-slug> to choose non-interactively."
|
|
66543
|
+
});
|
|
66544
|
+
org = orgs.find((o2) => o2.id === orgId);
|
|
66545
|
+
}
|
|
66546
|
+
const teamsSpinner = de();
|
|
66547
|
+
teamsSpinner.start(`Loading teams in ${org.name}…`);
|
|
66548
|
+
let teams;
|
|
66549
|
+
try {
|
|
66550
|
+
teams = await api.listTeams(org.id);
|
|
66551
|
+
} catch (err) {
|
|
66552
|
+
teamsSpinner.stop("Failed.");
|
|
66553
|
+
handleApiError8(err);
|
|
66554
|
+
process.exitCode = 1;
|
|
66555
|
+
return null;
|
|
66556
|
+
}
|
|
66557
|
+
teamsSpinner.stop(`Found ${teams.length} team${teams.length === 1 ? "" : "s"}.`);
|
|
66558
|
+
if (teams.length === 0) {
|
|
66559
|
+
f2.warn(`No teams in ${org.name} yet.`);
|
|
66560
|
+
process.exitCode = 1;
|
|
66561
|
+
return null;
|
|
66562
|
+
}
|
|
66563
|
+
let team;
|
|
66564
|
+
if (args.teamId) {
|
|
66565
|
+
const found = teams.find((t) => t.id === args.teamId);
|
|
66566
|
+
if (!found) {
|
|
66567
|
+
f2.error(`Team ${args.teamId} not found in this org.`);
|
|
66568
|
+
process.exitCode = 1;
|
|
66569
|
+
return null;
|
|
66570
|
+
}
|
|
66571
|
+
team = found;
|
|
66572
|
+
} else if (teams.length === 1) {
|
|
66573
|
+
team = teams[0];
|
|
66574
|
+
f2.info(`Using team ${import_picocolors38.default.bold(team.name)}.`);
|
|
66575
|
+
} else if (!isInteractive()) {
|
|
66576
|
+
throw new NonInteractiveError("Multiple teams. Pass --team <id> to choose non-interactively.");
|
|
66577
|
+
} else {
|
|
66578
|
+
const teamId = await select({
|
|
66579
|
+
message: "Pick a team",
|
|
66580
|
+
options: teams.map((t) => ({ value: t.id, label: t.name, hint: t.role })),
|
|
66581
|
+
flagHint: "Pass --team <id> to choose non-interactively."
|
|
66582
|
+
});
|
|
66583
|
+
team = teams.find((t) => t.id === teamId);
|
|
66584
|
+
}
|
|
66585
|
+
return { org, team };
|
|
66586
|
+
}
|
|
66587
|
+
function handleApiError8(err) {
|
|
66588
|
+
if (err instanceof ApiError) {
|
|
66589
|
+
if (err.status === 401) {
|
|
66590
|
+
f2.error("Your session is invalid. Run `brainbase login` and try again.");
|
|
66591
|
+
} else if (err.status === 403) {
|
|
66592
|
+
f2.error("You do not have access to create this orchestration.");
|
|
66593
|
+
} else {
|
|
66594
|
+
f2.error(err.message);
|
|
66595
|
+
}
|
|
66596
|
+
} else {
|
|
66597
|
+
f2.error(err.message);
|
|
66598
|
+
}
|
|
66599
|
+
}
|
|
66600
|
+
|
|
65823
66601
|
// src/cli/orchestration.ts
|
|
65824
66602
|
async function runOrchestration(cwd2, sub, args, opts) {
|
|
66603
|
+
if (args.some((arg) => arg === "--help" || arg === "-h")) {
|
|
66604
|
+
printHelp2();
|
|
66605
|
+
return;
|
|
66606
|
+
}
|
|
65825
66607
|
switch (sub) {
|
|
66608
|
+
case "create":
|
|
66609
|
+
await runOrchestrationCreate(cwd2, {
|
|
66610
|
+
yes: opts.yes,
|
|
66611
|
+
orgId: opts.orgId,
|
|
66612
|
+
teamId: opts.teamId
|
|
66613
|
+
});
|
|
66614
|
+
return;
|
|
65826
66615
|
case "pull":
|
|
65827
66616
|
await runOrchestrationPull(cwd2, {
|
|
65828
66617
|
orchestrationId: args[0],
|
|
@@ -65873,20 +66662,21 @@ async function runOrchestration(cwd2, sub, args, opts) {
|
|
|
65873
66662
|
function printHelp2() {
|
|
65874
66663
|
const out = [];
|
|
65875
66664
|
out.push("");
|
|
65876
|
-
out.push(` ${
|
|
66665
|
+
out.push(` ${import_picocolors39.default.bold("brainbase orchestration")} ${import_picocolors39.default.dim("<sub> [options]")}`);
|
|
65877
66666
|
out.push("");
|
|
65878
|
-
out.push(` ${
|
|
65879
|
-
out.push(` ${
|
|
65880
|
-
out.push(` ${
|
|
65881
|
-
out.push(` ${
|
|
65882
|
-
out.push(` ${
|
|
66667
|
+
out.push(` ${import_picocolors39.default.cyan("create")} ${import_picocolors39.default.dim("claim a local orchestration manifest and create it in the cloud")}`);
|
|
66668
|
+
out.push(` ${import_picocolors39.default.cyan("pull")} ${import_picocolors39.default.dim("<id>")} ${import_picocolors39.default.dim("fetch orchestration + every member agent into this folder")}`);
|
|
66669
|
+
out.push(` ${import_picocolors39.default.cyan("push")} ${import_picocolors39.default.dim("push each member, then update the orchestration graph")}`);
|
|
66670
|
+
out.push(` ${import_picocolors39.default.cyan("add-agent")} ${import_picocolors39.default.dim("<name>")} ${import_picocolors39.default.dim("create a member agent, wire edges (--from/--to), and push")}`);
|
|
66671
|
+
out.push(` ${import_picocolors39.default.cyan("status")} ${import_picocolors39.default.dim("show what would push and what would pull")}`);
|
|
66672
|
+
out.push(` ${import_picocolors39.default.cyan("list")} ${import_picocolors39.default.dim("list orchestrations under a team")}`);
|
|
65883
66673
|
out.push("");
|
|
65884
|
-
out.push(` ${
|
|
65885
|
-
out.push(` ${
|
|
65886
|
-
out.push(` ${
|
|
65887
|
-
out.push(` ${
|
|
65888
|
-
out.push(` ${
|
|
65889
|
-
out.push(` ${
|
|
66674
|
+
out.push(` ${import_picocolors39.default.bold("Flags")}`);
|
|
66675
|
+
out.push(` ${import_picocolors39.default.dim("--yes, -y")} skip confirmations`);
|
|
66676
|
+
out.push(` ${import_picocolors39.default.dim("--harness <id>")} harness for newly-created member folders (default claude-code)`);
|
|
66677
|
+
out.push(` ${import_picocolors39.default.dim("--graph-only")} for push: only update members + edges, skip per-member push`);
|
|
66678
|
+
out.push(` ${import_picocolors39.default.dim("--org <id>")} for create/list: org id or slug (CLI vocab — DB teams.id)`);
|
|
66679
|
+
out.push(` ${import_picocolors39.default.dim("--team <id>")} for create/list: team id (CLI vocab — DB groups.id)`);
|
|
65890
66680
|
out.push("");
|
|
65891
66681
|
console.log(out.join(`
|
|
65892
66682
|
`));
|
|
@@ -65931,16 +66721,16 @@ async function runRun(cwd2, args) {
|
|
|
65931
66721
|
}
|
|
65932
66722
|
|
|
65933
66723
|
// src/cli/publish.ts
|
|
65934
|
-
var
|
|
66724
|
+
var import_picocolors40 = __toESM(require_picocolors(), 1);
|
|
65935
66725
|
async function runPublish(cwd2, _args) {
|
|
65936
66726
|
banner("publish — send your changes to the team");
|
|
65937
66727
|
const link2 = readLink(cwd2);
|
|
65938
66728
|
if (!link2) {
|
|
65939
66729
|
f2.warn("This folder is not linked to any agent.");
|
|
65940
|
-
f2.info(`Run ${
|
|
66730
|
+
f2.info(`Run ${import_picocolors40.default.cyan("brainbase link")} first.`);
|
|
65941
66731
|
return;
|
|
65942
66732
|
}
|
|
65943
|
-
f2.info(`${
|
|
66733
|
+
f2.info(`${import_picocolors40.default.bold("publish")} is coming soon — for now, edit the agent on the web app and run ${import_picocolors40.default.cyan("brainbase sync")} to bring changes here.`);
|
|
65944
66734
|
}
|
|
65945
66735
|
|
|
65946
66736
|
// src/ui/ink/StatusCard.tsx
|
|
@@ -66238,7 +67028,7 @@ async function runStatus(cwd2) {
|
|
|
66238
67028
|
}
|
|
66239
67029
|
|
|
66240
67030
|
// src/cli/token.ts
|
|
66241
|
-
var
|
|
67031
|
+
var import_picocolors41 = __toESM(require_picocolors(), 1);
|
|
66242
67032
|
|
|
66243
67033
|
// src/ui/ink/TokenCards.tsx
|
|
66244
67034
|
var jsx_dev_runtime17 = __toESM(require_jsx_dev_runtime(), 1);
|
|
@@ -66532,7 +67322,7 @@ async function runTokenRevoke(args) {
|
|
|
66532
67322
|
}
|
|
66533
67323
|
if (!autoProceed(args.yes)) {
|
|
66534
67324
|
const ok = await se({
|
|
66535
|
-
message: `Revoke token ${
|
|
67325
|
+
message: `Revoke token ${import_picocolors41.default.bold(args.id)}? CIs and machines using it will stop working.`,
|
|
66536
67326
|
initialValue: false
|
|
66537
67327
|
});
|
|
66538
67328
|
if (!ensureNotCancelled(ok))
|
|
@@ -66547,7 +67337,7 @@ async function runTokenRevoke(args) {
|
|
|
66547
67337
|
}
|
|
66548
67338
|
async function runTokenClear() {
|
|
66549
67339
|
if (!readToken()) {
|
|
66550
|
-
console.log(
|
|
67340
|
+
console.log(import_picocolors41.default.dim("No local token stored."));
|
|
66551
67341
|
return;
|
|
66552
67342
|
}
|
|
66553
67343
|
clearToken();
|
|
@@ -66598,24 +67388,24 @@ async function runToken(sub, rest2, args) {
|
|
|
66598
67388
|
function printTokenHelp() {
|
|
66599
67389
|
const out = [];
|
|
66600
67390
|
out.push("");
|
|
66601
|
-
out.push(` ${
|
|
67391
|
+
out.push(` ${import_picocolors41.default.bold("brainbase token")} ${import_picocolors41.default.dim("<command>")}`);
|
|
66602
67392
|
out.push("");
|
|
66603
|
-
out.push(` ${
|
|
66604
|
-
out.push(` ${
|
|
66605
|
-
out.push(` ${
|
|
66606
|
-
out.push(` ${
|
|
67393
|
+
out.push(` ${import_picocolors41.default.cyan("create")} ${import_picocolors41.default.dim("issue a new long-lived CLI key (PAT)")}`);
|
|
67394
|
+
out.push(` ${import_picocolors41.default.cyan("list")} ${import_picocolors41.default.dim("show your active tokens")}`);
|
|
67395
|
+
out.push(` ${import_picocolors41.default.cyan("revoke")} ${import_picocolors41.default.dim("<id>")} ${import_picocolors41.default.dim("revoke a token by id")}`);
|
|
67396
|
+
out.push(` ${import_picocolors41.default.cyan("clear")} ${import_picocolors41.default.dim("forget the local token (does not revoke)")}`);
|
|
66607
67397
|
out.push("");
|
|
66608
|
-
out.push(` ${
|
|
66609
|
-
out.push(` ${
|
|
66610
|
-
out.push(` ${
|
|
66611
|
-
out.push(` ${
|
|
67398
|
+
out.push(` ${import_picocolors41.default.bold("create flags")}`);
|
|
67399
|
+
out.push(` ${import_picocolors41.default.cyan("--name, -n")} ${import_picocolors41.default.dim("<label>")} ${import_picocolors41.default.dim("token label (prompted if omitted)")}`);
|
|
67400
|
+
out.push(` ${import_picocolors41.default.cyan("--scopes")} ${import_picocolors41.default.dim("<list>")} ${import_picocolors41.default.dim("comma-separated; allowed: read, publish, admin")}`);
|
|
67401
|
+
out.push(` ${import_picocolors41.default.dim("default: read,publish")}`);
|
|
66612
67402
|
out.push("");
|
|
66613
67403
|
console.log(out.join(`
|
|
66614
67404
|
`));
|
|
66615
67405
|
}
|
|
66616
67406
|
|
|
66617
67407
|
// src/cli/mcp.ts
|
|
66618
|
-
var
|
|
67408
|
+
var import_picocolors42 = __toESM(require_picocolors(), 1);
|
|
66619
67409
|
|
|
66620
67410
|
// src/core/mcp-check/collect-servers.ts
|
|
66621
67411
|
import path83 from "node:path";
|
|
@@ -74963,17 +75753,17 @@ async function runMcpCheck(cwd2, options) {
|
|
|
74963
75753
|
function renderHuman(report) {
|
|
74964
75754
|
const lines = [];
|
|
74965
75755
|
if (report.check_status === "skipped") {
|
|
74966
|
-
lines.push(
|
|
75756
|
+
lines.push(import_picocolors42.default.dim("No MCP servers configured — nothing to check."));
|
|
74967
75757
|
return lines.join(`
|
|
74968
75758
|
`) + `
|
|
74969
75759
|
`;
|
|
74970
75760
|
}
|
|
74971
75761
|
for (const s3 of report.servers) {
|
|
74972
|
-
const mark = s3.status === "ok" ?
|
|
74973
|
-
const detail = s3.status === "ok" ?
|
|
75762
|
+
const mark = s3.status === "ok" ? import_picocolors42.default.green("✓") : s3.status === "auth_failed" ? import_picocolors42.default.red("✗") : import_picocolors42.default.yellow("⚠");
|
|
75763
|
+
const detail = s3.status === "ok" ? import_picocolors42.default.dim(`${s3.tool_count} tool${s3.tool_count === 1 ? "" : "s"}`) : import_picocolors42.default.dim(s3.status + (s3.error ? ` — ${s3.error}` : ""));
|
|
74974
75764
|
lines.push(` ${mark} ${s3.name} ${detail}`);
|
|
74975
75765
|
}
|
|
74976
|
-
const summary = report.check_status === "ok" ?
|
|
75766
|
+
const summary = report.check_status === "ok" ? import_picocolors42.default.green("All MCP servers connected.") : import_picocolors42.default.yellow("Some MCP servers are unhealthy.");
|
|
74977
75767
|
lines.push("", summary);
|
|
74978
75768
|
return lines.join(`
|
|
74979
75769
|
`) + `
|
|
@@ -75009,97 +75799,100 @@ var PROTECTED = new Set([
|
|
|
75009
75799
|
function help() {
|
|
75010
75800
|
const out = [];
|
|
75011
75801
|
out.push("");
|
|
75012
|
-
out.push(` ${brandTint("◆")} ${
|
|
75013
|
-
out.push(` ${
|
|
75802
|
+
out.push(` ${brandTint("◆")} ${import_picocolors43.default.bold("brainbase")} ${import_picocolors43.default.dim(`v${VERSION}`)}`);
|
|
75803
|
+
out.push(` ${import_picocolors43.default.dim("connect your local agent to the brainbase platform")}`);
|
|
75014
75804
|
out.push("");
|
|
75015
75805
|
out.push(divider("USAGE"));
|
|
75016
75806
|
out.push("");
|
|
75017
|
-
out.push(` ${
|
|
75807
|
+
out.push(` ${import_picocolors43.default.bold("brainbase")} ${import_picocolors43.default.dim("<command> [options]")}`);
|
|
75018
75808
|
out.push("");
|
|
75019
75809
|
out.push(divider("AUTH"));
|
|
75020
75810
|
out.push("");
|
|
75021
|
-
out.push(` ${
|
|
75022
|
-
out.push(` ${
|
|
75023
|
-
out.push(` ${
|
|
75811
|
+
out.push(` ${import_picocolors43.default.cyan("login")} ${import_picocolors43.default.dim(" open the web app and connect this device")}`);
|
|
75812
|
+
out.push(` ${import_picocolors43.default.cyan("logout")} ${import_picocolors43.default.dim(" clear the local session")}`);
|
|
75813
|
+
out.push(` ${import_picocolors43.default.cyan("whoami")} ${import_picocolors43.default.dim(" show the current user")}`);
|
|
75024
75814
|
out.push("");
|
|
75025
75815
|
out.push(divider("LINKED AGENT"));
|
|
75026
75816
|
out.push("");
|
|
75027
|
-
out.push(` ${
|
|
75028
|
-
out.push(` ${
|
|
75029
|
-
out.push(` ${
|
|
75030
|
-
out.push(` ${
|
|
75031
|
-
out.push(` ${
|
|
75032
|
-
out.push(` ${
|
|
75033
|
-
out.push(` ${
|
|
75034
|
-
out.push(` ${
|
|
75035
|
-
out.push(` ${
|
|
75036
|
-
out.push(` ${
|
|
75817
|
+
out.push(` ${import_picocolors43.default.cyan("agent create")} ${import_picocolors43.default.dim("claim an unclaimed brainbase.agent.yaml and create the cloud agent")}`);
|
|
75818
|
+
out.push(` ${import_picocolors43.default.cyan("agent pull")} ${import_picocolors43.default.dim("[<id>]")} ${import_picocolors43.default.dim("bring cloud changes into this folder (--force to override; --run-entrypoint to also execute the agent entrypoint)")}`);
|
|
75819
|
+
out.push(` ${import_picocolors43.default.cyan("agent push")} ${import_picocolors43.default.dim("send local changes to the cloud (--force to overwrite cloud-side conflicts with local)")}`);
|
|
75820
|
+
out.push(` ${import_picocolors43.default.cyan("agent unpack")} ${import_picocolors43.default.dim("install the claimed agent into a harness layout")}`);
|
|
75821
|
+
out.push(` ${import_picocolors43.default.cyan("link")} ${import_picocolors43.default.dim("attach this folder to an existing agent")}`);
|
|
75822
|
+
out.push(` ${import_picocolors43.default.cyan("agent status")} ${import_picocolors43.default.dim("show what would pull and what would push")}`);
|
|
75823
|
+
out.push(` ${import_picocolors43.default.cyan("agent env")} ${import_picocolors43.default.dim("print export lines for `eval $(brainbase agent env)`")}`);
|
|
75824
|
+
out.push(` ${import_picocolors43.default.cyan("run")} ${import_picocolors43.default.dim("<cmd> [args...]")} ${import_picocolors43.default.dim("run <cmd> with secrets.env loaded into env")}`);
|
|
75825
|
+
out.push(` ${import_picocolors43.default.cyan("status")} ${import_picocolors43.default.dim("show what this folder is linked to")}`);
|
|
75826
|
+
out.push(` ${import_picocolors43.default.cyan("unlink")} ${import_picocolors43.default.dim("disconnect this folder")}`);
|
|
75037
75827
|
out.push("");
|
|
75038
75828
|
out.push(divider("ORCHESTRATIONS"));
|
|
75039
75829
|
out.push("");
|
|
75040
|
-
out.push(` ${
|
|
75041
|
-
out.push(` ${
|
|
75042
|
-
out.push(` ${
|
|
75043
|
-
out.push(` ${
|
|
75830
|
+
out.push(` ${import_picocolors43.default.cyan("orchestration create")} ${import_picocolors43.default.dim("claim a local orchestration manifest and create it in the cloud")}`);
|
|
75831
|
+
out.push(` ${import_picocolors43.default.cyan("orchestration list")} ${import_picocolors43.default.dim("list orchestrations under a team")}`);
|
|
75832
|
+
out.push(` ${import_picocolors43.default.cyan("orchestration pull")} ${import_picocolors43.default.dim("<id>")} ${import_picocolors43.default.dim("recursively fetch an orchestration + every member agent")}`);
|
|
75833
|
+
out.push(` ${import_picocolors43.default.cyan("orchestration push")} ${import_picocolors43.default.dim("recursively push each member, then update the graph")}`);
|
|
75834
|
+
out.push(` ${import_picocolors43.default.cyan("orchestration status")} ${import_picocolors43.default.dim("show what would push and what would pull")}`);
|
|
75044
75835
|
out.push("");
|
|
75045
75836
|
out.push(divider("TEMPLATES"));
|
|
75046
75837
|
out.push("");
|
|
75047
|
-
out.push(` ${
|
|
75048
|
-
out.push(` ${
|
|
75049
|
-
out.push(` ${
|
|
75050
|
-
out.push(` ${
|
|
75051
|
-
out.push(` ${
|
|
75052
|
-
out.push(` ${
|
|
75053
|
-
out.push(` ${
|
|
75838
|
+
out.push(` ${import_picocolors43.default.cyan("template pack")} ${import_picocolors43.default.dim("bundle the current agent into a template")}`);
|
|
75839
|
+
out.push(` ${import_picocolors43.default.cyan("template publish")} ${import_picocolors43.default.dim("upload a template to the registry")}`);
|
|
75840
|
+
out.push(` ${import_picocolors43.default.cyan("template search")} ${import_picocolors43.default.dim("[query]")} ${import_picocolors43.default.dim("search the registry")}`);
|
|
75841
|
+
out.push(` ${import_picocolors43.default.cyan("template info")} ${import_picocolors43.default.dim("<creator/slug>")} ${import_picocolors43.default.dim("show registry details for a template")}`);
|
|
75842
|
+
out.push(` ${import_picocolors43.default.cyan("template onboard")} ${import_picocolors43.default.dim("<creator/slug>")} ${import_picocolors43.default.dim("install (or refresh) a template")}`);
|
|
75843
|
+
out.push(` ${import_picocolors43.default.cyan("template list")} ${import_picocolors43.default.dim("show installed templates")}`);
|
|
75844
|
+
out.push(` ${import_picocolors43.default.cyan("template remove")} ${import_picocolors43.default.dim("<creator/slug>")} ${import_picocolors43.default.dim("uninstall a template")}`);
|
|
75054
75845
|
out.push("");
|
|
75055
75846
|
out.push(divider("SKILLS"));
|
|
75056
75847
|
out.push("");
|
|
75057
|
-
out.push(` ${
|
|
75058
|
-
out.push(` ${
|
|
75059
|
-
out.push(` ${
|
|
75060
|
-
out.push(` ${
|
|
75061
|
-
out.push(` ${
|
|
75062
|
-
out.push(` ${
|
|
75063
|
-
out.push(` ${
|
|
75848
|
+
out.push(` ${import_picocolors43.default.cyan("skill add")} ${import_picocolors43.default.dim("<source>")} ${import_picocolors43.default.dim("install a skill (github / git / brainbase)")}`);
|
|
75849
|
+
out.push(` ${import_picocolors43.default.cyan("skill list")} ${import_picocolors43.default.dim("show locally installed skills + their source")}`);
|
|
75850
|
+
out.push(` ${import_picocolors43.default.cyan("skill update")} ${import_picocolors43.default.dim("<slug>")} ${import_picocolors43.default.dim("re-fetch a skill from its recorded source")}`);
|
|
75851
|
+
out.push(` ${import_picocolors43.default.cyan("skill remove")} ${import_picocolors43.default.dim("<slug>")} ${import_picocolors43.default.dim("uninstall a skill")}`);
|
|
75852
|
+
out.push(` ${import_picocolors43.default.cyan("skill search")} ${import_picocolors43.default.dim("[query]")} ${import_picocolors43.default.dim("search the brainbase skill registry")}`);
|
|
75853
|
+
out.push(` ${import_picocolors43.default.cyan("skill info")} ${import_picocolors43.default.dim("<creator/slug>")} ${import_picocolors43.default.dim("show registry details for a skill")}`);
|
|
75854
|
+
out.push(` ${import_picocolors43.default.cyan("skill publish")} ${import_picocolors43.default.dim("[dir]")} ${import_picocolors43.default.dim("publish a SKILL.md folder (defaults to .)")}`);
|
|
75064
75855
|
out.push("");
|
|
75065
75856
|
out.push(divider("CLI TOKENS"));
|
|
75066
75857
|
out.push("");
|
|
75067
|
-
out.push(` ${
|
|
75068
|
-
out.push(` ${
|
|
75069
|
-
out.push(` ${
|
|
75858
|
+
out.push(` ${import_picocolors43.default.cyan("token create")} ${import_picocolors43.default.dim("issue a long-lived CLI key for CI / scripts")}`);
|
|
75859
|
+
out.push(` ${import_picocolors43.default.cyan("token list")} ${import_picocolors43.default.dim("show your active tokens")}`);
|
|
75860
|
+
out.push(` ${import_picocolors43.default.cyan("token revoke")} ${import_picocolors43.default.dim("<id>")} ${import_picocolors43.default.dim("revoke a token")}`);
|
|
75070
75861
|
out.push("");
|
|
75071
75862
|
out.push(divider("MCP"));
|
|
75072
75863
|
out.push("");
|
|
75073
|
-
out.push(` ${
|
|
75864
|
+
out.push(` ${import_picocolors43.default.cyan("mcp check")} ${import_picocolors43.default.dim("[--json]")} ${import_picocolors43.default.dim("verify MCP server connectivity through the brainbase proxy (runs at sandbox bootstrap)")}`);
|
|
75074
75865
|
out.push("");
|
|
75075
75866
|
out.push(divider("FLAGS"));
|
|
75076
75867
|
out.push("");
|
|
75077
|
-
out.push(` ${
|
|
75078
|
-
out.push(` ${
|
|
75079
|
-
out.push(` ${
|
|
75080
|
-
out.push(` ${
|
|
75081
|
-
out.push(` ${
|
|
75082
|
-
out.push(` ${
|
|
75083
|
-
out.push(` ${
|
|
75084
|
-
out.push(` ${
|
|
75085
|
-
out.push(` ${
|
|
75868
|
+
out.push(` ${import_picocolors43.default.dim("--harness <id>")} force harness for onboard / sync (e.g. claude-code)`);
|
|
75869
|
+
out.push(` ${import_picocolors43.default.dim("--scope <s>")} force scope: global | project`);
|
|
75870
|
+
out.push(` ${import_picocolors43.default.dim("--yes, -y")} skip confirmations / auto-overwrite`);
|
|
75871
|
+
out.push(` ${import_picocolors43.default.dim("--agent <id>")} for link: attach this folder to an existing agent non-interactively`);
|
|
75872
|
+
out.push(` ${import_picocolors43.default.dim("--no-tracking")} for link: skip routing LLM traffic through brainbase`);
|
|
75873
|
+
out.push(` ${import_picocolors43.default.dim("--track")} for agent create: enable tracking non-interactively (off without a TTY)`);
|
|
75874
|
+
out.push(` ${import_picocolors43.default.dim("--shell <sh|fish>")} for agent env: pick output format (auto-detected from $SHELL)`);
|
|
75875
|
+
out.push(` ${import_picocolors43.default.dim("--all")} for template list: include installs from other folders`);
|
|
75876
|
+
out.push(` ${import_picocolors43.default.dim("--web <url>")} for login: web app URL (default https://new.usekafka.com)`);
|
|
75086
75877
|
out.push("");
|
|
75087
75878
|
out.push(divider("ENV"));
|
|
75088
75879
|
out.push("");
|
|
75089
|
-
out.push(` ${
|
|
75090
|
-
out.push(` ${
|
|
75091
|
-
out.push(` ${
|
|
75092
|
-
out.push(` ${
|
|
75093
|
-
out.push(` ${
|
|
75094
|
-
out.push(` ${
|
|
75095
|
-
out.push(` ${
|
|
75096
|
-
out.push(` ${
|
|
75880
|
+
out.push(` ${import_picocolors43.default.dim("BRAINBASE_HOME")} override the local config dir (default ~/.brainbase)`);
|
|
75881
|
+
out.push(` ${import_picocolors43.default.dim("BRAINBASE_WEB_URL")} override the web app URL used by login`);
|
|
75882
|
+
out.push(` ${import_picocolors43.default.dim("BRAINBASE_CONTROL_PLANE_URL")} override the MAS control-plane host (uses /v2/cli)`);
|
|
75883
|
+
out.push(` ${import_picocolors43.default.dim("BRAINBASE_API_URL")} legacy KLS host override (uses /api/cli; proxy/registry fallback)`);
|
|
75884
|
+
out.push(` ${import_picocolors43.default.dim("BRAINBASE_PROXY_URL")} override the model-proxy URL used by harness traffic (default https://api.v1.brainbaselabs.com)`);
|
|
75885
|
+
out.push(` ${import_picocolors43.default.dim("BRAINBASE_REGISTRY_URL")} override the registry API URL (default https://api.v1.brainbaselabs.com)`);
|
|
75886
|
+
out.push(` ${import_picocolors43.default.dim("BRAINBASE_TOKEN")} long-lived CLI PAT (overrides token.json)`);
|
|
75887
|
+
out.push(` ${import_picocolors43.default.dim("BRAINBASE_SKIP_AUTH")} bypass the auth gate for development`);
|
|
75888
|
+
out.push(` ${import_picocolors43.default.dim("BRAINBASE_NON_INTERACTIVE")} force non-interactive mode — skip/auto-default prompts (CI & agents)`);
|
|
75889
|
+
out.push(` ${import_picocolors43.default.dim("BRAINBASE_RUN_ENTRYPOINT")} =1 → agent pull executes the agent entrypoint (sandbox boots; or pass --run-entrypoint)`);
|
|
75097
75890
|
out.push("");
|
|
75098
75891
|
out.push(divider("HARNESSES"));
|
|
75099
75892
|
out.push("");
|
|
75100
|
-
out.push(` ${
|
|
75101
|
-
out.push(` ${
|
|
75102
|
-
out.push(` ${
|
|
75893
|
+
out.push(` ${import_picocolors43.default.dim("•")} ${import_picocolors43.default.bold("claude-code")} ${import_picocolors43.default.dim("skills, mcps, agents, commands, playbooks, instructions, files")}`);
|
|
75894
|
+
out.push(` ${import_picocolors43.default.dim("•")} ${import_picocolors43.default.bold("codex")} ${import_picocolors43.default.dim("skills, mcps, commands, playbooks, instructions, files")}`);
|
|
75895
|
+
out.push(` ${import_picocolors43.default.dim("•")} ${import_picocolors43.default.bold("kafka")} ${import_picocolors43.default.dim("skills, mcps, agents, commands, playbooks, instructions, files")}`);
|
|
75103
75896
|
out.push("");
|
|
75104
75897
|
console.log(out.join(`
|
|
75105
75898
|
`));
|
|
@@ -75153,13 +75946,13 @@ async function requireAuth(cmd) {
|
|
|
75153
75946
|
if (status.ok)
|
|
75154
75947
|
return;
|
|
75155
75948
|
console.error("");
|
|
75156
|
-
console.error(` ${brandTint("◆")} ${
|
|
75949
|
+
console.error(` ${brandTint("◆")} ${import_picocolors43.default.bold("brainbase")}`);
|
|
75157
75950
|
console.error("");
|
|
75158
|
-
console.error(` ${
|
|
75951
|
+
console.error(` ${import_picocolors43.default.red("✗")} You need to sign in to use ${import_picocolors43.default.bold("brainbase " + cmd)}.`);
|
|
75159
75952
|
if (status.reason)
|
|
75160
|
-
console.error(` ${
|
|
75953
|
+
console.error(` ${import_picocolors43.default.dim(status.reason)}`);
|
|
75161
75954
|
console.error("");
|
|
75162
|
-
console.error(` Run ${
|
|
75955
|
+
console.error(` Run ${import_picocolors43.default.cyan("brainbase login")} to connect this device.`);
|
|
75163
75956
|
console.error("");
|
|
75164
75957
|
process14.exit(1);
|
|
75165
75958
|
}
|
|
@@ -75337,7 +76130,7 @@ async function main() {
|
|
|
75337
76130
|
process14.exit(1);
|
|
75338
76131
|
}
|
|
75339
76132
|
} catch (err) {
|
|
75340
|
-
console.error(
|
|
76133
|
+
console.error(import_picocolors43.default.red(`
|
|
75341
76134
|
${err.message}`));
|
|
75342
76135
|
if (process14.env.BRAINBASE_DEBUG)
|
|
75343
76136
|
console.error(err.stack);
|