@brainbase-labs/cli 0.15.0-acp.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 +458 -422
  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.15.0-acp.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: {
@@ -59181,10 +59181,10 @@ var import_picocolors32 = __toESM(require_picocolors(), 1);
59181
59181
 
59182
59182
  // src/cli/agent-pull.ts
59183
59183
  import { spawn as spawn2 } from "node:child_process";
59184
- import path48 from "node:path";
59185
- import fs45 from "node:fs";
59186
- import os12 from "node:os";
59187
- 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);
59188
59188
 
59189
59189
  // src/core/agent-diff.ts
59190
59190
  import path46 from "node:path";
@@ -59579,6 +59579,282 @@ function entrypointExecutionAllowed(opts) {
59579
59579
  return v3 === "1" || v3 === "true";
59580
59580
  }
59581
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
+
59582
59858
  // src/cli/agent-pull.ts
59583
59859
  async function runAgentPull(cwd2, args) {
59584
59860
  banner("agent pull — bring cloud changes into this folder");
@@ -59641,7 +59917,7 @@ async function runAgentPull(cwd2, args) {
59641
59917
  }
59642
59918
  for (const r2 of conflicts) {
59643
59919
  const choice = await ie({
59644
- 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`,
59645
59921
  options: [
59646
59922
  { value: "cloud", label: "Use the cloud's version (discard local edits)" },
59647
59923
  { value: "keep", label: "Keep your local edits (skip this one)" }
@@ -59667,7 +59943,7 @@ async function runAgentPull(cwd2, args) {
59667
59943
  writeSyncState(cwd2, buildLockFromCloud(agentId, cloud, lock, cloudAgent));
59668
59944
  if (!existingManifest) {
59669
59945
  writeManifest(cwd2, mergeManifest(cwd2, null, cloud, cloudAgent, harness));
59670
- f2.info(`Wrote ${import_picocolors25.default.bold(AGENT_MANIFEST_FILE)}.`);
59946
+ f2.info(`Wrote ${import_picocolors26.default.bold(AGENT_MANIFEST_FILE)}.`);
59671
59947
  }
59672
59948
  return;
59673
59949
  }
@@ -59722,7 +59998,7 @@ async function runAgentPull(cwd2, args) {
59722
59998
  type: c2.type,
59723
59999
  slug: c2.slug,
59724
60000
  scope,
59725
- rootDir: path48.join(stageRoot, c2.type, c2.slug),
60001
+ rootDir: path49.join(stageRoot, c2.type, c2.slug),
59726
60002
  description: c2.description,
59727
60003
  meta: c2.meta,
59728
60004
  payload: proxifyMcpPayload(c2.meta?.mcp),
@@ -59736,7 +60012,7 @@ async function runAgentPull(cwd2, args) {
59736
60012
  resolveConflict: async (_c) => "overwrite",
59737
60013
  resolveSecret: async () => null
59738
60014
  };
59739
- const result2 = await runHarnessInstall2(adapter.id, toInstall, opts, cloudAgent.name);
60015
+ const result2 = await runHarnessInstall3(adapter.id, componentsForNativeInstall(toInstall, !!args.acp), opts, cloudAgent.name);
59740
60016
  installSpinner.stop("Applied.");
59741
60017
  for (const o2 of result2.installed) {
59742
60018
  justInstalledPaths.set(`${o2.type}/${o2.slug}`, o2.installedPaths);
@@ -59753,14 +60029,14 @@ async function runAgentPull(cwd2, args) {
59753
60029
  if (!prior)
59754
60030
  continue;
59755
60031
  for (const filePath of prior.installedPaths) {
59756
- if (!fs45.existsSync(filePath))
60032
+ if (!fs46.existsSync(filePath))
59757
60033
  continue;
59758
60034
  try {
59759
- const stat = fs45.statSync(filePath);
60035
+ const stat = fs46.statSync(filePath);
59760
60036
  if (stat.isDirectory())
59761
- fs45.rmSync(filePath, { recursive: true, force: true });
60037
+ fs46.rmSync(filePath, { recursive: true, force: true });
59762
60038
  else
59763
- fs45.rmSync(filePath);
60039
+ fs46.rmSync(filePath);
59764
60040
  } catch (err) {
59765
60041
  f2.warn(`Failed to remove ${filePath}: ${err.message}`);
59766
60042
  }
@@ -59798,7 +60074,7 @@ async function runAgentPull(cwd2, args) {
59798
60074
  $e(`Pulled ${cloudAgent.name} at revision ${cloud.revision}.`);
59799
60075
  } finally {
59800
60076
  try {
59801
- fs45.rmSync(stageRoot, { recursive: true, force: true });
60077
+ fs46.rmSync(stageRoot, { recursive: true, force: true });
59802
60078
  } catch {}
59803
60079
  }
59804
60080
  }
@@ -59814,8 +60090,8 @@ function resolveTargetAgentId(cwd2, args) {
59814
60090
  const manifestId = manifest?.id;
59815
60091
  if (arg && manifestId && arg !== manifestId) {
59816
60092
  if (!args.force) {
59817
- f2.error(`This folder is already linked to a different agent (${import_picocolors25.default.dim(manifestId)}).`);
59818
- 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."));
59819
60095
  return null;
59820
60096
  }
59821
60097
  return { agentId: arg, override: true };
@@ -59825,11 +60101,11 @@ function resolveTargetAgentId(cwd2, args) {
59825
60101
  if (manifestId)
59826
60102
  return { agentId: manifestId, override: false };
59827
60103
  if (manifest) {
59828
- f2.error(`${import_picocolors25.default.bold(AGENT_MANIFEST_FILE)} is unclaimed (no ${import_picocolors25.default.cyan("id")}).`);
59829
- 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.`);
59830
60106
  } else {
59831
- f2.error(`No ${import_picocolors25.default.bold(AGENT_MANIFEST_FILE)} here and no ${import_picocolors25.default.cyan("<id>")} given.`);
59832
- 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.`);
59833
60109
  }
59834
60110
  return null;
59835
60111
  }
@@ -59853,19 +60129,19 @@ function skillSourceFromMeta(c2) {
59853
60129
  }
59854
60130
  }
59855
60131
  function stageManifestComponents(components) {
59856
- const root = fs45.mkdtempSync(path48.join(os12.tmpdir(), "brainbase-pull-"));
60132
+ const root = fs46.mkdtempSync(path49.join(os13.tmpdir(), "brainbase-pull-"));
59857
60133
  for (const c2 of components) {
59858
- const compDir = path48.join(root, c2.type, c2.slug);
60134
+ const compDir = path49.join(root, c2.type, c2.slug);
59859
60135
  ensureDir(compDir);
59860
60136
  for (const f4 of c2.files) {
59861
- const target = path48.join(compDir, f4.path);
59862
- ensureDir(path48.dirname(target));
59863
- fs45.writeFileSync(target, f4.content);
60137
+ const target = path49.join(compDir, f4.path);
60138
+ ensureDir(path49.dirname(target));
60139
+ fs46.writeFileSync(target, f4.content);
59864
60140
  }
59865
60141
  }
59866
60142
  return root;
59867
60143
  }
59868
- function runHarnessInstall2(harnessId, components, opts, agentName) {
60144
+ function runHarnessInstall3(harnessId, components, opts, agentName) {
59869
60145
  if (harnessId === "claude-code")
59870
60146
  return installClaudeCodeWithCtx(components, opts, agentName);
59871
60147
  if (harnessId === "codex")
@@ -59889,9 +60165,9 @@ function materializeInstructions(cwd2, cloud, toInstall, keepLocal, existingMani
59889
60165
  if (existingManifest?.instructions?.text !== undefined)
59890
60166
  continue;
59891
60167
  const targetRel = existingManifest?.instructions?.file ?? DEFAULT_INSTRUCTIONS_FILE;
59892
- const target = path48.resolve(cwd2, targetRel);
59893
- ensureDir(path48.dirname(target));
59894
- 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");
59895
60171
  }
59896
60172
  }
59897
60173
  function materializePlaybooks(cwd2, cloud, toInstall, keepLocal, existingManifest) {
@@ -59910,10 +60186,10 @@ function materializePlaybooks(cwd2, cloud, toInstall, keepLocal, existingManifes
59910
60186
  const existing = existingManifest?.playbooks?.find((p2) => slugifyPlaybookTitle(p2.title) === c2.slug);
59911
60187
  if (existing?.content?.text !== undefined)
59912
60188
  continue;
59913
- const targetRel = existing?.content?.file ?? path48.join(DEFAULT_PLAYBOOKS_DIR, `${c2.slug}.md`);
59914
- const target = path48.resolve(cwd2, targetRel);
59915
- ensureDir(path48.dirname(target));
59916
- 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");
59917
60193
  }
59918
60194
  }
59919
60195
  function mergeManifest(cwd2, prev, cloud, cloudAgent, harness) {
@@ -59951,7 +60227,7 @@ function mergeManifest(cwd2, prev, cloud, cloudAgent, harness) {
59951
60227
  const title = local?.title ?? (typeof frontmatter.title === "string" && frontmatter.title || c2.slug);
59952
60228
  const description = local?.description ?? (typeof frontmatter.description === "string" ? frontmatter.description : undefined);
59953
60229
  const content = local?.content?.text !== undefined ? { text: local.content.text } : {
59954
- 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`)
59955
60231
  };
59956
60232
  const pbMeta = c2.meta ?? {};
59957
60233
  return {
@@ -60010,10 +60286,10 @@ function materializeEntrypoint(cwd2, cloudEntrypoint, prev) {
60010
60286
  if (prev?.entrypoint?.text !== undefined)
60011
60287
  return;
60012
60288
  const filename = prev?.entrypoint?.file ?? DEFAULT_ENTRYPOINT_FILE;
60013
- const target = path48.resolve(cwd2, filename);
60014
- fs45.writeFileSync(target, cloudEntrypoint, "utf8");
60289
+ const target = path49.resolve(cwd2, filename);
60290
+ fs46.writeFileSync(target, cloudEntrypoint, "utf8");
60015
60291
  try {
60016
- fs45.chmodSync(target, 493);
60292
+ fs46.chmodSync(target, 493);
60017
60293
  } catch {}
60018
60294
  }
60019
60295
  function buildLockComponents(input) {
@@ -60086,22 +60362,22 @@ async function runEntrypointIfPresent(cwd2, manifest, execute) {
60086
60362
  const body = resolveEntrypoint(cwd2, manifest);
60087
60363
  if (body === null || !body.trim())
60088
60364
  return;
60089
- const stateDir = path48.join(cwd2, LINK_DIR);
60365
+ const stateDir = path49.join(cwd2, LINK_DIR);
60090
60366
  ensureDir(stateDir);
60091
- const scriptPath = path48.join(stateDir, "entrypoint.sh");
60092
- const logPath = path48.join(stateDir, "entrypoint.log");
60093
- 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");
60094
60370
  try {
60095
- fs45.chmodSync(scriptPath, 493);
60371
+ fs46.chmodSync(scriptPath, 493);
60096
60372
  } catch {}
60097
60373
  if (!execute) {
60098
- 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.`);
60099
60375
  return;
60100
60376
  }
60101
- 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)})`)}`);
60102
60378
  const secrets = readLocalSecrets(cwd2);
60103
60379
  const env3 = { ...process.env, ...secrets };
60104
- const logStream = fs45.createWriteStream(logPath, { flags: "w" });
60380
+ const logStream = fs46.createWriteStream(logPath, { flags: "w" });
60105
60381
  const exitCode = await new Promise((resolve) => {
60106
60382
  const child = spawn2("bash", [scriptPath], {
60107
60383
  cwd: cwd2,
@@ -60126,7 +60402,7 @@ async function runEntrypointIfPresent(cwd2, manifest, execute) {
60126
60402
  if (exitCode === 0) {
60127
60403
  f2.info("Entrypoint completed.");
60128
60404
  } else if (exitCode === null) {} else {
60129
- 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))}.`);
60130
60406
  }
60131
60407
  }
60132
60408
  async function pullSecrets(cwd2, agentId) {
@@ -60148,10 +60424,10 @@ async function pullSecrets(cwd2, agentId) {
60148
60424
  const diff2 = diffSecrets(localSecrets, cloudSecrets);
60149
60425
  if (diff2.localOnly.length > 0 || diff2.changed.length > 0) {
60150
60426
  if (diff2.localOnly.length) {
60151
- 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.")}`);
60152
60428
  }
60153
60429
  if (diff2.changed.length) {
60154
- 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.")}`);
60155
60431
  }
60156
60432
  }
60157
60433
  const merged = { ...cloudSecrets, ...localSecrets };
@@ -60172,21 +60448,21 @@ function handleApiError2(err) {
60172
60448
  }
60173
60449
 
60174
60450
  // src/cli/agent-push.ts
60175
- var import_picocolors27 = __toESM(require_picocolors(), 1);
60451
+ var import_picocolors28 = __toESM(require_picocolors(), 1);
60176
60452
 
60177
60453
  // src/core/agent-outgoing.ts
60178
- var import_picocolors26 = __toESM(require_picocolors(), 1);
60454
+ var import_picocolors27 = __toESM(require_picocolors(), 1);
60179
60455
  async function buildOutgoingComponents(cwd2, manifest, cloud, resolvedVersions) {
60180
60456
  const out = [];
60181
60457
  if (manifest.instructions) {
60182
60458
  if (manifest.instructions.text !== undefined && manifest.instructions.file !== undefined) {
60183
- 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.`);
60184
60460
  return null;
60185
60461
  }
60186
60462
  const body = readInstructions(cwd2, manifest);
60187
60463
  if (body === null) {
60188
60464
  if (manifest.instructions.file) {
60189
- 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.`);
60190
60466
  } else {
60191
60467
  f2.error("Instructions block is empty.");
60192
60468
  }
@@ -60219,7 +60495,7 @@ async function buildOutgoingComponents(cwd2, manifest, cloud, resolvedVersions)
60219
60495
  continue;
60220
60496
  }
60221
60497
  if (parsed.kind === "local") {
60222
- 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\`).`);
60223
60499
  return null;
60224
60500
  }
60225
60501
  const slug = registrySkillComponentSlug(parsed);
@@ -60242,15 +60518,15 @@ async function buildOutgoingComponents(cwd2, manifest, cloud, resolvedVersions)
60242
60518
  const entry = playbookEntries[i];
60243
60519
  const slug = playbookSlugs[i];
60244
60520
  if (entry.content.text !== undefined && entry.content.file !== undefined) {
60245
- 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.`);
60246
60522
  return null;
60247
60523
  }
60248
60524
  const body = resolvePlaybookContent(cwd2, entry);
60249
60525
  if (body === null) {
60250
60526
  if (entry.content.file) {
60251
- 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.`);
60252
60528
  } else {
60253
- 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.`);
60254
60530
  }
60255
60531
  return null;
60256
60532
  }
@@ -60278,7 +60554,7 @@ async function buildOutgoingComponents(cwd2, manifest, cloud, resolvedVersions)
60278
60554
  }
60279
60555
  for (const entry of manifest.mcp ?? []) {
60280
60556
  if (!entry.url && !entry.command) {
60281
- 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")}.`);
60282
60558
  return null;
60283
60559
  }
60284
60560
  const payload = {};
@@ -60364,8 +60640,8 @@ function planRegistrySkillUpdates(skills, cloudComponents, latestByName) {
60364
60640
  async function runAgentPush(cwd2, args) {
60365
60641
  banner("agent push — send your local changes to the cloud");
60366
60642
  if (!hasManifest(cwd2)) {
60367
- f2.warn(`No ${import_picocolors27.default.bold(AGENT_MANIFEST_FILE)} here.`);
60368
- 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.`);
60369
60645
  return;
60370
60646
  }
60371
60647
  let manifest;
@@ -60376,8 +60652,8 @@ async function runAgentPush(cwd2, args) {
60376
60652
  return;
60377
60653
  }
60378
60654
  if (!manifest.id) {
60379
- f2.warn(`${import_picocolors27.default.bold(AGENT_MANIFEST_FILE)} is unclaimed (no ${import_picocolors27.default.cyan("id")}). Nothing to push to.`);
60380
- 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.`);
60381
60657
  return;
60382
60658
  }
60383
60659
  const agentId = manifest.id;
@@ -60438,13 +60714,13 @@ async function runAgentPush(cwd2, args) {
60438
60714
  });
60439
60715
  if (unresolvable.length > 0) {
60440
60716
  for (const name of unresolvable) {
60441
- 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).`);
60442
60718
  }
60443
60719
  const noun = unresolvable.length === 1 ? "it" : "each one";
60444
60720
  f2.info(`Publish ${noun} first, then push again:`);
60445
60721
  for (const name of unresolvable) {
60446
60722
  const version = registryRefs.get(name)?.version ?? "0.1.0";
60447
- 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`)}`);
60448
60724
  }
60449
60725
  return;
60450
60726
  }
@@ -60469,7 +60745,7 @@ async function runAgentPush(cwd2, args) {
60469
60745
  const body = resolveEntrypoint(cwd2, manifest);
60470
60746
  if (body === null) {
60471
60747
  if (manifest.entrypoint.file) {
60472
- 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.`);
60473
60749
  } else {
60474
60750
  f2.error("Entrypoint block is empty.");
60475
60751
  }
@@ -60484,7 +60760,7 @@ async function runAgentPush(cwd2, args) {
60484
60760
  const entrypointChanged = resolvedEntrypoint !== undefined && (resolvedEntrypoint ?? "").trim() !== (lock?.agentMeta?.entrypoint ?? "").trim();
60485
60761
  for (const r2 of rows) {
60486
60762
  if (r2.type !== "instruction" && r2.type !== "skill" && r2.type !== "mcp" && r2.type !== "playbook") {
60487
- 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.`);
60488
60764
  return;
60489
60765
  }
60490
60766
  }
@@ -60496,7 +60772,7 @@ async function runAgentPush(cwd2, args) {
60496
60772
  continue;
60497
60773
  }
60498
60774
  if (parsed.kind === "local") {
60499
- 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\`).`);
60500
60776
  return;
60501
60777
  }
60502
60778
  }
@@ -60508,7 +60784,7 @@ async function runAgentPush(cwd2, args) {
60508
60784
  return typeof id === "string" && id && !localPlaybooks.some((p2) => p2.id === id) && idlessLocalSlugs.has(c2.slug);
60509
60785
  }).map((c2) => c2.slug);
60510
60786
  if (preIdSchemaSlugs.length > 0) {
60511
- 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.`);
60512
60788
  return;
60513
60789
  }
60514
60790
  const { toSend, conflicts, upstreamOnly } = partitionPushRows(rows, !!args.force);
@@ -60520,21 +60796,21 @@ async function runAgentPush(cwd2, args) {
60520
60796
  if (conflicts.length > 0) {
60521
60797
  f2.error(`Cannot push: ${conflicts.length} component${conflicts.length === 1 ? "" : "s"} changed both locally and on the cloud:`);
60522
60798
  for (const r2 of conflicts) {
60523
- 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)}`);
60524
60800
  }
60525
- 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.`);
60526
60802
  return;
60527
60803
  }
60528
60804
  if (forcedOverrides.length > 0) {
60529
- 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):`);
60530
60806
  for (const r2 of forcedOverrides) {
60531
- 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)}`);
60532
60808
  }
60533
60809
  }
60534
60810
  if (upstreamOnly.length > 0 && !args.yes) {
60535
60811
  f2.warn(`Cloud has ${upstreamOnly.length} change${upstreamOnly.length === 1 ? "" : "s"} you don't have locally:`);
60536
60812
  for (const r2 of upstreamOnly) {
60537
- 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})`)}`);
60538
60814
  }
60539
60815
  f2.info(`If you push now, your push targets revision ${cloud.revision} and may race. Consider \`brainbase agent pull\` first.`);
60540
60816
  }
@@ -60543,9 +60819,9 @@ async function runAgentPush(cwd2, args) {
60543
60819
  if (!sendKeys.has(compKey("skill", u2.componentSlug)))
60544
60820
  continue;
60545
60821
  if (u2.direction === "downgrade") {
60546
- 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.`);
60547
60823
  } else {
60548
- 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}` : ""}).`);
60549
60825
  }
60550
60826
  }
60551
60827
  const resultRows = [];
@@ -60619,7 +60895,7 @@ async function runAgentPush(cwd2, args) {
60619
60895
  pushSpinner.stop("Failed.");
60620
60896
  if (err instanceof ApiError && err.status === 409) {
60621
60897
  f2.error(err.message);
60622
- 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.`);
60623
60899
  return;
60624
60900
  }
60625
60901
  return handleApiError3(err);
@@ -60656,7 +60932,7 @@ async function runAgentPush(cwd2, args) {
60656
60932
  return false;
60657
60933
  }
60658
60934
  })?.source;
60659
- 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);
60660
60936
  const localHash = localHashByKey.get(`${c2.type}/${c2.slug}`);
60661
60937
  return {
60662
60938
  type: c2.type,
@@ -60715,13 +60991,13 @@ function handleApiError3(err) {
60715
60991
  }
60716
60992
 
60717
60993
  // src/cli/agent-status.ts
60718
- var import_picocolors28 = __toESM(require_picocolors(), 1);
60994
+ var import_picocolors29 = __toESM(require_picocolors(), 1);
60719
60995
  async function runAgentStatus(cwd2) {
60720
60996
  banner("agent status — what changed locally, remotely, both");
60721
60997
  const link2 = readLink(cwd2);
60722
60998
  if (!link2) {
60723
60999
  f2.warn("This folder is not linked to any agent.");
60724
- f2.info(`Run ${import_picocolors28.default.cyan("brainbase link")} first.`);
61000
+ f2.info(`Run ${import_picocolors29.default.cyan("brainbase link")} first.`);
60725
61001
  return;
60726
61002
  }
60727
61003
  const manifest = hasManifest(cwd2) ? readManifest(cwd2) : null;
@@ -60742,8 +61018,8 @@ async function runAgentStatus(cwd2) {
60742
61018
  return;
60743
61019
  }
60744
61020
  if (!manifest) {
60745
- 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.`);
60746
- 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}.`);
60747
61023
  return;
60748
61024
  }
60749
61025
  const localComponents = readLocalComponents(cwd2, manifest);
@@ -60782,17 +61058,17 @@ async function runAgentStatus(cwd2) {
60782
61058
  }
60783
61059
  const lines = [];
60784
61060
  lines.push("");
60785
- lines.push(` ${import_picocolors28.default.bold(link2.name)} ${import_picocolors28.default.dim(`(${link2.slug})`)}`);
60786
- lines.push(` ${import_picocolors28.default.dim("agent_id")} ${link2.agent_id}`);
60787
- 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"}`);
60788
61064
  lines.push("");
60789
61065
  if (meta.localChanged || meta.cloudChanged) {
60790
- lines.push(` ${import_picocolors28.default.bold("agent metadata")}`);
61066
+ lines.push(` ${import_picocolors29.default.bold("agent metadata")}`);
60791
61067
  if (meta.localChanged) {
60792
- 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`);
60793
61069
  }
60794
61070
  if (meta.cloudChanged) {
60795
- 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`);
60796
61072
  }
60797
61073
  lines.push("");
60798
61074
  }
@@ -60802,65 +61078,65 @@ async function runAgentStatus(cwd2) {
60802
61078
  const cloudSecrets = cloudRes.secrets ?? {};
60803
61079
  const sd = diffSecrets(localSecrets, cloudSecrets);
60804
61080
  if (sd.localOnly.length || sd.cloudOnly.length || sd.changed.length) {
60805
- lines.push(` ${import_picocolors28.default.bold("secrets")}`);
61081
+ lines.push(` ${import_picocolors29.default.bold("secrets")}`);
60806
61082
  if (sd.localOnly.length)
60807
- 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(", ")}`);
60808
61084
  if (sd.changed.length)
60809
- 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(", ")}`);
60810
61086
  if (sd.cloudOnly.length)
60811
- 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(", ")}`);
60812
61088
  lines.push("");
60813
61089
  }
60814
61090
  } catch {}
60815
61091
  if (conflicts.length === 0 && toPush.length === 0 && toPull.length === 0) {
60816
- lines.push(` ${import_picocolors28.default.green("✓")} everything is in sync`);
61092
+ lines.push(` ${import_picocolors29.default.green("✓")} everything is in sync`);
60817
61093
  lines.push("");
60818
61094
  console.log(lines.join(`
60819
61095
  `));
60820
61096
  return;
60821
61097
  }
60822
61098
  if (toPush.length) {
60823
- 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})`)}`);
60824
61100
  for (const r2 of toPush)
60825
- lines.push(` ${import_picocolors28.default.yellow("→")} ${fmtRow(r2)}`);
61101
+ lines.push(` ${import_picocolors29.default.yellow("→")} ${fmtRow(r2)}`);
60826
61102
  lines.push("");
60827
61103
  }
60828
61104
  if (toPull.length) {
60829
- 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})`)}`);
60830
61106
  for (const r2 of toPull)
60831
- lines.push(` ${import_picocolors28.default.cyan("←")} ${fmtRow(r2)}`);
61107
+ lines.push(` ${import_picocolors29.default.cyan("←")} ${fmtRow(r2)}`);
60832
61108
  lines.push("");
60833
61109
  }
60834
61110
  if (conflicts.length) {
60835
- 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})`)}`);
60836
61112
  for (const r2 of conflicts)
60837
- lines.push(` ${import_picocolors28.default.red("!")} ${fmtRow(r2)}`);
61113
+ lines.push(` ${import_picocolors29.default.red("!")} ${fmtRow(r2)}`);
60838
61114
  lines.push("");
60839
61115
  }
60840
- 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")}`);
60841
61117
  lines.push("");
60842
61118
  console.log(lines.join(`
60843
61119
  `));
60844
61120
  }
60845
61121
  function fmtRow(r2) {
60846
- const head3 = `${fmtType(r2.type)} ${import_picocolors28.default.bold(r2.slug)}`;
61122
+ const head3 = `${fmtType(r2.type)} ${import_picocolors29.default.bold(r2.slug)}`;
60847
61123
  switch (r2.status) {
60848
61124
  case "added-only-local":
60849
- 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)")}`;
60850
61126
  case "added-cloud":
60851
- return `${head3} ${import_picocolors28.default.dim("(new on cloud)")}`;
61127
+ return `${head3} ${import_picocolors29.default.dim("(new on cloud)")}`;
60852
61128
  case "added-local":
60853
- 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)")}`;
60854
61130
  case "removed-local":
60855
- return `${head3} ${import_picocolors28.default.dim("(removed from brainbase.agent.yaml)")}`;
61131
+ return `${head3} ${import_picocolors29.default.dim("(removed from brainbase.agent.yaml)")}`;
60856
61132
  case "removed-cloud":
60857
- return `${head3} ${import_picocolors28.default.dim("(removed on cloud)")}`;
61133
+ return `${head3} ${import_picocolors29.default.dim("(removed on cloud)")}`;
60858
61134
  case "modified-local":
60859
- return `${head3} ${import_picocolors28.default.dim("(you edited it)")}`;
61135
+ return `${head3} ${import_picocolors29.default.dim("(you edited it)")}`;
60860
61136
  case "modified-cloud":
60861
- return `${head3} ${import_picocolors28.default.dim("(cloud was updated)")}`;
61137
+ return `${head3} ${import_picocolors29.default.dim("(cloud was updated)")}`;
60862
61138
  case "modified-both":
60863
- return `${head3} ${import_picocolors28.default.dim("(both diverged — needs resolution)")}`;
61139
+ return `${head3} ${import_picocolors29.default.dim("(both diverged — needs resolution)")}`;
60864
61140
  default:
60865
61141
  return head3;
60866
61142
  }
@@ -60897,11 +61173,11 @@ function formatExport(shell, key2, value) {
60897
61173
  }
60898
61174
 
60899
61175
  // src/cli/agent-create.ts
60900
- import path49 from "node:path";
60901
- var import_picocolors30 = __toESM(require_picocolors(), 1);
61176
+ import path50 from "node:path";
61177
+ var import_picocolors31 = __toESM(require_picocolors(), 1);
60902
61178
 
60903
61179
  // src/ui/box.ts
60904
- var import_picocolors29 = __toESM(require_picocolors(), 1);
61180
+ var import_picocolors30 = __toESM(require_picocolors(), 1);
60905
61181
  var H3 = "─";
60906
61182
  var TINT = {
60907
61183
  ok: COLOR.ok,
@@ -60913,15 +61189,15 @@ var TINT = {
60913
61189
  function divider(label, width = 56, indent = 2) {
60914
61190
  const ind = " ".repeat(indent);
60915
61191
  if (!label)
60916
- return `${ind}${import_picocolors29.default.dim(H3.repeat(width))}`;
61192
+ return `${ind}${import_picocolors30.default.dim(H3.repeat(width))}`;
60917
61193
  const labelText = ` ${label} `;
60918
61194
  const labelLen = visibleLength(labelText);
60919
- const left = import_picocolors29.default.dim(H3.repeat(2));
60920
- const right = import_picocolors29.default.dim(H3.repeat(Math.max(0, width - labelLen - 2)));
60921
- 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}`;
60922
61198
  }
60923
61199
  function tip(text2, indent = 2) {
60924
- 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);
60925
61201
  }
60926
61202
 
60927
61203
  // src/cli/agent-create.ts
@@ -60931,8 +61207,8 @@ async function runAgentCreate(cwd2, args) {
60931
61207
  if (!manifest)
60932
61208
  return;
60933
61209
  if (manifest.id) {
60934
- f2.warn(`This folder already belongs to an agent — ${import_picocolors30.default.bold(manifest.agent.name)} (${import_picocolors30.default.dim(manifest.id)}).`);
60935
- 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.`);
60936
61212
  return;
60937
61213
  }
60938
61214
  const orgsSpinner = de();
@@ -60961,7 +61237,7 @@ async function runAgentCreate(cwd2, args) {
60961
61237
  org = found;
60962
61238
  } else if (orgs.length === 1) {
60963
61239
  org = orgs[0];
60964
- f2.info(`Using organization ${import_picocolors30.default.bold(org.name)}.`);
61240
+ f2.info(`Using organization ${import_picocolors31.default.bold(org.name)}.`);
60965
61241
  } else {
60966
61242
  const orgId = await select({
60967
61243
  message: "Pick an organization",
@@ -60992,7 +61268,7 @@ async function runAgentCreate(cwd2, args) {
60992
61268
  } else if (!isInteractive()) {
60993
61269
  if (teams.length === 1) {
60994
61270
  team = teams[0];
60995
- f2.info(`Using team ${import_picocolors30.default.bold(team.name)}.`);
61271
+ f2.info(`Using team ${import_picocolors31.default.bold(team.name)}.`);
60996
61272
  } else if (teams.length === 0) {
60997
61273
  throw new NonInteractiveError(`No teams in ${org.name} yet — create one in the web app, then re-run.`);
60998
61274
  } else {
@@ -61018,7 +61294,7 @@ async function runAgentCreate(cwd2, args) {
61018
61294
  createSpinner2.start("Creating team…");
61019
61295
  try {
61020
61296
  team = await api.createTeam(org.id, teamName.trim());
61021
- createSpinner2.stop(`Created team ${import_picocolors30.default.bold(team.name)}.`);
61297
+ createSpinner2.stop(`Created team ${import_picocolors31.default.bold(team.name)}.`);
61022
61298
  } catch (err) {
61023
61299
  createSpinner2.stop("Failed.");
61024
61300
  handleApiError4(err);
@@ -61028,7 +61304,7 @@ async function runAgentCreate(cwd2, args) {
61028
61304
  team = teams.find((t) => t.id === picked);
61029
61305
  }
61030
61306
  }
61031
- const harness = normalizeHarnessId(args.harness ?? manifest.harness ?? await pickHarness(cwd2));
61307
+ const harness = normalizeHarnessId(args.harness ?? manifest.harness ?? await pickHarness2(cwd2));
61032
61308
  let agentName = args.name?.trim() || manifest.agent.name.trim();
61033
61309
  if (!agentName) {
61034
61310
  agentName = (await text({
@@ -61050,11 +61326,11 @@ async function runAgentCreate(cwd2, args) {
61050
61326
  }
61051
61327
  if (!autoProceed(args.yes)) {
61052
61328
  le([
61053
- `${import_picocolors30.default.dim("org")} ${import_picocolors30.default.bold(org.name)}`,
61054
- `${import_picocolors30.default.dim("team")} ${import_picocolors30.default.bold(team.name)}`,
61055
- `${import_picocolors30.default.dim("harness")} ${import_picocolors30.default.bold(harness)}`,
61056
- `${import_picocolors30.default.dim("agent")} ${import_picocolors30.default.bold(agentName)}`,
61057
- ...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}`] : []
61058
61334
  ].join(`
61059
61335
  `), "Will create");
61060
61336
  const confirmed = await se({ message: "Create this agent?", initialValue: true });
@@ -61068,7 +61344,7 @@ async function runAgentCreate(cwd2, args) {
61068
61344
  const body = resolveEntrypoint(cwd2, manifest);
61069
61345
  if (body === null) {
61070
61346
  if (manifest.entrypoint.file) {
61071
- 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.`);
61072
61348
  } else {
61073
61349
  f2.error("Entrypoint block is empty.");
61074
61350
  }
@@ -61088,7 +61364,7 @@ async function runAgentCreate(cwd2, args) {
61088
61364
  harness,
61089
61365
  ...resolvedEntrypoint !== undefined ? { entrypoint: resolvedEntrypoint } : {}
61090
61366
  });
61091
- createSpinner.stop(`Created ${import_picocolors30.default.bold(agent.name)}.`);
61367
+ createSpinner.stop(`Created ${import_picocolors31.default.bold(agent.name)}.`);
61092
61368
  } catch (err) {
61093
61369
  createSpinner.stop("Failed.");
61094
61370
  handleApiError4(err);
@@ -61103,12 +61379,12 @@ async function runAgentCreate(cwd2, args) {
61103
61379
  wantsTracking = true;
61104
61380
  } else if (!isInteractive()) {
61105
61381
  wantsTracking = false;
61106
- 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.`);
61107
61383
  } else if (args.yes) {
61108
61384
  wantsTracking = true;
61109
61385
  } else {
61110
61386
  const ans = await se({
61111
- 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)")}`,
61112
61388
  initialValue: true
61113
61389
  });
61114
61390
  wantsTracking = ensureNotCancelled(ans);
@@ -61168,7 +61444,7 @@ async function runAgentCreate(cwd2, args) {
61168
61444
  if (hasContent) {
61169
61445
  const outgoing = await buildOutgoingComponents(cwd2, manifest, null);
61170
61446
  if (outgoing === null) {
61171
- 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")}.`);
61172
61448
  } else if (outgoing.length > 0) {
61173
61449
  const pushSpinner = de();
61174
61450
  pushSpinner.start("Pushing local content…");
@@ -61182,9 +61458,9 @@ async function runAgentCreate(cwd2, args) {
61182
61458
  } catch (err) {
61183
61459
  pushSpinner.stop("Failed.");
61184
61460
  if (err instanceof ApiError) {
61185
- 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.`);
61186
61462
  } else {
61187
- 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.`);
61188
61464
  }
61189
61465
  }
61190
61466
  }
@@ -61220,7 +61496,7 @@ async function runAgentCreate(cwd2, args) {
61220
61496
  };
61221
61497
  writeSyncState(cwd2, state);
61222
61498
  }
61223
- $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.`);
61224
61500
  await showResultCard({
61225
61501
  title: "CREATED",
61226
61502
  tone: "ok",
@@ -61233,9 +61509,9 @@ async function runAgentCreate(cwd2, args) {
61233
61509
  });
61234
61510
  console.log();
61235
61511
  if (tracking && harness === "codex") {
61236
- 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.")}`));
61237
61513
  }
61238
- 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/, …")}`));
61239
61515
  console.log();
61240
61516
  }
61241
61517
  async function loadOrScaffoldManifest(cwd2, args) {
@@ -61247,13 +61523,13 @@ async function loadOrScaffoldManifest(cwd2, args) {
61247
61523
  return null;
61248
61524
  }
61249
61525
  }
61250
- f2.warn(`No ${import_picocolors30.default.bold(AGENT_MANIFEST_FILE)} here.`);
61526
+ f2.warn(`No ${import_picocolors31.default.bold(AGENT_MANIFEST_FILE)} here.`);
61251
61527
  if (!args.yes) {
61252
61528
  if (!isInteractive()) {
61253
61529
  throw new NonInteractiveError(`No ${AGENT_MANIFEST_FILE} here. Create one first, or re-run with --yes to scaffold a minimal one.`);
61254
61530
  }
61255
61531
  const ans = await se({
61256
- 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?`,
61257
61533
  initialValue: true
61258
61534
  });
61259
61535
  if (!ensureNotCancelled(ans)) {
@@ -61261,7 +61537,7 @@ async function loadOrScaffoldManifest(cwd2, args) {
61261
61537
  return null;
61262
61538
  }
61263
61539
  }
61264
- 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";
61265
61541
  const seedHarness = args.harness ? normalizeHarnessId(args.harness) : undefined;
61266
61542
  const scaffold = {
61267
61543
  schema: 1,
@@ -61274,18 +61550,18 @@ async function loadOrScaffoldManifest(cwd2, args) {
61274
61550
  };
61275
61551
  try {
61276
61552
  writeManifest(cwd2, scaffold);
61277
- f2.info(`Wrote ${import_picocolors30.default.bold(AGENT_MANIFEST_FILE)}.`);
61553
+ f2.info(`Wrote ${import_picocolors31.default.bold(AGENT_MANIFEST_FILE)}.`);
61278
61554
  } catch (err) {
61279
61555
  f2.error(`Failed to write manifest: ${err.message}`);
61280
61556
  return null;
61281
61557
  }
61282
61558
  return scaffold;
61283
61559
  }
61284
- async function pickHarness(cwd2) {
61560
+ async function pickHarness2(cwd2) {
61285
61561
  const detections = await detectHarnesses(cwd2);
61286
61562
  const detected = detections.filter((d3) => d3.detection.detected);
61287
61563
  if (detected.length === 1) {
61288
- 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)}.`);
61289
61565
  return detected[0].adapter.id;
61290
61566
  }
61291
61567
  return await select({
@@ -61311,278 +61587,6 @@ function handleApiError4(err) {
61311
61587
  $e("Aborted.");
61312
61588
  }
61313
61589
 
61314
- // src/cli/agent-unpack.ts
61315
- import path50 from "node:path";
61316
- import fs46 from "node:fs";
61317
- import os13 from "node:os";
61318
- var import_picocolors31 = __toESM(require_picocolors(), 1);
61319
- async function runAgentUnpack(cwd2, args) {
61320
- banner("agent unpack — install this agent into a harness layout");
61321
- if (!hasManifest(cwd2)) {
61322
- f2.error(`No ${import_picocolors31.default.bold(AGENT_MANIFEST_FILE)} here.`);
61323
- f2.info(`Run ${import_picocolors31.default.cyan("brainbase agent pull <id>")} to bring an agent into this folder first.`);
61324
- return;
61325
- }
61326
- let manifest;
61327
- try {
61328
- manifest = readManifest(cwd2);
61329
- } catch (err) {
61330
- f2.error(err.message);
61331
- return;
61332
- }
61333
- if (!manifest.id) {
61334
- f2.error(`${import_picocolors31.default.bold(AGENT_MANIFEST_FILE)} is unclaimed (no ${import_picocolors31.default.cyan("id")}).`);
61335
- 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.`);
61336
- return;
61337
- }
61338
- let harness;
61339
- if (args.harness) {
61340
- harness = normalizeHarnessId(args.harness);
61341
- } else if (args.yes) {
61342
- if (!manifest.harness) {
61343
- f2.error(`--yes mode but no harness — set ${import_picocolors31.default.cyan("harness")} in the manifest or pass ${import_picocolors31.default.cyan("--harness")}.`);
61344
- return;
61345
- }
61346
- harness = normalizeHarnessId(manifest.harness);
61347
- } else {
61348
- harness = await pickHarness2(manifest.harness);
61349
- }
61350
- if (!autoProceed(args.yes)) {
61351
- const ok = await se({
61352
- message: `Install ${import_picocolors31.default.bold(manifest.agent.name)} as ${import_picocolors31.default.bold(harness)} here?`,
61353
- initialValue: true
61354
- });
61355
- if (!ensureNotCancelled(ok)) {
61356
- $e("Aborted.");
61357
- return;
61358
- }
61359
- }
61360
- const scope = args.scope ?? "project";
61361
- const stageRoot = fs46.mkdtempSync(path50.join(os13.tmpdir(), "brainbase-unpack-"));
61362
- try {
61363
- const toInstall = [];
61364
- const instructionsBody = readInstructions(cwd2, manifest);
61365
- if (instructionsBody && instructionsBody.trim()) {
61366
- const compDir = path50.join(stageRoot, "instruction", "agent-instructions");
61367
- ensureDir(compDir);
61368
- fs46.writeFileSync(path50.join(compDir, "instructions.md"), instructionsBody, "utf8");
61369
- toInstall.push({
61370
- type: "instruction",
61371
- slug: "agent-instructions",
61372
- scope,
61373
- rootDir: compDir,
61374
- description: "Agent instructions",
61375
- checksum: ""
61376
- });
61377
- }
61378
- for (const entry of manifest.playbooks ?? []) {
61379
- const issue = stageLocalPlaybook(entry, cwd2, stageRoot, scope, toInstall);
61380
- if (issue) {
61381
- f2.warn(issue);
61382
- }
61383
- }
61384
- for (const entry of manifest.skills ?? []) {
61385
- const issue = stageLocalSkill(entry.source, cwd2, stageRoot, scope, toInstall);
61386
- if (issue) {
61387
- f2.warn(issue);
61388
- }
61389
- }
61390
- for (const entry of manifest.mcp ?? []) {
61391
- const compDir = path50.join(stageRoot, "mcp", entry.name);
61392
- ensureDir(compDir);
61393
- const payload = {};
61394
- if (entry.url !== undefined)
61395
- payload.url = entry.url;
61396
- if (entry.command !== undefined)
61397
- payload.command = entry.command;
61398
- if (entry.args !== undefined)
61399
- payload.args = entry.args;
61400
- if (entry.env !== undefined)
61401
- payload.env = entry.env;
61402
- if (entry.headers !== undefined)
61403
- payload.headers = entry.headers;
61404
- payload.is_enabled = entry.is_enabled ?? true;
61405
- toInstall.push({
61406
- type: "mcp",
61407
- slug: entry.name,
61408
- scope,
61409
- rootDir: compDir,
61410
- payload: proxifyMcpPayload(payload),
61411
- checksum: ""
61412
- });
61413
- }
61414
- const caps = capabilitiesFromManifest(manifest);
61415
- const declaredMcpSlugs = new Set((manifest.mcp ?? []).map((m3) => m3.name));
61416
- const { install: builtinInstall, removeSlugs: builtinRemoveSlugs } = resolveBuiltinMcps({
61417
- caps,
61418
- declaredSlugs: declaredMcpSlugs,
61419
- scope
61420
- });
61421
- toInstall.push(...builtinInstall);
61422
- writeResolvedMcps(cwd2, toInstall);
61423
- const opts = {
61424
- cwd: cwd2,
61425
- scope,
61426
- resolveConflict: async (_c) => "overwrite",
61427
- resolveSecret: async () => null
61428
- };
61429
- const sp = de();
61430
- sp.start("Installing harness layout…");
61431
- const result2 = await runHarnessInstall3(harness, toInstall, opts, manifest.agent.name);
61432
- sp.stop("Installed.");
61433
- if (result2.skipped.length) {
61434
- f2.warn(`Skipped: ${result2.skipped.map((s3) => `${s3.type}/${s3.slug} (${s3.reason})`).join(", ")}`);
61435
- }
61436
- if (builtinRemoveSlugs.length > 0) {
61437
- runHarnessRemoveMcp(harness, builtinRemoveSlugs, { cwd: cwd2, scope });
61438
- }
61439
- } catch (err) {
61440
- f2.error(`Install failed: ${err.message}`);
61441
- return;
61442
- } finally {
61443
- try {
61444
- fs46.rmSync(stageRoot, { recursive: true, force: true });
61445
- } catch {}
61446
- }
61447
- if (manifest.harness !== harness) {
61448
- manifest.harness = harness;
61449
- writeManifest(cwd2, manifest);
61450
- }
61451
- $e(`Unpacked ${import_picocolors31.default.bold(manifest.agent.name)} as ${import_picocolors31.default.bold(harness)}.`);
61452
- await showResultCard({
61453
- title: "UNPACKED",
61454
- tone: "ok",
61455
- subtitle: manifest.agent.name,
61456
- meta: [
61457
- ["harness", harness],
61458
- ["agent", manifest.id]
61459
- ]
61460
- });
61461
- }
61462
- function writeResolvedMcps(workdir, toInstall) {
61463
- const mcps = toInstall.filter((c2) => c2.type === "mcp").map((c2) => ({ name: c2.slug, ...c2.payload }));
61464
- const dir = path50.join(workdir, ".brainbase");
61465
- fs46.mkdirSync(dir, { recursive: true });
61466
- fs46.writeFileSync(path50.join(dir, "resolved-mcps.json"), JSON.stringify(mcps, null, 2));
61467
- }
61468
- function stageLocalPlaybook(entry, cwd2, stageRoot, scope, toInstall) {
61469
- if (entry.content.text !== undefined && entry.content.file !== undefined) {
61470
- return `Playbook ${entry.title}: both text and file set — skipped.`;
61471
- }
61472
- const body = resolvePlaybookContent(cwd2, entry);
61473
- if (body === null) {
61474
- return entry.content.file ? `Playbook ${entry.title}: file ${entry.content.file} not found — skipped.` : `Playbook ${entry.title}: content empty — skipped.`;
61475
- }
61476
- const slug = slugifyPlaybookTitle(entry.title);
61477
- const compDir = path50.join(stageRoot, "playbook", slug);
61478
- ensureDir(compDir);
61479
- const wireBody = /^---\s*\n/.test(body) ? body : assembleFrontmatter(entry.title, entry.description) + body.replace(/^\n+/, "");
61480
- fs46.writeFileSync(path50.join(compDir, `${slug}.md`), wireBody, "utf8");
61481
- toInstall.push({
61482
- type: "playbook",
61483
- slug,
61484
- scope,
61485
- rootDir: compDir,
61486
- description: entry.description,
61487
- checksum: ""
61488
- });
61489
- return null;
61490
- }
61491
- function stageLocalSkill(source, cwd2, stageRoot, scope, toInstall) {
61492
- if (source.startsWith("./") || source.startsWith("../") || source.startsWith("/")) {
61493
- const abs = path50.resolve(cwd2, source);
61494
- if (!fs46.existsSync(abs)) {
61495
- return `Skill ${source}: not found on disk — skipped.`;
61496
- }
61497
- const slug = path50.basename(abs);
61498
- const compDir = path50.join(stageRoot, "skill", slug);
61499
- ensureDir(compDir);
61500
- copyDirRecursive(abs, compDir);
61501
- toInstall.push({
61502
- type: "skill",
61503
- slug,
61504
- scope,
61505
- rootDir: compDir,
61506
- checksum: ""
61507
- });
61508
- return null;
61509
- }
61510
- try {
61511
- const parsed = parseSkillSource(source);
61512
- if (parsed.type === "local" || parsed.type === "inline")
61513
- return null;
61514
- const slug = defaultSlugForSource(source);
61515
- const compDir = path50.join(stageRoot, "skill", slug);
61516
- ensureDir(compDir);
61517
- toInstall.push({
61518
- type: "skill",
61519
- slug,
61520
- scope,
61521
- rootDir: compDir,
61522
- source: parsed,
61523
- checksum: ""
61524
- });
61525
- return null;
61526
- } catch (err) {
61527
- return `Skill ${source}: ${err.message} — skipped.`;
61528
- }
61529
- }
61530
- function defaultSlugForSource(source) {
61531
- const reg = /^registry:(?:[a-z0-9_-]+\/)?([a-z0-9_-]+)/i.exec(source);
61532
- if (reg)
61533
- return reg[1].toLowerCase();
61534
- const gh = /^(?:github|git):[^/]*\/?([a-z0-9_-]+)/i.exec(source);
61535
- if (gh)
61536
- return gh[1].toLowerCase();
61537
- return source.replace(/[^a-z0-9_-]/gi, "-").slice(0, 60) || "skill";
61538
- }
61539
- function copyDirRecursive(src, dest) {
61540
- ensureDir(dest);
61541
- for (const entry of fs46.readdirSync(src, { withFileTypes: true })) {
61542
- const s3 = path50.join(src, entry.name);
61543
- const d3 = path50.join(dest, entry.name);
61544
- if (entry.isDirectory())
61545
- copyDirRecursive(s3, d3);
61546
- else if (entry.isFile())
61547
- fs46.copyFileSync(s3, d3);
61548
- }
61549
- }
61550
- function assembleFrontmatter(title, description) {
61551
- const lines = ["---", `title: ${yamlScalar(title)}`];
61552
- if (description)
61553
- lines.push(`description: ${yamlScalar(description)}`);
61554
- lines.push("---", "");
61555
- return lines.join(`
61556
- `);
61557
- }
61558
- function yamlScalar(s3) {
61559
- if (!/[\n":#&*!|>'%@`{}[\]]/.test(s3) && s3.trim() === s3 && s3 !== "")
61560
- return s3;
61561
- return JSON.stringify(s3);
61562
- }
61563
- function runHarnessInstall3(harnessId, components, opts, agentName) {
61564
- if (harnessId === "claude-code")
61565
- return installClaudeCodeWithCtx(components, opts, agentName);
61566
- if (harnessId === "codex")
61567
- return installCodexWithCtx(components, opts, agentName);
61568
- if (harnessId === "kafka")
61569
- return installKafkaWithCtx(components, opts, agentName);
61570
- return getAdapter(harnessId).install(components, opts);
61571
- }
61572
- async function pickHarness2(current) {
61573
- const initial2 = current ? normalizeHarnessId(current) : undefined;
61574
- return select({
61575
- message: "Pick a harness to install as",
61576
- options: adapters.map((a3) => ({
61577
- value: a3.id,
61578
- label: a3.displayName,
61579
- hint: a3.id === initial2 ? "current" : undefined
61580
- })),
61581
- initialValue: initial2 ?? adapters[0].id,
61582
- flagHint: "Pass --harness <id> to choose non-interactively."
61583
- });
61584
- }
61585
-
61586
61590
  // src/cli/agent.ts
61587
61591
  async function runAgent(cwd2, sub, args, opts) {
61588
61592
  switch (sub) {
@@ -61604,7 +61608,8 @@ async function runAgent(cwd2, sub, args, opts) {
61604
61608
  scope: opts.scope,
61605
61609
  agentIdArg: args[0],
61606
61610
  force: opts.force,
61607
- runEntrypoint: opts.runEntrypoint
61611
+ runEntrypoint: opts.runEntrypoint,
61612
+ acp: opts.acp
61608
61613
  });
61609
61614
  return;
61610
61615
  case "push":
@@ -61614,7 +61619,8 @@ async function runAgent(cwd2, sub, args, opts) {
61614
61619
  await runAgentUnpack(cwd2, {
61615
61620
  yes: opts.yes,
61616
61621
  scope: opts.scope,
61617
- harness: opts.harness
61622
+ harness: opts.harness,
61623
+ acp: opts.acp
61618
61624
  });
61619
61625
  return;
61620
61626
  case "status":
@@ -63558,10 +63564,11 @@ var import_picocolors41 = __toESM(require_picocolors(), 1);
63558
63564
 
63559
63565
  // src/core/mcp-check/collect-servers.ts
63560
63566
  import path55 from "node:path";
63567
+ import fs52 from "node:fs";
63561
63568
  function collectServers(cwd2, env3 = process.env) {
63562
63569
  const out = [];
63563
63570
  const seen = new Set;
63564
- for (const source of [readClaudeCode, readCodex, readKafka]) {
63571
+ for (const source of [readClaudeCode, readCodex, readKafka, readResolvedMcps]) {
63565
63572
  for (const [name, entry] of source(cwd2)) {
63566
63573
  pushResolved(out, seen, name, entry, env3);
63567
63574
  }
@@ -63607,6 +63614,33 @@ function pushResolved(out, seen, name, entry, env3) {
63607
63614
  seen.add(name);
63608
63615
  out.push({ name, url: finalUrl, headers });
63609
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
+ }
63610
63644
  function readClaudeCode(cwd2) {
63611
63645
  const file = path55.join(cwd2, ".mcp.json");
63612
63646
  const map2 = listMcpServersFromMcpJson(file);
@@ -72080,7 +72114,7 @@ async function main() {
72080
72114
  const rawCwd = process14.cwd();
72081
72115
  const cwd2 = (() => {
72082
72116
  try {
72083
- return fs52.realpathSync(rawCwd);
72117
+ return fs53.realpathSync(rawCwd);
72084
72118
  } catch {
72085
72119
  return rawCwd;
72086
72120
  }
@@ -72122,6 +72156,7 @@ async function main() {
72122
72156
  const schemaFlag = getFlag(argv, "--schema");
72123
72157
  const noPushFlag = hasFlag2(argv, "--no-push");
72124
72158
  const jsonFlag = hasFlag2(argv, "--json");
72159
+ const acpFlag = hasFlag2(argv, "--acp");
72125
72160
  ensureSkillResolversRegistered();
72126
72161
  await requireAuth(cmd);
72127
72162
  try {
@@ -72203,7 +72238,8 @@ async function main() {
72203
72238
  noTracking,
72204
72239
  track,
72205
72240
  force: forceFlag,
72206
- runEntrypoint: runEntrypointFlag
72241
+ runEntrypoint: runEntrypointFlag,
72242
+ acp: acpFlag
72207
72243
  });
72208
72244
  break;
72209
72245
  }