@biffo/cli 0.103.0 → 0.103.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +203 -80
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -6627,8 +6627,8 @@ function printEntry(entry) {
6627
6627
  }
6628
6628
 
6629
6629
  // src/commands/plugin-install.ts
6630
- import { cpSync as cpSync3, existsSync as existsSync24, mkdirSync as mkdirSync9, readFileSync as readFileSync18, statSync as statSync6 } from "fs";
6631
- import { basename, join as join25, relative as relative3, resolve as resolve12 } from "path";
6630
+ import { cpSync as cpSync3, existsSync as existsSync25, mkdirSync as mkdirSync9, readFileSync as readFileSync19, statSync as statSync6 } from "fs";
6631
+ import { basename, join as join26, relative as relative3, resolve as resolve12 } from "path";
6632
6632
  import chalk15 from "chalk";
6633
6633
  import { Command as Command15 } from "commander";
6634
6634
 
@@ -6674,6 +6674,120 @@ var PluginMigrationsAdapter = class {
6674
6674
  }
6675
6675
  };
6676
6676
 
6677
+ // src/lib/plugin-workspace-sources.ts
6678
+ import { existsSync as existsSync24, readdirSync as readdirSync12, readFileSync as readFileSync18, writeFileSync as writeFileSync9 } from "fs";
6679
+ import { join as join25 } from "path";
6680
+ function readTomlStringArray(text, key) {
6681
+ const open = new RegExp(`^${key}\\s*=\\s*\\[`, "m").exec(text);
6682
+ if (!open) return [];
6683
+ const start = open.index + open[0].length;
6684
+ let depth = 1;
6685
+ let inString = false;
6686
+ let quote = "";
6687
+ let end = -1;
6688
+ for (let i = start; i < text.length; i++) {
6689
+ const c = text[i];
6690
+ if (inString) {
6691
+ if (c === quote) inString = false;
6692
+ } else if (c === '"' || c === "'") {
6693
+ inString = true;
6694
+ quote = c;
6695
+ } else if (c === "[") {
6696
+ depth++;
6697
+ } else if (c === "]") {
6698
+ depth--;
6699
+ if (depth === 0) {
6700
+ end = i;
6701
+ break;
6702
+ }
6703
+ }
6704
+ }
6705
+ if (end === -1) return [];
6706
+ const body = text.slice(start, end);
6707
+ return [...body.matchAll(/["']([^"']+)["']/g)].map((m) => m[1]);
6708
+ }
6709
+ function readProjectName(text) {
6710
+ let inProject = false;
6711
+ for (const line of text.split("\n")) {
6712
+ const trimmed = line.trim();
6713
+ if (trimmed.startsWith("[")) {
6714
+ inProject = trimmed === "[project]";
6715
+ continue;
6716
+ }
6717
+ if (inProject) {
6718
+ const m = /^name\s*=\s*["']([^"']+)["']/.exec(trimmed);
6719
+ if (m) return m[1];
6720
+ }
6721
+ }
6722
+ return null;
6723
+ }
6724
+ function readDependencyNames(text) {
6725
+ return readTomlStringArray(text, "dependencies").map((dep) => /^\s*([A-Za-z0-9._-]+)/.exec(dep)?.[1] ?? "").filter(Boolean);
6726
+ }
6727
+ function workspaceMemberNames(instanceRoot) {
6728
+ const rootPyproject = join25(instanceRoot, "pyproject.toml");
6729
+ if (!existsSync24(rootPyproject)) return /* @__PURE__ */ new Set();
6730
+ const text = readFileSync18(rootPyproject, "utf8");
6731
+ const members = readTomlStringArray(text, "members");
6732
+ const excluded = new Set(readTomlStringArray(text, "exclude"));
6733
+ const dirs = [];
6734
+ for (const member of members) {
6735
+ if (member.endsWith("/*")) {
6736
+ const base = member.slice(0, -2);
6737
+ let entries;
6738
+ try {
6739
+ entries = readdirSync12(join25(instanceRoot, base), { withFileTypes: true });
6740
+ } catch {
6741
+ continue;
6742
+ }
6743
+ for (const entry of entries) {
6744
+ const rel = `${base}/${entry.name}`;
6745
+ if (entry.isDirectory() && !entry.name.startsWith(".") && !excluded.has(rel)) dirs.push(rel);
6746
+ }
6747
+ } else if (!excluded.has(member)) {
6748
+ dirs.push(member);
6749
+ }
6750
+ }
6751
+ const names = /* @__PURE__ */ new Set();
6752
+ for (const dir of dirs) {
6753
+ const pp = join25(instanceRoot, dir, "pyproject.toml");
6754
+ if (!existsSync24(pp)) continue;
6755
+ const name = readProjectName(readFileSync18(pp, "utf8"));
6756
+ if (name) names.add(name);
6757
+ }
6758
+ return names;
6759
+ }
6760
+ function existingWorkspaceSources(text) {
6761
+ return new Set(
6762
+ [...text.matchAll(/^\s*([A-Za-z0-9._-]+)\s*=\s*\{[^}]*\bworkspace\b/gm)].map((m) => m[1])
6763
+ );
6764
+ }
6765
+ function ensureWorkspaceSources(pluginPyprojectPath, memberNames) {
6766
+ if (!existsSync24(pluginPyprojectPath) || memberNames.size === 0) return [];
6767
+ const text = readFileSync18(pluginPyprojectPath, "utf8");
6768
+ const already = existingWorkspaceSources(text);
6769
+ const toAdd = readDependencyNames(text).filter((n) => memberNames.has(n) && !already.has(n));
6770
+ if (toAdd.length === 0) return [];
6771
+ const lines = toAdd.map((n) => `${n} = { workspace = true }`);
6772
+ const header = /^\[tool\.uv\.sources\]\s*$/m.exec(text);
6773
+ let updated;
6774
+ if (header) {
6775
+ const insertAt = header.index + header[0].length;
6776
+ updated = `${text.slice(0, insertAt)}
6777
+ ${lines.join("\n")}${text.slice(insertAt)}`;
6778
+ } else {
6779
+ const sep4 = text.endsWith("\n") ? "" : "\n";
6780
+ updated = `${text}${sep4}
6781
+ # Vendored into this instance by \`biffo plugin install\`: resolve dependencies the
6782
+ # instance's uv workspace provides as members from the workspace, not PyPI.
6783
+ [tool.uv.sources]
6784
+ ${lines.join("\n")}
6785
+ `;
6786
+ }
6787
+ writeFileSync9(pluginPyprojectPath, updated);
6788
+ return toAdd;
6789
+ }
6790
+
6677
6791
  // src/commands/plugin-install.ts
6678
6792
  var TARGET_PATTERN = /^([a-z][a-z0-9-]*)@(\d+\.\d+)$/;
6679
6793
  var pluginInstallCommand = new Command15("install").description(
@@ -6716,14 +6830,14 @@ var LOCAL_COPY_EXCLUDES = /* @__PURE__ */ new Set([
6716
6830
  ".terraform"
6717
6831
  ]);
6718
6832
  function resolveLocalPlugin(localPath) {
6719
- if (!existsSync24(localPath)) {
6833
+ if (!existsSync25(localPath)) {
6720
6834
  throw new Error(`--local path does not exist: ${localPath}`);
6721
6835
  }
6722
6836
  if (!statSync6(localPath).isDirectory()) {
6723
6837
  throw new Error(`--local path is not a directory: ${localPath}`);
6724
6838
  }
6725
- const manifestPath = join25(localPath, "biffo.plugin.json");
6726
- if (!existsSync24(manifestPath)) {
6839
+ const manifestPath = join26(localPath, "biffo.plugin.json");
6840
+ if (!existsSync25(manifestPath)) {
6727
6841
  throw new Error(
6728
6842
  `${localPath} does not contain a biffo.plugin.json manifest at its root \u2014 is it a plugin directory? (Scaffold one with \`biffo plugin create <name>\`.)`
6729
6843
  );
@@ -6749,8 +6863,8 @@ function parsePluginTarget(target) {
6749
6863
  async function cloneAndValidatePlugin(entry, git) {
6750
6864
  const tmpDir = await git.cloneToTemp(entry.repo, `biffo-plugin-${entry.name}`);
6751
6865
  try {
6752
- const manifestPath = join25(tmpDir, "biffo.plugin.json");
6753
- if (!existsSync24(manifestPath)) {
6866
+ const manifestPath = join26(tmpDir, "biffo.plugin.json");
6867
+ if (!existsSync25(manifestPath)) {
6754
6868
  throw new Error(
6755
6869
  `Plugin repo ${entry.repo} does not contain a biffo.plugin.json manifest at its root.`
6756
6870
  );
@@ -6778,8 +6892,8 @@ async function runPluginInstall(target, options, deps) {
6778
6892
  `Nothing to install. Pass a registry target (e.g. \`biffo plugin install acme-crm@1.0\`) or a local plugin directory (\`biffo plugin install --local services/acme-crm\`).`
6779
6893
  );
6780
6894
  }
6781
- const servicesDir = join25(options.cwd, "services");
6782
- if (!existsSync24(servicesDir)) {
6895
+ const servicesDir = join26(options.cwd, "services");
6896
+ if (!existsSync25(servicesDir)) {
6783
6897
  throw new Error(
6784
6898
  `${servicesDir} does not exist \u2014 is ${options.cwd} the root of a Biffo project checkout?`
6785
6899
  );
@@ -6797,10 +6911,10 @@ async function runPluginInstall(target, options, deps) {
6797
6911
  }
6798
6912
  const pluginName = entry ? entry.name : source.name;
6799
6913
  const relTargetDir = pluginDir(pluginName, "third-party");
6800
- const targetDir = join25(options.cwd, relTargetDir);
6801
- const modulesDir = join25(options.cwd, "modules", "plugins", pluginName);
6914
+ const targetDir = join26(options.cwd, relTargetDir);
6915
+ const modulesDir = join26(options.cwd, "modules", "plugins", pluginName);
6802
6916
  const inTreeSource = options.local !== void 0 && resolve12(options.local) === resolve12(targetDir);
6803
- if (existsSync24(targetDir) && !inTreeSource) {
6917
+ if (existsSync25(targetDir) && !inTreeSource) {
6804
6918
  throw new Error(
6805
6919
  `Plugin '${pluginName}' is already installed at ${relTargetDir}/. Remove it first, or wait for a future 'biffo plugin upgrade' command.`
6806
6920
  );
@@ -6842,9 +6956,18 @@ async function runPluginInstall(target, options, deps) {
6842
6956
  });
6843
6957
  log.success(`Installed plugin source at ${relTargetDir}/`);
6844
6958
  }
6959
+ const pluginPyproject = join26(targetDir, "pyproject.toml");
6960
+ if (existsSync25(pluginPyproject)) {
6961
+ const sourced = ensureWorkspaceSources(pluginPyproject, workspaceMemberNames(options.cwd));
6962
+ if (sourced.length > 0) {
6963
+ log.info(
6964
+ `Sourced ${sourced.join(", ")} from the workspace in ${relTargetDir}/pyproject.toml (the instance provides it as a workspace member).`
6965
+ );
6966
+ }
6967
+ }
6845
6968
  const stagePaths = [relTargetDir];
6846
- const tfSourceDir = join25(targetDir, "terraform");
6847
- if (existsSync24(tfSourceDir)) {
6969
+ const tfSourceDir = join26(targetDir, "terraform");
6970
+ if (existsSync25(tfSourceDir)) {
6848
6971
  mkdirSync9(modulesDir, { recursive: true });
6849
6972
  cpSync3(tfSourceDir, modulesDir, { recursive: true });
6850
6973
  stagePaths.push(`modules/plugins/${pluginName}`);
@@ -6923,7 +7046,7 @@ async function runPluginInstall(target, options, deps) {
6923
7046
  }
6924
7047
  function parseManifestFile(path) {
6925
7048
  try {
6926
- return JSON.parse(readFileSync18(path, "utf8"));
7049
+ return JSON.parse(readFileSync19(path, "utf8"));
6927
7050
  } catch (err) {
6928
7051
  throw new Error(`Could not parse ${path} as JSON: ${err.message}`);
6929
7052
  }
@@ -6960,8 +7083,8 @@ function printDryRun4(entry, source, relTargetDir, inTreeSource) {
6960
7083
  }
6961
7084
 
6962
7085
  // src/commands/plugin-list.ts
6963
- import { existsSync as existsSync25, readFileSync as readFileSync19 } from "fs";
6964
- import { join as join26, resolve as resolve13 } from "path";
7086
+ import { existsSync as existsSync26, readFileSync as readFileSync20 } from "fs";
7087
+ import { join as join27, resolve as resolve13 } from "path";
6965
7088
  import chalk16 from "chalk";
6966
7089
  import { Command as Command16 } from "commander";
6967
7090
  var pluginListCommand = new Command16("list").description("List plugins installed in this project checkout").option("--cwd <path>", "Project root to scan (defaults to the current directory)").action(async (options) => {
@@ -6974,8 +7097,8 @@ var pluginListCommand = new Command16("list").description("List plugins installe
6974
7097
  }
6975
7098
  });
6976
7099
  async function runPluginList(options) {
6977
- const servicesDir = join26(options.cwd, "services");
6978
- if (!existsSync25(servicesDir)) {
7100
+ const servicesDir = join27(options.cwd, "services");
7101
+ if (!existsSync26(servicesDir)) {
6979
7102
  throw new Error(
6980
7103
  `${servicesDir} does not exist \u2014 is ${options.cwd} the root of a Biffo project checkout?`
6981
7104
  );
@@ -6983,7 +7106,7 @@ async function runPluginList(options) {
6983
7106
  const plugins = [];
6984
7107
  for (const location of findInstalledPlugins(options.cwd)) {
6985
7108
  try {
6986
- const manifest = validateManifest(JSON.parse(readFileSync19(location.manifestPath, "utf8")));
7109
+ const manifest = validateManifest(JSON.parse(readFileSync20(location.manifestPath, "utf8")));
6987
7110
  plugins.push({
6988
7111
  name: manifest.name,
6989
7112
  version: manifest.version,
@@ -7020,8 +7143,8 @@ async function runPluginList(options) {
7020
7143
  }
7021
7144
 
7022
7145
  // src/commands/plugin-sync-migrations.ts
7023
- import { existsSync as existsSync26 } from "fs";
7024
- import { join as join27, relative as relative4, resolve as resolve14 } from "path";
7146
+ import { existsSync as existsSync27 } from "fs";
7147
+ import { join as join28, relative as relative4, resolve as resolve14 } from "path";
7025
7148
  import chalk17 from "chalk";
7026
7149
  import { Command as Command17 } from "commander";
7027
7150
  var pluginSyncMigrationsCommand = new Command17("sync-migrations").description(
@@ -7042,11 +7165,11 @@ var pluginSyncMigrationsCommand = new Command17("sync-migrations").description(
7042
7165
  }
7043
7166
  );
7044
7167
  async function runPluginSyncMigrations(name, options, deps) {
7045
- const servicesDir = join27(options.cwd, "services");
7046
- if (!existsSync26(servicesDir)) {
7168
+ const servicesDir = join28(options.cwd, "services");
7169
+ if (!existsSync27(servicesDir)) {
7047
7170
  throw new Error(`${servicesDir} does not exist \u2014 is ${options.cwd} a Biffo project checkout?`);
7048
7171
  }
7049
- if (name && !existsSync26(join27(servicesDir, name, "biffo.plugin.json"))) {
7172
+ if (name && !existsSync27(join28(servicesDir, name, "biffo.plugin.json"))) {
7050
7173
  throw new Error(`Plugin '${name}' is not installed at services/${name}/.`);
7051
7174
  }
7052
7175
  if (options.dryRun) {
@@ -7082,8 +7205,8 @@ async function runPluginSyncMigrations(name, options, deps) {
7082
7205
  }
7083
7206
 
7084
7207
  // src/commands/plugin-uninstall.ts
7085
- import { existsSync as existsSync27, readFileSync as readFileSync20, rmSync as rmSync8 } from "fs";
7086
- import { join as join28, resolve as resolve15 } from "path";
7208
+ import { existsSync as existsSync28, readFileSync as readFileSync21, rmSync as rmSync8 } from "fs";
7209
+ import { join as join29, resolve as resolve15 } from "path";
7087
7210
  import chalk18 from "chalk";
7088
7211
  import { Command as Command18 } from "commander";
7089
7212
  import inquirer6 from "inquirer";
@@ -7115,16 +7238,16 @@ async function runPluginUninstall(name, options, deps) {
7115
7238
  if (!NAME_PATTERN2.test(name)) {
7116
7239
  throw new Error(`Invalid plugin name '${name}'. Expected a lowercase kebab-case slug.`);
7117
7240
  }
7118
- const servicesDir = join28(options.cwd, "services");
7119
- if (!existsSync27(servicesDir)) {
7241
+ const servicesDir = join29(options.cwd, "services");
7242
+ if (!existsSync28(servicesDir)) {
7120
7243
  throw new Error(
7121
7244
  `${servicesDir} does not exist \u2014 is ${options.cwd} the root of a Biffo project checkout?`
7122
7245
  );
7123
7246
  }
7124
- const targetDir = join28(servicesDir, name);
7125
- if (!existsSync27(targetDir)) {
7126
- const firstParty = join28(servicesDir, FIRST_PARTY_PLUGINS_DIR, name);
7127
- if (existsSync27(firstParty)) {
7247
+ const targetDir = join29(servicesDir, name);
7248
+ if (!existsSync28(targetDir)) {
7249
+ const firstParty = join29(servicesDir, FIRST_PARTY_PLUGINS_DIR, name);
7250
+ if (existsSync28(firstParty)) {
7128
7251
  throw new Error(
7129
7252
  `Plugin '${name}' is a first-party plugin at ${pluginDir(name, "first-party")}/, which is template-owned \u2014 \`biffo core upgrade\` would restore it on the next upgrade. Disable it instead by removing '${name}' from \`enabled_plugins\` in infra/environments/<env>/main.tf and re-applying.`
7130
7253
  );
@@ -7132,9 +7255,9 @@ async function runPluginUninstall(name, options, deps) {
7132
7255
  throw new Error(`Plugin '${name}' is not installed at services/${name}/.`);
7133
7256
  }
7134
7257
  const version = readInstalledVersion(targetDir);
7135
- const modulesDir = join28(options.cwd, "modules", "plugins", name);
7258
+ const modulesDir = join29(options.cwd, "modules", "plugins", name);
7136
7259
  const stagePaths = [`services/${name}`];
7137
- if (existsSync27(modulesDir)) {
7260
+ if (existsSync28(modulesDir)) {
7138
7261
  stagePaths.push(`modules/plugins/${name}`);
7139
7262
  }
7140
7263
  if (options.dryRun) {
@@ -7156,7 +7279,7 @@ async function runPluginUninstall(name, options, deps) {
7156
7279
  }
7157
7280
  rmSync8(targetDir, { recursive: true, force: true });
7158
7281
  log.success(`Removed services/${name}/`);
7159
- if (existsSync27(modulesDir)) {
7282
+ if (existsSync28(modulesDir)) {
7160
7283
  rmSync8(modulesDir, { recursive: true, force: true });
7161
7284
  log.success(`Removed modules/plugins/${name}/`);
7162
7285
  const wiring = syncPluginTerraform(options.cwd);
@@ -7193,10 +7316,10 @@ async function runPluginUninstall(name, options, deps) {
7193
7316
  }
7194
7317
  }
7195
7318
  function readInstalledVersion(targetDir) {
7196
- const manifestPath = join28(targetDir, "biffo.plugin.json");
7197
- if (!existsSync27(manifestPath)) return void 0;
7319
+ const manifestPath = join29(targetDir, "biffo.plugin.json");
7320
+ if (!existsSync28(manifestPath)) return void 0;
7198
7321
  try {
7199
- return validateManifest(JSON.parse(readFileSync20(manifestPath, "utf8"))).version;
7322
+ return validateManifest(JSON.parse(readFileSync21(manifestPath, "utf8"))).version;
7200
7323
  } catch {
7201
7324
  return void 0;
7202
7325
  }
@@ -7229,8 +7352,8 @@ function printDryRun5(name, version, stagePaths, keepData) {
7229
7352
  }
7230
7353
 
7231
7354
  // src/commands/plugin-upgrade.ts
7232
- import { cpSync as cpSync4, existsSync as existsSync28, mkdirSync as mkdirSync10, readFileSync as readFileSync21, rmSync as rmSync9 } from "fs";
7233
- import { join as join29, relative as relative5, resolve as resolve16 } from "path";
7355
+ import { cpSync as cpSync4, existsSync as existsSync29, mkdirSync as mkdirSync10, readFileSync as readFileSync22, rmSync as rmSync9 } from "fs";
7356
+ import { join as join30, relative as relative5, resolve as resolve16 } from "path";
7234
7357
  import chalk19 from "chalk";
7235
7358
  import { Command as Command19 } from "commander";
7236
7359
  import inquirer7 from "inquirer";
@@ -7255,14 +7378,14 @@ var pluginUpgradeCommand = new Command19("upgrade").description(
7255
7378
  });
7256
7379
  async function runPluginUpgrade(target, options, deps) {
7257
7380
  const { name, minor } = parsePluginTarget(target);
7258
- const servicesDir = join29(options.cwd, "services");
7259
- if (!existsSync28(servicesDir)) {
7381
+ const servicesDir = join30(options.cwd, "services");
7382
+ if (!existsSync29(servicesDir)) {
7260
7383
  throw new Error(
7261
7384
  `${servicesDir} does not exist \u2014 is ${options.cwd} the root of a Biffo project checkout?`
7262
7385
  );
7263
7386
  }
7264
- const targetDir = join29(servicesDir, name);
7265
- if (!existsSync28(targetDir)) {
7387
+ const targetDir = join30(servicesDir, name);
7388
+ if (!existsSync29(targetDir)) {
7266
7389
  throw new Error(
7267
7390
  `Plugin '${name}' is not installed at services/${name}/. Use 'biffo plugin install ${name}@${minor}' instead.`
7268
7391
  );
@@ -7276,7 +7399,7 @@ async function runPluginUpgrade(target, options, deps) {
7276
7399
  `Plugin declares required_core_version '${entry.required_core_version}'. The CLI cannot verify this against your deployment \u2014 the Core API exposes no version endpoint and services/api/pyproject.toml's version is a static placeholder, not a real release marker. Confirm compatibility yourself before deploying.`
7277
7400
  );
7278
7401
  }
7279
- const modulesDir = join29(options.cwd, "modules", "plugins", entry.name);
7402
+ const modulesDir = join30(options.cwd, "modules", "plugins", entry.name);
7280
7403
  if (options.dryRun) {
7281
7404
  printDryRun6(entry, currentVersion);
7282
7405
  return;
@@ -7309,11 +7432,11 @@ async function runPluginUpgrade(target, options, deps) {
7309
7432
  cpSync4(tmpDir, targetDir, { recursive: true });
7310
7433
  log.success(`Upgraded plugin source at services/${entry.name}/`);
7311
7434
  const stagePaths = [`services/${entry.name}`];
7312
- if (existsSync28(modulesDir)) {
7435
+ if (existsSync29(modulesDir)) {
7313
7436
  rmSync9(modulesDir, { recursive: true, force: true });
7314
7437
  }
7315
- const tfSourceDir = join29(targetDir, "terraform");
7316
- if (existsSync28(tfSourceDir)) {
7438
+ const tfSourceDir = join30(targetDir, "terraform");
7439
+ if (existsSync29(tfSourceDir)) {
7317
7440
  mkdirSync10(modulesDir, { recursive: true });
7318
7441
  cpSync4(tfSourceDir, modulesDir, { recursive: true });
7319
7442
  stagePaths.push(`modules/plugins/${entry.name}`);
@@ -7347,10 +7470,10 @@ async function runPluginUpgrade(target, options, deps) {
7347
7470
  }
7348
7471
  }
7349
7472
  function readInstalledVersion2(targetDir) {
7350
- const manifestPath = join29(targetDir, "biffo.plugin.json");
7351
- if (!existsSync28(manifestPath)) return void 0;
7473
+ const manifestPath = join30(targetDir, "biffo.plugin.json");
7474
+ if (!existsSync29(manifestPath)) return void 0;
7352
7475
  try {
7353
- return validateManifest(JSON.parse(readFileSync21(manifestPath, "utf8"))).version;
7476
+ return validateManifest(JSON.parse(readFileSync22(manifestPath, "utf8"))).version;
7354
7477
  } catch {
7355
7478
  return void 0;
7356
7479
  }
@@ -7379,14 +7502,14 @@ function printDryRun6(entry, currentVersion) {
7379
7502
  }
7380
7503
 
7381
7504
  // src/commands/plugin-wire.ts
7382
- import { existsSync as existsSync30, readFileSync as readFileSync23 } from "fs";
7505
+ import { existsSync as existsSync31, readFileSync as readFileSync24 } from "fs";
7383
7506
  import { resolve as resolve17 } from "path";
7384
7507
  import chalk20 from "chalk";
7385
7508
  import { Command as Command20 } from "commander";
7386
7509
 
7387
7510
  // src/lib/plugin-origin.ts
7388
- import { existsSync as existsSync29, readFileSync as readFileSync22, writeFileSync as writeFileSync9 } from "fs";
7389
- import { join as join30 } from "path";
7511
+ import { existsSync as existsSync30, readFileSync as readFileSync23, writeFileSync as writeFileSync10 } from "fs";
7512
+ import { join as join31 } from "path";
7390
7513
  var PLUGIN_API_TFVARS = "plugin-apis.auto.tfvars.json";
7391
7514
  var SIBLINGS_TFVARS = "siblings.auto.tfvars.json";
7392
7515
  function upsertPluginApiOrigin(existing, entry) {
@@ -7396,9 +7519,9 @@ function serializePluginApiRegistry(origins) {
7396
7519
  return JSON.stringify({ plugin_api_origins: origins }, null, 2) + "\n";
7397
7520
  }
7398
7521
  function readArray(path, key) {
7399
- if (!existsSync29(path)) return [];
7522
+ if (!existsSync30(path)) return [];
7400
7523
  try {
7401
- const parsed = JSON.parse(readFileSync22(path, "utf8"));
7524
+ const parsed = JSON.parse(readFileSync23(path, "utf8"));
7402
7525
  const arr = parsed[key];
7403
7526
  return Array.isArray(arr) ? arr : [];
7404
7527
  } catch {
@@ -7406,19 +7529,19 @@ function readArray(path, key) {
7406
7529
  }
7407
7530
  }
7408
7531
  function registerUserFacingPlugin(cwd, environment, reg) {
7409
- const envDir = join30(cwd, "infra", "environments", environment);
7410
- const apiPath = join30(envDir, PLUGIN_API_TFVARS);
7411
- const siblingPath = join30(envDir, SIBLINGS_TFVARS);
7532
+ const envDir = join31(cwd, "infra", "environments", environment);
7533
+ const apiPath = join31(envDir, PLUGIN_API_TFVARS);
7534
+ const siblingPath = join31(envDir, SIBLINGS_TFVARS);
7412
7535
  const apis = upsertPluginApiOrigin(readArray(apiPath, "plugin_api_origins"), {
7413
7536
  name: reg.name,
7414
7537
  function_url_domain: reg.functionUrlDomain
7415
7538
  });
7416
- writeFileSync9(apiPath, serializePluginApiRegistry(apis));
7539
+ writeFileSync10(apiPath, serializePluginApiRegistry(apis));
7417
7540
  const siblings = upsertSiblingOrigin(readArray(siblingPath, "sibling_origins"), {
7418
7541
  name: reg.name,
7419
7542
  bucket_regional_domain: reg.bucketRegionalDomain
7420
7543
  });
7421
- writeFileSync9(siblingPath, serializeRegistry(siblings));
7544
+ writeFileSync10(siblingPath, serializeRegistry(siblings));
7422
7545
  return [
7423
7546
  `infra/environments/${environment}/${PLUGIN_API_TFVARS}`,
7424
7547
  `infra/environments/${environment}/${SIBLINGS_TFVARS}`
@@ -7499,7 +7622,7 @@ var pluginWireCommand = new Command20("wire").description(
7499
7622
  );
7500
7623
  async function resolveConfig4(options) {
7501
7624
  if (options.config) {
7502
- const raw = JSON.parse(readFileSync23(resolve17(options.config), "utf8"));
7625
+ const raw = JSON.parse(readFileSync24(resolve17(options.config), "utf8"));
7503
7626
  const result = BiffoConfigSchema.safeParse(raw);
7504
7627
  if (!result.success) {
7505
7628
  log.error(`Invalid config at ${options.config}:`);
@@ -7519,8 +7642,8 @@ async function resolveConfig4(options) {
7519
7642
  return cfg;
7520
7643
  }
7521
7644
  const localConfigPath = resolve17(process.cwd(), "biffo.config.json");
7522
- if (existsSync30(localConfigPath)) {
7523
- const raw = JSON.parse(readFileSync23(localConfigPath, "utf8"));
7645
+ if (existsSync31(localConfigPath)) {
7646
+ const raw = JSON.parse(readFileSync24(localConfigPath, "utf8"));
7524
7647
  const result = BiffoConfigSchema.safeParse(raw);
7525
7648
  if (result.success) return result.data;
7526
7649
  if (isTemplatePlaceholderConfig(raw)) {
@@ -7555,7 +7678,7 @@ pluginCommand.addCommand(pluginInfoCommand);
7555
7678
  import { Command as Command23 } from "commander";
7556
7679
 
7557
7680
  // src/commands/sibling-check-identity.ts
7558
- import { existsSync as existsSync31, readFileSync as readFileSync24 } from "fs";
7681
+ import { existsSync as existsSync32, readFileSync as readFileSync25 } from "fs";
7559
7682
  import { resolve as resolve18 } from "path";
7560
7683
  import chalk21 from "chalk";
7561
7684
  import { Command as Command22 } from "commander";
@@ -7749,7 +7872,7 @@ async function fetchPublishedIdentity(portalUrl) {
7749
7872
  }
7750
7873
  async function resolveConfig5(options) {
7751
7874
  if (options.config) {
7752
- const raw = JSON.parse(readFileSync24(resolve18(options.config), "utf8"));
7875
+ const raw = JSON.parse(readFileSync25(resolve18(options.config), "utf8"));
7753
7876
  const result = BiffoConfigSchema.safeParse(raw);
7754
7877
  if (!result.success) {
7755
7878
  log.error(`Invalid config at ${options.config}:`);
@@ -7769,8 +7892,8 @@ async function resolveConfig5(options) {
7769
7892
  return cfg;
7770
7893
  }
7771
7894
  const localConfigPath = resolve18(process.cwd(), "biffo.config.json");
7772
- if (existsSync31(localConfigPath)) {
7773
- const raw = JSON.parse(readFileSync24(localConfigPath, "utf8"));
7895
+ if (existsSync32(localConfigPath)) {
7896
+ const raw = JSON.parse(readFileSync25(localConfigPath, "utf8"));
7774
7897
  const result = BiffoConfigSchema.safeParse(raw);
7775
7898
  if (result.success) return result.data;
7776
7899
  if (isTemplatePlaceholderConfig(raw)) {
@@ -7839,8 +7962,8 @@ async function runOwnershipCheck(argv) {
7839
7962
  const { stdout } = await execa5("git", ["diff", "--cached", "--name-status"], { cwd: root });
7840
7963
  ({ changed: changedFiles, deleted: deletedFiles } = parseNameStatus(stdout));
7841
7964
  if (messageFile) {
7842
- const { readFileSync: readFileSync26, existsSync: existsSync33 } = await import("fs");
7843
- if (existsSync33(messageFile)) commitMessage = readFileSync26(messageFile, "utf8");
7965
+ const { readFileSync: readFileSync27, existsSync: existsSync34 } = await import("fs");
7966
+ if (existsSync34(messageFile)) commitMessage = readFileSync27(messageFile, "utf8");
7844
7967
  }
7845
7968
  } else {
7846
7969
  const base = process.env["GITHUB_BASE_REF"] ?? args[0];
@@ -7944,8 +8067,8 @@ ${BOLD}If the divergence is deliberate${OFF}
7944
8067
  import { execa as execa6 } from "execa";
7945
8068
 
7946
8069
  // src/lib/plugin-terraform-guard.ts
7947
- import { existsSync as existsSync32, readFileSync as readFileSync25, readdirSync as readdirSync12 } from "fs";
7948
- import { dirname as dirname9, join as join31, relative as relative6, sep as sep3 } from "path";
8070
+ import { existsSync as existsSync33, readFileSync as readFileSync26, readdirSync as readdirSync13 } from "fs";
8071
+ import { dirname as dirname9, join as join32, relative as relative6, sep as sep3 } from "path";
7949
8072
  var SKIP_DIRS = /* @__PURE__ */ new Set(["node_modules", ".git", ".worktrees", "dist", ".venv", "__pycache__"]);
7950
8073
  var PLUGIN_MANIFEST_FILE2 = "biffo.plugin.json";
7951
8074
  function findPluginManifests(root) {
@@ -7953,16 +8076,16 @@ function findPluginManifests(root) {
7953
8076
  const walk = (dir) => {
7954
8077
  let entries;
7955
8078
  try {
7956
- entries = readdirSync12(dir, { withFileTypes: true });
8079
+ entries = readdirSync13(dir, { withFileTypes: true });
7957
8080
  } catch {
7958
8081
  return;
7959
8082
  }
7960
8083
  for (const entry of entries) {
7961
8084
  if (entry.isDirectory()) {
7962
8085
  if (SKIP_DIRS.has(entry.name)) continue;
7963
- walk(join31(dir, entry.name));
8086
+ walk(join32(dir, entry.name));
7964
8087
  } else if (entry.isFile() && entry.name === PLUGIN_MANIFEST_FILE2) {
7965
- found.push(relative6(root, join31(dir, entry.name)).split(sep3).join("/"));
8088
+ found.push(relative6(root, join32(dir, entry.name)).split(sep3).join("/"));
7966
8089
  }
7967
8090
  }
7968
8091
  };
@@ -7972,7 +8095,7 @@ function findPluginManifests(root) {
7972
8095
  function readSubscriptions(absManifestPath) {
7973
8096
  let parsed;
7974
8097
  try {
7975
- parsed = JSON.parse(readFileSync25(absManifestPath, "utf8"));
8098
+ parsed = JSON.parse(readFileSync26(absManifestPath, "utf8"));
7976
8099
  } catch {
7977
8100
  return null;
7978
8101
  }
@@ -7987,14 +8110,14 @@ function readSubscriptions(absManifestPath) {
7987
8110
  }
7988
8111
  function checkPluginTerraform(root) {
7989
8112
  const violations = [];
7990
- const coreManifest = existsSync32(join31(root, CORE_MANIFEST_FILE)) ? readCoreManifest(root) : null;
8113
+ const coreManifest = existsSync33(join32(root, CORE_MANIFEST_FILE)) ? readCoreManifest(root) : null;
7991
8114
  for (const manifest of findPluginManifests(root)) {
7992
8115
  if (coreManifest && !isTemplateOwned(manifest, coreManifest)) continue;
7993
- const absManifest = join31(root, manifest);
8116
+ const absManifest = join32(root, manifest);
7994
8117
  const subscriptions = readSubscriptions(absManifest);
7995
8118
  if (subscriptions === null) continue;
7996
8119
  const pluginDir2 = dirname9(absManifest);
7997
- if (existsSync32(join31(pluginDir2, "terraform"))) continue;
8120
+ if (existsSync33(join32(pluginDir2, "terraform"))) continue;
7998
8121
  const relPluginDir = relative6(root, pluginDir2).split(sep3).join("/");
7999
8122
  violations.push({
8000
8123
  manifest,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@biffo/cli",
3
- "version": "0.103.0",
3
+ "version": "0.103.2",
4
4
  "description": "Biffo project scaffolding CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",