@brainbase-labs/cli 0.11.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +201 -77
- 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.13.0",
|
|
29453
29453
|
description: "Pack, share, and install agent templates across harnesses (Claude Code, Codex, ...).",
|
|
29454
29454
|
type: "module",
|
|
29455
29455
|
bin: {
|
|
@@ -43741,6 +43741,33 @@ function removeInstalledRecord(name, scope, cwd2) {
|
|
|
43741
43741
|
// src/core/registry-remote.ts
|
|
43742
43742
|
import fs22 from "node:fs";
|
|
43743
43743
|
|
|
43744
|
+
// src/core/api-error-message.ts
|
|
43745
|
+
function apiErrorMessage(body, status) {
|
|
43746
|
+
if (body && typeof body === "object") {
|
|
43747
|
+
const obj = body;
|
|
43748
|
+
for (const key2 of ["error", "message", "detail"]) {
|
|
43749
|
+
const v2 = obj[key2];
|
|
43750
|
+
if (typeof v2 === "string" && v2.trim())
|
|
43751
|
+
return v2.trim();
|
|
43752
|
+
if (Array.isArray(v2)) {
|
|
43753
|
+
const msgs = v2.map((item) => {
|
|
43754
|
+
if (typeof item === "string" && item.trim())
|
|
43755
|
+
return item.trim();
|
|
43756
|
+
if (item && typeof item === "object" && typeof item.msg === "string") {
|
|
43757
|
+
return item.msg;
|
|
43758
|
+
}
|
|
43759
|
+
return null;
|
|
43760
|
+
}).filter((m2) => !!m2);
|
|
43761
|
+
if (msgs.length)
|
|
43762
|
+
return msgs.join("; ");
|
|
43763
|
+
}
|
|
43764
|
+
}
|
|
43765
|
+
} else if (typeof body === "string" && body.trim()) {
|
|
43766
|
+
return body.trim();
|
|
43767
|
+
}
|
|
43768
|
+
return `HTTP ${status}`;
|
|
43769
|
+
}
|
|
43770
|
+
|
|
43744
43771
|
// src/core/api.ts
|
|
43745
43772
|
var DEFAULT_API_BASE = "https://kafka-llm-service.onrender.com";
|
|
43746
43773
|
|
|
@@ -43800,8 +43827,7 @@ async function request(pathname, init = {}) {
|
|
|
43800
43827
|
body = text2 ? JSON.parse(text2) : null;
|
|
43801
43828
|
} catch {}
|
|
43802
43829
|
if (!res.ok) {
|
|
43803
|
-
|
|
43804
|
-
throw new ApiError(msg, res.status, body);
|
|
43830
|
+
throw new ApiError(apiErrorMessage(body, res.status), res.status, body);
|
|
43805
43831
|
}
|
|
43806
43832
|
return body;
|
|
43807
43833
|
}
|
|
@@ -51126,8 +51152,10 @@ var PlaybookContentSchema = exports_external.object({
|
|
|
51126
51152
|
message: "playbook content must set either `file` or `text`"
|
|
51127
51153
|
});
|
|
51128
51154
|
var PlaybookSchema = exports_external.object({
|
|
51155
|
+
id: exports_external.string().optional(),
|
|
51129
51156
|
title: exports_external.string().min(1),
|
|
51130
51157
|
description: exports_external.string().optional(),
|
|
51158
|
+
icon: exports_external.string().optional(),
|
|
51131
51159
|
content: PlaybookContentSchema
|
|
51132
51160
|
});
|
|
51133
51161
|
var SkillEntrySchema = exports_external.object({
|
|
@@ -51145,7 +51173,8 @@ var McpEntrySchema = exports_external.object({
|
|
|
51145
51173
|
var CapabilitiesSchema = exports_external.object({
|
|
51146
51174
|
memory: exports_external.boolean().optional(),
|
|
51147
51175
|
browser: exports_external.boolean().optional(),
|
|
51148
|
-
slack: exports_external.boolean().optional()
|
|
51176
|
+
slack: exports_external.boolean().optional(),
|
|
51177
|
+
meeting: exports_external.boolean().optional()
|
|
51149
51178
|
});
|
|
51150
51179
|
var AgentManifestSchema = exports_external.object({
|
|
51151
51180
|
schema: exports_external.literal(1),
|
|
@@ -51252,7 +51281,38 @@ function resolvePlaybookContent(cwd2, entry) {
|
|
|
51252
51281
|
return null;
|
|
51253
51282
|
}
|
|
51254
51283
|
function slugifyPlaybookTitle(title) {
|
|
51255
|
-
return title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 60) || "playbook";
|
|
51284
|
+
return title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 60).replace(/^-+|-+$/g, "") || "playbook";
|
|
51285
|
+
}
|
|
51286
|
+
function playbookYamlScalar(value) {
|
|
51287
|
+
const safe = value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"").replace(/\n/g, " ").trim();
|
|
51288
|
+
return `"${safe}"`;
|
|
51289
|
+
}
|
|
51290
|
+
function assemblePlaybookWireBody(entry, body) {
|
|
51291
|
+
const lines = ["---", `title: ${playbookYamlScalar(entry.title)}`];
|
|
51292
|
+
if (entry.description) {
|
|
51293
|
+
lines.push(`description: ${playbookYamlScalar(entry.description)}`);
|
|
51294
|
+
}
|
|
51295
|
+
if (entry.icon) {
|
|
51296
|
+
lines.push(`icon: ${playbookYamlScalar(entry.icon)}`);
|
|
51297
|
+
}
|
|
51298
|
+
lines.push("---", "", "");
|
|
51299
|
+
return lines.join(`
|
|
51300
|
+
`) + body.replace(/^\n+/, "").trimEnd() + `
|
|
51301
|
+
`;
|
|
51302
|
+
}
|
|
51303
|
+
function assignPlaybookSlugs(titles) {
|
|
51304
|
+
const used = new Set;
|
|
51305
|
+
return titles.map((t) => {
|
|
51306
|
+
const base2 = slugifyPlaybookTitle(t);
|
|
51307
|
+
let slug = base2;
|
|
51308
|
+
let n = 1;
|
|
51309
|
+
while (used.has(slug)) {
|
|
51310
|
+
n += 1;
|
|
51311
|
+
slug = `${base2}-${n}`;
|
|
51312
|
+
}
|
|
51313
|
+
used.add(slug);
|
|
51314
|
+
return slug;
|
|
51315
|
+
});
|
|
51256
51316
|
}
|
|
51257
51317
|
|
|
51258
51318
|
// src/core/link.ts
|
|
@@ -51301,7 +51361,7 @@ var SyncedComponentSchema = exports_external.object({
|
|
|
51301
51361
|
});
|
|
51302
51362
|
var AgentMetaSnapshotSchema = exports_external.object({
|
|
51303
51363
|
name: exports_external.string(),
|
|
51304
|
-
tagline: exports_external.string().
|
|
51364
|
+
tagline: exports_external.string().nullish().transform((v3) => v3 ?? undefined),
|
|
51305
51365
|
entrypoint: exports_external.string().optional()
|
|
51306
51366
|
});
|
|
51307
51367
|
var SyncStateSchema = exports_external.object({
|
|
@@ -52043,6 +52103,39 @@ function buildSlackMcpComponent(scope) {
|
|
|
52043
52103
|
};
|
|
52044
52104
|
}
|
|
52045
52105
|
|
|
52106
|
+
// src/core/meeting-mcp.ts
|
|
52107
|
+
var DEFAULT_MEETING_MCP_BASE = "https://meeting.mcp.brainbaselabs.com";
|
|
52108
|
+
var MEETING_MCP_SLUG = "brainbase-meeting";
|
|
52109
|
+
function meetingMcpBaseUrl() {
|
|
52110
|
+
const envOverride = process.env.BRAINBASE_MEETING_MCP_URL;
|
|
52111
|
+
if (envOverride)
|
|
52112
|
+
return envOverride.replace(/\/+$/, "");
|
|
52113
|
+
return DEFAULT_MEETING_MCP_BASE;
|
|
52114
|
+
}
|
|
52115
|
+
function meetingMcpUrl() {
|
|
52116
|
+
return `${meetingMcpBaseUrl()}/t/\${BRAINBASE_THREAD_ID}/mcp`;
|
|
52117
|
+
}
|
|
52118
|
+
function meetingMcpPayload() {
|
|
52119
|
+
return {
|
|
52120
|
+
url: meetingMcpUrl(),
|
|
52121
|
+
headers: {
|
|
52122
|
+
Authorization: "Bearer ${BRAINBASE_TOKEN}"
|
|
52123
|
+
}
|
|
52124
|
+
};
|
|
52125
|
+
}
|
|
52126
|
+
function buildMeetingMcpComponent(scope) {
|
|
52127
|
+
return {
|
|
52128
|
+
type: "mcp",
|
|
52129
|
+
slug: MEETING_MCP_SLUG,
|
|
52130
|
+
scope,
|
|
52131
|
+
rootDir: "",
|
|
52132
|
+
description: "This agent's Meeting connector (join calls, read transcripts, manage " + "recordings and notes). Scoped to this agent only.",
|
|
52133
|
+
meta: { mcp: meetingMcpPayload() },
|
|
52134
|
+
payload: meetingMcpPayload(),
|
|
52135
|
+
checksum: "builtin:brainbase-meeting:v1"
|
|
52136
|
+
};
|
|
52137
|
+
}
|
|
52138
|
+
|
|
52046
52139
|
// src/core/browser-mcp.ts
|
|
52047
52140
|
var DEFAULT_BROWSER_MCP_BASE = "https://brainbase-browser-mcp.onrender.com";
|
|
52048
52141
|
var BROWSER_MCP_SLUG = "brainbase-browser";
|
|
@@ -52081,7 +52174,8 @@ function capabilitiesFromAgent(agent) {
|
|
|
52081
52174
|
return {
|
|
52082
52175
|
memory: agent.memory_enabled !== false,
|
|
52083
52176
|
browser: agent.browser_enabled !== false,
|
|
52084
|
-
slack: agent.slack_connected === true
|
|
52177
|
+
slack: agent.slack_connected === true,
|
|
52178
|
+
meeting: agent.meeting_connected === true
|
|
52085
52179
|
};
|
|
52086
52180
|
}
|
|
52087
52181
|
function capabilitiesFromManifest(manifest) {
|
|
@@ -52089,7 +52183,8 @@ function capabilitiesFromManifest(manifest) {
|
|
|
52089
52183
|
return {
|
|
52090
52184
|
memory: c2.memory !== false,
|
|
52091
52185
|
browser: c2.browser !== false,
|
|
52092
|
-
slack: c2.slack === true
|
|
52186
|
+
slack: c2.slack === true,
|
|
52187
|
+
meeting: c2.meeting === true
|
|
52093
52188
|
};
|
|
52094
52189
|
}
|
|
52095
52190
|
function resolveBuiltinMcps(input) {
|
|
@@ -52098,7 +52193,8 @@ function resolveBuiltinMcps(input) {
|
|
|
52098
52193
|
{ slug: ORCHESTRATION_MCP_SLUG, enabled: true, build: buildOrchestrationMcpComponent },
|
|
52099
52194
|
{ slug: MEMORY_MCP_SLUG, enabled: caps.memory, build: buildMemoryMcpComponent },
|
|
52100
52195
|
{ slug: BROWSER_MCP_SLUG, enabled: caps.browser, build: buildBrowserMcpComponent },
|
|
52101
|
-
{ slug: SLACK_MCP_SLUG, enabled: caps.slack, build: buildSlackMcpComponent }
|
|
52196
|
+
{ slug: SLACK_MCP_SLUG, enabled: caps.slack, build: buildSlackMcpComponent },
|
|
52197
|
+
{ slug: MEETING_MCP_SLUG, enabled: caps.meeting, build: buildMeetingMcpComponent }
|
|
52102
52198
|
];
|
|
52103
52199
|
const install = [];
|
|
52104
52200
|
const removeSlugs = [];
|
|
@@ -52578,34 +52674,25 @@ function readLocalComponents(cwd2, manifest) {
|
|
|
52578
52674
|
hash: hashMcpEntry(entry)
|
|
52579
52675
|
});
|
|
52580
52676
|
}
|
|
52581
|
-
|
|
52677
|
+
const pbEntries = manifest.playbooks ?? [];
|
|
52678
|
+
const pbSlugs = assignPlaybookSlugs(pbEntries.map((e2) => e2.title));
|
|
52679
|
+
for (let i = 0;i < pbEntries.length; i++) {
|
|
52680
|
+
const entry = pbEntries[i];
|
|
52681
|
+
const slug = pbSlugs[i];
|
|
52582
52682
|
const body = resolvePlaybookContent(cwd2, entry);
|
|
52583
52683
|
if (body === null) {
|
|
52584
|
-
out.push({
|
|
52585
|
-
type: "playbook",
|
|
52586
|
-
slug: slugifyPlaybookTitle(entry.title),
|
|
52587
|
-
hash: null
|
|
52588
|
-
});
|
|
52684
|
+
out.push({ type: "playbook", slug, hash: null });
|
|
52589
52685
|
continue;
|
|
52590
52686
|
}
|
|
52591
|
-
const wireBody =
|
|
52592
|
-
title: ${jsonOrPlain(entry.title)}` + (entry.description ? `
|
|
52593
|
-
description: ${jsonOrPlain(entry.description)}` : "") + `
|
|
52594
|
-
---
|
|
52595
|
-
${body.replace(/^\n+/, "")}`;
|
|
52687
|
+
const wireBody = assemblePlaybookWireBody(entry, body);
|
|
52596
52688
|
out.push({
|
|
52597
52689
|
type: "playbook",
|
|
52598
|
-
slug
|
|
52690
|
+
slug,
|
|
52599
52691
|
hash: componentHashFromFileHashes([hashString(wireBody)])
|
|
52600
52692
|
});
|
|
52601
52693
|
}
|
|
52602
52694
|
return out;
|
|
52603
52695
|
}
|
|
52604
|
-
function jsonOrPlain(s3) {
|
|
52605
|
-
if (!/[\n":#&*!|>'%@`{}[\]]/.test(s3) && s3.trim() === s3 && s3 !== "")
|
|
52606
|
-
return s3;
|
|
52607
|
-
return JSON.stringify(s3);
|
|
52608
|
-
}
|
|
52609
52696
|
function threeWayDiff(input) {
|
|
52610
52697
|
const lockMap = new Map;
|
|
52611
52698
|
for (const c2 of input.lock)
|
|
@@ -53128,7 +53215,7 @@ function materializePlaybooks(cwd2, cloud, toInstall, keepLocal, existingManifes
|
|
|
53128
53215
|
if (!raw.trim())
|
|
53129
53216
|
continue;
|
|
53130
53217
|
const { body } = stripFrontmatter(raw);
|
|
53131
|
-
const existing = existingManifest?.playbooks?.find((p2) =>
|
|
53218
|
+
const existing = existingManifest?.playbooks?.find((p2) => slugifyPlaybookTitle(p2.title) === c2.slug);
|
|
53132
53219
|
if (existing?.content?.text !== undefined)
|
|
53133
53220
|
continue;
|
|
53134
53221
|
const targetRel = existing?.content?.file ?? path48.join(DEFAULT_PLAYBOOKS_DIR, `${c2.slug}.md`);
|
|
@@ -53137,9 +53224,6 @@ function materializePlaybooks(cwd2, cloud, toInstall, keepLocal, existingManifes
|
|
|
53137
53224
|
fs45.writeFileSync(target, body, "utf8");
|
|
53138
53225
|
}
|
|
53139
53226
|
}
|
|
53140
|
-
function slugifyForCompare(s3) {
|
|
53141
|
-
return s3.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 60) || "playbook";
|
|
53142
|
-
}
|
|
53143
53227
|
function stripFrontmatter(raw) {
|
|
53144
53228
|
const m3 = /^---\s*\n([\s\S]*?)\n---\s*\n?/.exec(raw);
|
|
53145
53229
|
if (!m3)
|
|
@@ -53192,15 +53276,18 @@ function mergeManifest(cwd2, prev, cloud, cloudAgent, harness) {
|
|
|
53192
53276
|
const playbooks = cloud.components.filter((c2) => c2.type === "playbook").map((c2) => {
|
|
53193
53277
|
const raw = c2.files[0]?.content ?? "";
|
|
53194
53278
|
const { frontmatter } = stripFrontmatter(raw);
|
|
53195
|
-
const local = prev?.playbooks?.find((pb) =>
|
|
53279
|
+
const local = prev?.playbooks?.find((pb) => slugifyPlaybookTitle(pb.title) === c2.slug);
|
|
53196
53280
|
const title = local?.title ?? (typeof frontmatter.title === "string" && frontmatter.title || c2.slug);
|
|
53197
53281
|
const description = local?.description ?? (typeof frontmatter.description === "string" ? frontmatter.description : undefined);
|
|
53198
53282
|
const content = local?.content?.text !== undefined ? { text: local.content.text } : {
|
|
53199
53283
|
file: local?.content?.file ?? path48.join(DEFAULT_PLAYBOOKS_DIR, `${c2.slug}.md`)
|
|
53200
53284
|
};
|
|
53285
|
+
const pbMeta = c2.meta ?? {};
|
|
53201
53286
|
return {
|
|
53287
|
+
...typeof pbMeta.playbook_id === "string" && pbMeta.playbook_id ? { id: pbMeta.playbook_id } : {},
|
|
53202
53288
|
title,
|
|
53203
53289
|
...description ? { description } : {},
|
|
53290
|
+
...typeof pbMeta.icon === "string" && pbMeta.icon ? { icon: pbMeta.icon } : {},
|
|
53204
53291
|
content
|
|
53205
53292
|
};
|
|
53206
53293
|
});
|
|
@@ -53235,7 +53322,12 @@ function mergeManifest(cwd2, prev, cloud, cloudAgent, harness) {
|
|
|
53235
53322
|
playbooks,
|
|
53236
53323
|
skills,
|
|
53237
53324
|
mcp,
|
|
53238
|
-
capabilities: {
|
|
53325
|
+
capabilities: {
|
|
53326
|
+
memory: caps.memory,
|
|
53327
|
+
browser: caps.browser,
|
|
53328
|
+
slack: caps.slack,
|
|
53329
|
+
meeting: caps.meeting
|
|
53330
|
+
}
|
|
53239
53331
|
};
|
|
53240
53332
|
}
|
|
53241
53333
|
function materializeEntrypoint(cwd2, cloudEntrypoint, prev) {
|
|
@@ -53489,8 +53581,11 @@ async function buildOutgoingComponents(cwd2, manifest, cloud, resolvedVersions)
|
|
|
53489
53581
|
}
|
|
53490
53582
|
});
|
|
53491
53583
|
}
|
|
53492
|
-
const
|
|
53493
|
-
|
|
53584
|
+
const playbookEntries = manifest.playbooks ?? [];
|
|
53585
|
+
const playbookSlugs = assignPlaybookSlugs(playbookEntries.map((e2) => e2.title));
|
|
53586
|
+
for (let i = 0;i < playbookEntries.length; i++) {
|
|
53587
|
+
const entry = playbookEntries[i];
|
|
53588
|
+
const slug = playbookSlugs[i];
|
|
53494
53589
|
if (entry.content.text !== undefined && entry.content.file !== undefined) {
|
|
53495
53590
|
f2.error(`Playbook ${import_picocolors26.default.bold(entry.title)} sets both ${import_picocolors26.default.cyan("text")} and ${import_picocolors26.default.cyan("file")} — pick one.`);
|
|
53496
53591
|
return null;
|
|
@@ -53504,24 +53599,25 @@ async function buildOutgoingComponents(cwd2, manifest, cloud, resolvedVersions)
|
|
|
53504
53599
|
}
|
|
53505
53600
|
return null;
|
|
53506
53601
|
}
|
|
53507
|
-
const
|
|
53508
|
-
if (seenPlaybookSlugs.has(slug)) {
|
|
53509
|
-
f2.error(`Two playbooks resolve to the same slug ${import_picocolors26.default.bold(slug)} (from title ${import_picocolors26.default.bold(entry.title)}). Pick distinct titles.`);
|
|
53510
|
-
return null;
|
|
53511
|
-
}
|
|
53512
|
-
seenPlaybookSlugs.add(slug);
|
|
53513
|
-
const wireBody = assemblePlaybookBody(entry, body);
|
|
53602
|
+
const wireBody = assemblePlaybookWireBody(entry, body);
|
|
53514
53603
|
const fileName = `${slug}.md`;
|
|
53515
53604
|
const fileHash2 = hashString(wireBody);
|
|
53605
|
+
const file = {
|
|
53606
|
+
path: fileName,
|
|
53607
|
+
content: wireBody,
|
|
53608
|
+
hash: fileHash2
|
|
53609
|
+
};
|
|
53516
53610
|
out.push({
|
|
53517
53611
|
type: "playbook",
|
|
53518
53612
|
slug,
|
|
53519
53613
|
description: entry.description,
|
|
53520
53614
|
hash: componentHashFromFileHashes([fileHash2]),
|
|
53521
|
-
files: [
|
|
53615
|
+
files: [file],
|
|
53522
53616
|
meta: {
|
|
53523
53617
|
title: entry.title,
|
|
53524
|
-
...entry.description ? { description: entry.description } : {}
|
|
53618
|
+
...entry.description ? { description: entry.description } : {},
|
|
53619
|
+
...entry.icon ? { icon: entry.icon } : {},
|
|
53620
|
+
...entry.id ? { playbook_id: entry.id } : {}
|
|
53525
53621
|
}
|
|
53526
53622
|
});
|
|
53527
53623
|
}
|
|
@@ -53552,23 +53648,6 @@ async function buildOutgoingComponents(cwd2, manifest, cloud, resolvedVersions)
|
|
|
53552
53648
|
}
|
|
53553
53649
|
return out;
|
|
53554
53650
|
}
|
|
53555
|
-
function assemblePlaybookBody(entry, body) {
|
|
53556
|
-
if (/^---\s*\n/.test(body))
|
|
53557
|
-
return body;
|
|
53558
|
-
const lines = ["---", `title: ${yamlScalar(entry.title)}`];
|
|
53559
|
-
if (entry.description) {
|
|
53560
|
-
lines.push(`description: ${yamlScalar(entry.description)}`);
|
|
53561
|
-
}
|
|
53562
|
-
lines.push("---", "");
|
|
53563
|
-
return lines.join(`
|
|
53564
|
-
`) + body.replace(/^\n+/, "");
|
|
53565
|
-
}
|
|
53566
|
-
function yamlScalar(s3) {
|
|
53567
|
-
if (!/[\n":#&*!|>'%@`{}[\]]/.test(s3) && s3.trim() === s3 && s3 !== "") {
|
|
53568
|
-
return s3;
|
|
53569
|
-
}
|
|
53570
|
-
return JSON.stringify(s3);
|
|
53571
|
-
}
|
|
53572
53651
|
|
|
53573
53652
|
// src/core/registry-skill-updates.ts
|
|
53574
53653
|
function parseSemver2(v3) {
|
|
@@ -53664,29 +53743,56 @@ async function runAgentPush(cwd2, args) {
|
|
|
53664
53743
|
lock: lock?.components ?? [],
|
|
53665
53744
|
cloud: cloud.components
|
|
53666
53745
|
});
|
|
53667
|
-
const
|
|
53746
|
+
const registryRefs = new Map;
|
|
53668
53747
|
for (const entry of manifest.skills) {
|
|
53669
53748
|
try {
|
|
53670
53749
|
const parsed = parseSkillSource2(entry.source);
|
|
53671
|
-
if (parsed.kind === "registry" &&
|
|
53672
|
-
|
|
53750
|
+
if (parsed.kind === "registry" && parsed.creator) {
|
|
53751
|
+
registryRefs.set(`${parsed.creator}/${parsed.slug}`, {
|
|
53673
53752
|
creator: parsed.creator,
|
|
53674
|
-
slug: parsed.slug
|
|
53753
|
+
slug: parsed.slug,
|
|
53754
|
+
version: parsed.version
|
|
53675
53755
|
});
|
|
53676
53756
|
}
|
|
53677
53757
|
} catch {}
|
|
53678
53758
|
}
|
|
53679
53759
|
const latestByName = new Map;
|
|
53680
|
-
|
|
53681
|
-
|
|
53760
|
+
const notInRegistry = new Set;
|
|
53761
|
+
if (registryRefs.size > 0) {
|
|
53762
|
+
await Promise.all([...registryRefs.entries()].map(async ([name, ref]) => {
|
|
53682
53763
|
try {
|
|
53683
53764
|
const pkg = await skillsApi.getPackage(ref.creator, ref.slug);
|
|
53684
53765
|
if (pkg.latest_version?.version) {
|
|
53685
53766
|
latestByName.set(name, pkg.latest_version.version);
|
|
53686
53767
|
}
|
|
53687
|
-
} catch {
|
|
53768
|
+
} catch (err) {
|
|
53769
|
+
if (err instanceof ApiError && err.status === 404) {
|
|
53770
|
+
notInRegistry.add(name);
|
|
53771
|
+
}
|
|
53772
|
+
}
|
|
53688
53773
|
}));
|
|
53689
53774
|
}
|
|
53775
|
+
const unresolvable = [...notInRegistry].filter((name) => {
|
|
53776
|
+
const ref = registryRefs.get(name);
|
|
53777
|
+
const componentSlug = registrySkillComponentSlug({
|
|
53778
|
+
kind: "registry",
|
|
53779
|
+
creator: ref.creator,
|
|
53780
|
+
slug: ref.slug
|
|
53781
|
+
});
|
|
53782
|
+
return !cloud.components.some((c2) => c2.type === "skill" && c2.slug === componentSlug);
|
|
53783
|
+
});
|
|
53784
|
+
if (unresolvable.length > 0) {
|
|
53785
|
+
for (const name of unresolvable) {
|
|
53786
|
+
f2.error(`Skill ${import_picocolors27.default.bold(name)} isn't in the registry (not published, or private to another owner).`);
|
|
53787
|
+
}
|
|
53788
|
+
const noun = unresolvable.length === 1 ? "it" : "each one";
|
|
53789
|
+
f2.info(`Publish ${noun} first, then push again:`);
|
|
53790
|
+
for (const name of unresolvable) {
|
|
53791
|
+
const version = registryRefs.get(name)?.version ?? "0.1.0";
|
|
53792
|
+
f2.info(` ${import_picocolors27.default.cyan(`brainbase skill publish ./path/to/skill --name ${name} --skill-version ${version} --yes`)}`);
|
|
53793
|
+
}
|
|
53794
|
+
return;
|
|
53795
|
+
}
|
|
53690
53796
|
const skillUpdates = planRegistrySkillUpdates(manifest.skills, cloud.components, latestByName);
|
|
53691
53797
|
const resolvedVersions = new Map(skillUpdates.map((u2) => [u2.componentSlug, u2.latest]));
|
|
53692
53798
|
for (const u2 of skillUpdates) {
|
|
@@ -53723,7 +53829,7 @@ async function runAgentPush(cwd2, args) {
|
|
|
53723
53829
|
const entrypointChanged = resolvedEntrypoint !== undefined && (resolvedEntrypoint ?? "").trim() !== (lock?.agentMeta?.entrypoint ?? "").trim();
|
|
53724
53830
|
for (const r2 of rows) {
|
|
53725
53831
|
if (r2.type !== "instruction" && r2.type !== "skill" && r2.type !== "mcp" && r2.type !== "playbook") {
|
|
53726
|
-
f2.error(`Component ${fmtType(r2.type)} ${import_picocolors27.default.bold(r2.slug)} can't be pushed yet — the server accepts instructions, skills,
|
|
53832
|
+
f2.error(`Component ${fmtType(r2.type)} ${import_picocolors27.default.bold(r2.slug)} can't be pushed yet — the server accepts instructions, skills, and mcps in this version.`);
|
|
53727
53833
|
return;
|
|
53728
53834
|
}
|
|
53729
53835
|
}
|
|
@@ -53739,6 +53845,17 @@ async function runAgentPush(cwd2, args) {
|
|
|
53739
53845
|
return;
|
|
53740
53846
|
}
|
|
53741
53847
|
}
|
|
53848
|
+
const localPlaybooks = manifest.playbooks ?? [];
|
|
53849
|
+
const localPlaybookSlugs = assignPlaybookSlugs(localPlaybooks.map((entry) => entry.title));
|
|
53850
|
+
const idlessLocalSlugs = new Set(localPlaybooks.flatMap((entry, i) => entry.id ? [] : [localPlaybookSlugs[i]]));
|
|
53851
|
+
const preIdSchemaSlugs = cloud.components.filter((c2) => c2.type === "playbook").filter((c2) => {
|
|
53852
|
+
const id = c2.meta?.playbook_id;
|
|
53853
|
+
return typeof id === "string" && id && !localPlaybooks.some((p2) => p2.id === id) && idlessLocalSlugs.has(c2.slug);
|
|
53854
|
+
}).map((c2) => c2.slug);
|
|
53855
|
+
if (preIdSchemaSlugs.length > 0) {
|
|
53856
|
+
f2.error(`Playbook ${preIdSchemaSlugs.length === 1 ? "entry" : "entries"} ${preIdSchemaSlugs.map((s3) => import_picocolors27.default.bold(s3)).join(", ")} in ${import_picocolors27.default.bold("brainbase.agent.yaml")} ${preIdSchemaSlugs.length === 1 ? "is" : "are"} missing ${import_picocolors27.default.cyan("id:")}. Run ${import_picocolors27.default.bold("brainbase agent pull")} first to sync playbook ids, then push.`);
|
|
53857
|
+
return;
|
|
53858
|
+
}
|
|
53742
53859
|
const toSend = [];
|
|
53743
53860
|
const conflicts = [];
|
|
53744
53861
|
const upstreamOnly = [];
|
|
@@ -53851,7 +53968,8 @@ async function runAgentPush(cwd2, args) {
|
|
|
53851
53968
|
try {
|
|
53852
53969
|
updatedCloud = await api.pushAgentManifest(agentId, {
|
|
53853
53970
|
components: outgoing,
|
|
53854
|
-
base_revision: cloud.revision
|
|
53971
|
+
base_revision: cloud.revision,
|
|
53972
|
+
reconcile_playbooks: true
|
|
53855
53973
|
});
|
|
53856
53974
|
pushSpinner.stop(`Pushed. New revision ${updatedCloud.revision}.`);
|
|
53857
53975
|
} catch (err) {
|
|
@@ -54398,7 +54516,7 @@ async function runAgentCreate(cwd2, args) {
|
|
|
54398
54516
|
writeLink(cwd2, link2);
|
|
54399
54517
|
manifest = readManifest(cwd2);
|
|
54400
54518
|
let updatedCloud = null;
|
|
54401
|
-
const hasContent = !!manifest.instructions || manifest.skills.length > 0 || (manifest.mcp ?? []).length > 0;
|
|
54519
|
+
const hasContent = !!manifest.instructions || manifest.skills.length > 0 || (manifest.mcp ?? []).length > 0 || (manifest.playbooks ?? []).length > 0;
|
|
54402
54520
|
if (hasContent) {
|
|
54403
54521
|
const outgoing = await buildOutgoingComponents(cwd2, manifest, null);
|
|
54404
54522
|
if (outgoing === null) {
|
|
@@ -54409,7 +54527,8 @@ async function runAgentCreate(cwd2, args) {
|
|
|
54409
54527
|
try {
|
|
54410
54528
|
updatedCloud = await api.pushAgentManifest(agent.id, {
|
|
54411
54529
|
components: outgoing,
|
|
54412
|
-
base_revision: 0
|
|
54530
|
+
base_revision: 0,
|
|
54531
|
+
reconcile_playbooks: true
|
|
54413
54532
|
});
|
|
54414
54533
|
pushSpinner.stop(`Pushed at revision ${updatedCloud.revision}.`);
|
|
54415
54534
|
} catch (err) {
|
|
@@ -54768,14 +54887,14 @@ function copyDirRecursive(src, dest) {
|
|
|
54768
54887
|
}
|
|
54769
54888
|
}
|
|
54770
54889
|
function assembleFrontmatter(title, description) {
|
|
54771
|
-
const lines = ["---", `title: ${
|
|
54890
|
+
const lines = ["---", `title: ${yamlScalar(title)}`];
|
|
54772
54891
|
if (description)
|
|
54773
|
-
lines.push(`description: ${
|
|
54892
|
+
lines.push(`description: ${yamlScalar(description)}`);
|
|
54774
54893
|
lines.push("---", "");
|
|
54775
54894
|
return lines.join(`
|
|
54776
54895
|
`);
|
|
54777
54896
|
}
|
|
54778
|
-
function
|
|
54897
|
+
function yamlScalar(s3) {
|
|
54779
54898
|
if (!/[\n":#&*!|>'%@`{}[\]]/.test(s3) && s3.trim() === s3 && s3 !== "")
|
|
54780
54899
|
return s3;
|
|
54781
54900
|
return JSON.stringify(s3);
|
|
@@ -54863,7 +54982,7 @@ function printHelp() {
|
|
|
54863
54982
|
out.push("");
|
|
54864
54983
|
out.push(` ${import_picocolors32.default.cyan("create")} ${import_picocolors32.default.dim("claim an unclaimed brainbase.agent.yaml and create the cloud agent")}`);
|
|
54865
54984
|
out.push(` ${import_picocolors32.default.cyan("pull")} ${import_picocolors32.default.dim("[<id>]")} ${import_picocolors32.default.dim("apply cloud changes into this folder — pass <id> to switch (--force to override); --run-entrypoint to also execute the agent entrypoint")}`);
|
|
54866
|
-
out.push(` ${import_picocolors32.default.cyan("push")} ${import_picocolors32.default.dim("send local changes to the cloud")}`);
|
|
54985
|
+
out.push(` ${import_picocolors32.default.cyan("push")} ${import_picocolors32.default.dim("send local changes to the cloud — instructions, playbooks, skills, MCPs, entrypoint")}`);
|
|
54867
54986
|
out.push(` ${import_picocolors32.default.cyan("unpack")} ${import_picocolors32.default.dim("install the claimed agent into a harness layout (--harness to override)")}`);
|
|
54868
54987
|
out.push(` ${import_picocolors32.default.cyan("status")} ${import_picocolors32.default.dim("show what would push and what would pull")}`);
|
|
54869
54988
|
out.push(` ${import_picocolors32.default.cyan("env")} ${import_picocolors32.default.dim('print export statements — use with `eval "$(brainbase agent env)"`')}`);
|
|
@@ -55239,7 +55358,12 @@ function buildManifestFromCloud(cloud, agent) {
|
|
|
55239
55358
|
playbooks: [],
|
|
55240
55359
|
skills,
|
|
55241
55360
|
mcp,
|
|
55242
|
-
capabilities: {
|
|
55361
|
+
capabilities: {
|
|
55362
|
+
memory: caps.memory,
|
|
55363
|
+
browser: caps.browser,
|
|
55364
|
+
slack: caps.slack,
|
|
55365
|
+
meeting: caps.meeting
|
|
55366
|
+
}
|
|
55243
55367
|
};
|
|
55244
55368
|
}
|
|
55245
55369
|
async function pullAgentSecrets(cwd2, agentId) {
|
|
@@ -56796,7 +56920,7 @@ function help() {
|
|
|
56796
56920
|
out.push("");
|
|
56797
56921
|
out.push(` ${import_picocolors41.default.cyan("agent create")} ${import_picocolors41.default.dim("claim an unclaimed brainbase.agent.yaml and create the cloud agent")}`);
|
|
56798
56922
|
out.push(` ${import_picocolors41.default.cyan("agent pull")} ${import_picocolors41.default.dim("[<id>]")} ${import_picocolors41.default.dim("bring cloud changes into this folder (--force to override; --run-entrypoint to also execute the agent entrypoint)")}`);
|
|
56799
|
-
out.push(` ${import_picocolors41.default.cyan("agent push")} ${import_picocolors41.default.dim("send local changes to the cloud")}`);
|
|
56923
|
+
out.push(` ${import_picocolors41.default.cyan("agent push")} ${import_picocolors41.default.dim("send local changes to the cloud — instructions, playbooks, skills, MCPs, entrypoint")}`);
|
|
56800
56924
|
out.push(` ${import_picocolors41.default.cyan("agent unpack")} ${import_picocolors41.default.dim("install the claimed agent into a harness layout")}`);
|
|
56801
56925
|
out.push(` ${import_picocolors41.default.cyan("link")} ${import_picocolors41.default.dim("attach this folder to an existing agent")}`);
|
|
56802
56926
|
out.push(` ${import_picocolors41.default.cyan("agent status")} ${import_picocolors41.default.dim("show what would pull and what would push")}`);
|