@brainbase-labs/cli 0.13.1 → 0.13.2
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 +77 -51
- 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.13.
|
|
29452
|
+
version: "0.13.2",
|
|
29453
29453
|
description: "Pack, share, and install agent templates across harnesses (Claude Code, Codex, ...).",
|
|
29454
29454
|
type: "module",
|
|
29455
29455
|
bin: {
|
|
@@ -51336,6 +51336,23 @@ function backfillPlaybookIds(playbooks, cloudComponents) {
|
|
|
51336
51336
|
});
|
|
51337
51337
|
return { playbooks: changed ? next : playbooks, changed };
|
|
51338
51338
|
}
|
|
51339
|
+
function stripPlaybookFrontmatter(raw) {
|
|
51340
|
+
const m3 = /^---\s*\n([\s\S]*?)\n---[ \t]*(?:\n|$)/.exec(raw);
|
|
51341
|
+
if (!m3)
|
|
51342
|
+
return { frontmatter: {}, body: raw };
|
|
51343
|
+
let fm = {};
|
|
51344
|
+
try {
|
|
51345
|
+
const parsed = import_yaml2.default.parse(m3[1] ?? "");
|
|
51346
|
+
if (parsed && typeof parsed === "object")
|
|
51347
|
+
fm = parsed;
|
|
51348
|
+
} catch {
|
|
51349
|
+
return { frontmatter: {}, body: raw };
|
|
51350
|
+
}
|
|
51351
|
+
return { frontmatter: fm, body: raw.slice(m3[0].length).replace(/^\n+/, "") };
|
|
51352
|
+
}
|
|
51353
|
+
function normalizeInstructionBody(body) {
|
|
51354
|
+
return body.trim();
|
|
51355
|
+
}
|
|
51339
51356
|
|
|
51340
51357
|
// src/core/link.ts
|
|
51341
51358
|
var LINK_DIR = ".brainbase";
|
|
@@ -52549,7 +52566,6 @@ import path48 from "node:path";
|
|
|
52549
52566
|
import fs45 from "node:fs";
|
|
52550
52567
|
import os12 from "node:os";
|
|
52551
52568
|
var import_picocolors25 = __toESM(require_picocolors(), 1);
|
|
52552
|
-
var import_yaml3 = __toESM(require_dist(), 1);
|
|
52553
52569
|
|
|
52554
52570
|
// src/core/agent-diff.ts
|
|
52555
52571
|
import path46 from "node:path";
|
|
@@ -52561,6 +52577,9 @@ function compKey(type, slug) {
|
|
|
52561
52577
|
function hashString(s3) {
|
|
52562
52578
|
return crypto4.createHash("sha256").update(s3).digest("hex");
|
|
52563
52579
|
}
|
|
52580
|
+
function jsonStringAsciiSafe(s3) {
|
|
52581
|
+
return JSON.stringify(s3).replace(/[\u007f-\uffff]/g, (c2) => "\\u" + c2.charCodeAt(0).toString(16).padStart(4, "0"));
|
|
52582
|
+
}
|
|
52564
52583
|
function canonicalJson(value) {
|
|
52565
52584
|
if (value === null)
|
|
52566
52585
|
return "null";
|
|
@@ -52572,14 +52591,14 @@ function canonicalJson(value) {
|
|
|
52572
52591
|
return String(value);
|
|
52573
52592
|
}
|
|
52574
52593
|
if (typeof value === "string")
|
|
52575
|
-
return
|
|
52594
|
+
return jsonStringAsciiSafe(value);
|
|
52576
52595
|
if (Array.isArray(value)) {
|
|
52577
52596
|
return "[" + value.map(canonicalJson).join(",") + "]";
|
|
52578
52597
|
}
|
|
52579
52598
|
if (typeof value === "object") {
|
|
52580
52599
|
const obj = value;
|
|
52581
52600
|
const keys2 = Object.keys(obj).sort();
|
|
52582
|
-
return "{" + keys2.map((k3) => `${
|
|
52601
|
+
return "{" + keys2.map((k3) => `${jsonStringAsciiSafe(k3)}:${canonicalJson(obj[k3])}`).join(",") + "}";
|
|
52583
52602
|
}
|
|
52584
52603
|
throw new Error(`Unsupported value in canonicalJson: ${typeof value}`);
|
|
52585
52604
|
}
|
|
@@ -52649,7 +52668,7 @@ function readLocalComponents(cwd2, manifest) {
|
|
|
52649
52668
|
out.push({
|
|
52650
52669
|
type: "instruction",
|
|
52651
52670
|
slug: "agent-instructions",
|
|
52652
|
-
hash: componentHashFromFileHashes([hashString(instr)])
|
|
52671
|
+
hash: componentHashFromFileHashes([hashString(normalizeInstructionBody(instr))])
|
|
52653
52672
|
});
|
|
52654
52673
|
}
|
|
52655
52674
|
for (const entry of manifest.skills) {
|
|
@@ -52787,6 +52806,38 @@ function threeWayDiff(input) {
|
|
|
52787
52806
|
}
|
|
52788
52807
|
return rows;
|
|
52789
52808
|
}
|
|
52809
|
+
function partitionPushRows(rows, force) {
|
|
52810
|
+
const toSend = [];
|
|
52811
|
+
const conflicts = [];
|
|
52812
|
+
const upstreamOnly = [];
|
|
52813
|
+
for (const r2 of rows) {
|
|
52814
|
+
switch (r2.status) {
|
|
52815
|
+
case "modified-local":
|
|
52816
|
+
case "added-only-local":
|
|
52817
|
+
case "added-local":
|
|
52818
|
+
case "removed-local":
|
|
52819
|
+
toSend.push(r2);
|
|
52820
|
+
break;
|
|
52821
|
+
case "modified-both":
|
|
52822
|
+
if (force)
|
|
52823
|
+
toSend.push(r2);
|
|
52824
|
+
else
|
|
52825
|
+
conflicts.push(r2);
|
|
52826
|
+
break;
|
|
52827
|
+
case "modified-cloud":
|
|
52828
|
+
case "added-cloud":
|
|
52829
|
+
case "removed-cloud":
|
|
52830
|
+
upstreamOnly.push(r2);
|
|
52831
|
+
break;
|
|
52832
|
+
case "in-sync":
|
|
52833
|
+
break;
|
|
52834
|
+
default: {
|
|
52835
|
+
const _exhaustive = r2.status;
|
|
52836
|
+
}
|
|
52837
|
+
}
|
|
52838
|
+
}
|
|
52839
|
+
return { toSend, conflicts, upstreamOnly };
|
|
52840
|
+
}
|
|
52790
52841
|
function diffAgentMeta(manifestMeta, lockMeta, cloudMeta) {
|
|
52791
52842
|
const eq = (a3, b4) => {
|
|
52792
52843
|
if (!a3 && !b4)
|
|
@@ -53221,7 +53272,7 @@ function materializeInstructions(cwd2, cloud, toInstall, keepLocal, existingMani
|
|
|
53221
53272
|
const targetRel = existingManifest?.instructions?.file ?? DEFAULT_INSTRUCTIONS_FILE;
|
|
53222
53273
|
const target = path48.resolve(cwd2, targetRel);
|
|
53223
53274
|
ensureDir(path48.dirname(target));
|
|
53224
|
-
fs45.writeFileSync(target, body, "utf8");
|
|
53275
|
+
fs45.writeFileSync(target, normalizeInstructionBody(body), "utf8");
|
|
53225
53276
|
}
|
|
53226
53277
|
}
|
|
53227
53278
|
function materializePlaybooks(cwd2, cloud, toInstall, keepLocal, existingManifest) {
|
|
@@ -53236,7 +53287,7 @@ function materializePlaybooks(cwd2, cloud, toInstall, keepLocal, existingManifes
|
|
|
53236
53287
|
const raw = c2.files[0]?.content ?? "";
|
|
53237
53288
|
if (!raw.trim())
|
|
53238
53289
|
continue;
|
|
53239
|
-
const { body } =
|
|
53290
|
+
const { body } = stripPlaybookFrontmatter(raw);
|
|
53240
53291
|
const existing = existingManifest?.playbooks?.find((p2) => slugifyPlaybookTitle(p2.title) === c2.slug);
|
|
53241
53292
|
if (existing?.content?.text !== undefined)
|
|
53242
53293
|
continue;
|
|
@@ -53246,20 +53297,6 @@ function materializePlaybooks(cwd2, cloud, toInstall, keepLocal, existingManifes
|
|
|
53246
53297
|
fs45.writeFileSync(target, body, "utf8");
|
|
53247
53298
|
}
|
|
53248
53299
|
}
|
|
53249
|
-
function stripFrontmatter(raw) {
|
|
53250
|
-
const m3 = /^---\s*\n([\s\S]*?)\n---\s*\n?/.exec(raw);
|
|
53251
|
-
if (!m3)
|
|
53252
|
-
return { frontmatter: {}, body: raw };
|
|
53253
|
-
let fm = {};
|
|
53254
|
-
try {
|
|
53255
|
-
const parsed = import_yaml3.default.parse(m3[1] ?? "");
|
|
53256
|
-
if (parsed && typeof parsed === "object")
|
|
53257
|
-
fm = parsed;
|
|
53258
|
-
} catch {
|
|
53259
|
-
return { frontmatter: {}, body: raw };
|
|
53260
|
-
}
|
|
53261
|
-
return { frontmatter: fm, body: raw.slice(m3[0].length) };
|
|
53262
|
-
}
|
|
53263
53300
|
function mergeManifest(cwd2, prev, cloud, cloudAgent, harness) {
|
|
53264
53301
|
const skills = cloud.components.filter((c2) => c2.type === "skill").map((c2) => {
|
|
53265
53302
|
const localDecl = prev?.skills.find((s3) => {
|
|
@@ -53297,7 +53334,7 @@ function mergeManifest(cwd2, prev, cloud, cloudAgent, harness) {
|
|
|
53297
53334
|
}
|
|
53298
53335
|
const playbooks = cloud.components.filter((c2) => c2.type === "playbook").map((c2) => {
|
|
53299
53336
|
const raw = c2.files[0]?.content ?? "";
|
|
53300
|
-
const { frontmatter } =
|
|
53337
|
+
const { frontmatter } = stripPlaybookFrontmatter(raw);
|
|
53301
53338
|
const local = prev?.playbooks?.find((pb) => slugifyPlaybookTitle(pb.title) === c2.slug);
|
|
53302
53339
|
const title = local?.title ?? (typeof frontmatter.title === "string" && frontmatter.title || c2.slug);
|
|
53303
53340
|
const description = local?.description ?? (typeof frontmatter.description === "string" ? frontmatter.description : undefined);
|
|
@@ -53562,10 +53599,11 @@ async function buildOutgoingComponents(cwd2, manifest, cloud, resolvedVersions)
|
|
|
53562
53599
|
}
|
|
53563
53600
|
if (body.trim()) {
|
|
53564
53601
|
const fileName = manifest.instructions.file ?? "instructions.md";
|
|
53565
|
-
const
|
|
53602
|
+
const wireBody = normalizeInstructionBody(body);
|
|
53603
|
+
const fileHash2 = hashString(wireBody);
|
|
53566
53604
|
const file = {
|
|
53567
53605
|
path: fileName,
|
|
53568
|
-
content:
|
|
53606
|
+
content: wireBody,
|
|
53569
53607
|
hash: fileHash2
|
|
53570
53608
|
};
|
|
53571
53609
|
out.push({
|
|
@@ -53878,26 +53916,8 @@ async function runAgentPush(cwd2, args) {
|
|
|
53878
53916
|
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.`);
|
|
53879
53917
|
return;
|
|
53880
53918
|
}
|
|
53881
|
-
const toSend =
|
|
53882
|
-
const
|
|
53883
|
-
const upstreamOnly = [];
|
|
53884
|
-
for (const r2 of rows) {
|
|
53885
|
-
switch (r2.status) {
|
|
53886
|
-
case "modified-local":
|
|
53887
|
-
case "added-only-local":
|
|
53888
|
-
case "removed-local":
|
|
53889
|
-
toSend.push(r2);
|
|
53890
|
-
break;
|
|
53891
|
-
case "modified-both":
|
|
53892
|
-
conflicts.push(r2);
|
|
53893
|
-
break;
|
|
53894
|
-
case "modified-cloud":
|
|
53895
|
-
case "added-cloud":
|
|
53896
|
-
case "removed-cloud":
|
|
53897
|
-
upstreamOnly.push(r2);
|
|
53898
|
-
break;
|
|
53899
|
-
}
|
|
53900
|
-
}
|
|
53919
|
+
const { toSend, conflicts, upstreamOnly } = partitionPushRows(rows, !!args.force);
|
|
53920
|
+
const forcedOverrides = args.force ? rows.filter((r2) => r2.status === "modified-both") : [];
|
|
53901
53921
|
if (!meta.localChanged && !entrypointChanged && toSend.length === 0 && conflicts.length === 0) {
|
|
53902
53922
|
f2.info("Nothing to push — local is in sync with the cloud.");
|
|
53903
53923
|
return;
|
|
@@ -53907,9 +53927,15 @@ async function runAgentPush(cwd2, args) {
|
|
|
53907
53927
|
for (const r2 of conflicts) {
|
|
53908
53928
|
console.error(` ${import_picocolors27.default.red("!")} ${fmtType(r2.type)} ${import_picocolors27.default.bold(r2.slug)}`);
|
|
53909
53929
|
}
|
|
53910
|
-
f2.info(`Run ${import_picocolors27.default.cyan("brainbase agent pull")} first to reconcile, then push again.`);
|
|
53930
|
+
f2.info(`Run ${import_picocolors27.default.cyan("brainbase agent pull")} first to reconcile, then push again — or ${import_picocolors27.default.cyan("brainbase agent push --force")} to overwrite the cloud with your local version.`);
|
|
53911
53931
|
return;
|
|
53912
53932
|
}
|
|
53933
|
+
if (forcedOverrides.length > 0) {
|
|
53934
|
+
f2.warn(`${import_picocolors27.default.yellow("--force")}: overwriting ${forcedOverrides.length} cloud change${forcedOverrides.length === 1 ? "" : "s"} with your local version (cloud edits discarded):`);
|
|
53935
|
+
for (const r2 of forcedOverrides) {
|
|
53936
|
+
console.warn(` ${import_picocolors27.default.yellow("⤒")} ${fmtType(r2.type)} ${import_picocolors27.default.bold(r2.slug)}`);
|
|
53937
|
+
}
|
|
53938
|
+
}
|
|
53913
53939
|
if (upstreamOnly.length > 0 && !args.yes) {
|
|
53914
53940
|
f2.warn(`Cloud has ${upstreamOnly.length} change${upstreamOnly.length === 1 ? "" : "s"} you don't have locally:`);
|
|
53915
53941
|
for (const r2 of upstreamOnly) {
|
|
@@ -54979,7 +55005,7 @@ async function runAgent(cwd2, sub, args, opts) {
|
|
|
54979
55005
|
});
|
|
54980
55006
|
return;
|
|
54981
55007
|
case "push":
|
|
54982
|
-
await runAgentPush(cwd2, { yes: opts.yes });
|
|
55008
|
+
await runAgentPush(cwd2, { yes: opts.yes, force: opts.force });
|
|
54983
55009
|
return;
|
|
54984
55010
|
case "unpack":
|
|
54985
55011
|
await runAgentUnpack(cwd2, {
|
|
@@ -55014,7 +55040,7 @@ function printHelp() {
|
|
|
55014
55040
|
out.push("");
|
|
55015
55041
|
out.push(` ${import_picocolors32.default.cyan("create")} ${import_picocolors32.default.dim("claim an unclaimed brainbase.agent.yaml and create the cloud agent")}`);
|
|
55016
55042
|
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")}`);
|
|
55017
|
-
out.push(` ${import_picocolors32.default.cyan("push")} ${import_picocolors32.default.dim("send local changes to the cloud — instructions, playbooks, skills, MCPs, entrypoint")}`);
|
|
55043
|
+
out.push(` ${import_picocolors32.default.cyan("push")} ${import_picocolors32.default.dim("send local changes to the cloud — instructions, playbooks, skills, MCPs, entrypoint (--force to overwrite cloud-side conflicts with local)")}`);
|
|
55018
55044
|
out.push(` ${import_picocolors32.default.cyan("unpack")} ${import_picocolors32.default.dim("install the claimed agent into a harness layout (--harness to override)")}`);
|
|
55019
55045
|
out.push(` ${import_picocolors32.default.cyan("status")} ${import_picocolors32.default.dim("show what would push and what would pull")}`);
|
|
55020
55046
|
out.push(` ${import_picocolors32.default.cyan("env")} ${import_picocolors32.default.dim('print export statements — use with `eval "$(brainbase agent env)"`')}`);
|
|
@@ -55034,7 +55060,7 @@ var import_picocolors33 = __toESM(require_picocolors(), 1);
|
|
|
55034
55060
|
// src/core/orchestration-manifest.ts
|
|
55035
55061
|
import path51 from "node:path";
|
|
55036
55062
|
import fs47 from "node:fs";
|
|
55037
|
-
var
|
|
55063
|
+
var import_yaml3 = __toESM(require_dist(), 1);
|
|
55038
55064
|
var ORCH_MANIFEST_FILE = "brainbase-orchestration.yaml";
|
|
55039
55065
|
var ORCH_MEMBERS_DIR = "agents";
|
|
55040
55066
|
var OrchMetaSchema = exports_external.object({
|
|
@@ -55086,7 +55112,7 @@ function readOrchManifest(cwd2) {
|
|
|
55086
55112
|
const raw = fs47.readFileSync(p2, "utf8");
|
|
55087
55113
|
let parsed;
|
|
55088
55114
|
try {
|
|
55089
|
-
parsed =
|
|
55115
|
+
parsed = import_yaml3.default.parse(raw);
|
|
55090
55116
|
} catch (err) {
|
|
55091
55117
|
throw new Error(`${ORCH_MANIFEST_FILE} is not valid YAML: ${err.message}`);
|
|
55092
55118
|
}
|
|
@@ -55097,7 +55123,7 @@ function readOrchManifest(cwd2) {
|
|
|
55097
55123
|
return result2.data;
|
|
55098
55124
|
}
|
|
55099
55125
|
function writeOrchManifest(cwd2, manifest) {
|
|
55100
|
-
const doc = new
|
|
55126
|
+
const doc = new import_yaml3.default.Document;
|
|
55101
55127
|
doc.contents = manifest;
|
|
55102
55128
|
doc.commentBefore = ` brainbase-orchestration.yaml — declarative orchestration manifest.
|
|
55103
55129
|
` + ` Committed to source control. Edit by hand, then
|
|
@@ -56952,7 +56978,7 @@ function help() {
|
|
|
56952
56978
|
out.push("");
|
|
56953
56979
|
out.push(` ${import_picocolors41.default.cyan("agent create")} ${import_picocolors41.default.dim("claim an unclaimed brainbase.agent.yaml and create the cloud agent")}`);
|
|
56954
56980
|
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)")}`);
|
|
56955
|
-
out.push(` ${import_picocolors41.default.cyan("agent push")} ${import_picocolors41.default.dim("send local changes to the cloud
|
|
56981
|
+
out.push(` ${import_picocolors41.default.cyan("agent push")} ${import_picocolors41.default.dim("send local changes to the cloud (--force to overwrite cloud-side conflicts with local)")}`);
|
|
56956
56982
|
out.push(` ${import_picocolors41.default.cyan("agent unpack")} ${import_picocolors41.default.dim("install the claimed agent into a harness layout")}`);
|
|
56957
56983
|
out.push(` ${import_picocolors41.default.cyan("link")} ${import_picocolors41.default.dim("attach this folder to an existing agent")}`);
|
|
56958
56984
|
out.push(` ${import_picocolors41.default.cyan("agent status")} ${import_picocolors41.default.dim("show what would pull and what would push")}`);
|