@brainbase-labs/cli 0.14.0 → 0.15.0-acp.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 +502 -415
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -35128,12 +35128,12 @@ var require_dist2 = __commonJS((exports, module) => {
|
|
|
35128
35128
|
throw new Error(`Unknown format "${name}"`);
|
|
35129
35129
|
return f4;
|
|
35130
35130
|
};
|
|
35131
|
-
function addFormats(ajv, list,
|
|
35131
|
+
function addFormats(ajv, list, fs53, exportName) {
|
|
35132
35132
|
var _a;
|
|
35133
35133
|
var _b;
|
|
35134
35134
|
(_a = (_b = ajv.opts.code).formats) !== null && _a !== undefined || (_b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`);
|
|
35135
35135
|
for (const f4 of list)
|
|
35136
|
-
ajv.addFormat(f4,
|
|
35136
|
+
ajv.addFormat(f4, fs53[f4]);
|
|
35137
35137
|
}
|
|
35138
35138
|
module.exports = exports = formatsPlugin;
|
|
35139
35139
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -35143,7 +35143,7 @@ var require_dist2 = __commonJS((exports, module) => {
|
|
|
35143
35143
|
// src/index.ts
|
|
35144
35144
|
var import_picocolors42 = __toESM(require_picocolors(), 1);
|
|
35145
35145
|
import process14 from "node:process";
|
|
35146
|
-
import
|
|
35146
|
+
import fs53 from "node:fs";
|
|
35147
35147
|
|
|
35148
35148
|
// src/cli/template.ts
|
|
35149
35149
|
var import_picocolors12 = __toESM(require_picocolors(), 1);
|
|
@@ -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.15.0-acp.1",
|
|
36012
36012
|
description: "Pack, share, and install agent templates across harnesses (Claude Code, Codex, ...).",
|
|
36013
36013
|
type: "module",
|
|
36014
36014
|
bin: {
|
|
@@ -57754,6 +57754,32 @@ var CapabilitiesSchema = exports_external.object({
|
|
|
57754
57754
|
slack: exports_external.boolean().optional(),
|
|
57755
57755
|
meeting: exports_external.boolean().optional()
|
|
57756
57756
|
});
|
|
57757
|
+
var EvalOutputShape = exports_external.enum(["binary", "rating", "classification"]);
|
|
57758
|
+
var EVAL_SLUG_RE = /^[a-z0-9][a-z0-9-]*$/;
|
|
57759
|
+
var EvalSchema = exports_external.object({
|
|
57760
|
+
id: exports_external.string().min(1).optional(),
|
|
57761
|
+
slug: exports_external.string().regex(EVAL_SLUG_RE, "slug must be kebab-case (a-z, 0-9, hyphens)"),
|
|
57762
|
+
criteria: exports_external.string().min(1).max(4000),
|
|
57763
|
+
icon: exports_external.string().max(64).optional(),
|
|
57764
|
+
enabled: exports_external.boolean().default(true),
|
|
57765
|
+
judge_model: exports_external.string().min(1).max(128).default("claude-sonnet-4-6"),
|
|
57766
|
+
judge_type: exports_external.enum(["model", "agent"]).default("model"),
|
|
57767
|
+
judge_agent: exports_external.string().min(1).optional(),
|
|
57768
|
+
output_shape: EvalOutputShape.default("binary"),
|
|
57769
|
+
classification_values: exports_external.array(exports_external.string().min(1)).optional()
|
|
57770
|
+
}).refine((v3) => v3.output_shape === "classification" ? !!v3.classification_values && v3.classification_values.length > 0 : v3.classification_values === undefined, {
|
|
57771
|
+
message: 'classification_values must be a non-empty list iff output_shape is "classification"',
|
|
57772
|
+
path: ["classification_values"]
|
|
57773
|
+
}).refine((v3) => v3.judge_type === "agent" ? v3.judge_agent !== undefined : v3.judge_agent === undefined, {
|
|
57774
|
+
message: 'judge_agent is required iff judge_type is "agent"',
|
|
57775
|
+
path: ["judge_agent"]
|
|
57776
|
+
}).refine((v3) => v3.judge_agent === undefined || EVAL_SLUG_RE.test(v3.judge_agent), {
|
|
57777
|
+
message: "judge_agent must be kebab-case (a slug, or a raw agent id)",
|
|
57778
|
+
path: ["judge_agent"]
|
|
57779
|
+
}).refine((v3) => v3.classification_values === undefined || new Set(v3.classification_values).size === v3.classification_values.length, {
|
|
57780
|
+
message: "classification_values must not contain duplicate labels",
|
|
57781
|
+
path: ["classification_values"]
|
|
57782
|
+
});
|
|
57757
57783
|
var AgentManifestSchema = exports_external.object({
|
|
57758
57784
|
schema: exports_external.literal(1),
|
|
57759
57785
|
id: exports_external.string().min(1).optional(),
|
|
@@ -57764,6 +57790,19 @@ var AgentManifestSchema = exports_external.object({
|
|
|
57764
57790
|
playbooks: exports_external.array(PlaybookSchema).default([]),
|
|
57765
57791
|
skills: exports_external.array(SkillEntrySchema).default([]),
|
|
57766
57792
|
mcp: exports_external.array(McpEntrySchema).default([]),
|
|
57793
|
+
evals: exports_external.array(EvalSchema).superRefine((evals, ctx) => {
|
|
57794
|
+
const seen = new Set;
|
|
57795
|
+
evals.forEach((e2, i) => {
|
|
57796
|
+
if (seen.has(e2.slug)) {
|
|
57797
|
+
ctx.addIssue({
|
|
57798
|
+
code: exports_external.ZodIssueCode.custom,
|
|
57799
|
+
message: `duplicate eval slug "${e2.slug}" — slugs must be unique within an agent`,
|
|
57800
|
+
path: [i, "slug"]
|
|
57801
|
+
});
|
|
57802
|
+
}
|
|
57803
|
+
seen.add(e2.slug);
|
|
57804
|
+
});
|
|
57805
|
+
}).default([]),
|
|
57767
57806
|
capabilities: CapabilitiesSchema.optional(),
|
|
57768
57807
|
commands: exports_external.array(exports_external.record(exports_external.unknown())).optional(),
|
|
57769
57808
|
hooks: exports_external.array(exports_external.record(exports_external.unknown())).optional(),
|
|
@@ -58085,6 +58124,7 @@ function writeLink(cwd2, link2) {
|
|
|
58085
58124
|
schema: 1,
|
|
58086
58125
|
agent: { name: link2.name },
|
|
58087
58126
|
playbooks: [],
|
|
58127
|
+
evals: [],
|
|
58088
58128
|
skills: [],
|
|
58089
58129
|
mcp: []
|
|
58090
58130
|
};
|
|
@@ -58093,6 +58133,7 @@ function writeLink(cwd2, link2) {
|
|
|
58093
58133
|
schema: 1,
|
|
58094
58134
|
agent: { name: link2.name },
|
|
58095
58135
|
playbooks: [],
|
|
58136
|
+
evals: [],
|
|
58096
58137
|
skills: [],
|
|
58097
58138
|
mcp: []
|
|
58098
58139
|
};
|
|
@@ -59140,10 +59181,10 @@ var import_picocolors32 = __toESM(require_picocolors(), 1);
|
|
|
59140
59181
|
|
|
59141
59182
|
// src/cli/agent-pull.ts
|
|
59142
59183
|
import { spawn as spawn2 } from "node:child_process";
|
|
59143
|
-
import
|
|
59144
|
-
import
|
|
59145
|
-
import
|
|
59146
|
-
var
|
|
59184
|
+
import path49 from "node:path";
|
|
59185
|
+
import fs46 from "node:fs";
|
|
59186
|
+
import os13 from "node:os";
|
|
59187
|
+
var import_picocolors26 = __toESM(require_picocolors(), 1);
|
|
59147
59188
|
|
|
59148
59189
|
// src/core/agent-diff.ts
|
|
59149
59190
|
import path46 from "node:path";
|
|
@@ -59538,6 +59579,282 @@ function entrypointExecutionAllowed(opts) {
|
|
|
59538
59579
|
return v3 === "1" || v3 === "true";
|
|
59539
59580
|
}
|
|
59540
59581
|
|
|
59582
|
+
// src/cli/agent-unpack.ts
|
|
59583
|
+
import path48 from "node:path";
|
|
59584
|
+
import fs45 from "node:fs";
|
|
59585
|
+
import os12 from "node:os";
|
|
59586
|
+
var import_picocolors25 = __toESM(require_picocolors(), 1);
|
|
59587
|
+
function componentsForNativeInstall(components, acp) {
|
|
59588
|
+
return acp ? components.filter((c2) => c2.type !== "mcp") : components;
|
|
59589
|
+
}
|
|
59590
|
+
async function runAgentUnpack(cwd2, args) {
|
|
59591
|
+
banner("agent unpack — install this agent into a harness layout");
|
|
59592
|
+
if (!hasManifest(cwd2)) {
|
|
59593
|
+
f2.error(`No ${import_picocolors25.default.bold(AGENT_MANIFEST_FILE)} here.`);
|
|
59594
|
+
f2.info(`Run ${import_picocolors25.default.cyan("brainbase agent pull <id>")} to bring an agent into this folder first.`);
|
|
59595
|
+
return;
|
|
59596
|
+
}
|
|
59597
|
+
let manifest;
|
|
59598
|
+
try {
|
|
59599
|
+
manifest = readManifest(cwd2);
|
|
59600
|
+
} catch (err) {
|
|
59601
|
+
f2.error(err.message);
|
|
59602
|
+
return;
|
|
59603
|
+
}
|
|
59604
|
+
if (!manifest.id) {
|
|
59605
|
+
f2.error(`${import_picocolors25.default.bold(AGENT_MANIFEST_FILE)} is unclaimed (no ${import_picocolors25.default.cyan("id")}).`);
|
|
59606
|
+
f2.info(`Run ${import_picocolors25.default.cyan("brainbase agent create")} to claim it, ` + `or ${import_picocolors25.default.cyan("brainbase agent pull <id>")} to link it to an existing agent.`);
|
|
59607
|
+
return;
|
|
59608
|
+
}
|
|
59609
|
+
let harness;
|
|
59610
|
+
if (args.harness) {
|
|
59611
|
+
harness = normalizeHarnessId(args.harness);
|
|
59612
|
+
} else if (args.yes) {
|
|
59613
|
+
if (!manifest.harness) {
|
|
59614
|
+
f2.error(`--yes mode but no harness — set ${import_picocolors25.default.cyan("harness")} in the manifest or pass ${import_picocolors25.default.cyan("--harness")}.`);
|
|
59615
|
+
return;
|
|
59616
|
+
}
|
|
59617
|
+
harness = normalizeHarnessId(manifest.harness);
|
|
59618
|
+
} else {
|
|
59619
|
+
harness = await pickHarness(manifest.harness);
|
|
59620
|
+
}
|
|
59621
|
+
if (!autoProceed(args.yes)) {
|
|
59622
|
+
const ok = await se({
|
|
59623
|
+
message: `Install ${import_picocolors25.default.bold(manifest.agent.name)} as ${import_picocolors25.default.bold(harness)} here?`,
|
|
59624
|
+
initialValue: true
|
|
59625
|
+
});
|
|
59626
|
+
if (!ensureNotCancelled(ok)) {
|
|
59627
|
+
$e("Aborted.");
|
|
59628
|
+
return;
|
|
59629
|
+
}
|
|
59630
|
+
}
|
|
59631
|
+
const scope = args.scope ?? "project";
|
|
59632
|
+
const stageRoot = fs45.mkdtempSync(path48.join(os12.tmpdir(), "brainbase-unpack-"));
|
|
59633
|
+
try {
|
|
59634
|
+
const toInstall = [];
|
|
59635
|
+
const instructionsBody = readInstructions(cwd2, manifest);
|
|
59636
|
+
if (instructionsBody && instructionsBody.trim()) {
|
|
59637
|
+
const compDir = path48.join(stageRoot, "instruction", "agent-instructions");
|
|
59638
|
+
ensureDir(compDir);
|
|
59639
|
+
fs45.writeFileSync(path48.join(compDir, "instructions.md"), instructionsBody, "utf8");
|
|
59640
|
+
toInstall.push({
|
|
59641
|
+
type: "instruction",
|
|
59642
|
+
slug: "agent-instructions",
|
|
59643
|
+
scope,
|
|
59644
|
+
rootDir: compDir,
|
|
59645
|
+
description: "Agent instructions",
|
|
59646
|
+
checksum: ""
|
|
59647
|
+
});
|
|
59648
|
+
}
|
|
59649
|
+
for (const entry of manifest.playbooks ?? []) {
|
|
59650
|
+
const issue = stageLocalPlaybook(entry, cwd2, stageRoot, scope, toInstall);
|
|
59651
|
+
if (issue) {
|
|
59652
|
+
f2.warn(issue);
|
|
59653
|
+
}
|
|
59654
|
+
}
|
|
59655
|
+
for (const entry of manifest.skills ?? []) {
|
|
59656
|
+
const issue = stageLocalSkill(entry.source, cwd2, stageRoot, scope, toInstall);
|
|
59657
|
+
if (issue) {
|
|
59658
|
+
f2.warn(issue);
|
|
59659
|
+
}
|
|
59660
|
+
}
|
|
59661
|
+
for (const entry of manifest.mcp ?? []) {
|
|
59662
|
+
const compDir = path48.join(stageRoot, "mcp", entry.name);
|
|
59663
|
+
ensureDir(compDir);
|
|
59664
|
+
const payload = {};
|
|
59665
|
+
if (entry.url !== undefined)
|
|
59666
|
+
payload.url = entry.url;
|
|
59667
|
+
if (entry.command !== undefined)
|
|
59668
|
+
payload.command = entry.command;
|
|
59669
|
+
if (entry.args !== undefined)
|
|
59670
|
+
payload.args = entry.args;
|
|
59671
|
+
if (entry.env !== undefined)
|
|
59672
|
+
payload.env = entry.env;
|
|
59673
|
+
if (entry.headers !== undefined)
|
|
59674
|
+
payload.headers = entry.headers;
|
|
59675
|
+
payload.is_enabled = entry.is_enabled ?? true;
|
|
59676
|
+
toInstall.push({
|
|
59677
|
+
type: "mcp",
|
|
59678
|
+
slug: entry.name,
|
|
59679
|
+
scope,
|
|
59680
|
+
rootDir: compDir,
|
|
59681
|
+
payload: proxifyMcpPayload(payload),
|
|
59682
|
+
checksum: ""
|
|
59683
|
+
});
|
|
59684
|
+
}
|
|
59685
|
+
const caps = capabilitiesFromManifest(manifest);
|
|
59686
|
+
const declaredMcpSlugs = new Set((manifest.mcp ?? []).map((m3) => m3.name));
|
|
59687
|
+
const { install: builtinInstall, removeSlugs: builtinRemoveSlugs } = resolveBuiltinMcps({
|
|
59688
|
+
caps,
|
|
59689
|
+
declaredSlugs: declaredMcpSlugs,
|
|
59690
|
+
scope
|
|
59691
|
+
});
|
|
59692
|
+
toInstall.push(...builtinInstall);
|
|
59693
|
+
writeResolvedMcps(cwd2, toInstall);
|
|
59694
|
+
const opts = {
|
|
59695
|
+
cwd: cwd2,
|
|
59696
|
+
scope,
|
|
59697
|
+
resolveConflict: async (_c) => "overwrite",
|
|
59698
|
+
resolveSecret: async () => null
|
|
59699
|
+
};
|
|
59700
|
+
const sp = de();
|
|
59701
|
+
sp.start("Installing harness layout…");
|
|
59702
|
+
const nativeComponents = componentsForNativeInstall(toInstall, !!args.acp);
|
|
59703
|
+
const result2 = await runHarnessInstall2(harness, nativeComponents, opts, manifest.agent.name);
|
|
59704
|
+
sp.stop("Installed.");
|
|
59705
|
+
if (result2.skipped.length) {
|
|
59706
|
+
f2.warn(`Skipped: ${result2.skipped.map((s3) => `${s3.type}/${s3.slug} (${s3.reason})`).join(", ")}`);
|
|
59707
|
+
}
|
|
59708
|
+
if (builtinRemoveSlugs.length > 0) {
|
|
59709
|
+
runHarnessRemoveMcp(harness, builtinRemoveSlugs, { cwd: cwd2, scope });
|
|
59710
|
+
}
|
|
59711
|
+
} catch (err) {
|
|
59712
|
+
f2.error(`Install failed: ${err.message}`);
|
|
59713
|
+
return;
|
|
59714
|
+
} finally {
|
|
59715
|
+
try {
|
|
59716
|
+
fs45.rmSync(stageRoot, { recursive: true, force: true });
|
|
59717
|
+
} catch {}
|
|
59718
|
+
}
|
|
59719
|
+
if (manifest.harness !== harness) {
|
|
59720
|
+
manifest.harness = harness;
|
|
59721
|
+
writeManifest(cwd2, manifest);
|
|
59722
|
+
}
|
|
59723
|
+
$e(`Unpacked ${import_picocolors25.default.bold(manifest.agent.name)} as ${import_picocolors25.default.bold(harness)}.`);
|
|
59724
|
+
await showResultCard({
|
|
59725
|
+
title: "UNPACKED",
|
|
59726
|
+
tone: "ok",
|
|
59727
|
+
subtitle: manifest.agent.name,
|
|
59728
|
+
meta: [
|
|
59729
|
+
["harness", harness],
|
|
59730
|
+
["agent", manifest.id]
|
|
59731
|
+
]
|
|
59732
|
+
});
|
|
59733
|
+
}
|
|
59734
|
+
function writeResolvedMcps(workdir, toInstall) {
|
|
59735
|
+
const mcps = toInstall.filter((c2) => c2.type === "mcp").map((c2) => ({ name: c2.slug, ...c2.payload }));
|
|
59736
|
+
const dir = path48.join(workdir, ".brainbase");
|
|
59737
|
+
fs45.mkdirSync(dir, { recursive: true });
|
|
59738
|
+
fs45.writeFileSync(path48.join(dir, "resolved-mcps.json"), JSON.stringify(mcps, null, 2));
|
|
59739
|
+
}
|
|
59740
|
+
function stageLocalPlaybook(entry, cwd2, stageRoot, scope, toInstall) {
|
|
59741
|
+
if (entry.content.text !== undefined && entry.content.file !== undefined) {
|
|
59742
|
+
return `Playbook ${entry.title}: both text and file set — skipped.`;
|
|
59743
|
+
}
|
|
59744
|
+
const body = resolvePlaybookContent(cwd2, entry);
|
|
59745
|
+
if (body === null) {
|
|
59746
|
+
return entry.content.file ? `Playbook ${entry.title}: file ${entry.content.file} not found — skipped.` : `Playbook ${entry.title}: content empty — skipped.`;
|
|
59747
|
+
}
|
|
59748
|
+
const slug = slugifyPlaybookTitle(entry.title);
|
|
59749
|
+
const compDir = path48.join(stageRoot, "playbook", slug);
|
|
59750
|
+
ensureDir(compDir);
|
|
59751
|
+
const wireBody = /^---\s*\n/.test(body) ? body : assembleFrontmatter(entry.title, entry.description) + body.replace(/^\n+/, "");
|
|
59752
|
+
fs45.writeFileSync(path48.join(compDir, `${slug}.md`), wireBody, "utf8");
|
|
59753
|
+
toInstall.push({
|
|
59754
|
+
type: "playbook",
|
|
59755
|
+
slug,
|
|
59756
|
+
scope,
|
|
59757
|
+
rootDir: compDir,
|
|
59758
|
+
description: entry.description,
|
|
59759
|
+
checksum: ""
|
|
59760
|
+
});
|
|
59761
|
+
return null;
|
|
59762
|
+
}
|
|
59763
|
+
function stageLocalSkill(source, cwd2, stageRoot, scope, toInstall) {
|
|
59764
|
+
if (source.startsWith("./") || source.startsWith("../") || source.startsWith("/")) {
|
|
59765
|
+
const abs = path48.resolve(cwd2, source);
|
|
59766
|
+
if (!fs45.existsSync(abs)) {
|
|
59767
|
+
return `Skill ${source}: not found on disk — skipped.`;
|
|
59768
|
+
}
|
|
59769
|
+
const slug = path48.basename(abs);
|
|
59770
|
+
const compDir = path48.join(stageRoot, "skill", slug);
|
|
59771
|
+
ensureDir(compDir);
|
|
59772
|
+
copyDirRecursive(abs, compDir);
|
|
59773
|
+
toInstall.push({
|
|
59774
|
+
type: "skill",
|
|
59775
|
+
slug,
|
|
59776
|
+
scope,
|
|
59777
|
+
rootDir: compDir,
|
|
59778
|
+
checksum: ""
|
|
59779
|
+
});
|
|
59780
|
+
return null;
|
|
59781
|
+
}
|
|
59782
|
+
try {
|
|
59783
|
+
const parsed = parseSkillSource(source);
|
|
59784
|
+
if (parsed.type === "local" || parsed.type === "inline")
|
|
59785
|
+
return null;
|
|
59786
|
+
const slug = defaultSlugForSource(source);
|
|
59787
|
+
const compDir = path48.join(stageRoot, "skill", slug);
|
|
59788
|
+
ensureDir(compDir);
|
|
59789
|
+
toInstall.push({
|
|
59790
|
+
type: "skill",
|
|
59791
|
+
slug,
|
|
59792
|
+
scope,
|
|
59793
|
+
rootDir: compDir,
|
|
59794
|
+
source: parsed,
|
|
59795
|
+
checksum: ""
|
|
59796
|
+
});
|
|
59797
|
+
return null;
|
|
59798
|
+
} catch (err) {
|
|
59799
|
+
return `Skill ${source}: ${err.message} — skipped.`;
|
|
59800
|
+
}
|
|
59801
|
+
}
|
|
59802
|
+
function defaultSlugForSource(source) {
|
|
59803
|
+
const reg = /^registry:(?:[a-z0-9_-]+\/)?([a-z0-9_-]+)/i.exec(source);
|
|
59804
|
+
if (reg)
|
|
59805
|
+
return reg[1].toLowerCase();
|
|
59806
|
+
const gh = /^(?:github|git):[^/]*\/?([a-z0-9_-]+)/i.exec(source);
|
|
59807
|
+
if (gh)
|
|
59808
|
+
return gh[1].toLowerCase();
|
|
59809
|
+
return source.replace(/[^a-z0-9_-]/gi, "-").slice(0, 60) || "skill";
|
|
59810
|
+
}
|
|
59811
|
+
function copyDirRecursive(src, dest) {
|
|
59812
|
+
ensureDir(dest);
|
|
59813
|
+
for (const entry of fs45.readdirSync(src, { withFileTypes: true })) {
|
|
59814
|
+
const s3 = path48.join(src, entry.name);
|
|
59815
|
+
const d3 = path48.join(dest, entry.name);
|
|
59816
|
+
if (entry.isDirectory())
|
|
59817
|
+
copyDirRecursive(s3, d3);
|
|
59818
|
+
else if (entry.isFile())
|
|
59819
|
+
fs45.copyFileSync(s3, d3);
|
|
59820
|
+
}
|
|
59821
|
+
}
|
|
59822
|
+
function assembleFrontmatter(title, description) {
|
|
59823
|
+
const lines = ["---", `title: ${yamlScalar(title)}`];
|
|
59824
|
+
if (description)
|
|
59825
|
+
lines.push(`description: ${yamlScalar(description)}`);
|
|
59826
|
+
lines.push("---", "");
|
|
59827
|
+
return lines.join(`
|
|
59828
|
+
`);
|
|
59829
|
+
}
|
|
59830
|
+
function yamlScalar(s3) {
|
|
59831
|
+
if (!/[\n":#&*!|>'%@`{}[\]]/.test(s3) && s3.trim() === s3 && s3 !== "")
|
|
59832
|
+
return s3;
|
|
59833
|
+
return JSON.stringify(s3);
|
|
59834
|
+
}
|
|
59835
|
+
function runHarnessInstall2(harnessId, components, opts, agentName) {
|
|
59836
|
+
if (harnessId === "claude-code")
|
|
59837
|
+
return installClaudeCodeWithCtx(components, opts, agentName);
|
|
59838
|
+
if (harnessId === "codex")
|
|
59839
|
+
return installCodexWithCtx(components, opts, agentName);
|
|
59840
|
+
if (harnessId === "kafka")
|
|
59841
|
+
return installKafkaWithCtx(components, opts, agentName);
|
|
59842
|
+
return getAdapter(harnessId).install(components, opts);
|
|
59843
|
+
}
|
|
59844
|
+
async function pickHarness(current) {
|
|
59845
|
+
const initial2 = current ? normalizeHarnessId(current) : undefined;
|
|
59846
|
+
return select({
|
|
59847
|
+
message: "Pick a harness to install as",
|
|
59848
|
+
options: adapters.map((a3) => ({
|
|
59849
|
+
value: a3.id,
|
|
59850
|
+
label: a3.displayName,
|
|
59851
|
+
hint: a3.id === initial2 ? "current" : undefined
|
|
59852
|
+
})),
|
|
59853
|
+
initialValue: initial2 ?? adapters[0].id,
|
|
59854
|
+
flagHint: "Pass --harness <id> to choose non-interactively."
|
|
59855
|
+
});
|
|
59856
|
+
}
|
|
59857
|
+
|
|
59541
59858
|
// src/cli/agent-pull.ts
|
|
59542
59859
|
async function runAgentPull(cwd2, args) {
|
|
59543
59860
|
banner("agent pull — bring cloud changes into this folder");
|
|
@@ -59600,7 +59917,7 @@ async function runAgentPull(cwd2, args) {
|
|
|
59600
59917
|
}
|
|
59601
59918
|
for (const r2 of conflicts) {
|
|
59602
59919
|
const choice = await ie({
|
|
59603
|
-
message: r2.status === "modified-both" ? `${fmtType(r2.type)} ${
|
|
59920
|
+
message: r2.status === "modified-both" ? `${fmtType(r2.type)} ${import_picocolors26.default.bold(r2.slug)} — both you and the cloud edited it` : `${fmtType(r2.type)} ${import_picocolors26.default.bold(r2.slug)} — you have local edits not yet pushed`,
|
|
59604
59921
|
options: [
|
|
59605
59922
|
{ value: "cloud", label: "Use the cloud's version (discard local edits)" },
|
|
59606
59923
|
{ value: "keep", label: "Keep your local edits (skip this one)" }
|
|
@@ -59626,7 +59943,7 @@ async function runAgentPull(cwd2, args) {
|
|
|
59626
59943
|
writeSyncState(cwd2, buildLockFromCloud(agentId, cloud, lock, cloudAgent));
|
|
59627
59944
|
if (!existingManifest) {
|
|
59628
59945
|
writeManifest(cwd2, mergeManifest(cwd2, null, cloud, cloudAgent, harness));
|
|
59629
|
-
f2.info(`Wrote ${
|
|
59946
|
+
f2.info(`Wrote ${import_picocolors26.default.bold(AGENT_MANIFEST_FILE)}.`);
|
|
59630
59947
|
}
|
|
59631
59948
|
return;
|
|
59632
59949
|
}
|
|
@@ -59681,7 +59998,7 @@ async function runAgentPull(cwd2, args) {
|
|
|
59681
59998
|
type: c2.type,
|
|
59682
59999
|
slug: c2.slug,
|
|
59683
60000
|
scope,
|
|
59684
|
-
rootDir:
|
|
60001
|
+
rootDir: path49.join(stageRoot, c2.type, c2.slug),
|
|
59685
60002
|
description: c2.description,
|
|
59686
60003
|
meta: c2.meta,
|
|
59687
60004
|
payload: proxifyMcpPayload(c2.meta?.mcp),
|
|
@@ -59695,7 +60012,7 @@ async function runAgentPull(cwd2, args) {
|
|
|
59695
60012
|
resolveConflict: async (_c) => "overwrite",
|
|
59696
60013
|
resolveSecret: async () => null
|
|
59697
60014
|
};
|
|
59698
|
-
const result2 = await
|
|
60015
|
+
const result2 = await runHarnessInstall3(adapter.id, componentsForNativeInstall(toInstall, !!args.acp), opts, cloudAgent.name);
|
|
59699
60016
|
installSpinner.stop("Applied.");
|
|
59700
60017
|
for (const o2 of result2.installed) {
|
|
59701
60018
|
justInstalledPaths.set(`${o2.type}/${o2.slug}`, o2.installedPaths);
|
|
@@ -59712,14 +60029,14 @@ async function runAgentPull(cwd2, args) {
|
|
|
59712
60029
|
if (!prior)
|
|
59713
60030
|
continue;
|
|
59714
60031
|
for (const filePath of prior.installedPaths) {
|
|
59715
|
-
if (!
|
|
60032
|
+
if (!fs46.existsSync(filePath))
|
|
59716
60033
|
continue;
|
|
59717
60034
|
try {
|
|
59718
|
-
const stat =
|
|
60035
|
+
const stat = fs46.statSync(filePath);
|
|
59719
60036
|
if (stat.isDirectory())
|
|
59720
|
-
|
|
60037
|
+
fs46.rmSync(filePath, { recursive: true, force: true });
|
|
59721
60038
|
else
|
|
59722
|
-
|
|
60039
|
+
fs46.rmSync(filePath);
|
|
59723
60040
|
} catch (err) {
|
|
59724
60041
|
f2.warn(`Failed to remove ${filePath}: ${err.message}`);
|
|
59725
60042
|
}
|
|
@@ -59757,7 +60074,7 @@ async function runAgentPull(cwd2, args) {
|
|
|
59757
60074
|
$e(`Pulled ${cloudAgent.name} at revision ${cloud.revision}.`);
|
|
59758
60075
|
} finally {
|
|
59759
60076
|
try {
|
|
59760
|
-
|
|
60077
|
+
fs46.rmSync(stageRoot, { recursive: true, force: true });
|
|
59761
60078
|
} catch {}
|
|
59762
60079
|
}
|
|
59763
60080
|
}
|
|
@@ -59773,8 +60090,8 @@ function resolveTargetAgentId(cwd2, args) {
|
|
|
59773
60090
|
const manifestId = manifest?.id;
|
|
59774
60091
|
if (arg && manifestId && arg !== manifestId) {
|
|
59775
60092
|
if (!args.force) {
|
|
59776
|
-
f2.error(`This folder is already linked to a different agent (${
|
|
59777
|
-
f2.info(`Run ${
|
|
60093
|
+
f2.error(`This folder is already linked to a different agent (${import_picocolors26.default.dim(manifestId)}).`);
|
|
60094
|
+
f2.info(`Run ${import_picocolors26.default.cyan(`brainbase agent pull ${arg} --force`)} to override. ` + import_picocolors26.default.yellow("This will overwrite brainbase.agent.yaml and any local progress will be lost."));
|
|
59778
60095
|
return null;
|
|
59779
60096
|
}
|
|
59780
60097
|
return { agentId: arg, override: true };
|
|
@@ -59784,11 +60101,11 @@ function resolveTargetAgentId(cwd2, args) {
|
|
|
59784
60101
|
if (manifestId)
|
|
59785
60102
|
return { agentId: manifestId, override: false };
|
|
59786
60103
|
if (manifest) {
|
|
59787
|
-
f2.error(`${
|
|
59788
|
-
f2.info(`Run ${
|
|
60104
|
+
f2.error(`${import_picocolors26.default.bold(AGENT_MANIFEST_FILE)} is unclaimed (no ${import_picocolors26.default.cyan("id")}).`);
|
|
60105
|
+
f2.info(`Run ${import_picocolors26.default.cyan("brainbase agent create")} to create a new agent from this manifest, ` + `or ${import_picocolors26.default.cyan("brainbase agent pull <id>")} to pull an existing one.`);
|
|
59789
60106
|
} else {
|
|
59790
|
-
f2.error(`No ${
|
|
59791
|
-
f2.info(`Run ${
|
|
60107
|
+
f2.error(`No ${import_picocolors26.default.bold(AGENT_MANIFEST_FILE)} here and no ${import_picocolors26.default.cyan("<id>")} given.`);
|
|
60108
|
+
f2.info(`Run ${import_picocolors26.default.cyan("brainbase agent pull <id>")} to pull an existing agent into this folder.`);
|
|
59792
60109
|
}
|
|
59793
60110
|
return null;
|
|
59794
60111
|
}
|
|
@@ -59812,19 +60129,19 @@ function skillSourceFromMeta(c2) {
|
|
|
59812
60129
|
}
|
|
59813
60130
|
}
|
|
59814
60131
|
function stageManifestComponents(components) {
|
|
59815
|
-
const root =
|
|
60132
|
+
const root = fs46.mkdtempSync(path49.join(os13.tmpdir(), "brainbase-pull-"));
|
|
59816
60133
|
for (const c2 of components) {
|
|
59817
|
-
const compDir =
|
|
60134
|
+
const compDir = path49.join(root, c2.type, c2.slug);
|
|
59818
60135
|
ensureDir(compDir);
|
|
59819
60136
|
for (const f4 of c2.files) {
|
|
59820
|
-
const target =
|
|
59821
|
-
ensureDir(
|
|
59822
|
-
|
|
60137
|
+
const target = path49.join(compDir, f4.path);
|
|
60138
|
+
ensureDir(path49.dirname(target));
|
|
60139
|
+
fs46.writeFileSync(target, f4.content);
|
|
59823
60140
|
}
|
|
59824
60141
|
}
|
|
59825
60142
|
return root;
|
|
59826
60143
|
}
|
|
59827
|
-
function
|
|
60144
|
+
function runHarnessInstall3(harnessId, components, opts, agentName) {
|
|
59828
60145
|
if (harnessId === "claude-code")
|
|
59829
60146
|
return installClaudeCodeWithCtx(components, opts, agentName);
|
|
59830
60147
|
if (harnessId === "codex")
|
|
@@ -59848,9 +60165,9 @@ function materializeInstructions(cwd2, cloud, toInstall, keepLocal, existingMani
|
|
|
59848
60165
|
if (existingManifest?.instructions?.text !== undefined)
|
|
59849
60166
|
continue;
|
|
59850
60167
|
const targetRel = existingManifest?.instructions?.file ?? DEFAULT_INSTRUCTIONS_FILE;
|
|
59851
|
-
const target =
|
|
59852
|
-
ensureDir(
|
|
59853
|
-
|
|
60168
|
+
const target = path49.resolve(cwd2, targetRel);
|
|
60169
|
+
ensureDir(path49.dirname(target));
|
|
60170
|
+
fs46.writeFileSync(target, normalizeInstructionBody(body), "utf8");
|
|
59854
60171
|
}
|
|
59855
60172
|
}
|
|
59856
60173
|
function materializePlaybooks(cwd2, cloud, toInstall, keepLocal, existingManifest) {
|
|
@@ -59869,10 +60186,10 @@ function materializePlaybooks(cwd2, cloud, toInstall, keepLocal, existingManifes
|
|
|
59869
60186
|
const existing = existingManifest?.playbooks?.find((p2) => slugifyPlaybookTitle(p2.title) === c2.slug);
|
|
59870
60187
|
if (existing?.content?.text !== undefined)
|
|
59871
60188
|
continue;
|
|
59872
|
-
const targetRel = existing?.content?.file ??
|
|
59873
|
-
const target =
|
|
59874
|
-
ensureDir(
|
|
59875
|
-
|
|
60189
|
+
const targetRel = existing?.content?.file ?? path49.join(DEFAULT_PLAYBOOKS_DIR, `${c2.slug}.md`);
|
|
60190
|
+
const target = path49.resolve(cwd2, targetRel);
|
|
60191
|
+
ensureDir(path49.dirname(target));
|
|
60192
|
+
fs46.writeFileSync(target, body, "utf8");
|
|
59876
60193
|
}
|
|
59877
60194
|
}
|
|
59878
60195
|
function mergeManifest(cwd2, prev, cloud, cloudAgent, harness) {
|
|
@@ -59910,7 +60227,7 @@ function mergeManifest(cwd2, prev, cloud, cloudAgent, harness) {
|
|
|
59910
60227
|
const title = local?.title ?? (typeof frontmatter.title === "string" && frontmatter.title || c2.slug);
|
|
59911
60228
|
const description = local?.description ?? (typeof frontmatter.description === "string" ? frontmatter.description : undefined);
|
|
59912
60229
|
const content = local?.content?.text !== undefined ? { text: local.content.text } : {
|
|
59913
|
-
file: local?.content?.file ??
|
|
60230
|
+
file: local?.content?.file ?? path49.join(DEFAULT_PLAYBOOKS_DIR, `${c2.slug}.md`)
|
|
59914
60231
|
};
|
|
59915
60232
|
const pbMeta = c2.meta ?? {};
|
|
59916
60233
|
return {
|
|
@@ -59952,6 +60269,7 @@ function mergeManifest(cwd2, prev, cloud, cloudAgent, harness) {
|
|
|
59952
60269
|
playbooks,
|
|
59953
60270
|
skills,
|
|
59954
60271
|
mcp,
|
|
60272
|
+
evals: prev?.evals ?? [],
|
|
59955
60273
|
capabilities: {
|
|
59956
60274
|
memory: caps.memory,
|
|
59957
60275
|
browser: caps.browser,
|
|
@@ -59968,10 +60286,10 @@ function materializeEntrypoint(cwd2, cloudEntrypoint, prev) {
|
|
|
59968
60286
|
if (prev?.entrypoint?.text !== undefined)
|
|
59969
60287
|
return;
|
|
59970
60288
|
const filename = prev?.entrypoint?.file ?? DEFAULT_ENTRYPOINT_FILE;
|
|
59971
|
-
const target =
|
|
59972
|
-
|
|
60289
|
+
const target = path49.resolve(cwd2, filename);
|
|
60290
|
+
fs46.writeFileSync(target, cloudEntrypoint, "utf8");
|
|
59973
60291
|
try {
|
|
59974
|
-
|
|
60292
|
+
fs46.chmodSync(target, 493);
|
|
59975
60293
|
} catch {}
|
|
59976
60294
|
}
|
|
59977
60295
|
function buildLockComponents(input) {
|
|
@@ -60044,22 +60362,22 @@ async function runEntrypointIfPresent(cwd2, manifest, execute) {
|
|
|
60044
60362
|
const body = resolveEntrypoint(cwd2, manifest);
|
|
60045
60363
|
if (body === null || !body.trim())
|
|
60046
60364
|
return;
|
|
60047
|
-
const stateDir =
|
|
60365
|
+
const stateDir = path49.join(cwd2, LINK_DIR);
|
|
60048
60366
|
ensureDir(stateDir);
|
|
60049
|
-
const scriptPath =
|
|
60050
|
-
const logPath =
|
|
60051
|
-
|
|
60367
|
+
const scriptPath = path49.join(stateDir, "entrypoint.sh");
|
|
60368
|
+
const logPath = path49.join(stateDir, "entrypoint.log");
|
|
60369
|
+
fs46.writeFileSync(scriptPath, body, "utf8");
|
|
60052
60370
|
try {
|
|
60053
|
-
|
|
60371
|
+
fs46.chmodSync(scriptPath, 493);
|
|
60054
60372
|
} catch {}
|
|
60055
60373
|
if (!execute) {
|
|
60056
|
-
f2.info(`Agent has an entrypoint — written to ${
|
|
60374
|
+
f2.info(`Agent has an entrypoint — written to ${import_picocolors26.default.dim(path49.relative(cwd2, scriptPath))}, not executed. ` + `Run it with ${import_picocolors26.default.cyan("brainbase run bash .brainbase/entrypoint.sh")} or re-pull with ${import_picocolors26.default.cyan("--run-entrypoint")}. Sandboxes run it automatically.`);
|
|
60057
60375
|
return;
|
|
60058
60376
|
}
|
|
60059
|
-
f2.info(`Running entrypoint ${
|
|
60377
|
+
f2.info(`Running entrypoint ${import_picocolors26.default.dim(`(${path49.relative(cwd2, scriptPath)})`)}`);
|
|
60060
60378
|
const secrets = readLocalSecrets(cwd2);
|
|
60061
60379
|
const env3 = { ...process.env, ...secrets };
|
|
60062
|
-
const logStream =
|
|
60380
|
+
const logStream = fs46.createWriteStream(logPath, { flags: "w" });
|
|
60063
60381
|
const exitCode = await new Promise((resolve) => {
|
|
60064
60382
|
const child = spawn2("bash", [scriptPath], {
|
|
60065
60383
|
cwd: cwd2,
|
|
@@ -60084,7 +60402,7 @@ async function runEntrypointIfPresent(cwd2, manifest, execute) {
|
|
|
60084
60402
|
if (exitCode === 0) {
|
|
60085
60403
|
f2.info("Entrypoint completed.");
|
|
60086
60404
|
} else if (exitCode === null) {} else {
|
|
60087
|
-
f2.warn(`Entrypoint exited ${exitCode} — continuing. Log at ${
|
|
60405
|
+
f2.warn(`Entrypoint exited ${exitCode} — continuing. Log at ${import_picocolors26.default.dim(path49.relative(cwd2, logPath))}.`);
|
|
60088
60406
|
}
|
|
60089
60407
|
}
|
|
60090
60408
|
async function pullSecrets(cwd2, agentId) {
|
|
@@ -60106,10 +60424,10 @@ async function pullSecrets(cwd2, agentId) {
|
|
|
60106
60424
|
const diff2 = diffSecrets(localSecrets, cloudSecrets);
|
|
60107
60425
|
if (diff2.localOnly.length > 0 || diff2.changed.length > 0) {
|
|
60108
60426
|
if (diff2.localOnly.length) {
|
|
60109
|
-
f2.warn(`Local secrets not on cloud: ${diff2.localOnly.join(", ")}. ${
|
|
60427
|
+
f2.warn(`Local secrets not on cloud: ${diff2.localOnly.join(", ")}. ${import_picocolors26.default.dim("They will be kept locally; run `agent push` to upload.")}`);
|
|
60110
60428
|
}
|
|
60111
60429
|
if (diff2.changed.length) {
|
|
60112
|
-
f2.warn(`Local values differ from cloud for: ${diff2.changed.join(", ")}. ${
|
|
60430
|
+
f2.warn(`Local values differ from cloud for: ${diff2.changed.join(", ")}. ${import_picocolors26.default.dim("Local wins on pull; run `agent push` to overwrite cloud.")}`);
|
|
60113
60431
|
}
|
|
60114
60432
|
}
|
|
60115
60433
|
const merged = { ...cloudSecrets, ...localSecrets };
|
|
@@ -60130,21 +60448,21 @@ function handleApiError2(err) {
|
|
|
60130
60448
|
}
|
|
60131
60449
|
|
|
60132
60450
|
// src/cli/agent-push.ts
|
|
60133
|
-
var
|
|
60451
|
+
var import_picocolors28 = __toESM(require_picocolors(), 1);
|
|
60134
60452
|
|
|
60135
60453
|
// src/core/agent-outgoing.ts
|
|
60136
|
-
var
|
|
60454
|
+
var import_picocolors27 = __toESM(require_picocolors(), 1);
|
|
60137
60455
|
async function buildOutgoingComponents(cwd2, manifest, cloud, resolvedVersions) {
|
|
60138
60456
|
const out = [];
|
|
60139
60457
|
if (manifest.instructions) {
|
|
60140
60458
|
if (manifest.instructions.text !== undefined && manifest.instructions.file !== undefined) {
|
|
60141
|
-
f2.error(`instructions block sets both ${
|
|
60459
|
+
f2.error(`instructions block sets both ${import_picocolors27.default.cyan("text")} and ${import_picocolors27.default.cyan("file")} — pick one.`);
|
|
60142
60460
|
return null;
|
|
60143
60461
|
}
|
|
60144
60462
|
const body = readInstructions(cwd2, manifest);
|
|
60145
60463
|
if (body === null) {
|
|
60146
60464
|
if (manifest.instructions.file) {
|
|
60147
|
-
f2.error(`Instructions file ${
|
|
60465
|
+
f2.error(`Instructions file ${import_picocolors27.default.bold(manifest.instructions.file)} not found.`);
|
|
60148
60466
|
} else {
|
|
60149
60467
|
f2.error("Instructions block is empty.");
|
|
60150
60468
|
}
|
|
@@ -60177,7 +60495,7 @@ async function buildOutgoingComponents(cwd2, manifest, cloud, resolvedVersions)
|
|
|
60177
60495
|
continue;
|
|
60178
60496
|
}
|
|
60179
60497
|
if (parsed.kind === "local") {
|
|
60180
|
-
f2.error(`Skill ${
|
|
60498
|
+
f2.error(`Skill ${import_picocolors27.default.bold(entry.source)} is a local-authored skill. Local skill push isn't supported yet — publish it to the registry first (\`brainbase skill publish\`).`);
|
|
60181
60499
|
return null;
|
|
60182
60500
|
}
|
|
60183
60501
|
const slug = registrySkillComponentSlug(parsed);
|
|
@@ -60200,15 +60518,15 @@ async function buildOutgoingComponents(cwd2, manifest, cloud, resolvedVersions)
|
|
|
60200
60518
|
const entry = playbookEntries[i];
|
|
60201
60519
|
const slug = playbookSlugs[i];
|
|
60202
60520
|
if (entry.content.text !== undefined && entry.content.file !== undefined) {
|
|
60203
|
-
f2.error(`Playbook ${
|
|
60521
|
+
f2.error(`Playbook ${import_picocolors27.default.bold(entry.title)} sets both ${import_picocolors27.default.cyan("text")} and ${import_picocolors27.default.cyan("file")} — pick one.`);
|
|
60204
60522
|
return null;
|
|
60205
60523
|
}
|
|
60206
60524
|
const body = resolvePlaybookContent(cwd2, entry);
|
|
60207
60525
|
if (body === null) {
|
|
60208
60526
|
if (entry.content.file) {
|
|
60209
|
-
f2.error(`Playbook ${
|
|
60527
|
+
f2.error(`Playbook ${import_picocolors27.default.bold(entry.title)} content file ${import_picocolors27.default.bold(entry.content.file)} not found.`);
|
|
60210
60528
|
} else {
|
|
60211
|
-
f2.error(`Playbook ${
|
|
60529
|
+
f2.error(`Playbook ${import_picocolors27.default.bold(entry.title)} content is empty.`);
|
|
60212
60530
|
}
|
|
60213
60531
|
return null;
|
|
60214
60532
|
}
|
|
@@ -60236,7 +60554,7 @@ async function buildOutgoingComponents(cwd2, manifest, cloud, resolvedVersions)
|
|
|
60236
60554
|
}
|
|
60237
60555
|
for (const entry of manifest.mcp ?? []) {
|
|
60238
60556
|
if (!entry.url && !entry.command) {
|
|
60239
|
-
f2.error(`MCP ${
|
|
60557
|
+
f2.error(`MCP ${import_picocolors27.default.bold(entry.name)} needs either ${import_picocolors27.default.cyan("url")} or ${import_picocolors27.default.cyan("command")}.`);
|
|
60240
60558
|
return null;
|
|
60241
60559
|
}
|
|
60242
60560
|
const payload = {};
|
|
@@ -60322,8 +60640,8 @@ function planRegistrySkillUpdates(skills, cloudComponents, latestByName) {
|
|
|
60322
60640
|
async function runAgentPush(cwd2, args) {
|
|
60323
60641
|
banner("agent push — send your local changes to the cloud");
|
|
60324
60642
|
if (!hasManifest(cwd2)) {
|
|
60325
|
-
f2.warn(`No ${
|
|
60326
|
-
f2.info(`Run ${
|
|
60643
|
+
f2.warn(`No ${import_picocolors28.default.bold(AGENT_MANIFEST_FILE)} here.`);
|
|
60644
|
+
f2.info(`Run ${import_picocolors28.default.cyan("brainbase agent create")} to claim a new agent from a manifest, ` + `or ${import_picocolors28.default.cyan("brainbase agent pull <id>")} to pull an existing one.`);
|
|
60327
60645
|
return;
|
|
60328
60646
|
}
|
|
60329
60647
|
let manifest;
|
|
@@ -60334,8 +60652,8 @@ async function runAgentPush(cwd2, args) {
|
|
|
60334
60652
|
return;
|
|
60335
60653
|
}
|
|
60336
60654
|
if (!manifest.id) {
|
|
60337
|
-
f2.warn(`${
|
|
60338
|
-
f2.info(`Run ${
|
|
60655
|
+
f2.warn(`${import_picocolors28.default.bold(AGENT_MANIFEST_FILE)} is unclaimed (no ${import_picocolors28.default.cyan("id")}). Nothing to push to.`);
|
|
60656
|
+
f2.info(`Run ${import_picocolors28.default.cyan("brainbase agent create")} first — that creates the cloud agent and stamps an id here.`);
|
|
60339
60657
|
return;
|
|
60340
60658
|
}
|
|
60341
60659
|
const agentId = manifest.id;
|
|
@@ -60396,13 +60714,13 @@ async function runAgentPush(cwd2, args) {
|
|
|
60396
60714
|
});
|
|
60397
60715
|
if (unresolvable.length > 0) {
|
|
60398
60716
|
for (const name of unresolvable) {
|
|
60399
|
-
f2.error(`Skill ${
|
|
60717
|
+
f2.error(`Skill ${import_picocolors28.default.bold(name)} isn't in the registry (not published, or private to another owner).`);
|
|
60400
60718
|
}
|
|
60401
60719
|
const noun = unresolvable.length === 1 ? "it" : "each one";
|
|
60402
60720
|
f2.info(`Publish ${noun} first, then push again:`);
|
|
60403
60721
|
for (const name of unresolvable) {
|
|
60404
60722
|
const version = registryRefs.get(name)?.version ?? "0.1.0";
|
|
60405
|
-
f2.info(` ${
|
|
60723
|
+
f2.info(` ${import_picocolors28.default.cyan(`brainbase skill publish ./path/to/skill --name ${name} --skill-version ${version} --yes`)}`);
|
|
60406
60724
|
}
|
|
60407
60725
|
return;
|
|
60408
60726
|
}
|
|
@@ -60427,7 +60745,7 @@ async function runAgentPush(cwd2, args) {
|
|
|
60427
60745
|
const body = resolveEntrypoint(cwd2, manifest);
|
|
60428
60746
|
if (body === null) {
|
|
60429
60747
|
if (manifest.entrypoint.file) {
|
|
60430
|
-
f2.error(`Entrypoint file ${
|
|
60748
|
+
f2.error(`Entrypoint file ${import_picocolors28.default.bold(manifest.entrypoint.file)} not found.`);
|
|
60431
60749
|
} else {
|
|
60432
60750
|
f2.error("Entrypoint block is empty.");
|
|
60433
60751
|
}
|
|
@@ -60442,7 +60760,7 @@ async function runAgentPush(cwd2, args) {
|
|
|
60442
60760
|
const entrypointChanged = resolvedEntrypoint !== undefined && (resolvedEntrypoint ?? "").trim() !== (lock?.agentMeta?.entrypoint ?? "").trim();
|
|
60443
60761
|
for (const r2 of rows) {
|
|
60444
60762
|
if (r2.type !== "instruction" && r2.type !== "skill" && r2.type !== "mcp" && r2.type !== "playbook") {
|
|
60445
|
-
f2.error(`Component ${fmtType(r2.type)} ${
|
|
60763
|
+
f2.error(`Component ${fmtType(r2.type)} ${import_picocolors28.default.bold(r2.slug)} can't be pushed yet — the server accepts instructions, skills, and mcps in this version.`);
|
|
60446
60764
|
return;
|
|
60447
60765
|
}
|
|
60448
60766
|
}
|
|
@@ -60454,7 +60772,7 @@ async function runAgentPush(cwd2, args) {
|
|
|
60454
60772
|
continue;
|
|
60455
60773
|
}
|
|
60456
60774
|
if (parsed.kind === "local") {
|
|
60457
|
-
f2.error(`Skill ${
|
|
60775
|
+
f2.error(`Skill ${import_picocolors28.default.bold(entry.source)} is a local-authored skill. Local skill push isn't supported yet — publish it to the registry first (\`brainbase skill publish\`).`);
|
|
60458
60776
|
return;
|
|
60459
60777
|
}
|
|
60460
60778
|
}
|
|
@@ -60466,7 +60784,7 @@ async function runAgentPush(cwd2, args) {
|
|
|
60466
60784
|
return typeof id === "string" && id && !localPlaybooks.some((p2) => p2.id === id) && idlessLocalSlugs.has(c2.slug);
|
|
60467
60785
|
}).map((c2) => c2.slug);
|
|
60468
60786
|
if (preIdSchemaSlugs.length > 0) {
|
|
60469
|
-
f2.error(`Playbook ${preIdSchemaSlugs.length === 1 ? "entry" : "entries"} ${preIdSchemaSlugs.map((s3) =>
|
|
60787
|
+
f2.error(`Playbook ${preIdSchemaSlugs.length === 1 ? "entry" : "entries"} ${preIdSchemaSlugs.map((s3) => import_picocolors28.default.bold(s3)).join(", ")} in ${import_picocolors28.default.bold("brainbase.agent.yaml")} ${preIdSchemaSlugs.length === 1 ? "is" : "are"} missing ${import_picocolors28.default.cyan("id:")}. Run ${import_picocolors28.default.bold("brainbase agent pull")} first to sync playbook ids, then push.`);
|
|
60470
60788
|
return;
|
|
60471
60789
|
}
|
|
60472
60790
|
const { toSend, conflicts, upstreamOnly } = partitionPushRows(rows, !!args.force);
|
|
@@ -60478,21 +60796,21 @@ async function runAgentPush(cwd2, args) {
|
|
|
60478
60796
|
if (conflicts.length > 0) {
|
|
60479
60797
|
f2.error(`Cannot push: ${conflicts.length} component${conflicts.length === 1 ? "" : "s"} changed both locally and on the cloud:`);
|
|
60480
60798
|
for (const r2 of conflicts) {
|
|
60481
|
-
console.error(` ${
|
|
60799
|
+
console.error(` ${import_picocolors28.default.red("!")} ${fmtType(r2.type)} ${import_picocolors28.default.bold(r2.slug)}`);
|
|
60482
60800
|
}
|
|
60483
|
-
f2.info(`Run ${
|
|
60801
|
+
f2.info(`Run ${import_picocolors28.default.cyan("brainbase agent pull")} first to reconcile, then push again — or ${import_picocolors28.default.cyan("brainbase agent push --force")} to overwrite the cloud with your local version.`);
|
|
60484
60802
|
return;
|
|
60485
60803
|
}
|
|
60486
60804
|
if (forcedOverrides.length > 0) {
|
|
60487
|
-
f2.warn(`${
|
|
60805
|
+
f2.warn(`${import_picocolors28.default.yellow("--force")}: overwriting ${forcedOverrides.length} cloud change${forcedOverrides.length === 1 ? "" : "s"} with your local version (cloud edits discarded):`);
|
|
60488
60806
|
for (const r2 of forcedOverrides) {
|
|
60489
|
-
console.warn(` ${
|
|
60807
|
+
console.warn(` ${import_picocolors28.default.yellow("⤒")} ${fmtType(r2.type)} ${import_picocolors28.default.bold(r2.slug)}`);
|
|
60490
60808
|
}
|
|
60491
60809
|
}
|
|
60492
60810
|
if (upstreamOnly.length > 0 && !args.yes) {
|
|
60493
60811
|
f2.warn(`Cloud has ${upstreamOnly.length} change${upstreamOnly.length === 1 ? "" : "s"} you don't have locally:`);
|
|
60494
60812
|
for (const r2 of upstreamOnly) {
|
|
60495
|
-
console.warn(` ${
|
|
60813
|
+
console.warn(` ${import_picocolors28.default.cyan("←")} ${fmtType(r2.type)} ${import_picocolors28.default.bold(r2.slug)} ${import_picocolors28.default.dim(`(${r2.status})`)}`);
|
|
60496
60814
|
}
|
|
60497
60815
|
f2.info(`If you push now, your push targets revision ${cloud.revision} and may race. Consider \`brainbase agent pull\` first.`);
|
|
60498
60816
|
}
|
|
@@ -60501,9 +60819,9 @@ async function runAgentPush(cwd2, args) {
|
|
|
60501
60819
|
if (!sendKeys.has(compKey("skill", u2.componentSlug)))
|
|
60502
60820
|
continue;
|
|
60503
60821
|
if (u2.direction === "downgrade") {
|
|
60504
|
-
f2.warn(`Skill ${
|
|
60822
|
+
f2.warn(`Skill ${import_picocolors28.default.bold(u2.name)}: registry latest is ${import_picocolors28.default.bold(u2.latest)}, below the agent's ${import_picocolors28.default.dim(u2.current)} — the agent's version was likely yanked. Converging on latest.`);
|
|
60505
60823
|
} else {
|
|
60506
|
-
f2.info(`Skill ${
|
|
60824
|
+
f2.info(`Skill ${import_picocolors28.default.bold(u2.name)} → ${import_picocolors28.default.bold(u2.latest)} (registry latest${u2.current ? `, agent has ${u2.current}` : ""}).`);
|
|
60507
60825
|
}
|
|
60508
60826
|
}
|
|
60509
60827
|
const resultRows = [];
|
|
@@ -60577,7 +60895,7 @@ async function runAgentPush(cwd2, args) {
|
|
|
60577
60895
|
pushSpinner.stop("Failed.");
|
|
60578
60896
|
if (err instanceof ApiError && err.status === 409) {
|
|
60579
60897
|
f2.error(err.message);
|
|
60580
|
-
f2.info(`Run ${
|
|
60898
|
+
f2.info(`Run ${import_picocolors28.default.cyan("brainbase agent pull")} and try again.`);
|
|
60581
60899
|
return;
|
|
60582
60900
|
}
|
|
60583
60901
|
return handleApiError3(err);
|
|
@@ -60614,7 +60932,7 @@ async function runAgentPush(cwd2, args) {
|
|
|
60614
60932
|
return false;
|
|
60615
60933
|
}
|
|
60616
60934
|
})?.source;
|
|
60617
|
-
const prior = lock?.components.find((
|
|
60935
|
+
const prior = lock?.components.find((pc27) => pc27.type === c2.type && pc27.slug === c2.slug);
|
|
60618
60936
|
const localHash = localHashByKey.get(`${c2.type}/${c2.slug}`);
|
|
60619
60937
|
return {
|
|
60620
60938
|
type: c2.type,
|
|
@@ -60673,13 +60991,13 @@ function handleApiError3(err) {
|
|
|
60673
60991
|
}
|
|
60674
60992
|
|
|
60675
60993
|
// src/cli/agent-status.ts
|
|
60676
|
-
var
|
|
60994
|
+
var import_picocolors29 = __toESM(require_picocolors(), 1);
|
|
60677
60995
|
async function runAgentStatus(cwd2) {
|
|
60678
60996
|
banner("agent status — what changed locally, remotely, both");
|
|
60679
60997
|
const link2 = readLink(cwd2);
|
|
60680
60998
|
if (!link2) {
|
|
60681
60999
|
f2.warn("This folder is not linked to any agent.");
|
|
60682
|
-
f2.info(`Run ${
|
|
61000
|
+
f2.info(`Run ${import_picocolors29.default.cyan("brainbase link")} first.`);
|
|
60683
61001
|
return;
|
|
60684
61002
|
}
|
|
60685
61003
|
const manifest = hasManifest(cwd2) ? readManifest(cwd2) : null;
|
|
@@ -60700,8 +61018,8 @@ async function runAgentStatus(cwd2) {
|
|
|
60700
61018
|
return;
|
|
60701
61019
|
}
|
|
60702
61020
|
if (!manifest) {
|
|
60703
|
-
f2.info(`${
|
|
60704
|
-
f2.info(`Cloud has ${
|
|
61021
|
+
f2.info(`${import_picocolors29.default.dim("No")} ${import_picocolors29.default.bold("brainbase.agent.yaml")} ${import_picocolors29.default.dim("here yet.")} Run ${import_picocolors29.default.cyan("brainbase agent pull")} to populate this folder.`);
|
|
61022
|
+
f2.info(`Cloud has ${import_picocolors29.default.bold(String(cloud.components.length))} component${cloud.components.length === 1 ? "" : "s"} at revision ${cloud.revision}.`);
|
|
60705
61023
|
return;
|
|
60706
61024
|
}
|
|
60707
61025
|
const localComponents = readLocalComponents(cwd2, manifest);
|
|
@@ -60740,17 +61058,17 @@ async function runAgentStatus(cwd2) {
|
|
|
60740
61058
|
}
|
|
60741
61059
|
const lines = [];
|
|
60742
61060
|
lines.push("");
|
|
60743
|
-
lines.push(` ${
|
|
60744
|
-
lines.push(` ${
|
|
60745
|
-
lines.push(` ${
|
|
61061
|
+
lines.push(` ${import_picocolors29.default.bold(link2.name)} ${import_picocolors29.default.dim(`(${link2.slug})`)}`);
|
|
61062
|
+
lines.push(` ${import_picocolors29.default.dim("agent_id")} ${link2.agent_id}`);
|
|
61063
|
+
lines.push(` ${import_picocolors29.default.dim("revision")} cloud ${cloud.revision}${lock ? ` · lock ${lock.revision}` : " · never pulled"}`);
|
|
60746
61064
|
lines.push("");
|
|
60747
61065
|
if (meta.localChanged || meta.cloudChanged) {
|
|
60748
|
-
lines.push(` ${
|
|
61066
|
+
lines.push(` ${import_picocolors29.default.bold("agent metadata")}`);
|
|
60749
61067
|
if (meta.localChanged) {
|
|
60750
|
-
lines.push(` ${
|
|
61068
|
+
lines.push(` ${import_picocolors29.default.yellow("→ push")} name/tagline edited in brainbase.agent.yaml`);
|
|
60751
61069
|
}
|
|
60752
61070
|
if (meta.cloudChanged) {
|
|
60753
|
-
lines.push(` ${
|
|
61071
|
+
lines.push(` ${import_picocolors29.default.cyan("← pull")} name/tagline changed on cloud`);
|
|
60754
61072
|
}
|
|
60755
61073
|
lines.push("");
|
|
60756
61074
|
}
|
|
@@ -60760,65 +61078,65 @@ async function runAgentStatus(cwd2) {
|
|
|
60760
61078
|
const cloudSecrets = cloudRes.secrets ?? {};
|
|
60761
61079
|
const sd = diffSecrets(localSecrets, cloudSecrets);
|
|
60762
61080
|
if (sd.localOnly.length || sd.cloudOnly.length || sd.changed.length) {
|
|
60763
|
-
lines.push(` ${
|
|
61081
|
+
lines.push(` ${import_picocolors29.default.bold("secrets")}`);
|
|
60764
61082
|
if (sd.localOnly.length)
|
|
60765
|
-
lines.push(` ${
|
|
61083
|
+
lines.push(` ${import_picocolors29.default.yellow("→ push")} new locally: ${sd.localOnly.join(", ")}`);
|
|
60766
61084
|
if (sd.changed.length)
|
|
60767
|
-
lines.push(` ${
|
|
61085
|
+
lines.push(` ${import_picocolors29.default.yellow("→ push")} values changed: ${sd.changed.join(", ")}`);
|
|
60768
61086
|
if (sd.cloudOnly.length)
|
|
60769
|
-
lines.push(` ${
|
|
61087
|
+
lines.push(` ${import_picocolors29.default.cyan("← pull")} new on cloud: ${sd.cloudOnly.join(", ")}`);
|
|
60770
61088
|
lines.push("");
|
|
60771
61089
|
}
|
|
60772
61090
|
} catch {}
|
|
60773
61091
|
if (conflicts.length === 0 && toPush.length === 0 && toPull.length === 0) {
|
|
60774
|
-
lines.push(` ${
|
|
61092
|
+
lines.push(` ${import_picocolors29.default.green("✓")} everything is in sync`);
|
|
60775
61093
|
lines.push("");
|
|
60776
61094
|
console.log(lines.join(`
|
|
60777
61095
|
`));
|
|
60778
61096
|
return;
|
|
60779
61097
|
}
|
|
60780
61098
|
if (toPush.length) {
|
|
60781
|
-
lines.push(` ${
|
|
61099
|
+
lines.push(` ${import_picocolors29.default.bold("changes to push")} ${import_picocolors29.default.dim(`(${toPush.length})`)}`);
|
|
60782
61100
|
for (const r2 of toPush)
|
|
60783
|
-
lines.push(` ${
|
|
61101
|
+
lines.push(` ${import_picocolors29.default.yellow("→")} ${fmtRow(r2)}`);
|
|
60784
61102
|
lines.push("");
|
|
60785
61103
|
}
|
|
60786
61104
|
if (toPull.length) {
|
|
60787
|
-
lines.push(` ${
|
|
61105
|
+
lines.push(` ${import_picocolors29.default.bold("changes to pull")} ${import_picocolors29.default.dim(`(${toPull.length})`)}`);
|
|
60788
61106
|
for (const r2 of toPull)
|
|
60789
|
-
lines.push(` ${
|
|
61107
|
+
lines.push(` ${import_picocolors29.default.cyan("←")} ${fmtRow(r2)}`);
|
|
60790
61108
|
lines.push("");
|
|
60791
61109
|
}
|
|
60792
61110
|
if (conflicts.length) {
|
|
60793
|
-
lines.push(` ${
|
|
61111
|
+
lines.push(` ${import_picocolors29.default.bold(import_picocolors29.default.red("conflicts"))} ${import_picocolors29.default.dim(`(${conflicts.length})`)}`);
|
|
60794
61112
|
for (const r2 of conflicts)
|
|
60795
|
-
lines.push(` ${
|
|
61113
|
+
lines.push(` ${import_picocolors29.default.red("!")} ${fmtRow(r2)}`);
|
|
60796
61114
|
lines.push("");
|
|
60797
61115
|
}
|
|
60798
|
-
lines.push(` ${
|
|
61116
|
+
lines.push(` ${import_picocolors29.default.dim("run")} ${import_picocolors29.default.cyan("brainbase agent pull")} ${import_picocolors29.default.dim("to apply cloud changes,")} ${import_picocolors29.default.cyan("brainbase agent push")} ${import_picocolors29.default.dim("to send yours")}`);
|
|
60799
61117
|
lines.push("");
|
|
60800
61118
|
console.log(lines.join(`
|
|
60801
61119
|
`));
|
|
60802
61120
|
}
|
|
60803
61121
|
function fmtRow(r2) {
|
|
60804
|
-
const head3 = `${fmtType(r2.type)} ${
|
|
61122
|
+
const head3 = `${fmtType(r2.type)} ${import_picocolors29.default.bold(r2.slug)}`;
|
|
60805
61123
|
switch (r2.status) {
|
|
60806
61124
|
case "added-only-local":
|
|
60807
|
-
return `${head3} ${
|
|
61125
|
+
return `${head3} ${import_picocolors29.default.dim("(new — only in brainbase.agent.yaml)")}`;
|
|
60808
61126
|
case "added-cloud":
|
|
60809
|
-
return `${head3} ${
|
|
61127
|
+
return `${head3} ${import_picocolors29.default.dim("(new on cloud)")}`;
|
|
60810
61128
|
case "added-local":
|
|
60811
|
-
return `${head3} ${
|
|
61129
|
+
return `${head3} ${import_picocolors29.default.dim("(present locally and on cloud, never synced here)")}`;
|
|
60812
61130
|
case "removed-local":
|
|
60813
|
-
return `${head3} ${
|
|
61131
|
+
return `${head3} ${import_picocolors29.default.dim("(removed from brainbase.agent.yaml)")}`;
|
|
60814
61132
|
case "removed-cloud":
|
|
60815
|
-
return `${head3} ${
|
|
61133
|
+
return `${head3} ${import_picocolors29.default.dim("(removed on cloud)")}`;
|
|
60816
61134
|
case "modified-local":
|
|
60817
|
-
return `${head3} ${
|
|
61135
|
+
return `${head3} ${import_picocolors29.default.dim("(you edited it)")}`;
|
|
60818
61136
|
case "modified-cloud":
|
|
60819
|
-
return `${head3} ${
|
|
61137
|
+
return `${head3} ${import_picocolors29.default.dim("(cloud was updated)")}`;
|
|
60820
61138
|
case "modified-both":
|
|
60821
|
-
return `${head3} ${
|
|
61139
|
+
return `${head3} ${import_picocolors29.default.dim("(both diverged — needs resolution)")}`;
|
|
60822
61140
|
default:
|
|
60823
61141
|
return head3;
|
|
60824
61142
|
}
|
|
@@ -60855,11 +61173,11 @@ function formatExport(shell, key2, value) {
|
|
|
60855
61173
|
}
|
|
60856
61174
|
|
|
60857
61175
|
// src/cli/agent-create.ts
|
|
60858
|
-
import
|
|
60859
|
-
var
|
|
61176
|
+
import path50 from "node:path";
|
|
61177
|
+
var import_picocolors31 = __toESM(require_picocolors(), 1);
|
|
60860
61178
|
|
|
60861
61179
|
// src/ui/box.ts
|
|
60862
|
-
var
|
|
61180
|
+
var import_picocolors30 = __toESM(require_picocolors(), 1);
|
|
60863
61181
|
var H3 = "─";
|
|
60864
61182
|
var TINT = {
|
|
60865
61183
|
ok: COLOR.ok,
|
|
@@ -60871,15 +61189,15 @@ var TINT = {
|
|
|
60871
61189
|
function divider(label, width = 56, indent = 2) {
|
|
60872
61190
|
const ind = " ".repeat(indent);
|
|
60873
61191
|
if (!label)
|
|
60874
|
-
return `${ind}${
|
|
61192
|
+
return `${ind}${import_picocolors30.default.dim(H3.repeat(width))}`;
|
|
60875
61193
|
const labelText = ` ${label} `;
|
|
60876
61194
|
const labelLen = visibleLength(labelText);
|
|
60877
|
-
const left =
|
|
60878
|
-
const right =
|
|
60879
|
-
return `${ind}${left}${
|
|
61195
|
+
const left = import_picocolors30.default.dim(H3.repeat(2));
|
|
61196
|
+
const right = import_picocolors30.default.dim(H3.repeat(Math.max(0, width - labelLen - 2)));
|
|
61197
|
+
return `${ind}${left}${import_picocolors30.default.bold(import_picocolors30.default.dim(labelText))}${right}`;
|
|
60880
61198
|
}
|
|
60881
61199
|
function tip(text2, indent = 2) {
|
|
60882
|
-
return " ".repeat(indent) +
|
|
61200
|
+
return " ".repeat(indent) + import_picocolors30.default.dim("›") + " " + import_picocolors30.default.dim(text2);
|
|
60883
61201
|
}
|
|
60884
61202
|
|
|
60885
61203
|
// src/cli/agent-create.ts
|
|
@@ -60889,8 +61207,8 @@ async function runAgentCreate(cwd2, args) {
|
|
|
60889
61207
|
if (!manifest)
|
|
60890
61208
|
return;
|
|
60891
61209
|
if (manifest.id) {
|
|
60892
|
-
f2.warn(`This folder already belongs to an agent — ${
|
|
60893
|
-
f2.info(`If you want to detach it, run ${
|
|
61210
|
+
f2.warn(`This folder already belongs to an agent — ${import_picocolors31.default.bold(manifest.agent.name)} (${import_picocolors31.default.dim(manifest.id)}).`);
|
|
61211
|
+
f2.info(`If you want to detach it, run ${import_picocolors31.default.cyan("brainbase unlink")} first; or move to a different directory.`);
|
|
60894
61212
|
return;
|
|
60895
61213
|
}
|
|
60896
61214
|
const orgsSpinner = de();
|
|
@@ -60919,7 +61237,7 @@ async function runAgentCreate(cwd2, args) {
|
|
|
60919
61237
|
org = found;
|
|
60920
61238
|
} else if (orgs.length === 1) {
|
|
60921
61239
|
org = orgs[0];
|
|
60922
|
-
f2.info(`Using organization ${
|
|
61240
|
+
f2.info(`Using organization ${import_picocolors31.default.bold(org.name)}.`);
|
|
60923
61241
|
} else {
|
|
60924
61242
|
const orgId = await select({
|
|
60925
61243
|
message: "Pick an organization",
|
|
@@ -60950,7 +61268,7 @@ async function runAgentCreate(cwd2, args) {
|
|
|
60950
61268
|
} else if (!isInteractive()) {
|
|
60951
61269
|
if (teams.length === 1) {
|
|
60952
61270
|
team = teams[0];
|
|
60953
|
-
f2.info(`Using team ${
|
|
61271
|
+
f2.info(`Using team ${import_picocolors31.default.bold(team.name)}.`);
|
|
60954
61272
|
} else if (teams.length === 0) {
|
|
60955
61273
|
throw new NonInteractiveError(`No teams in ${org.name} yet — create one in the web app, then re-run.`);
|
|
60956
61274
|
} else {
|
|
@@ -60976,7 +61294,7 @@ async function runAgentCreate(cwd2, args) {
|
|
|
60976
61294
|
createSpinner2.start("Creating team…");
|
|
60977
61295
|
try {
|
|
60978
61296
|
team = await api.createTeam(org.id, teamName.trim());
|
|
60979
|
-
createSpinner2.stop(`Created team ${
|
|
61297
|
+
createSpinner2.stop(`Created team ${import_picocolors31.default.bold(team.name)}.`);
|
|
60980
61298
|
} catch (err) {
|
|
60981
61299
|
createSpinner2.stop("Failed.");
|
|
60982
61300
|
handleApiError4(err);
|
|
@@ -60986,7 +61304,7 @@ async function runAgentCreate(cwd2, args) {
|
|
|
60986
61304
|
team = teams.find((t) => t.id === picked);
|
|
60987
61305
|
}
|
|
60988
61306
|
}
|
|
60989
|
-
const harness = normalizeHarnessId(args.harness ?? manifest.harness ?? await
|
|
61307
|
+
const harness = normalizeHarnessId(args.harness ?? manifest.harness ?? await pickHarness2(cwd2));
|
|
60990
61308
|
let agentName = args.name?.trim() || manifest.agent.name.trim();
|
|
60991
61309
|
if (!agentName) {
|
|
60992
61310
|
agentName = (await text({
|
|
@@ -61008,11 +61326,11 @@ async function runAgentCreate(cwd2, args) {
|
|
|
61008
61326
|
}
|
|
61009
61327
|
if (!autoProceed(args.yes)) {
|
|
61010
61328
|
le([
|
|
61011
|
-
`${
|
|
61012
|
-
`${
|
|
61013
|
-
`${
|
|
61014
|
-
`${
|
|
61015
|
-
...tagline ? [`${
|
|
61329
|
+
`${import_picocolors31.default.dim("org")} ${import_picocolors31.default.bold(org.name)}`,
|
|
61330
|
+
`${import_picocolors31.default.dim("team")} ${import_picocolors31.default.bold(team.name)}`,
|
|
61331
|
+
`${import_picocolors31.default.dim("harness")} ${import_picocolors31.default.bold(harness)}`,
|
|
61332
|
+
`${import_picocolors31.default.dim("agent")} ${import_picocolors31.default.bold(agentName)}`,
|
|
61333
|
+
...tagline ? [`${import_picocolors31.default.dim("tagline")} ${tagline}`] : []
|
|
61016
61334
|
].join(`
|
|
61017
61335
|
`), "Will create");
|
|
61018
61336
|
const confirmed = await se({ message: "Create this agent?", initialValue: true });
|
|
@@ -61026,7 +61344,7 @@ async function runAgentCreate(cwd2, args) {
|
|
|
61026
61344
|
const body = resolveEntrypoint(cwd2, manifest);
|
|
61027
61345
|
if (body === null) {
|
|
61028
61346
|
if (manifest.entrypoint.file) {
|
|
61029
|
-
f2.error(`Entrypoint file ${
|
|
61347
|
+
f2.error(`Entrypoint file ${import_picocolors31.default.bold(manifest.entrypoint.file)} not found.`);
|
|
61030
61348
|
} else {
|
|
61031
61349
|
f2.error("Entrypoint block is empty.");
|
|
61032
61350
|
}
|
|
@@ -61046,7 +61364,7 @@ async function runAgentCreate(cwd2, args) {
|
|
|
61046
61364
|
harness,
|
|
61047
61365
|
...resolvedEntrypoint !== undefined ? { entrypoint: resolvedEntrypoint } : {}
|
|
61048
61366
|
});
|
|
61049
|
-
createSpinner.stop(`Created ${
|
|
61367
|
+
createSpinner.stop(`Created ${import_picocolors31.default.bold(agent.name)}.`);
|
|
61050
61368
|
} catch (err) {
|
|
61051
61369
|
createSpinner.stop("Failed.");
|
|
61052
61370
|
handleApiError4(err);
|
|
@@ -61061,12 +61379,12 @@ async function runAgentCreate(cwd2, args) {
|
|
|
61061
61379
|
wantsTracking = true;
|
|
61062
61380
|
} else if (!isInteractive()) {
|
|
61063
61381
|
wantsTracking = false;
|
|
61064
|
-
f2.info(`Tracking left off (non-interactive). Re-run with ${
|
|
61382
|
+
f2.info(`Tracking left off (non-interactive). Re-run with ${import_picocolors31.default.cyan("--track")} to route ${harness} LLM traffic through brainbase.`);
|
|
61065
61383
|
} else if (args.yes) {
|
|
61066
61384
|
wantsTracking = true;
|
|
61067
61385
|
} else {
|
|
61068
61386
|
const ans = await se({
|
|
61069
|
-
message: `Track ${harness} conversations on the brainbase platform? ${
|
|
61387
|
+
message: `Track ${harness} conversations on the brainbase platform? ${import_picocolors31.default.dim("(routes LLM calls through brainbase so they appear under this agent)")}`,
|
|
61070
61388
|
initialValue: true
|
|
61071
61389
|
});
|
|
61072
61390
|
wantsTracking = ensureNotCancelled(ans);
|
|
@@ -61126,7 +61444,7 @@ async function runAgentCreate(cwd2, args) {
|
|
|
61126
61444
|
if (hasContent) {
|
|
61127
61445
|
const outgoing = await buildOutgoingComponents(cwd2, manifest, null);
|
|
61128
61446
|
if (outgoing === null) {
|
|
61129
|
-
f2.warn(`Agent created, but local content wasn't uploaded. Fix the issue above and run ${
|
|
61447
|
+
f2.warn(`Agent created, but local content wasn't uploaded. Fix the issue above and run ${import_picocolors31.default.cyan("brainbase agent push")}.`);
|
|
61130
61448
|
} else if (outgoing.length > 0) {
|
|
61131
61449
|
const pushSpinner = de();
|
|
61132
61450
|
pushSpinner.start("Pushing local content…");
|
|
@@ -61140,9 +61458,9 @@ async function runAgentCreate(cwd2, args) {
|
|
|
61140
61458
|
} catch (err) {
|
|
61141
61459
|
pushSpinner.stop("Failed.");
|
|
61142
61460
|
if (err instanceof ApiError) {
|
|
61143
|
-
f2.warn(`Content upload failed: ${err.message}. Run ${
|
|
61461
|
+
f2.warn(`Content upload failed: ${err.message}. Run ${import_picocolors31.default.cyan("brainbase agent push")} to retry.`);
|
|
61144
61462
|
} else {
|
|
61145
|
-
f2.warn(`Content upload failed: ${err.message}. Run ${
|
|
61463
|
+
f2.warn(`Content upload failed: ${err.message}. Run ${import_picocolors31.default.cyan("brainbase agent push")} to retry.`);
|
|
61146
61464
|
}
|
|
61147
61465
|
}
|
|
61148
61466
|
}
|
|
@@ -61178,7 +61496,7 @@ async function runAgentCreate(cwd2, args) {
|
|
|
61178
61496
|
};
|
|
61179
61497
|
writeSyncState(cwd2, state);
|
|
61180
61498
|
}
|
|
61181
|
-
$e(`Created ${
|
|
61499
|
+
$e(`Created ${import_picocolors31.default.bold(agent.name)} and linked this folder.`);
|
|
61182
61500
|
await showResultCard({
|
|
61183
61501
|
title: "CREATED",
|
|
61184
61502
|
tone: "ok",
|
|
@@ -61191,9 +61509,9 @@ async function runAgentCreate(cwd2, args) {
|
|
|
61191
61509
|
});
|
|
61192
61510
|
console.log();
|
|
61193
61511
|
if (tracking && harness === "codex") {
|
|
61194
|
-
console.log(tip(`Run ${
|
|
61512
|
+
console.log(tip(`Run ${import_picocolors31.default.cyan("codex")} once in this folder and approve trust ${import_picocolors31.default.dim("— Codex only loads project-scope config in trusted projects.")}`));
|
|
61195
61513
|
}
|
|
61196
|
-
console.log(tip(`brainbase agent unpack ${
|
|
61514
|
+
console.log(tip(`brainbase agent unpack ${import_picocolors31.default.dim("— install harness files (skills/mcps) under .claude/, .codex/, …")}`));
|
|
61197
61515
|
console.log();
|
|
61198
61516
|
}
|
|
61199
61517
|
async function loadOrScaffoldManifest(cwd2, args) {
|
|
@@ -61205,13 +61523,13 @@ async function loadOrScaffoldManifest(cwd2, args) {
|
|
|
61205
61523
|
return null;
|
|
61206
61524
|
}
|
|
61207
61525
|
}
|
|
61208
|
-
f2.warn(`No ${
|
|
61526
|
+
f2.warn(`No ${import_picocolors31.default.bold(AGENT_MANIFEST_FILE)} here.`);
|
|
61209
61527
|
if (!args.yes) {
|
|
61210
61528
|
if (!isInteractive()) {
|
|
61211
61529
|
throw new NonInteractiveError(`No ${AGENT_MANIFEST_FILE} here. Create one first, or re-run with --yes to scaffold a minimal one.`);
|
|
61212
61530
|
}
|
|
61213
61531
|
const ans = await se({
|
|
61214
|
-
message: `Scaffold a minimal ${
|
|
61532
|
+
message: `Scaffold a minimal ${import_picocolors31.default.bold(AGENT_MANIFEST_FILE)} and continue?`,
|
|
61215
61533
|
initialValue: true
|
|
61216
61534
|
});
|
|
61217
61535
|
if (!ensureNotCancelled(ans)) {
|
|
@@ -61219,30 +61537,31 @@ async function loadOrScaffoldManifest(cwd2, args) {
|
|
|
61219
61537
|
return null;
|
|
61220
61538
|
}
|
|
61221
61539
|
}
|
|
61222
|
-
const seedName = args.name?.trim() ??
|
|
61540
|
+
const seedName = args.name?.trim() ?? path50.basename(path50.resolve(cwd2)) ?? "My Agent";
|
|
61223
61541
|
const seedHarness = args.harness ? normalizeHarnessId(args.harness) : undefined;
|
|
61224
61542
|
const scaffold = {
|
|
61225
61543
|
schema: 1,
|
|
61226
61544
|
...seedHarness ? { harness: seedHarness } : {},
|
|
61227
61545
|
agent: { name: seedName, ...args.tagline ? { tagline: args.tagline } : {} },
|
|
61228
61546
|
playbooks: [],
|
|
61547
|
+
evals: [],
|
|
61229
61548
|
skills: [],
|
|
61230
61549
|
mcp: []
|
|
61231
61550
|
};
|
|
61232
61551
|
try {
|
|
61233
61552
|
writeManifest(cwd2, scaffold);
|
|
61234
|
-
f2.info(`Wrote ${
|
|
61553
|
+
f2.info(`Wrote ${import_picocolors31.default.bold(AGENT_MANIFEST_FILE)}.`);
|
|
61235
61554
|
} catch (err) {
|
|
61236
61555
|
f2.error(`Failed to write manifest: ${err.message}`);
|
|
61237
61556
|
return null;
|
|
61238
61557
|
}
|
|
61239
61558
|
return scaffold;
|
|
61240
61559
|
}
|
|
61241
|
-
async function
|
|
61560
|
+
async function pickHarness2(cwd2) {
|
|
61242
61561
|
const detections = await detectHarnesses(cwd2);
|
|
61243
61562
|
const detected = detections.filter((d3) => d3.detection.detected);
|
|
61244
61563
|
if (detected.length === 1) {
|
|
61245
|
-
f2.info(`Detected harness: ${
|
|
61564
|
+
f2.info(`Detected harness: ${import_picocolors31.default.bold(detected[0].adapter.displayName)}.`);
|
|
61246
61565
|
return detected[0].adapter.id;
|
|
61247
61566
|
}
|
|
61248
61567
|
return await select({
|
|
@@ -61268,271 +61587,6 @@ function handleApiError4(err) {
|
|
|
61268
61587
|
$e("Aborted.");
|
|
61269
61588
|
}
|
|
61270
61589
|
|
|
61271
|
-
// src/cli/agent-unpack.ts
|
|
61272
|
-
import path50 from "node:path";
|
|
61273
|
-
import fs46 from "node:fs";
|
|
61274
|
-
import os13 from "node:os";
|
|
61275
|
-
var import_picocolors31 = __toESM(require_picocolors(), 1);
|
|
61276
|
-
async function runAgentUnpack(cwd2, args) {
|
|
61277
|
-
banner("agent unpack — install this agent into a harness layout");
|
|
61278
|
-
if (!hasManifest(cwd2)) {
|
|
61279
|
-
f2.error(`No ${import_picocolors31.default.bold(AGENT_MANIFEST_FILE)} here.`);
|
|
61280
|
-
f2.info(`Run ${import_picocolors31.default.cyan("brainbase agent pull <id>")} to bring an agent into this folder first.`);
|
|
61281
|
-
return;
|
|
61282
|
-
}
|
|
61283
|
-
let manifest;
|
|
61284
|
-
try {
|
|
61285
|
-
manifest = readManifest(cwd2);
|
|
61286
|
-
} catch (err) {
|
|
61287
|
-
f2.error(err.message);
|
|
61288
|
-
return;
|
|
61289
|
-
}
|
|
61290
|
-
if (!manifest.id) {
|
|
61291
|
-
f2.error(`${import_picocolors31.default.bold(AGENT_MANIFEST_FILE)} is unclaimed (no ${import_picocolors31.default.cyan("id")}).`);
|
|
61292
|
-
f2.info(`Run ${import_picocolors31.default.cyan("brainbase agent create")} to claim it, ` + `or ${import_picocolors31.default.cyan("brainbase agent pull <id>")} to link it to an existing agent.`);
|
|
61293
|
-
return;
|
|
61294
|
-
}
|
|
61295
|
-
let harness;
|
|
61296
|
-
if (args.harness) {
|
|
61297
|
-
harness = normalizeHarnessId(args.harness);
|
|
61298
|
-
} else if (args.yes) {
|
|
61299
|
-
if (!manifest.harness) {
|
|
61300
|
-
f2.error(`--yes mode but no harness — set ${import_picocolors31.default.cyan("harness")} in the manifest or pass ${import_picocolors31.default.cyan("--harness")}.`);
|
|
61301
|
-
return;
|
|
61302
|
-
}
|
|
61303
|
-
harness = normalizeHarnessId(manifest.harness);
|
|
61304
|
-
} else {
|
|
61305
|
-
harness = await pickHarness2(manifest.harness);
|
|
61306
|
-
}
|
|
61307
|
-
if (!autoProceed(args.yes)) {
|
|
61308
|
-
const ok = await se({
|
|
61309
|
-
message: `Install ${import_picocolors31.default.bold(manifest.agent.name)} as ${import_picocolors31.default.bold(harness)} here?`,
|
|
61310
|
-
initialValue: true
|
|
61311
|
-
});
|
|
61312
|
-
if (!ensureNotCancelled(ok)) {
|
|
61313
|
-
$e("Aborted.");
|
|
61314
|
-
return;
|
|
61315
|
-
}
|
|
61316
|
-
}
|
|
61317
|
-
const scope = args.scope ?? "project";
|
|
61318
|
-
const stageRoot = fs46.mkdtempSync(path50.join(os13.tmpdir(), "brainbase-unpack-"));
|
|
61319
|
-
try {
|
|
61320
|
-
const toInstall = [];
|
|
61321
|
-
const instructionsBody = readInstructions(cwd2, manifest);
|
|
61322
|
-
if (instructionsBody && instructionsBody.trim()) {
|
|
61323
|
-
const compDir = path50.join(stageRoot, "instruction", "agent-instructions");
|
|
61324
|
-
ensureDir(compDir);
|
|
61325
|
-
fs46.writeFileSync(path50.join(compDir, "instructions.md"), instructionsBody, "utf8");
|
|
61326
|
-
toInstall.push({
|
|
61327
|
-
type: "instruction",
|
|
61328
|
-
slug: "agent-instructions",
|
|
61329
|
-
scope,
|
|
61330
|
-
rootDir: compDir,
|
|
61331
|
-
description: "Agent instructions",
|
|
61332
|
-
checksum: ""
|
|
61333
|
-
});
|
|
61334
|
-
}
|
|
61335
|
-
for (const entry of manifest.playbooks ?? []) {
|
|
61336
|
-
const issue = stageLocalPlaybook(entry, cwd2, stageRoot, scope, toInstall);
|
|
61337
|
-
if (issue) {
|
|
61338
|
-
f2.warn(issue);
|
|
61339
|
-
}
|
|
61340
|
-
}
|
|
61341
|
-
for (const entry of manifest.skills ?? []) {
|
|
61342
|
-
const issue = stageLocalSkill(entry.source, cwd2, stageRoot, scope, toInstall);
|
|
61343
|
-
if (issue) {
|
|
61344
|
-
f2.warn(issue);
|
|
61345
|
-
}
|
|
61346
|
-
}
|
|
61347
|
-
for (const entry of manifest.mcp ?? []) {
|
|
61348
|
-
const compDir = path50.join(stageRoot, "mcp", entry.name);
|
|
61349
|
-
ensureDir(compDir);
|
|
61350
|
-
const payload = {};
|
|
61351
|
-
if (entry.url !== undefined)
|
|
61352
|
-
payload.url = entry.url;
|
|
61353
|
-
if (entry.command !== undefined)
|
|
61354
|
-
payload.command = entry.command;
|
|
61355
|
-
if (entry.args !== undefined)
|
|
61356
|
-
payload.args = entry.args;
|
|
61357
|
-
if (entry.env !== undefined)
|
|
61358
|
-
payload.env = entry.env;
|
|
61359
|
-
if (entry.headers !== undefined)
|
|
61360
|
-
payload.headers = entry.headers;
|
|
61361
|
-
payload.is_enabled = entry.is_enabled ?? true;
|
|
61362
|
-
toInstall.push({
|
|
61363
|
-
type: "mcp",
|
|
61364
|
-
slug: entry.name,
|
|
61365
|
-
scope,
|
|
61366
|
-
rootDir: compDir,
|
|
61367
|
-
payload: proxifyMcpPayload(payload),
|
|
61368
|
-
checksum: ""
|
|
61369
|
-
});
|
|
61370
|
-
}
|
|
61371
|
-
const caps = capabilitiesFromManifest(manifest);
|
|
61372
|
-
const declaredMcpSlugs = new Set((manifest.mcp ?? []).map((m3) => m3.name));
|
|
61373
|
-
const { install: builtinInstall, removeSlugs: builtinRemoveSlugs } = resolveBuiltinMcps({
|
|
61374
|
-
caps,
|
|
61375
|
-
declaredSlugs: declaredMcpSlugs,
|
|
61376
|
-
scope
|
|
61377
|
-
});
|
|
61378
|
-
toInstall.push(...builtinInstall);
|
|
61379
|
-
const opts = {
|
|
61380
|
-
cwd: cwd2,
|
|
61381
|
-
scope,
|
|
61382
|
-
resolveConflict: async (_c) => "overwrite",
|
|
61383
|
-
resolveSecret: async () => null
|
|
61384
|
-
};
|
|
61385
|
-
const sp = de();
|
|
61386
|
-
sp.start("Installing harness layout…");
|
|
61387
|
-
const result2 = await runHarnessInstall3(harness, toInstall, opts, manifest.agent.name);
|
|
61388
|
-
sp.stop("Installed.");
|
|
61389
|
-
if (result2.skipped.length) {
|
|
61390
|
-
f2.warn(`Skipped: ${result2.skipped.map((s3) => `${s3.type}/${s3.slug} (${s3.reason})`).join(", ")}`);
|
|
61391
|
-
}
|
|
61392
|
-
if (builtinRemoveSlugs.length > 0) {
|
|
61393
|
-
runHarnessRemoveMcp(harness, builtinRemoveSlugs, { cwd: cwd2, scope });
|
|
61394
|
-
}
|
|
61395
|
-
} catch (err) {
|
|
61396
|
-
f2.error(`Install failed: ${err.message}`);
|
|
61397
|
-
return;
|
|
61398
|
-
} finally {
|
|
61399
|
-
try {
|
|
61400
|
-
fs46.rmSync(stageRoot, { recursive: true, force: true });
|
|
61401
|
-
} catch {}
|
|
61402
|
-
}
|
|
61403
|
-
if (manifest.harness !== harness) {
|
|
61404
|
-
manifest.harness = harness;
|
|
61405
|
-
writeManifest(cwd2, manifest);
|
|
61406
|
-
}
|
|
61407
|
-
$e(`Unpacked ${import_picocolors31.default.bold(manifest.agent.name)} as ${import_picocolors31.default.bold(harness)}.`);
|
|
61408
|
-
await showResultCard({
|
|
61409
|
-
title: "UNPACKED",
|
|
61410
|
-
tone: "ok",
|
|
61411
|
-
subtitle: manifest.agent.name,
|
|
61412
|
-
meta: [
|
|
61413
|
-
["harness", harness],
|
|
61414
|
-
["agent", manifest.id]
|
|
61415
|
-
]
|
|
61416
|
-
});
|
|
61417
|
-
}
|
|
61418
|
-
function stageLocalPlaybook(entry, cwd2, stageRoot, scope, toInstall) {
|
|
61419
|
-
if (entry.content.text !== undefined && entry.content.file !== undefined) {
|
|
61420
|
-
return `Playbook ${entry.title}: both text and file set — skipped.`;
|
|
61421
|
-
}
|
|
61422
|
-
const body = resolvePlaybookContent(cwd2, entry);
|
|
61423
|
-
if (body === null) {
|
|
61424
|
-
return entry.content.file ? `Playbook ${entry.title}: file ${entry.content.file} not found — skipped.` : `Playbook ${entry.title}: content empty — skipped.`;
|
|
61425
|
-
}
|
|
61426
|
-
const slug = slugifyPlaybookTitle(entry.title);
|
|
61427
|
-
const compDir = path50.join(stageRoot, "playbook", slug);
|
|
61428
|
-
ensureDir(compDir);
|
|
61429
|
-
const wireBody = /^---\s*\n/.test(body) ? body : assembleFrontmatter(entry.title, entry.description) + body.replace(/^\n+/, "");
|
|
61430
|
-
fs46.writeFileSync(path50.join(compDir, `${slug}.md`), wireBody, "utf8");
|
|
61431
|
-
toInstall.push({
|
|
61432
|
-
type: "playbook",
|
|
61433
|
-
slug,
|
|
61434
|
-
scope,
|
|
61435
|
-
rootDir: compDir,
|
|
61436
|
-
description: entry.description,
|
|
61437
|
-
checksum: ""
|
|
61438
|
-
});
|
|
61439
|
-
return null;
|
|
61440
|
-
}
|
|
61441
|
-
function stageLocalSkill(source, cwd2, stageRoot, scope, toInstall) {
|
|
61442
|
-
if (source.startsWith("./") || source.startsWith("../") || source.startsWith("/")) {
|
|
61443
|
-
const abs = path50.resolve(cwd2, source);
|
|
61444
|
-
if (!fs46.existsSync(abs)) {
|
|
61445
|
-
return `Skill ${source}: not found on disk — skipped.`;
|
|
61446
|
-
}
|
|
61447
|
-
const slug = path50.basename(abs);
|
|
61448
|
-
const compDir = path50.join(stageRoot, "skill", slug);
|
|
61449
|
-
ensureDir(compDir);
|
|
61450
|
-
copyDirRecursive(abs, compDir);
|
|
61451
|
-
toInstall.push({
|
|
61452
|
-
type: "skill",
|
|
61453
|
-
slug,
|
|
61454
|
-
scope,
|
|
61455
|
-
rootDir: compDir,
|
|
61456
|
-
checksum: ""
|
|
61457
|
-
});
|
|
61458
|
-
return null;
|
|
61459
|
-
}
|
|
61460
|
-
try {
|
|
61461
|
-
const parsed = parseSkillSource(source);
|
|
61462
|
-
if (parsed.type === "local" || parsed.type === "inline")
|
|
61463
|
-
return null;
|
|
61464
|
-
const slug = defaultSlugForSource(source);
|
|
61465
|
-
const compDir = path50.join(stageRoot, "skill", slug);
|
|
61466
|
-
ensureDir(compDir);
|
|
61467
|
-
toInstall.push({
|
|
61468
|
-
type: "skill",
|
|
61469
|
-
slug,
|
|
61470
|
-
scope,
|
|
61471
|
-
rootDir: compDir,
|
|
61472
|
-
source: parsed,
|
|
61473
|
-
checksum: ""
|
|
61474
|
-
});
|
|
61475
|
-
return null;
|
|
61476
|
-
} catch (err) {
|
|
61477
|
-
return `Skill ${source}: ${err.message} — skipped.`;
|
|
61478
|
-
}
|
|
61479
|
-
}
|
|
61480
|
-
function defaultSlugForSource(source) {
|
|
61481
|
-
const reg = /^registry:(?:[a-z0-9_-]+\/)?([a-z0-9_-]+)/i.exec(source);
|
|
61482
|
-
if (reg)
|
|
61483
|
-
return reg[1].toLowerCase();
|
|
61484
|
-
const gh = /^(?:github|git):[^/]*\/?([a-z0-9_-]+)/i.exec(source);
|
|
61485
|
-
if (gh)
|
|
61486
|
-
return gh[1].toLowerCase();
|
|
61487
|
-
return source.replace(/[^a-z0-9_-]/gi, "-").slice(0, 60) || "skill";
|
|
61488
|
-
}
|
|
61489
|
-
function copyDirRecursive(src, dest) {
|
|
61490
|
-
ensureDir(dest);
|
|
61491
|
-
for (const entry of fs46.readdirSync(src, { withFileTypes: true })) {
|
|
61492
|
-
const s3 = path50.join(src, entry.name);
|
|
61493
|
-
const d3 = path50.join(dest, entry.name);
|
|
61494
|
-
if (entry.isDirectory())
|
|
61495
|
-
copyDirRecursive(s3, d3);
|
|
61496
|
-
else if (entry.isFile())
|
|
61497
|
-
fs46.copyFileSync(s3, d3);
|
|
61498
|
-
}
|
|
61499
|
-
}
|
|
61500
|
-
function assembleFrontmatter(title, description) {
|
|
61501
|
-
const lines = ["---", `title: ${yamlScalar(title)}`];
|
|
61502
|
-
if (description)
|
|
61503
|
-
lines.push(`description: ${yamlScalar(description)}`);
|
|
61504
|
-
lines.push("---", "");
|
|
61505
|
-
return lines.join(`
|
|
61506
|
-
`);
|
|
61507
|
-
}
|
|
61508
|
-
function yamlScalar(s3) {
|
|
61509
|
-
if (!/[\n":#&*!|>'%@`{}[\]]/.test(s3) && s3.trim() === s3 && s3 !== "")
|
|
61510
|
-
return s3;
|
|
61511
|
-
return JSON.stringify(s3);
|
|
61512
|
-
}
|
|
61513
|
-
function runHarnessInstall3(harnessId, components, opts, agentName) {
|
|
61514
|
-
if (harnessId === "claude-code")
|
|
61515
|
-
return installClaudeCodeWithCtx(components, opts, agentName);
|
|
61516
|
-
if (harnessId === "codex")
|
|
61517
|
-
return installCodexWithCtx(components, opts, agentName);
|
|
61518
|
-
if (harnessId === "kafka")
|
|
61519
|
-
return installKafkaWithCtx(components, opts, agentName);
|
|
61520
|
-
return getAdapter(harnessId).install(components, opts);
|
|
61521
|
-
}
|
|
61522
|
-
async function pickHarness2(current) {
|
|
61523
|
-
const initial2 = current ? normalizeHarnessId(current) : undefined;
|
|
61524
|
-
return select({
|
|
61525
|
-
message: "Pick a harness to install as",
|
|
61526
|
-
options: adapters.map((a3) => ({
|
|
61527
|
-
value: a3.id,
|
|
61528
|
-
label: a3.displayName,
|
|
61529
|
-
hint: a3.id === initial2 ? "current" : undefined
|
|
61530
|
-
})),
|
|
61531
|
-
initialValue: initial2 ?? adapters[0].id,
|
|
61532
|
-
flagHint: "Pass --harness <id> to choose non-interactively."
|
|
61533
|
-
});
|
|
61534
|
-
}
|
|
61535
|
-
|
|
61536
61590
|
// src/cli/agent.ts
|
|
61537
61591
|
async function runAgent(cwd2, sub, args, opts) {
|
|
61538
61592
|
switch (sub) {
|
|
@@ -61554,7 +61608,8 @@ async function runAgent(cwd2, sub, args, opts) {
|
|
|
61554
61608
|
scope: opts.scope,
|
|
61555
61609
|
agentIdArg: args[0],
|
|
61556
61610
|
force: opts.force,
|
|
61557
|
-
runEntrypoint: opts.runEntrypoint
|
|
61611
|
+
runEntrypoint: opts.runEntrypoint,
|
|
61612
|
+
acp: opts.acp
|
|
61558
61613
|
});
|
|
61559
61614
|
return;
|
|
61560
61615
|
case "push":
|
|
@@ -61564,7 +61619,8 @@ async function runAgent(cwd2, sub, args, opts) {
|
|
|
61564
61619
|
await runAgentUnpack(cwd2, {
|
|
61565
61620
|
yes: opts.yes,
|
|
61566
61621
|
scope: opts.scope,
|
|
61567
|
-
harness: opts.harness
|
|
61622
|
+
harness: opts.harness,
|
|
61623
|
+
acp: opts.acp
|
|
61568
61624
|
});
|
|
61569
61625
|
return;
|
|
61570
61626
|
case "status":
|
|
@@ -61969,6 +62025,7 @@ function buildManifestFromCloud(cloud, agent) {
|
|
|
61969
62025
|
},
|
|
61970
62026
|
...hasInstructions ? { instructions: { file: DEFAULT_INSTRUCTIONS_FILE } } : {},
|
|
61971
62027
|
playbooks: [],
|
|
62028
|
+
evals: [],
|
|
61972
62029
|
skills,
|
|
61973
62030
|
mcp,
|
|
61974
62031
|
capabilities: {
|
|
@@ -63507,10 +63564,11 @@ var import_picocolors41 = __toESM(require_picocolors(), 1);
|
|
|
63507
63564
|
|
|
63508
63565
|
// src/core/mcp-check/collect-servers.ts
|
|
63509
63566
|
import path55 from "node:path";
|
|
63567
|
+
import fs52 from "node:fs";
|
|
63510
63568
|
function collectServers(cwd2, env3 = process.env) {
|
|
63511
63569
|
const out = [];
|
|
63512
63570
|
const seen = new Set;
|
|
63513
|
-
for (const source of [readClaudeCode, readCodex, readKafka]) {
|
|
63571
|
+
for (const source of [readClaudeCode, readCodex, readKafka, readResolvedMcps]) {
|
|
63514
63572
|
for (const [name, entry] of source(cwd2)) {
|
|
63515
63573
|
pushResolved(out, seen, name, entry, env3);
|
|
63516
63574
|
}
|
|
@@ -63556,6 +63614,33 @@ function pushResolved(out, seen, name, entry, env3) {
|
|
|
63556
63614
|
seen.add(name);
|
|
63557
63615
|
out.push({ name, url: finalUrl, headers });
|
|
63558
63616
|
}
|
|
63617
|
+
function* readResolvedMcps(cwd2) {
|
|
63618
|
+
const p2 = path55.join(cwd2, ".brainbase", "resolved-mcps.json");
|
|
63619
|
+
let raw;
|
|
63620
|
+
try {
|
|
63621
|
+
raw = fs52.readFileSync(p2, "utf-8");
|
|
63622
|
+
} catch {
|
|
63623
|
+
return;
|
|
63624
|
+
}
|
|
63625
|
+
let list;
|
|
63626
|
+
try {
|
|
63627
|
+
const parsed = JSON.parse(raw);
|
|
63628
|
+
list = Array.isArray(parsed) ? parsed : Array.isArray(parsed?.mcpServers) ? parsed.mcpServers : [];
|
|
63629
|
+
} catch {
|
|
63630
|
+
return;
|
|
63631
|
+
}
|
|
63632
|
+
for (const m3 of list) {
|
|
63633
|
+
if (!m3 || typeof m3 !== "object")
|
|
63634
|
+
continue;
|
|
63635
|
+
const entry = m3;
|
|
63636
|
+
if (typeof entry.name !== "string" || !entry.name)
|
|
63637
|
+
continue;
|
|
63638
|
+
if (entry.is_enabled === false)
|
|
63639
|
+
continue;
|
|
63640
|
+
const { name, ...rest2 } = entry;
|
|
63641
|
+
yield [name, rest2];
|
|
63642
|
+
}
|
|
63643
|
+
}
|
|
63559
63644
|
function readClaudeCode(cwd2) {
|
|
63560
63645
|
const file = path55.join(cwd2, ".mcp.json");
|
|
63561
63646
|
const map2 = listMcpServersFromMcpJson(file);
|
|
@@ -72029,7 +72114,7 @@ async function main() {
|
|
|
72029
72114
|
const rawCwd = process14.cwd();
|
|
72030
72115
|
const cwd2 = (() => {
|
|
72031
72116
|
try {
|
|
72032
|
-
return
|
|
72117
|
+
return fs53.realpathSync(rawCwd);
|
|
72033
72118
|
} catch {
|
|
72034
72119
|
return rawCwd;
|
|
72035
72120
|
}
|
|
@@ -72071,6 +72156,7 @@ async function main() {
|
|
|
72071
72156
|
const schemaFlag = getFlag(argv, "--schema");
|
|
72072
72157
|
const noPushFlag = hasFlag2(argv, "--no-push");
|
|
72073
72158
|
const jsonFlag = hasFlag2(argv, "--json");
|
|
72159
|
+
const acpFlag = hasFlag2(argv, "--acp");
|
|
72074
72160
|
ensureSkillResolversRegistered();
|
|
72075
72161
|
await requireAuth(cmd);
|
|
72076
72162
|
try {
|
|
@@ -72152,7 +72238,8 @@ async function main() {
|
|
|
72152
72238
|
noTracking,
|
|
72153
72239
|
track,
|
|
72154
72240
|
force: forceFlag,
|
|
72155
|
-
runEntrypoint: runEntrypointFlag
|
|
72241
|
+
runEntrypoint: runEntrypointFlag,
|
|
72242
|
+
acp: acpFlag
|
|
72156
72243
|
});
|
|
72157
72244
|
break;
|
|
72158
72245
|
}
|