@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.
Files changed (2) hide show
  1. package/dist/index.js +502 -415
  2. 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, fs52, exportName) {
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, fs52[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 fs52 from "node:fs";
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.14.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 path48 from "node:path";
59144
- import fs45 from "node:fs";
59145
- import os12 from "node:os";
59146
- var import_picocolors25 = __toESM(require_picocolors(), 1);
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)} ${import_picocolors25.default.bold(r2.slug)} — both you and the cloud edited it` : `${fmtType(r2.type)} ${import_picocolors25.default.bold(r2.slug)} — you have local edits not yet pushed`,
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 ${import_picocolors25.default.bold(AGENT_MANIFEST_FILE)}.`);
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: path48.join(stageRoot, c2.type, c2.slug),
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 runHarnessInstall2(adapter.id, toInstall, opts, cloudAgent.name);
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 (!fs45.existsSync(filePath))
60032
+ if (!fs46.existsSync(filePath))
59716
60033
  continue;
59717
60034
  try {
59718
- const stat = fs45.statSync(filePath);
60035
+ const stat = fs46.statSync(filePath);
59719
60036
  if (stat.isDirectory())
59720
- fs45.rmSync(filePath, { recursive: true, force: true });
60037
+ fs46.rmSync(filePath, { recursive: true, force: true });
59721
60038
  else
59722
- fs45.rmSync(filePath);
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
- fs45.rmSync(stageRoot, { recursive: true, force: true });
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 (${import_picocolors25.default.dim(manifestId)}).`);
59777
- f2.info(`Run ${import_picocolors25.default.cyan(`brainbase agent pull ${arg} --force`)} to override. ` + import_picocolors25.default.yellow("This will overwrite brainbase.agent.yaml and any local progress will be lost."));
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(`${import_picocolors25.default.bold(AGENT_MANIFEST_FILE)} is unclaimed (no ${import_picocolors25.default.cyan("id")}).`);
59788
- f2.info(`Run ${import_picocolors25.default.cyan("brainbase agent create")} to create a new agent from this manifest, ` + `or ${import_picocolors25.default.cyan("brainbase agent pull <id>")} to pull an existing one.`);
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 ${import_picocolors25.default.bold(AGENT_MANIFEST_FILE)} here and no ${import_picocolors25.default.cyan("<id>")} given.`);
59791
- f2.info(`Run ${import_picocolors25.default.cyan("brainbase agent pull <id>")} to pull an existing agent into this folder.`);
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 = fs45.mkdtempSync(path48.join(os12.tmpdir(), "brainbase-pull-"));
60132
+ const root = fs46.mkdtempSync(path49.join(os13.tmpdir(), "brainbase-pull-"));
59816
60133
  for (const c2 of components) {
59817
- const compDir = path48.join(root, c2.type, c2.slug);
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 = path48.join(compDir, f4.path);
59821
- ensureDir(path48.dirname(target));
59822
- fs45.writeFileSync(target, f4.content);
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 runHarnessInstall2(harnessId, components, opts, agentName) {
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 = path48.resolve(cwd2, targetRel);
59852
- ensureDir(path48.dirname(target));
59853
- fs45.writeFileSync(target, normalizeInstructionBody(body), "utf8");
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 ?? path48.join(DEFAULT_PLAYBOOKS_DIR, `${c2.slug}.md`);
59873
- const target = path48.resolve(cwd2, targetRel);
59874
- ensureDir(path48.dirname(target));
59875
- fs45.writeFileSync(target, body, "utf8");
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 ?? path48.join(DEFAULT_PLAYBOOKS_DIR, `${c2.slug}.md`)
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 = path48.resolve(cwd2, filename);
59972
- fs45.writeFileSync(target, cloudEntrypoint, "utf8");
60289
+ const target = path49.resolve(cwd2, filename);
60290
+ fs46.writeFileSync(target, cloudEntrypoint, "utf8");
59973
60291
  try {
59974
- fs45.chmodSync(target, 493);
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 = path48.join(cwd2, LINK_DIR);
60365
+ const stateDir = path49.join(cwd2, LINK_DIR);
60048
60366
  ensureDir(stateDir);
60049
- const scriptPath = path48.join(stateDir, "entrypoint.sh");
60050
- const logPath = path48.join(stateDir, "entrypoint.log");
60051
- fs45.writeFileSync(scriptPath, body, "utf8");
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
- fs45.chmodSync(scriptPath, 493);
60371
+ fs46.chmodSync(scriptPath, 493);
60054
60372
  } catch {}
60055
60373
  if (!execute) {
60056
- f2.info(`Agent has an entrypoint — written to ${import_picocolors25.default.dim(path48.relative(cwd2, scriptPath))}, not executed. ` + `Run it with ${import_picocolors25.default.cyan("brainbase run bash .brainbase/entrypoint.sh")} or re-pull with ${import_picocolors25.default.cyan("--run-entrypoint")}. Sandboxes run it automatically.`);
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 ${import_picocolors25.default.dim(`(${path48.relative(cwd2, scriptPath)})`)}`);
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 = fs45.createWriteStream(logPath, { flags: "w" });
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 ${import_picocolors25.default.dim(path48.relative(cwd2, logPath))}.`);
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(", ")}. ${import_picocolors25.default.dim("They will be kept locally; run `agent push` to upload.")}`);
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(", ")}. ${import_picocolors25.default.dim("Local wins on pull; run `agent push` to overwrite cloud.")}`);
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 import_picocolors27 = __toESM(require_picocolors(), 1);
60451
+ var import_picocolors28 = __toESM(require_picocolors(), 1);
60134
60452
 
60135
60453
  // src/core/agent-outgoing.ts
60136
- var import_picocolors26 = __toESM(require_picocolors(), 1);
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 ${import_picocolors26.default.cyan("text")} and ${import_picocolors26.default.cyan("file")} — pick one.`);
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 ${import_picocolors26.default.bold(manifest.instructions.file)} not found.`);
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 ${import_picocolors26.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\`).`);
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 ${import_picocolors26.default.bold(entry.title)} sets both ${import_picocolors26.default.cyan("text")} and ${import_picocolors26.default.cyan("file")} — pick one.`);
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 ${import_picocolors26.default.bold(entry.title)} content file ${import_picocolors26.default.bold(entry.content.file)} not found.`);
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 ${import_picocolors26.default.bold(entry.title)} content is empty.`);
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 ${import_picocolors26.default.bold(entry.name)} needs either ${import_picocolors26.default.cyan("url")} or ${import_picocolors26.default.cyan("command")}.`);
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 ${import_picocolors27.default.bold(AGENT_MANIFEST_FILE)} here.`);
60326
- f2.info(`Run ${import_picocolors27.default.cyan("brainbase agent create")} to claim a new agent from a manifest, ` + `or ${import_picocolors27.default.cyan("brainbase agent pull <id>")} to pull an existing one.`);
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(`${import_picocolors27.default.bold(AGENT_MANIFEST_FILE)} is unclaimed (no ${import_picocolors27.default.cyan("id")}). Nothing to push to.`);
60338
- f2.info(`Run ${import_picocolors27.default.cyan("brainbase agent create")} first — that creates the cloud agent and stamps an id here.`);
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 ${import_picocolors27.default.bold(name)} isn't in the registry (not published, or private to another owner).`);
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(` ${import_picocolors27.default.cyan(`brainbase skill publish ./path/to/skill --name ${name} --skill-version ${version} --yes`)}`);
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 ${import_picocolors27.default.bold(manifest.entrypoint.file)} not found.`);
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)} ${import_picocolors27.default.bold(r2.slug)} can't be pushed yet — the server accepts instructions, skills, and mcps in this version.`);
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 ${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\`).`);
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) => 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.`);
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(` ${import_picocolors27.default.red("!")} ${fmtType(r2.type)} ${import_picocolors27.default.bold(r2.slug)}`);
60799
+ console.error(` ${import_picocolors28.default.red("!")} ${fmtType(r2.type)} ${import_picocolors28.default.bold(r2.slug)}`);
60482
60800
  }
60483
- 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.`);
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(`${import_picocolors27.default.yellow("--force")}: overwriting ${forcedOverrides.length} cloud change${forcedOverrides.length === 1 ? "" : "s"} with your local version (cloud edits discarded):`);
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(` ${import_picocolors27.default.yellow("⤒")} ${fmtType(r2.type)} ${import_picocolors27.default.bold(r2.slug)}`);
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(` ${import_picocolors27.default.cyan("←")} ${fmtType(r2.type)} ${import_picocolors27.default.bold(r2.slug)} ${import_picocolors27.default.dim(`(${r2.status})`)}`);
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 ${import_picocolors27.default.bold(u2.name)}: registry latest is ${import_picocolors27.default.bold(u2.latest)}, below the agent's ${import_picocolors27.default.dim(u2.current)} — the agent's version was likely yanked. Converging on latest.`);
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 ${import_picocolors27.default.bold(u2.name)} → ${import_picocolors27.default.bold(u2.latest)} (registry latest${u2.current ? `, agent has ${u2.current}` : ""}).`);
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 ${import_picocolors27.default.cyan("brainbase agent pull")} and try again.`);
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((pc26) => pc26.type === c2.type && pc26.slug === c2.slug);
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 import_picocolors28 = __toESM(require_picocolors(), 1);
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 ${import_picocolors28.default.cyan("brainbase link")} first.`);
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(`${import_picocolors28.default.dim("No")} ${import_picocolors28.default.bold("brainbase.agent.yaml")} ${import_picocolors28.default.dim("here yet.")} Run ${import_picocolors28.default.cyan("brainbase agent pull")} to populate this folder.`);
60704
- f2.info(`Cloud has ${import_picocolors28.default.bold(String(cloud.components.length))} component${cloud.components.length === 1 ? "" : "s"} at revision ${cloud.revision}.`);
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(` ${import_picocolors28.default.bold(link2.name)} ${import_picocolors28.default.dim(`(${link2.slug})`)}`);
60744
- lines.push(` ${import_picocolors28.default.dim("agent_id")} ${link2.agent_id}`);
60745
- lines.push(` ${import_picocolors28.default.dim("revision")} cloud ${cloud.revision}${lock ? ` · lock ${lock.revision}` : " · never pulled"}`);
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(` ${import_picocolors28.default.bold("agent metadata")}`);
61066
+ lines.push(` ${import_picocolors29.default.bold("agent metadata")}`);
60749
61067
  if (meta.localChanged) {
60750
- lines.push(` ${import_picocolors28.default.yellow("→ push")} name/tagline edited in brainbase.agent.yaml`);
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(` ${import_picocolors28.default.cyan("← pull")} name/tagline changed on cloud`);
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(` ${import_picocolors28.default.bold("secrets")}`);
61081
+ lines.push(` ${import_picocolors29.default.bold("secrets")}`);
60764
61082
  if (sd.localOnly.length)
60765
- lines.push(` ${import_picocolors28.default.yellow("→ push")} new locally: ${sd.localOnly.join(", ")}`);
61083
+ lines.push(` ${import_picocolors29.default.yellow("→ push")} new locally: ${sd.localOnly.join(", ")}`);
60766
61084
  if (sd.changed.length)
60767
- lines.push(` ${import_picocolors28.default.yellow("→ push")} values changed: ${sd.changed.join(", ")}`);
61085
+ lines.push(` ${import_picocolors29.default.yellow("→ push")} values changed: ${sd.changed.join(", ")}`);
60768
61086
  if (sd.cloudOnly.length)
60769
- lines.push(` ${import_picocolors28.default.cyan("← pull")} new on cloud: ${sd.cloudOnly.join(", ")}`);
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(` ${import_picocolors28.default.green("✓")} everything is in sync`);
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(` ${import_picocolors28.default.bold("changes to push")} ${import_picocolors28.default.dim(`(${toPush.length})`)}`);
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(` ${import_picocolors28.default.yellow("→")} ${fmtRow(r2)}`);
61101
+ lines.push(` ${import_picocolors29.default.yellow("→")} ${fmtRow(r2)}`);
60784
61102
  lines.push("");
60785
61103
  }
60786
61104
  if (toPull.length) {
60787
- lines.push(` ${import_picocolors28.default.bold("changes to pull")} ${import_picocolors28.default.dim(`(${toPull.length})`)}`);
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(` ${import_picocolors28.default.cyan("←")} ${fmtRow(r2)}`);
61107
+ lines.push(` ${import_picocolors29.default.cyan("←")} ${fmtRow(r2)}`);
60790
61108
  lines.push("");
60791
61109
  }
60792
61110
  if (conflicts.length) {
60793
- lines.push(` ${import_picocolors28.default.bold(import_picocolors28.default.red("conflicts"))} ${import_picocolors28.default.dim(`(${conflicts.length})`)}`);
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(` ${import_picocolors28.default.red("!")} ${fmtRow(r2)}`);
61113
+ lines.push(` ${import_picocolors29.default.red("!")} ${fmtRow(r2)}`);
60796
61114
  lines.push("");
60797
61115
  }
60798
- lines.push(` ${import_picocolors28.default.dim("run")} ${import_picocolors28.default.cyan("brainbase agent pull")} ${import_picocolors28.default.dim("to apply cloud changes,")} ${import_picocolors28.default.cyan("brainbase agent push")} ${import_picocolors28.default.dim("to send yours")}`);
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)} ${import_picocolors28.default.bold(r2.slug)}`;
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} ${import_picocolors28.default.dim("(new — only in brainbase.agent.yaml)")}`;
61125
+ return `${head3} ${import_picocolors29.default.dim("(new — only in brainbase.agent.yaml)")}`;
60808
61126
  case "added-cloud":
60809
- return `${head3} ${import_picocolors28.default.dim("(new on cloud)")}`;
61127
+ return `${head3} ${import_picocolors29.default.dim("(new on cloud)")}`;
60810
61128
  case "added-local":
60811
- return `${head3} ${import_picocolors28.default.dim("(present locally and on cloud, never synced here)")}`;
61129
+ return `${head3} ${import_picocolors29.default.dim("(present locally and on cloud, never synced here)")}`;
60812
61130
  case "removed-local":
60813
- return `${head3} ${import_picocolors28.default.dim("(removed from brainbase.agent.yaml)")}`;
61131
+ return `${head3} ${import_picocolors29.default.dim("(removed from brainbase.agent.yaml)")}`;
60814
61132
  case "removed-cloud":
60815
- return `${head3} ${import_picocolors28.default.dim("(removed on cloud)")}`;
61133
+ return `${head3} ${import_picocolors29.default.dim("(removed on cloud)")}`;
60816
61134
  case "modified-local":
60817
- return `${head3} ${import_picocolors28.default.dim("(you edited it)")}`;
61135
+ return `${head3} ${import_picocolors29.default.dim("(you edited it)")}`;
60818
61136
  case "modified-cloud":
60819
- return `${head3} ${import_picocolors28.default.dim("(cloud was updated)")}`;
61137
+ return `${head3} ${import_picocolors29.default.dim("(cloud was updated)")}`;
60820
61138
  case "modified-both":
60821
- return `${head3} ${import_picocolors28.default.dim("(both diverged — needs resolution)")}`;
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 path49 from "node:path";
60859
- var import_picocolors30 = __toESM(require_picocolors(), 1);
61176
+ import path50 from "node:path";
61177
+ var import_picocolors31 = __toESM(require_picocolors(), 1);
60860
61178
 
60861
61179
  // src/ui/box.ts
60862
- var import_picocolors29 = __toESM(require_picocolors(), 1);
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}${import_picocolors29.default.dim(H3.repeat(width))}`;
61192
+ return `${ind}${import_picocolors30.default.dim(H3.repeat(width))}`;
60875
61193
  const labelText = ` ${label} `;
60876
61194
  const labelLen = visibleLength(labelText);
60877
- const left = import_picocolors29.default.dim(H3.repeat(2));
60878
- const right = import_picocolors29.default.dim(H3.repeat(Math.max(0, width - labelLen - 2)));
60879
- return `${ind}${left}${import_picocolors29.default.bold(import_picocolors29.default.dim(labelText))}${right}`;
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) + import_picocolors29.default.dim("›") + " " + import_picocolors29.default.dim(text2);
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 — ${import_picocolors30.default.bold(manifest.agent.name)} (${import_picocolors30.default.dim(manifest.id)}).`);
60893
- f2.info(`If you want to detach it, run ${import_picocolors30.default.cyan("brainbase unlink")} first; or move to a different directory.`);
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 ${import_picocolors30.default.bold(org.name)}.`);
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 ${import_picocolors30.default.bold(team.name)}.`);
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 ${import_picocolors30.default.bold(team.name)}.`);
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 pickHarness(cwd2));
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
- `${import_picocolors30.default.dim("org")} ${import_picocolors30.default.bold(org.name)}`,
61012
- `${import_picocolors30.default.dim("team")} ${import_picocolors30.default.bold(team.name)}`,
61013
- `${import_picocolors30.default.dim("harness")} ${import_picocolors30.default.bold(harness)}`,
61014
- `${import_picocolors30.default.dim("agent")} ${import_picocolors30.default.bold(agentName)}`,
61015
- ...tagline ? [`${import_picocolors30.default.dim("tagline")} ${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 ${import_picocolors30.default.bold(manifest.entrypoint.file)} not found.`);
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 ${import_picocolors30.default.bold(agent.name)}.`);
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 ${import_picocolors30.default.cyan("--track")} to route ${harness} LLM traffic through brainbase.`);
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? ${import_picocolors30.default.dim("(routes LLM calls through brainbase so they appear under this agent)")}`,
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 ${import_picocolors30.default.cyan("brainbase agent push")}.`);
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 ${import_picocolors30.default.cyan("brainbase agent push")} to retry.`);
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 ${import_picocolors30.default.cyan("brainbase agent push")} to retry.`);
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 ${import_picocolors30.default.bold(agent.name)} and linked this folder.`);
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 ${import_picocolors30.default.cyan("codex")} once in this folder and approve trust ${import_picocolors30.default.dim("— Codex only loads project-scope config in trusted projects.")}`));
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 ${import_picocolors30.default.dim("— install harness files (skills/mcps) under .claude/, .codex/, …")}`));
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 ${import_picocolors30.default.bold(AGENT_MANIFEST_FILE)} here.`);
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 ${import_picocolors30.default.bold(AGENT_MANIFEST_FILE)} and continue?`,
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() ?? path49.basename(path49.resolve(cwd2)) ?? "My Agent";
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 ${import_picocolors30.default.bold(AGENT_MANIFEST_FILE)}.`);
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 pickHarness(cwd2) {
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: ${import_picocolors30.default.bold(detected[0].adapter.displayName)}.`);
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 fs52.realpathSync(rawCwd);
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
  }