@biffo/cli 0.318.4 → 0.319.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -9835,6 +9835,9 @@ var pluginInstallCommand = new Command15("install").description(
9835
9835
  "--local <path>",
9836
9836
  "Install from a local, unpublished plugin directory instead of the registry"
9837
9837
  ).option("--dry-run", "Resolve the plugin and print planned changes without modifying the repo").option("--cwd <path>", "Project root to install into (defaults to the current directory)").option(
9838
+ "--frontend-cwd <path>",
9839
+ "Dashboard sibling checkout to write the user_frontend dashboard-registry entry into, when the core project and its dashboard are split siblings (biffo-template#2012) \u2014 e.g. biffo-platform / biffo-platform-app. Every other write (backend scaffolding, Terraform, the migration, the manifest) still resolves against --cwd only. Omit it for the common single-repo topology, where the registry entry is written into --cwd as before. Ignored for a plugin manifest with no user_frontend block, since there is nothing to register."
9840
+ ).option(
9838
9841
  "--config <name=value>",
9839
9842
  "Supply an instance value for one manifest `config:` declaration (biffo-template#1517) \u2014 repeatable. For a 'secret' declaration, value must be an SSM parameter PATH, never the credential itself.",
9840
9843
  (value, previous) => [...previous, value],
@@ -9849,6 +9852,7 @@ var pluginInstallCommand = new Command15("install").description(
9849
9852
  ...options.local ? { local: resolve12(options.local) } : {},
9850
9853
  dryRun: options.dryRun ?? false,
9851
9854
  cwd,
9855
+ ...options.frontendCwd ? { frontendCwd: resolve12(options.frontendCwd) } : {},
9852
9856
  config: parseConfigOptionValues(options.config)
9853
9857
  },
9854
9858
  {
@@ -9947,6 +9951,7 @@ async function runPluginInstall(target, options, deps) {
9947
9951
  const relTargetDir = pluginDir(pluginName, "third-party");
9948
9952
  const targetDir = join34(options.cwd, relTargetDir);
9949
9953
  const modulesDir = join34(options.cwd, "modules", "plugins", pluginName);
9954
+ const registryCwd = options.frontendCwd ?? options.cwd;
9950
9955
  const inTreeSource = options.local !== void 0 && resolve12(options.local) === resolve12(targetDir);
9951
9956
  if (existsSync32(targetDir) && !inTreeSource) {
9952
9957
  throw new Error(
@@ -9954,7 +9959,14 @@ async function runPluginInstall(target, options, deps) {
9954
9959
  );
9955
9960
  }
9956
9961
  if (options.dryRun) {
9957
- printDryRun4(entry, source, relTargetDir, inTreeSource, options.config ?? {});
9962
+ printDryRun4(
9963
+ entry,
9964
+ source,
9965
+ relTargetDir,
9966
+ inTreeSource,
9967
+ options.config ?? {},
9968
+ options.frontendCwd
9969
+ );
9958
9970
  return;
9959
9971
  }
9960
9972
  const isRepo = await deps.git.isGitRepo(options.cwd);
@@ -9993,7 +10005,15 @@ async function runPluginInstall(target, options, deps) {
9993
10005
  throw new Error(missingRequiredConfigMessage(pluginName, configSupply.missingRequired));
9994
10006
  }
9995
10007
  if (manifest.user_frontend) {
9996
- assertPluginRegistryReady(options.cwd, pluginName);
10008
+ if (options.frontendCwd) {
10009
+ const frontendIsRepo = await deps.git.isGitRepo(registryCwd);
10010
+ if (!frontendIsRepo) {
10011
+ throw new Error(
10012
+ `${registryCwd} (--frontend-cwd) is not a git repository \u2014 biffo plugin install must write the dashboard registry into a real checkout.`
10013
+ );
10014
+ }
10015
+ }
10016
+ assertPluginRegistryReady(registryCwd, pluginName);
9997
10017
  }
9998
10018
  if (inTreeSource) {
9999
10019
  log.info(`${relTargetDir}/ is already in this checkout \u2014 installing in place.`);
@@ -10079,13 +10099,22 @@ async function runPluginInstall(target, options, deps) {
10079
10099
  );
10080
10100
  }
10081
10101
  if (manifest.user_frontend) {
10082
- upsertPluginRegistryEntry(options.cwd, {
10102
+ upsertPluginRegistryEntry(registryCwd, {
10083
10103
  slug: pluginName,
10084
10104
  title: titleFromSlug(pluginName),
10085
10105
  frontendUrl: frontendUrlForSlug(pluginName)
10086
10106
  });
10087
- stagePaths.push(PLUGIN_REGISTRY_RELATIVE_PATH);
10088
- log.success(`Registered ${pluginName} in ${PLUGIN_REGISTRY_RELATIVE_PATH}`);
10107
+ if (options.frontendCwd) {
10108
+ const dashboardCommitMessage = `feat(plugins): register ${pluginName}@${source.version} in dashboard`;
10109
+ await deps.git.add(registryCwd, [PLUGIN_REGISTRY_RELATIVE_PATH]);
10110
+ await deps.git.commit(registryCwd, dashboardCommitMessage);
10111
+ log.success(
10112
+ `Registered ${pluginName} in ${registryCwd}/${PLUGIN_REGISTRY_RELATIVE_PATH} (committed there: "${dashboardCommitMessage}")`
10113
+ );
10114
+ } else {
10115
+ stagePaths.push(PLUGIN_REGISTRY_RELATIVE_PATH);
10116
+ log.success(`Registered ${pluginName} in ${PLUGIN_REGISTRY_RELATIVE_PATH}`);
10117
+ }
10089
10118
  }
10090
10119
  const commitMessage = `feat(plugins): install ${pluginName}@${source.version}`;
10091
10120
  await deps.git.add(options.cwd, stagePaths);
@@ -10093,8 +10122,16 @@ async function runPluginInstall(target, options, deps) {
10093
10122
  log.success(`Committed: ${commitMessage}`);
10094
10123
  console.log(chalk15.bold("\n Plugin installed!\n"));
10095
10124
  console.log(` ${pluginName}@${source.version} is committed at ${relTargetDir}/`);
10125
+ if (manifest.user_frontend && options.frontendCwd) {
10126
+ console.log(
10127
+ ` Its dashboard registration is committed separately at ${registryCwd}/${PLUGIN_REGISTRY_RELATIVE_PATH}.`
10128
+ );
10129
+ }
10096
10130
  console.log(" Push and redeploy to apply its migration and register its routes:");
10097
10131
  console.log(chalk15.dim(` git push`));
10132
+ if (manifest.user_frontend && options.frontendCwd) {
10133
+ console.log(chalk15.dim(` (and, in ${registryCwd}) git push`));
10134
+ }
10098
10135
  console.log(chalk15.dim(` biffo deploy <environment> --app-only
10099
10136
  `));
10100
10137
  printConfigWiringInstructions(pluginName, configSupply.resolved);
@@ -10126,7 +10163,7 @@ function parseManifestFile(path) {
10126
10163
  throw new Error(`Could not parse ${path} as JSON: ${err.message}`);
10127
10164
  }
10128
10165
  }
10129
- function printDryRun4(entry, source, relTargetDir, inTreeSource, suppliedConfig = {}) {
10166
+ function printDryRun4(entry, source, relTargetDir, inTreeSource, suppliedConfig = {}, frontendCwd) {
10130
10167
  const name = entry ? entry.name : source.name;
10131
10168
  const version = entry ? entry.version : source.version;
10132
10169
  console.log(chalk15.bold("\n Dry run \u2014 no changes will be made\n"));
@@ -10158,6 +10195,11 @@ function printDryRun4(entry, source, relTargetDir, inTreeSource, suppliedConfig
10158
10195
  ` Would vendor seed DDL into: ${pluginSeedImportDir(name)}/ (baseline_tables: ${source.manifest.seed.baseline_tables.join(", ") || "none declared"})`
10159
10196
  );
10160
10197
  }
10198
+ if (source && source.manifest.user_frontend) {
10199
+ console.log(
10200
+ frontendCwd ? ` Would register in dashboard at: ${frontendCwd}/${PLUGIN_REGISTRY_RELATIVE_PATH} (separate --frontend-cwd checkout, committed there)` : ` Would register in dashboard at: ${PLUGIN_REGISTRY_RELATIVE_PATH}`
10201
+ );
10202
+ }
10161
10203
  if (source && source.manifest.config.length > 0) {
10162
10204
  const { resolved, missingRequired } = resolvePluginConfigSupply(
10163
10205
  name,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@biffo/cli",
3
- "version": "0.318.4",
3
+ "version": "0.319.0",
4
4
  "description": "Biffo project scaffolding CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/scripts/verify.sh CHANGED
@@ -1527,6 +1527,16 @@ fi
1527
1527
  [ -f scripts/rerun-on-runner-loss.test.sh ] &&
1528
1528
  run_check rerun-on-runner-loss sh scripts/rerun-on-runner-loss.test.sh
1529
1529
 
1530
+ # Same shape again (#2076): stubs `gh` on PATH and runs the extracted
1531
+ # plugin-staleness filing step, discovery loop and tagger against fixtures,
1532
+ # so no network and no Actions run. Needs `node`, which every JS-backed check
1533
+ # above already needs. Measured here: ~0.4s. It belongs in the local gate for
1534
+ # the same reason rerun-on-runner-loss does -- plugin-staleness-report.yml is
1535
+ # a scheduled workflow, so the pull request that changes it never runs it, and
1536
+ # this self-test is the only thing that sees the change before it is live.
1537
+ [ -f scripts/plugin-staleness-target-repo.test.sh ] &&
1538
+ run_check plugin-staleness-target-repo sh scripts/plugin-staleness-target-repo.test.sh
1539
+
1530
1540
  # The DDL module-number allocator's own race-freedom proof (#1886): races real
1531
1541
  # `git` processes against throwaway local bare repos (never a mock of git, and
1532
1542
  # never /tmp -- repo-local scratch dirs cleaned up by its own trap), so it needs