@brainbase-labs/cli 0.9.0 → 0.10.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/dist/index.js +406 -141
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -29449,7 +29449,7 @@ function padStart(s, n) {
|
|
|
29449
29449
|
// package.json
|
|
29450
29450
|
var package_default = {
|
|
29451
29451
|
name: "@brainbase-labs/cli",
|
|
29452
|
-
version: "0.
|
|
29452
|
+
version: "0.10.1",
|
|
29453
29453
|
description: "Pack, share, and install agent templates across harnesses (Claude Code, Codex, ...).",
|
|
29454
29454
|
type: "module",
|
|
29455
29455
|
bin: {
|
|
@@ -29921,6 +29921,73 @@ function scopePaths(cwd, scope) {
|
|
|
29921
29921
|
return scope === "global" ? globalPaths() : projectPaths(cwd);
|
|
29922
29922
|
}
|
|
29923
29923
|
|
|
29924
|
+
// src/harnesses/claude-code/settings.ts
|
|
29925
|
+
function readSettings(file) {
|
|
29926
|
+
return readJsonOr(file, {});
|
|
29927
|
+
}
|
|
29928
|
+
function writeSettings(file, settings) {
|
|
29929
|
+
writeJson(file, settings);
|
|
29930
|
+
}
|
|
29931
|
+
function setMcpServer(file, name, entry) {
|
|
29932
|
+
const s = readSettings(file);
|
|
29933
|
+
if (!s.mcpServers)
|
|
29934
|
+
s.mcpServers = {};
|
|
29935
|
+
s.mcpServers[name] = entry;
|
|
29936
|
+
writeSettings(file, s);
|
|
29937
|
+
}
|
|
29938
|
+
function removeMcpServer(file, name) {
|
|
29939
|
+
if (!exists(file))
|
|
29940
|
+
return;
|
|
29941
|
+
const s = readSettings(file);
|
|
29942
|
+
if (s.mcpServers && name in s.mcpServers) {
|
|
29943
|
+
delete s.mcpServers[name];
|
|
29944
|
+
writeSettings(file, s);
|
|
29945
|
+
}
|
|
29946
|
+
}
|
|
29947
|
+
function getMcpServer(file, name) {
|
|
29948
|
+
const s = readSettings(file);
|
|
29949
|
+
return s.mcpServers?.[name];
|
|
29950
|
+
}
|
|
29951
|
+
function listMcpServers(file) {
|
|
29952
|
+
return readSettings(file).mcpServers ?? {};
|
|
29953
|
+
}
|
|
29954
|
+
function normalizeMcpPayload(payload) {
|
|
29955
|
+
const out = { ...payload };
|
|
29956
|
+
delete out.is_enabled;
|
|
29957
|
+
const hasUrl = typeof out.url === "string" && out.url.length > 0;
|
|
29958
|
+
const hasCommand = typeof out.command === "string" && out.command.length > 0;
|
|
29959
|
+
if (!out.type) {
|
|
29960
|
+
if (hasUrl)
|
|
29961
|
+
out.type = "http";
|
|
29962
|
+
else if (hasCommand)
|
|
29963
|
+
out.type = "stdio";
|
|
29964
|
+
}
|
|
29965
|
+
if (out.type === "http" || out.type === "sse") {
|
|
29966
|
+
if (Array.isArray(out.args) && out.args.length === 0)
|
|
29967
|
+
delete out.args;
|
|
29968
|
+
if (out.env && typeof out.env === "object" && Object.keys(out.env).length === 0) {
|
|
29969
|
+
delete out.env;
|
|
29970
|
+
}
|
|
29971
|
+
if (out.headers && typeof out.headers === "object" && Object.keys(out.headers).length === 0) {
|
|
29972
|
+
delete out.headers;
|
|
29973
|
+
}
|
|
29974
|
+
}
|
|
29975
|
+
if (out.type === "stdio") {
|
|
29976
|
+
delete out.url;
|
|
29977
|
+
delete out.headers;
|
|
29978
|
+
}
|
|
29979
|
+
return out;
|
|
29980
|
+
}
|
|
29981
|
+
function listMcpServersFromMcpJson(file) {
|
|
29982
|
+
return readJsonOr(file, {}).mcpServers ?? {};
|
|
29983
|
+
}
|
|
29984
|
+
function listMcpServersFromClaudeJson(file, projectKey) {
|
|
29985
|
+
const data = readJsonOr(file, {});
|
|
29986
|
+
if (projectKey)
|
|
29987
|
+
return data.projects?.[projectKey]?.mcpServers ?? {};
|
|
29988
|
+
return data.mcpServers ?? {};
|
|
29989
|
+
}
|
|
29990
|
+
|
|
29924
29991
|
// src/harnesses/claude-code/inventory.ts
|
|
29925
29992
|
import fs4 from "node:fs";
|
|
29926
29993
|
import path6 from "node:path";
|
|
@@ -33961,73 +34028,6 @@ function manifestSourceForPack(source) {
|
|
|
33961
34028
|
return source.type === "local" ? { type: "inline" } : source;
|
|
33962
34029
|
}
|
|
33963
34030
|
|
|
33964
|
-
// src/harnesses/claude-code/settings.ts
|
|
33965
|
-
function readSettings(file) {
|
|
33966
|
-
return readJsonOr(file, {});
|
|
33967
|
-
}
|
|
33968
|
-
function writeSettings(file, settings) {
|
|
33969
|
-
writeJson(file, settings);
|
|
33970
|
-
}
|
|
33971
|
-
function setMcpServer(file, name, entry) {
|
|
33972
|
-
const s = readSettings(file);
|
|
33973
|
-
if (!s.mcpServers)
|
|
33974
|
-
s.mcpServers = {};
|
|
33975
|
-
s.mcpServers[name] = entry;
|
|
33976
|
-
writeSettings(file, s);
|
|
33977
|
-
}
|
|
33978
|
-
function removeMcpServer(file, name) {
|
|
33979
|
-
if (!exists(file))
|
|
33980
|
-
return;
|
|
33981
|
-
const s = readSettings(file);
|
|
33982
|
-
if (s.mcpServers && name in s.mcpServers) {
|
|
33983
|
-
delete s.mcpServers[name];
|
|
33984
|
-
writeSettings(file, s);
|
|
33985
|
-
}
|
|
33986
|
-
}
|
|
33987
|
-
function getMcpServer(file, name) {
|
|
33988
|
-
const s = readSettings(file);
|
|
33989
|
-
return s.mcpServers?.[name];
|
|
33990
|
-
}
|
|
33991
|
-
function listMcpServers(file) {
|
|
33992
|
-
return readSettings(file).mcpServers ?? {};
|
|
33993
|
-
}
|
|
33994
|
-
function normalizeMcpPayload(payload) {
|
|
33995
|
-
const out = { ...payload };
|
|
33996
|
-
delete out.is_enabled;
|
|
33997
|
-
const hasUrl = typeof out.url === "string" && out.url.length > 0;
|
|
33998
|
-
const hasCommand = typeof out.command === "string" && out.command.length > 0;
|
|
33999
|
-
if (!out.type) {
|
|
34000
|
-
if (hasUrl)
|
|
34001
|
-
out.type = "http";
|
|
34002
|
-
else if (hasCommand)
|
|
34003
|
-
out.type = "stdio";
|
|
34004
|
-
}
|
|
34005
|
-
if (out.type === "http" || out.type === "sse") {
|
|
34006
|
-
if (Array.isArray(out.args) && out.args.length === 0)
|
|
34007
|
-
delete out.args;
|
|
34008
|
-
if (out.env && typeof out.env === "object" && Object.keys(out.env).length === 0) {
|
|
34009
|
-
delete out.env;
|
|
34010
|
-
}
|
|
34011
|
-
if (out.headers && typeof out.headers === "object" && Object.keys(out.headers).length === 0) {
|
|
34012
|
-
delete out.headers;
|
|
34013
|
-
}
|
|
34014
|
-
}
|
|
34015
|
-
if (out.type === "stdio") {
|
|
34016
|
-
delete out.url;
|
|
34017
|
-
delete out.headers;
|
|
34018
|
-
}
|
|
34019
|
-
return out;
|
|
34020
|
-
}
|
|
34021
|
-
function listMcpServersFromMcpJson(file) {
|
|
34022
|
-
return readJsonOr(file, {}).mcpServers ?? {};
|
|
34023
|
-
}
|
|
34024
|
-
function listMcpServersFromClaudeJson(file, projectKey) {
|
|
34025
|
-
const data = readJsonOr(file, {});
|
|
34026
|
-
if (projectKey)
|
|
34027
|
-
return data.projects?.[projectKey]?.mcpServers ?? {};
|
|
34028
|
-
return data.mcpServers ?? {};
|
|
34029
|
-
}
|
|
34030
|
-
|
|
34031
34031
|
// src/harnesses/claude-code/inventory.ts
|
|
34032
34032
|
function firstLine(file, max = 200) {
|
|
34033
34033
|
try {
|
|
@@ -35070,6 +35070,11 @@ var claudeCode = {
|
|
|
35070
35070
|
async function installClaudeCodeWithCtx(components, opts, templateName) {
|
|
35071
35071
|
return installClaudeCode(components, opts, { templateName });
|
|
35072
35072
|
}
|
|
35073
|
+
function removeClaudeCodeMcp(slugs, opts) {
|
|
35074
|
+
const { mcpStore } = scopePaths(opts.cwd, opts.scope);
|
|
35075
|
+
for (const slug of slugs)
|
|
35076
|
+
removeMcpServer(mcpStore, slug);
|
|
35077
|
+
}
|
|
35073
35078
|
|
|
35074
35079
|
// src/harnesses/codex/paths.ts
|
|
35075
35080
|
import path13 from "node:path";
|
|
@@ -35101,10 +35106,6 @@ function isBundledSkillDir(name) {
|
|
|
35101
35106
|
return name === ".system" || name.startsWith(".");
|
|
35102
35107
|
}
|
|
35103
35108
|
|
|
35104
|
-
// src/harnesses/codex/inventory.ts
|
|
35105
|
-
import fs12 from "node:fs";
|
|
35106
|
-
import path15 from "node:path";
|
|
35107
|
-
|
|
35108
35109
|
// src/harnesses/codex/config-toml.ts
|
|
35109
35110
|
import fs11 from "node:fs";
|
|
35110
35111
|
|
|
@@ -36269,6 +36270,8 @@ function listMcpServers2(file) {
|
|
|
36269
36270
|
}
|
|
36270
36271
|
|
|
36271
36272
|
// src/harnesses/codex/inventory.ts
|
|
36273
|
+
import fs12 from "node:fs";
|
|
36274
|
+
import path15 from "node:path";
|
|
36272
36275
|
function firstLine2(file, max = 200) {
|
|
36273
36276
|
try {
|
|
36274
36277
|
const head = fs12.readFileSync(file, "utf8").slice(0, 2000);
|
|
@@ -36882,6 +36885,11 @@ var codex = {
|
|
|
36882
36885
|
async function installCodexWithCtx(components, opts, templateName) {
|
|
36883
36886
|
return installCodex(components, opts, { templateName });
|
|
36884
36887
|
}
|
|
36888
|
+
function removeCodexMcp(slugs, opts) {
|
|
36889
|
+
const { config } = scopePaths2(opts.cwd, opts.scope);
|
|
36890
|
+
for (const slug of slugs)
|
|
36891
|
+
removeMcpServer2(config, slug);
|
|
36892
|
+
}
|
|
36885
36893
|
|
|
36886
36894
|
// src/harnesses/kafka/paths.ts
|
|
36887
36895
|
import path19 from "node:path";
|
|
@@ -36919,10 +36927,6 @@ function scopePaths3(cwd, scope) {
|
|
|
36919
36927
|
return scope === "global" ? globalPaths3() : projectPaths3(cwd);
|
|
36920
36928
|
}
|
|
36921
36929
|
|
|
36922
|
-
// src/harnesses/kafka/inventory.ts
|
|
36923
|
-
import fs15 from "node:fs";
|
|
36924
|
-
import path20 from "node:path";
|
|
36925
|
-
|
|
36926
36930
|
// src/harnesses/kafka/settings.ts
|
|
36927
36931
|
function readSettings2(file) {
|
|
36928
36932
|
return readJsonOr(file, {});
|
|
@@ -36972,6 +36976,22 @@ function setMcpServer3(file, name, entry) {
|
|
|
36972
36976
|
}
|
|
36973
36977
|
writeSettings2(file, s);
|
|
36974
36978
|
}
|
|
36979
|
+
function removeMcpServer3(file, name) {
|
|
36980
|
+
if (!exists(file))
|
|
36981
|
+
return;
|
|
36982
|
+
const s = readSettings2(file);
|
|
36983
|
+
const raw = s.mcp_servers ?? s.mcpServers;
|
|
36984
|
+
if (!raw)
|
|
36985
|
+
return;
|
|
36986
|
+
if (Array.isArray(raw)) {
|
|
36987
|
+
s.mcp_servers = raw.filter((e2) => e2.name !== name);
|
|
36988
|
+
} else {
|
|
36989
|
+
delete raw[name];
|
|
36990
|
+
s.mcp_servers = raw;
|
|
36991
|
+
}
|
|
36992
|
+
delete s.mcpServers;
|
|
36993
|
+
writeSettings2(file, s);
|
|
36994
|
+
}
|
|
36975
36995
|
function normalizeMcpPayload2(payload) {
|
|
36976
36996
|
const out = { ...payload };
|
|
36977
36997
|
delete out.is_enabled;
|
|
@@ -37001,6 +37021,8 @@ function normalizeMcpPayload2(payload) {
|
|
|
37001
37021
|
}
|
|
37002
37022
|
|
|
37003
37023
|
// src/harnesses/kafka/inventory.ts
|
|
37024
|
+
import fs15 from "node:fs";
|
|
37025
|
+
import path20 from "node:path";
|
|
37004
37026
|
function firstLine3(file, max = 200) {
|
|
37005
37027
|
try {
|
|
37006
37028
|
const head = fs15.readFileSync(file, "utf8").slice(0, 2000);
|
|
@@ -37650,6 +37672,11 @@ var kafka = {
|
|
|
37650
37672
|
async function installKafkaWithCtx(components, opts, templateName) {
|
|
37651
37673
|
return installKafka(components, opts, { templateName });
|
|
37652
37674
|
}
|
|
37675
|
+
function removeKafkaMcp(slugs, opts) {
|
|
37676
|
+
const { mcpStore } = scopePaths3(opts.cwd, opts.scope);
|
|
37677
|
+
for (const slug of slugs)
|
|
37678
|
+
removeMcpServer3(mcpStore, slug);
|
|
37679
|
+
}
|
|
37653
37680
|
|
|
37654
37681
|
// src/harnesses/index.ts
|
|
37655
37682
|
var adapters = [claudeCode, codex, kafka];
|
|
@@ -37679,6 +37706,17 @@ async function detectHarnesses(cwd) {
|
|
|
37679
37706
|
}
|
|
37680
37707
|
return out;
|
|
37681
37708
|
}
|
|
37709
|
+
function runHarnessRemoveMcp(harnessId, slugs, opts) {
|
|
37710
|
+
if (slugs.length === 0)
|
|
37711
|
+
return;
|
|
37712
|
+
const canonical = normalizeHarnessId(harnessId);
|
|
37713
|
+
if (canonical === "claude-code")
|
|
37714
|
+
return removeClaudeCodeMcp(slugs, opts);
|
|
37715
|
+
if (canonical === "codex")
|
|
37716
|
+
return removeCodexMcp(slugs, opts);
|
|
37717
|
+
if (canonical === "kafka")
|
|
37718
|
+
return removeKafkaMcp(slugs, opts);
|
|
37719
|
+
}
|
|
37682
37720
|
|
|
37683
37721
|
// src/core/registry.ts
|
|
37684
37722
|
import fs18 from "node:fs";
|
|
@@ -48632,6 +48670,8 @@ async function runRemove(cwd2, args) {
|
|
|
48632
48670
|
if (c2.type === "mcp" && c2.settingsFile && c2.embeddedKey) {
|
|
48633
48671
|
if (inst.harness === "codex")
|
|
48634
48672
|
removeMcpServer2(c2.settingsFile, c2.embeddedKey);
|
|
48673
|
+
else if (inst.harness === "kafka")
|
|
48674
|
+
removeMcpServer3(c2.settingsFile, c2.embeddedKey);
|
|
48635
48675
|
else
|
|
48636
48676
|
removeMcpServer(c2.settingsFile, c2.embeddedKey);
|
|
48637
48677
|
} else if (c2.type === "instruction") {
|
|
@@ -50373,6 +50413,7 @@ async function runSkillPublish(cwd2, args) {
|
|
|
50373
50413
|
writeSkillMarker(skillDir, newSource);
|
|
50374
50414
|
$e(`${import_picocolors16.default.bold(creator + "/" + pkgSlug)}@${version} published.`);
|
|
50375
50415
|
f2.info(import_picocolors16.default.dim(`id: ${result2.id}`));
|
|
50416
|
+
f2.info(import_picocolors16.default.dim(`To use it on an agent: add ${import_picocolors16.default.cyan(`source: registry:${creator}/${pkgSlug}`)} under ${import_picocolors16.default.cyan("skills:")} in brainbase.agent.yaml, then ${import_picocolors16.default.cyan("brainbase agent push")}. Agents already linking it pick up ${version} on their next push.`));
|
|
50376
50417
|
} finally {
|
|
50377
50418
|
try {
|
|
50378
50419
|
fs37.rmSync(tmp, { recursive: true, force: true });
|
|
@@ -50504,6 +50545,9 @@ async function runSkillUpdate(cwd2, args) {
|
|
|
50504
50545
|
}
|
|
50505
50546
|
writeSkillMarker(target.dir, marker.source);
|
|
50506
50547
|
$e(`${import_picocolors17.default.bold(args.slug)} updated.`);
|
|
50548
|
+
if (marker.source.type === "brainbase") {
|
|
50549
|
+
f2.info(import_picocolors17.default.dim(`This refreshed your local copy only. Agents using this skill update on their next ${import_picocolors17.default.cyan("brainbase agent push")} (run it in the agent's folder).`));
|
|
50550
|
+
}
|
|
50507
50551
|
}
|
|
50508
50552
|
|
|
50509
50553
|
// src/cli/skill-search.ts
|
|
@@ -51098,6 +51142,11 @@ var McpEntrySchema = exports_external.object({
|
|
|
51098
51142
|
headers: exports_external.record(exports_external.string()).optional(),
|
|
51099
51143
|
is_enabled: exports_external.boolean().optional()
|
|
51100
51144
|
});
|
|
51145
|
+
var CapabilitiesSchema = exports_external.object({
|
|
51146
|
+
memory: exports_external.boolean().optional(),
|
|
51147
|
+
browser: exports_external.boolean().optional(),
|
|
51148
|
+
slack: exports_external.boolean().optional()
|
|
51149
|
+
});
|
|
51101
51150
|
var AgentManifestSchema = exports_external.object({
|
|
51102
51151
|
schema: exports_external.literal(1),
|
|
51103
51152
|
id: exports_external.string().min(1).optional(),
|
|
@@ -51108,6 +51157,7 @@ var AgentManifestSchema = exports_external.object({
|
|
|
51108
51157
|
playbooks: exports_external.array(PlaybookSchema).default([]),
|
|
51109
51158
|
skills: exports_external.array(SkillEntrySchema).default([]),
|
|
51110
51159
|
mcp: exports_external.array(McpEntrySchema).default([]),
|
|
51160
|
+
capabilities: CapabilitiesSchema.optional(),
|
|
51111
51161
|
commands: exports_external.array(exports_external.record(exports_external.unknown())).optional(),
|
|
51112
51162
|
hooks: exports_external.array(exports_external.record(exports_external.unknown())).optional(),
|
|
51113
51163
|
files: exports_external.array(exports_external.record(exports_external.unknown())).optional()
|
|
@@ -51894,6 +51944,39 @@ import os11 from "node:os";
|
|
|
51894
51944
|
import crypto3 from "node:crypto";
|
|
51895
51945
|
var import_picocolors24 = __toESM(require_picocolors(), 1);
|
|
51896
51946
|
|
|
51947
|
+
// src/core/memory-mcp.ts
|
|
51948
|
+
var DEFAULT_MEMORY_MCP_BASE = "https://brainbase-memory-mcp.onrender.com";
|
|
51949
|
+
var MEMORY_MCP_SLUG = "brainbase-memory";
|
|
51950
|
+
function memoryMcpBaseUrl() {
|
|
51951
|
+
const envOverride = process.env.BRAINBASE_MEMORY_MCP_URL;
|
|
51952
|
+
if (envOverride)
|
|
51953
|
+
return envOverride.replace(/\/+$/, "");
|
|
51954
|
+
return DEFAULT_MEMORY_MCP_BASE;
|
|
51955
|
+
}
|
|
51956
|
+
function memoryMcpUrl() {
|
|
51957
|
+
return `${memoryMcpBaseUrl()}/t/\${BRAINBASE_THREAD_ID}/mcp`;
|
|
51958
|
+
}
|
|
51959
|
+
function memoryMcpPayload() {
|
|
51960
|
+
return {
|
|
51961
|
+
url: memoryMcpUrl(),
|
|
51962
|
+
headers: {
|
|
51963
|
+
Authorization: "Bearer ${BRAINBASE_TOKEN}"
|
|
51964
|
+
}
|
|
51965
|
+
};
|
|
51966
|
+
}
|
|
51967
|
+
function buildMemoryMcpComponent(scope) {
|
|
51968
|
+
return {
|
|
51969
|
+
type: "mcp",
|
|
51970
|
+
slug: MEMORY_MCP_SLUG,
|
|
51971
|
+
scope,
|
|
51972
|
+
rootDir: "",
|
|
51973
|
+
description: "This agent's persistent SQL memory database (provision, query, " + "inspect schema). Scoped to this agent only.",
|
|
51974
|
+
meta: { mcp: memoryMcpPayload() },
|
|
51975
|
+
payload: memoryMcpPayload(),
|
|
51976
|
+
checksum: "builtin:brainbase-memory:v1"
|
|
51977
|
+
};
|
|
51978
|
+
}
|
|
51979
|
+
|
|
51897
51980
|
// src/core/orchestration-mcp.ts
|
|
51898
51981
|
var DEFAULT_ORCHESTRATION_MCP_BASE = "https://brainbase-orchestration-mcp.onrender.com";
|
|
51899
51982
|
var ORCHESTRATION_MCP_SLUG = "brainbase-orchestration";
|
|
@@ -51927,39 +52010,109 @@ function buildOrchestrationMcpComponent(scope) {
|
|
|
51927
52010
|
};
|
|
51928
52011
|
}
|
|
51929
52012
|
|
|
51930
|
-
// src/core/
|
|
51931
|
-
var
|
|
51932
|
-
var
|
|
51933
|
-
function
|
|
51934
|
-
const envOverride = process.env.
|
|
52013
|
+
// src/core/slack-mcp.ts
|
|
52014
|
+
var DEFAULT_SLACK_MCP_BASE = "https://brainbase-slack-mcp.onrender.com";
|
|
52015
|
+
var SLACK_MCP_SLUG = "brainbase-slack";
|
|
52016
|
+
function slackMcpBaseUrl() {
|
|
52017
|
+
const envOverride = process.env.BRAINBASE_SLACK_MCP_URL;
|
|
51935
52018
|
if (envOverride)
|
|
51936
52019
|
return envOverride.replace(/\/+$/, "");
|
|
51937
|
-
return
|
|
52020
|
+
return DEFAULT_SLACK_MCP_BASE;
|
|
51938
52021
|
}
|
|
51939
|
-
function
|
|
51940
|
-
return `${
|
|
52022
|
+
function slackMcpUrl() {
|
|
52023
|
+
return `${slackMcpBaseUrl()}/t/\${BRAINBASE_THREAD_ID}/mcp`;
|
|
51941
52024
|
}
|
|
51942
|
-
function
|
|
52025
|
+
function slackMcpPayload() {
|
|
51943
52026
|
return {
|
|
51944
|
-
url:
|
|
52027
|
+
url: slackMcpUrl(),
|
|
51945
52028
|
headers: {
|
|
51946
52029
|
Authorization: "Bearer ${BRAINBASE_TOKEN}"
|
|
51947
52030
|
}
|
|
51948
52031
|
};
|
|
51949
52032
|
}
|
|
51950
|
-
function
|
|
52033
|
+
function buildSlackMcpComponent(scope) {
|
|
51951
52034
|
return {
|
|
51952
52035
|
type: "mcp",
|
|
51953
|
-
slug:
|
|
52036
|
+
slug: SLACK_MCP_SLUG,
|
|
51954
52037
|
scope,
|
|
51955
52038
|
rootDir: "",
|
|
51956
|
-
description: "This agent's
|
|
51957
|
-
meta: { mcp:
|
|
51958
|
-
payload:
|
|
51959
|
-
checksum: "builtin:brainbase-
|
|
52039
|
+
description: "This agent's Slack connector (read channels, send messages, manage " + "the workspace it is installed in). Scoped to this agent only.",
|
|
52040
|
+
meta: { mcp: slackMcpPayload() },
|
|
52041
|
+
payload: slackMcpPayload(),
|
|
52042
|
+
checksum: "builtin:brainbase-slack:v1"
|
|
51960
52043
|
};
|
|
51961
52044
|
}
|
|
51962
52045
|
|
|
52046
|
+
// src/core/browser-mcp.ts
|
|
52047
|
+
var DEFAULT_BROWSER_MCP_BASE = "https://brainbase-browser-mcp.onrender.com";
|
|
52048
|
+
var BROWSER_MCP_SLUG = "brainbase-browser";
|
|
52049
|
+
function browserMcpBaseUrl() {
|
|
52050
|
+
const envOverride = process.env.BRAINBASE_BROWSER_MCP_URL;
|
|
52051
|
+
if (envOverride)
|
|
52052
|
+
return envOverride.replace(/\/+$/, "");
|
|
52053
|
+
return DEFAULT_BROWSER_MCP_BASE;
|
|
52054
|
+
}
|
|
52055
|
+
function browserMcpUrl() {
|
|
52056
|
+
return `${browserMcpBaseUrl()}/t/\${BRAINBASE_THREAD_ID}/mcp`;
|
|
52057
|
+
}
|
|
52058
|
+
function browserMcpPayload() {
|
|
52059
|
+
return {
|
|
52060
|
+
url: browserMcpUrl(),
|
|
52061
|
+
headers: {
|
|
52062
|
+
Authorization: "Bearer ${BRAINBASE_TOKEN}"
|
|
52063
|
+
}
|
|
52064
|
+
};
|
|
52065
|
+
}
|
|
52066
|
+
function buildBrowserMcpComponent(scope) {
|
|
52067
|
+
return {
|
|
52068
|
+
type: "mcp",
|
|
52069
|
+
slug: BROWSER_MCP_SLUG,
|
|
52070
|
+
scope,
|
|
52071
|
+
rootDir: "",
|
|
52072
|
+
description: "This agent's headless browser (navigate, read pages, fill forms). " + "Scoped to this agent only.",
|
|
52073
|
+
meta: { mcp: browserMcpPayload() },
|
|
52074
|
+
payload: browserMcpPayload(),
|
|
52075
|
+
checksum: "builtin:brainbase-browser:v1"
|
|
52076
|
+
};
|
|
52077
|
+
}
|
|
52078
|
+
|
|
52079
|
+
// src/core/builtin-mcps.ts
|
|
52080
|
+
function capabilitiesFromAgent(agent) {
|
|
52081
|
+
return {
|
|
52082
|
+
memory: agent.memory_enabled !== false,
|
|
52083
|
+
browser: agent.browser_enabled !== false,
|
|
52084
|
+
slack: agent.slack_connected === true
|
|
52085
|
+
};
|
|
52086
|
+
}
|
|
52087
|
+
function capabilitiesFromManifest(manifest) {
|
|
52088
|
+
const c2 = manifest?.capabilities ?? {};
|
|
52089
|
+
return {
|
|
52090
|
+
memory: c2.memory !== false,
|
|
52091
|
+
browser: c2.browser !== false,
|
|
52092
|
+
slack: c2.slack === true
|
|
52093
|
+
};
|
|
52094
|
+
}
|
|
52095
|
+
function resolveBuiltinMcps(input) {
|
|
52096
|
+
const { caps, declaredSlugs, scope } = input;
|
|
52097
|
+
const gated = [
|
|
52098
|
+
{ slug: ORCHESTRATION_MCP_SLUG, enabled: true, build: buildOrchestrationMcpComponent },
|
|
52099
|
+
{ slug: MEMORY_MCP_SLUG, enabled: caps.memory, build: buildMemoryMcpComponent },
|
|
52100
|
+
{ slug: BROWSER_MCP_SLUG, enabled: caps.browser, build: buildBrowserMcpComponent },
|
|
52101
|
+
{ slug: SLACK_MCP_SLUG, enabled: caps.slack, build: buildSlackMcpComponent }
|
|
52102
|
+
];
|
|
52103
|
+
const install = [];
|
|
52104
|
+
const removeSlugs = [];
|
|
52105
|
+
for (const g3 of gated) {
|
|
52106
|
+
if (declaredSlugs.has(g3.slug))
|
|
52107
|
+
continue;
|
|
52108
|
+
if (g3.enabled)
|
|
52109
|
+
install.push(g3.build(scope));
|
|
52110
|
+
else
|
|
52111
|
+
removeSlugs.push(g3.slug);
|
|
52112
|
+
}
|
|
52113
|
+
return { install, removeSlugs };
|
|
52114
|
+
}
|
|
52115
|
+
|
|
51963
52116
|
// src/cli/sync.ts
|
|
51964
52117
|
async function runSync(cwd2, args) {
|
|
51965
52118
|
banner("sync — bring in the latest changes from your team");
|
|
@@ -51986,11 +52139,21 @@ async function runSync(cwd2, args) {
|
|
|
51986
52139
|
}
|
|
51987
52140
|
const prevState = readSyncState(cwd2);
|
|
51988
52141
|
const diff2 = computeDiff(manifest.components, prevState);
|
|
51989
|
-
const
|
|
51990
|
-
|
|
51991
|
-
|
|
51992
|
-
|
|
51993
|
-
|
|
52142
|
+
const scope = args.scope ?? "project";
|
|
52143
|
+
let caps;
|
|
52144
|
+
try {
|
|
52145
|
+
caps = capabilitiesFromManifest(readManifest(cwd2));
|
|
52146
|
+
} catch (err) {
|
|
52147
|
+
f2.error(err.message);
|
|
52148
|
+
return;
|
|
52149
|
+
}
|
|
52150
|
+
const declaredMcpSlugs = new Set(manifest.components.filter((c2) => c2.type === "mcp").map((c2) => c2.slug));
|
|
52151
|
+
const { install: builtinInstall, removeSlugs: builtinRemoveSlugs } = resolveBuiltinMcps({
|
|
52152
|
+
caps,
|
|
52153
|
+
declaredSlugs: declaredMcpSlugs,
|
|
52154
|
+
scope
|
|
52155
|
+
});
|
|
52156
|
+
if (diff2.added.length === 0 && diff2.upstreamUpdated.length === 0 && diff2.localModified.length === 0 && diff2.deletedUpstream.length === 0 && builtinInstall.length === 0 && builtinRemoveSlugs.length === 0) {
|
|
51994
52157
|
f2.info(`${sym.same} You're up to date.`);
|
|
51995
52158
|
writeSyncState(cwd2, {
|
|
51996
52159
|
schemaVersion: 1,
|
|
@@ -52054,7 +52217,6 @@ async function runSync(cwd2, args) {
|
|
|
52054
52217
|
});
|
|
52055
52218
|
}
|
|
52056
52219
|
const adapter = getAdapter(adapterId);
|
|
52057
|
-
const scope = args.scope ?? "project";
|
|
52058
52220
|
const keepLocal = new Set;
|
|
52059
52221
|
if (diff2.localModified.length > 0) {
|
|
52060
52222
|
requireInteractive(`${diff2.localModified.length} component(s) changed both locally and in the cloud — run \`brainbase sync\` in an interactive terminal to resolve them (or revert your local changes).`);
|
|
@@ -52092,14 +52254,7 @@ async function runSync(cwd2, args) {
|
|
|
52092
52254
|
payload: proxifyMcpPayload(c2.meta?.mcp),
|
|
52093
52255
|
checksum: c2.hash
|
|
52094
52256
|
}));
|
|
52095
|
-
|
|
52096
|
-
if (!hasUserOrchestrationMcp) {
|
|
52097
|
-
toInstall.push(buildOrchestrationMcpComponent(scope));
|
|
52098
|
-
}
|
|
52099
|
-
const hasUserMemoryMcp = toInstall.some((c2) => c2.type === "mcp" && c2.slug === MEMORY_MCP_SLUG);
|
|
52100
|
-
if (!hasUserMemoryMcp) {
|
|
52101
|
-
toInstall.push(buildMemoryMcpComponent(scope));
|
|
52102
|
-
}
|
|
52257
|
+
toInstall.push(...builtinInstall);
|
|
52103
52258
|
const justInstalledPaths = new Map;
|
|
52104
52259
|
if (toInstall.length > 0) {
|
|
52105
52260
|
const installSpinner = de();
|
|
@@ -52119,6 +52274,9 @@ async function runSync(cwd2, args) {
|
|
|
52119
52274
|
f2.warn(`Skipped: ${result2.skipped.map((s3) => `${s3.type}/${s3.slug} (${s3.reason})`).join(", ")}`);
|
|
52120
52275
|
}
|
|
52121
52276
|
}
|
|
52277
|
+
if (builtinRemoveSlugs.length > 0) {
|
|
52278
|
+
runHarnessRemoveMcp(adapter.id, builtinRemoveSlugs, { cwd: cwd2, scope });
|
|
52279
|
+
}
|
|
52122
52280
|
if (diff2.deletedUpstream.length > 0) {
|
|
52123
52281
|
for (const removed of diff2.deletedUpstream) {
|
|
52124
52282
|
let goAhead = autoProceed(args.yes);
|
|
@@ -52495,7 +52653,8 @@ function threeWayDiff(input) {
|
|
|
52495
52653
|
} else if (present.local && !present.cloud && present.lock) {
|
|
52496
52654
|
status = "removed-cloud";
|
|
52497
52655
|
} else {
|
|
52498
|
-
const
|
|
52656
|
+
const sourceChanged = !!local && local.hash === null && !!local.declaredSource && lock?.source !== undefined && lock.source !== local.declaredSource;
|
|
52657
|
+
const localChanged = sourceChanged || localHash !== null && lockHash !== undefined && localHash !== lockHash;
|
|
52499
52658
|
const cloudChanged = cloudHash !== undefined && lockHash !== undefined && cloudHash !== lockHash;
|
|
52500
52659
|
if (localChanged && cloudChanged)
|
|
52501
52660
|
status = "modified-both";
|
|
@@ -52708,11 +52867,14 @@ async function runAgentPull(cwd2, args) {
|
|
|
52708
52867
|
else
|
|
52709
52868
|
toInstallKeys.add(r2.key);
|
|
52710
52869
|
}
|
|
52711
|
-
const
|
|
52712
|
-
const
|
|
52713
|
-
const
|
|
52714
|
-
|
|
52715
|
-
|
|
52870
|
+
const caps = capabilitiesFromAgent(cloudAgent);
|
|
52871
|
+
const declaredMcpSlugs = new Set(cloud.components.filter((c2) => c2.type === "mcp").map((c2) => c2.slug));
|
|
52872
|
+
const { install: builtinInstall, removeSlugs: builtinRemoveSlugs } = resolveBuiltinMcps({
|
|
52873
|
+
caps,
|
|
52874
|
+
declaredSlugs: declaredMcpSlugs,
|
|
52875
|
+
scope: args.scope ?? "project"
|
|
52876
|
+
});
|
|
52877
|
+
if (toInstallKeys.size === 0 && toRemoveKeys.size === 0 && builtinInstall.length === 0 && builtinRemoveSlugs.length === 0 && !override) {
|
|
52716
52878
|
f2.info(`You're up to date.`);
|
|
52717
52879
|
writeLink(cwd2, buildLinkFromAgent(cloudAgent, harness, readLink(cwd2)));
|
|
52718
52880
|
writeSyncState(cwd2, buildLockFromCloud(agentId, cloud, lock, cloudAgent));
|
|
@@ -52766,7 +52928,7 @@ async function runAgentPull(cwd2, args) {
|
|
|
52766
52928
|
const stageRoot = stageManifestComponents(installComponents);
|
|
52767
52929
|
const justInstalledPaths = new Map;
|
|
52768
52930
|
try {
|
|
52769
|
-
if (installComponents.length > 0 ||
|
|
52931
|
+
if (installComponents.length > 0 || builtinInstall.length > 0) {
|
|
52770
52932
|
const installSpinner = de();
|
|
52771
52933
|
installSpinner.start("Applying updates…");
|
|
52772
52934
|
const toInstall = installComponents.map((c2) => ({
|
|
@@ -52780,12 +52942,7 @@ async function runAgentPull(cwd2, args) {
|
|
|
52780
52942
|
checksum: c2.hash,
|
|
52781
52943
|
source: skillSourceFromMeta(c2)
|
|
52782
52944
|
}));
|
|
52783
|
-
|
|
52784
|
-
toInstall.push(buildOrchestrationMcpComponent(scope));
|
|
52785
|
-
}
|
|
52786
|
-
if (needMemoryMcpInstall) {
|
|
52787
|
-
toInstall.push(buildMemoryMcpComponent(scope));
|
|
52788
|
-
}
|
|
52945
|
+
toInstall.push(...builtinInstall);
|
|
52789
52946
|
const opts = {
|
|
52790
52947
|
cwd: cwd2,
|
|
52791
52948
|
scope,
|
|
@@ -52801,6 +52958,9 @@ async function runAgentPull(cwd2, args) {
|
|
|
52801
52958
|
f2.warn(`Skipped: ${result2.skipped.map((s3) => `${s3.type}/${s3.slug} (${s3.reason})`).join(", ")}`);
|
|
52802
52959
|
}
|
|
52803
52960
|
}
|
|
52961
|
+
if (builtinRemoveSlugs.length > 0) {
|
|
52962
|
+
runHarnessRemoveMcp(harness, builtinRemoveSlugs, { cwd: cwd2, scope });
|
|
52963
|
+
}
|
|
52804
52964
|
for (const r2 of removeRows) {
|
|
52805
52965
|
const prior = lock?.components.find((c2) => c2.type === r2.type && c2.slug === r2.slug);
|
|
52806
52966
|
if (!prior)
|
|
@@ -53053,6 +53213,7 @@ function mergeManifest(cwd2, prev, cloud, cloudAgent, harness) {
|
|
|
53053
53213
|
entry.is_enabled = payload.is_enabled;
|
|
53054
53214
|
return entry;
|
|
53055
53215
|
});
|
|
53216
|
+
const caps = capabilitiesFromAgent(cloudAgent);
|
|
53056
53217
|
return {
|
|
53057
53218
|
schema: 1,
|
|
53058
53219
|
id: cloudAgent.id,
|
|
@@ -53065,7 +53226,8 @@ function mergeManifest(cwd2, prev, cloud, cloudAgent, harness) {
|
|
|
53065
53226
|
...entrypoint ? { entrypoint } : {},
|
|
53066
53227
|
playbooks,
|
|
53067
53228
|
skills,
|
|
53068
|
-
mcp
|
|
53229
|
+
mcp,
|
|
53230
|
+
capabilities: { memory: caps.memory, browser: caps.browser, slack: caps.slack }
|
|
53069
53231
|
};
|
|
53070
53232
|
}
|
|
53071
53233
|
function materializeEntrypoint(cwd2, cloudEntrypoint, prev) {
|
|
@@ -53256,7 +53418,7 @@ var import_picocolors27 = __toESM(require_picocolors(), 1);
|
|
|
53256
53418
|
|
|
53257
53419
|
// src/core/agent-outgoing.ts
|
|
53258
53420
|
var import_picocolors26 = __toESM(require_picocolors(), 1);
|
|
53259
|
-
async function buildOutgoingComponents(cwd2, manifest, cloud) {
|
|
53421
|
+
async function buildOutgoingComponents(cwd2, manifest, cloud, resolvedVersions) {
|
|
53260
53422
|
const out = [];
|
|
53261
53423
|
if (manifest.instructions) {
|
|
53262
53424
|
if (manifest.instructions.text !== undefined && manifest.instructions.file !== undefined) {
|
|
@@ -53303,6 +53465,7 @@ async function buildOutgoingComponents(cwd2, manifest, cloud) {
|
|
|
53303
53465
|
}
|
|
53304
53466
|
const slug = registrySkillComponentSlug(parsed);
|
|
53305
53467
|
const cloudMatch = cloud?.components.find((c2) => c2.type === "skill" && c2.slug === slug);
|
|
53468
|
+
const version = parsed.version ?? resolvedVersions?.get(slug);
|
|
53306
53469
|
out.push({
|
|
53307
53470
|
type: "skill",
|
|
53308
53471
|
slug,
|
|
@@ -53310,7 +53473,7 @@ async function buildOutgoingComponents(cwd2, manifest, cloud) {
|
|
|
53310
53473
|
files: [],
|
|
53311
53474
|
meta: {
|
|
53312
53475
|
name: parsed.creator ? `${parsed.creator}/${parsed.slug}` : parsed.slug,
|
|
53313
|
-
...
|
|
53476
|
+
...version ? { version } : {}
|
|
53314
53477
|
}
|
|
53315
53478
|
});
|
|
53316
53479
|
}
|
|
@@ -53395,6 +53558,62 @@ function yamlScalar(s3) {
|
|
|
53395
53558
|
return JSON.stringify(s3);
|
|
53396
53559
|
}
|
|
53397
53560
|
|
|
53561
|
+
// src/core/registry-skill-updates.ts
|
|
53562
|
+
function parseSemver2(v3) {
|
|
53563
|
+
const m3 = /^(\d+)\.(\d+)\.(\d+)$/.exec(v3);
|
|
53564
|
+
if (!m3)
|
|
53565
|
+
return null;
|
|
53566
|
+
return [Number(m3[1]), Number(m3[2]), Number(m3[3])];
|
|
53567
|
+
}
|
|
53568
|
+
function compareDirection(current, latest) {
|
|
53569
|
+
if (!current)
|
|
53570
|
+
return "unknown";
|
|
53571
|
+
const a3 = parseSemver2(current);
|
|
53572
|
+
const b4 = parseSemver2(latest);
|
|
53573
|
+
if (!a3 || !b4)
|
|
53574
|
+
return "unknown";
|
|
53575
|
+
for (let i = 0;i < 3; i++) {
|
|
53576
|
+
if (b4[i] > a3[i])
|
|
53577
|
+
return "upgrade";
|
|
53578
|
+
if (b4[i] < a3[i])
|
|
53579
|
+
return "downgrade";
|
|
53580
|
+
}
|
|
53581
|
+
return "unknown";
|
|
53582
|
+
}
|
|
53583
|
+
function planRegistrySkillUpdates(skills, cloudComponents, latestByName) {
|
|
53584
|
+
const out = [];
|
|
53585
|
+
for (const entry of skills) {
|
|
53586
|
+
let parsed;
|
|
53587
|
+
try {
|
|
53588
|
+
parsed = parseSkillSource2(entry.source);
|
|
53589
|
+
} catch {
|
|
53590
|
+
continue;
|
|
53591
|
+
}
|
|
53592
|
+
if (parsed.kind !== "registry" || parsed.version || !parsed.creator) {
|
|
53593
|
+
continue;
|
|
53594
|
+
}
|
|
53595
|
+
const name = `${parsed.creator}/${parsed.slug}`;
|
|
53596
|
+
const latest = latestByName.get(name);
|
|
53597
|
+
if (!latest)
|
|
53598
|
+
continue;
|
|
53599
|
+
const componentSlug = registrySkillComponentSlug(parsed);
|
|
53600
|
+
const cloud = cloudComponents.find((c2) => c2.type === "skill" && c2.slug === componentSlug);
|
|
53601
|
+
if (!cloud)
|
|
53602
|
+
continue;
|
|
53603
|
+
const current = cloud.meta?.["version"];
|
|
53604
|
+
if (current === latest)
|
|
53605
|
+
continue;
|
|
53606
|
+
out.push({
|
|
53607
|
+
componentSlug,
|
|
53608
|
+
name,
|
|
53609
|
+
current,
|
|
53610
|
+
latest,
|
|
53611
|
+
direction: compareDirection(current, latest)
|
|
53612
|
+
});
|
|
53613
|
+
}
|
|
53614
|
+
return out;
|
|
53615
|
+
}
|
|
53616
|
+
|
|
53398
53617
|
// src/cli/agent-push.ts
|
|
53399
53618
|
async function runAgentPush(cwd2, args) {
|
|
53400
53619
|
banner("agent push — send your local changes to the cloud");
|
|
@@ -53433,6 +53652,37 @@ async function runAgentPush(cwd2, args) {
|
|
|
53433
53652
|
lock: lock?.components ?? [],
|
|
53434
53653
|
cloud: cloud.components
|
|
53435
53654
|
});
|
|
53655
|
+
const unpinned = new Map;
|
|
53656
|
+
for (const entry of manifest.skills) {
|
|
53657
|
+
try {
|
|
53658
|
+
const parsed = parseSkillSource2(entry.source);
|
|
53659
|
+
if (parsed.kind === "registry" && !parsed.version && parsed.creator) {
|
|
53660
|
+
unpinned.set(`${parsed.creator}/${parsed.slug}`, {
|
|
53661
|
+
creator: parsed.creator,
|
|
53662
|
+
slug: parsed.slug
|
|
53663
|
+
});
|
|
53664
|
+
}
|
|
53665
|
+
} catch {}
|
|
53666
|
+
}
|
|
53667
|
+
const latestByName = new Map;
|
|
53668
|
+
if (unpinned.size > 0) {
|
|
53669
|
+
await Promise.all([...unpinned.entries()].map(async ([name, ref]) => {
|
|
53670
|
+
try {
|
|
53671
|
+
const pkg = await skillsApi.getPackage(ref.creator, ref.slug);
|
|
53672
|
+
if (pkg.latest_version?.version) {
|
|
53673
|
+
latestByName.set(name, pkg.latest_version.version);
|
|
53674
|
+
}
|
|
53675
|
+
} catch {}
|
|
53676
|
+
}));
|
|
53677
|
+
}
|
|
53678
|
+
const skillUpdates = planRegistrySkillUpdates(manifest.skills, cloud.components, latestByName);
|
|
53679
|
+
const resolvedVersions = new Map(skillUpdates.map((u2) => [u2.componentSlug, u2.latest]));
|
|
53680
|
+
for (const u2 of skillUpdates) {
|
|
53681
|
+
const row = rows.find((r2) => r2.key === compKey("skill", u2.componentSlug));
|
|
53682
|
+
if (row && (row.status === "in-sync" || row.status === "modified-cloud" || row.status === "added-local")) {
|
|
53683
|
+
row.status = "modified-local";
|
|
53684
|
+
}
|
|
53685
|
+
}
|
|
53436
53686
|
let cloudMeta = lock?.agentMeta;
|
|
53437
53687
|
if (!cloudMeta) {
|
|
53438
53688
|
try {
|
|
@@ -53516,6 +53766,16 @@ async function runAgentPush(cwd2, args) {
|
|
|
53516
53766
|
}
|
|
53517
53767
|
f2.info(`If you push now, your push targets revision ${cloud.revision} and may race. Consider \`brainbase agent pull\` first.`);
|
|
53518
53768
|
}
|
|
53769
|
+
const sendKeys = new Set(toSend.map((r2) => r2.key));
|
|
53770
|
+
for (const u2 of skillUpdates) {
|
|
53771
|
+
if (!sendKeys.has(compKey("skill", u2.componentSlug)))
|
|
53772
|
+
continue;
|
|
53773
|
+
if (u2.direction === "downgrade") {
|
|
53774
|
+
f2.warn(`Skill ${import_picocolors27.default.bold(u2.name)}: registry latest is ${import_picocolors27.default.bold(u2.latest)}, below the agent's ${import_picocolors27.default.dim(u2.current)} — the agent's version was likely yanked. Converging on latest.`);
|
|
53775
|
+
} else {
|
|
53776
|
+
f2.info(`Skill ${import_picocolors27.default.bold(u2.name)} → ${import_picocolors27.default.bold(u2.latest)} (registry latest${u2.current ? `, agent has ${u2.current}` : ""}).`);
|
|
53777
|
+
}
|
|
53778
|
+
}
|
|
53519
53779
|
const resultRows = [];
|
|
53520
53780
|
if (meta.localChanged) {
|
|
53521
53781
|
resultRows.push({
|
|
@@ -53570,7 +53830,7 @@ async function runAgentPush(cwd2, args) {
|
|
|
53570
53830
|
return handleApiError3(err);
|
|
53571
53831
|
}
|
|
53572
53832
|
}
|
|
53573
|
-
const outgoing = await buildOutgoingComponents(cwd2, manifest, cloud);
|
|
53833
|
+
const outgoing = await buildOutgoingComponents(cwd2, manifest, cloud, resolvedVersions);
|
|
53574
53834
|
if (outgoing === null)
|
|
53575
53835
|
return;
|
|
53576
53836
|
const pushSpinner = de();
|
|
@@ -54366,12 +54626,14 @@ async function runAgentUnpack(cwd2, args) {
|
|
|
54366
54626
|
checksum: ""
|
|
54367
54627
|
});
|
|
54368
54628
|
}
|
|
54369
|
-
const
|
|
54370
|
-
const
|
|
54371
|
-
|
|
54372
|
-
|
|
54373
|
-
|
|
54374
|
-
|
|
54629
|
+
const caps = capabilitiesFromManifest(manifest);
|
|
54630
|
+
const declaredMcpSlugs = new Set((manifest.mcp ?? []).map((m3) => m3.name));
|
|
54631
|
+
const { install: builtinInstall, removeSlugs: builtinRemoveSlugs } = resolveBuiltinMcps({
|
|
54632
|
+
caps,
|
|
54633
|
+
declaredSlugs: declaredMcpSlugs,
|
|
54634
|
+
scope
|
|
54635
|
+
});
|
|
54636
|
+
toInstall.push(...builtinInstall);
|
|
54375
54637
|
const opts = {
|
|
54376
54638
|
cwd: cwd2,
|
|
54377
54639
|
scope,
|
|
@@ -54385,6 +54647,9 @@ async function runAgentUnpack(cwd2, args) {
|
|
|
54385
54647
|
if (result2.skipped.length) {
|
|
54386
54648
|
f2.warn(`Skipped: ${result2.skipped.map((s3) => `${s3.type}/${s3.slug} (${s3.reason})`).join(", ")}`);
|
|
54387
54649
|
}
|
|
54650
|
+
if (builtinRemoveSlugs.length > 0) {
|
|
54651
|
+
runHarnessRemoveMcp(harness, builtinRemoveSlugs, { cwd: cwd2, scope });
|
|
54652
|
+
}
|
|
54388
54653
|
} catch (err) {
|
|
54389
54654
|
f2.error(`Install failed: ${err.message}`);
|
|
54390
54655
|
return;
|
|
@@ -54813,12 +55078,15 @@ async function installAgentFresh(input) {
|
|
|
54813
55078
|
ensureDir(cwd2);
|
|
54814
55079
|
const stageRoot = stageManifestComponents2(cloud.components);
|
|
54815
55080
|
const justInstalledPaths = new Map;
|
|
54816
|
-
const
|
|
54817
|
-
const
|
|
54818
|
-
const
|
|
54819
|
-
|
|
55081
|
+
const caps = capabilitiesFromAgent(agent);
|
|
55082
|
+
const declaredMcpSlugs = new Set(cloud.components.filter((c2) => c2.type === "mcp").map((c2) => c2.slug));
|
|
55083
|
+
const { install: builtinInstall } = resolveBuiltinMcps({
|
|
55084
|
+
caps,
|
|
55085
|
+
declaredSlugs: declaredMcpSlugs,
|
|
55086
|
+
scope
|
|
55087
|
+
});
|
|
54820
55088
|
try {
|
|
54821
|
-
if (cloud.components.length > 0 ||
|
|
55089
|
+
if (cloud.components.length > 0 || builtinInstall.length > 0) {
|
|
54822
55090
|
const toInstall = cloud.components.map((c2) => ({
|
|
54823
55091
|
type: c2.type,
|
|
54824
55092
|
slug: c2.slug,
|
|
@@ -54829,12 +55097,7 @@ async function installAgentFresh(input) {
|
|
|
54829
55097
|
payload: proxifyMcpPayload(c2.meta?.mcp),
|
|
54830
55098
|
checksum: c2.hash
|
|
54831
55099
|
}));
|
|
54832
|
-
|
|
54833
|
-
toInstall.push(buildOrchestrationMcpComponent(scope));
|
|
54834
|
-
}
|
|
54835
|
-
if (needMemoryMcpInstall) {
|
|
54836
|
-
toInstall.push(buildMemoryMcpComponent(scope));
|
|
54837
|
-
}
|
|
55100
|
+
toInstall.push(...builtinInstall);
|
|
54838
55101
|
const installOpts = {
|
|
54839
55102
|
cwd: cwd2,
|
|
54840
55103
|
scope,
|
|
@@ -54952,6 +55215,7 @@ function buildManifestFromCloud(cloud, agent) {
|
|
|
54952
55215
|
entry.is_enabled = payload.is_enabled;
|
|
54953
55216
|
return entry;
|
|
54954
55217
|
});
|
|
55218
|
+
const caps = capabilitiesFromAgent(agent);
|
|
54955
55219
|
return {
|
|
54956
55220
|
schema: 1,
|
|
54957
55221
|
agent: {
|
|
@@ -54961,7 +55225,8 @@ function buildManifestFromCloud(cloud, agent) {
|
|
|
54961
55225
|
...hasInstructions ? { instructions: { file: DEFAULT_INSTRUCTIONS_FILE } } : {},
|
|
54962
55226
|
playbooks: [],
|
|
54963
55227
|
skills,
|
|
54964
|
-
mcp
|
|
55228
|
+
mcp,
|
|
55229
|
+
capabilities: { memory: caps.memory, browser: caps.browser, slack: caps.slack }
|
|
54965
55230
|
};
|
|
54966
55231
|
}
|
|
54967
55232
|
async function pullAgentSecrets(cwd2, agentId) {
|