baldart 4.58.0 → 4.59.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.
@@ -410,6 +410,17 @@ git:
410
410
  # worktree-isolated and respect the terminal-isolation rule.
411
411
  merge_strategy: pr
412
412
 
413
+ # Auto-deploy allowlist (since v4.59.0). Bounds what the `/new` `-auto-ship`
414
+ # autonomous mode may execute as an OUTWARD/IRREVERSIBLE action (remote schema
415
+ # deploy, env/feature-flag writes, etc.). A list of deploy targets/intents the
416
+ # orchestrator is authorized to run unattended; default empty = NOTHING
417
+ # auto-deploys (bare `-auto` ships nothing outward — outward actions defer to a
418
+ # follow-up card). This is layered ON TOP of `stack.schema_deploy_from_trunk_only`,
419
+ # which remains a hard branch floor — the allowlist authorizes WHAT may ship, the
420
+ # trunk-only invariant still constrains FROM WHERE. Free-form labels matched by
421
+ # the production-readiness gate, e.g. ["supabase-db-push", "vercel-prod"].
422
+ auto_deploy: []
423
+
413
424
  # ─── TOOLS ───────────────────────────────────────────────────────────────
414
425
  # Which AI CLI tools should the framework target on this machine?
415
426
  # Each enabled tool gets its own per-item skill symlinks pointing at the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "baldart",
3
- "version": "4.58.0",
3
+ "version": "4.59.0",
4
4
  "description": "Claude Agent Framework - Reusable framework for coordinating AI agents and humans in software projects",
5
5
  "bin": {
6
6
  "baldart": "./bin/baldart.js"
@@ -663,6 +663,19 @@ async function interactivePrompts(merged, detected) {
663
663
  UI.warning('You picked `local-push` but develop appears protected on origin — pushes will be rejected. Switch back to `pr` if it fails.');
664
664
  }
665
665
 
666
+ // ---- Auto-deploy allowlist (since v4.59.0) ----------------------------
667
+ // Bounds what `/new -auto-ship` may execute as an OUTWARD action. Empty =
668
+ // nothing auto-deploys (safe default). Layered ON TOP of
669
+ // stack.schema_deploy_from_trunk_only, which stays a hard branch floor.
670
+ const currentAutoDeploy = Array.isArray(merged.git.auto_deploy) ? merged.git.auto_deploy : [];
671
+ const autoDeployAnswer = (await UI.input(
672
+ `Auto-deploy allowlist for \`/new -auto-ship\` (comma-separated deploy targets/intents; blank = none) (current: ${currentAutoDeploy.join(', ') || '—'})`,
673
+ currentAutoDeploy.join(', ')
674
+ )).trim();
675
+ merged.git.auto_deploy = autoDeployAnswer
676
+ ? autoDeployAnswer.split(',').map((s) => s.trim()).filter(Boolean)
677
+ : [];
678
+
666
679
  UI.section('Features (explicit yes/no — option A: always ask)');
667
680
  for (const flag of [
668
681
  ['has_design_system', 'Project has a documented design system?'],
@@ -464,6 +464,21 @@ async function detectState(cwd, opts = {}) {
464
464
  }
465
465
  } catch (_) { /* never block doctor on i18n probe */ }
466
466
 
467
+ // ---- Auto-deploy allowlist presence (since v4.59.0) ----------------
468
+ // Purely informational: git.auto_deploy bounds what `/new -auto-ship`
469
+ // may execute as an OUTWARD action. An empty allowlist is the SAFE
470
+ // default (nothing auto-deploys), so this is only worth noting — never
471
+ // a fix. Surfaced so a user who relies on `-auto-ship` knows whether the
472
+ // gate is open. Empty/unset = closed (the common, safe case).
473
+ state.autoDeployConfigured = false;
474
+ try {
475
+ if (config && !config.__malformed && config.git
476
+ && Array.isArray(config.git.auto_deploy) && config.git.auto_deploy.length > 0) {
477
+ state.autoDeployConfigured = true;
478
+ state.autoDeployTargets = config.git.auto_deploy.slice();
479
+ }
480
+ } catch (_) { /* never block doctor on auto_deploy probe */ }
481
+
467
482
  // ---- External-tool version currency (since v4.38.0) ----------------
468
483
  // BALDART pins none of the external tools it installs (graphifyy via pipx,
469
484
  // language servers via npm/system) — pipx/npm never auto-upgrade, so a
@@ -983,6 +998,24 @@ function planActions(state) {
983
998
  });
984
999
  }
985
1000
 
1001
+ // Auto-deploy allowlist (since v4.59.0). Advisory print-only — surfaced ONLY
1002
+ // when the allowlist is non-empty (the safe default of empty/unset opens
1003
+ // nothing, so it warrants no nag). Reminds the user that `/new -auto-ship`
1004
+ // may execute the listed OUTWARD targets unattended. Never a fix; safe in
1005
+ // --auto since run() only prints. The trunk-only branch floor still applies.
1006
+ if (state.autoDeployConfigured) {
1007
+ actions.push({
1008
+ key: 'auto-deploy-allowlist',
1009
+ label: `Auto-deploy allowlist active: ${state.autoDeployTargets.join(', ')}`,
1010
+ why: `git.auto_deploy authorizes \`/new -auto-ship\` to auto-execute these OUTWARD deploy targets unattended. Only relevant when you run with -auto-ship; otherwise nothing auto-deploys. stack.schema_deploy_from_trunk_only still constrains FROM WHERE a schema deploy may run. Empty the list in baldart.config.yml to close the gate.`,
1011
+ autoOk: true, // advisory print-only; run() does NOT mutate config
1012
+ run: () => {
1013
+ UI.info(`git.auto_deploy = [${state.autoDeployTargets.join(', ')}] — \`/new -auto-ship\` may auto-execute these targets.`);
1014
+ UI.info('Empty `git.auto_deploy` in baldart.config.yml to disable all unattended deploys.');
1015
+ },
1016
+ });
1017
+ }
1018
+
986
1019
  // External-tool version currency (since v4.38.0). One non-blocking upgrade
987
1020
  // action per managed tool confirmed behind upstream — the tool-dependency
988
1021
  // analogue of the `baldart` CLI's own UpdateNotifier. `unknown`/`current`
@@ -1283,6 +1283,9 @@ async function update(options = {}, unknownArgs = []) {
1283
1283
  .filter((k) => !(k in (cur2.features || {})));
1284
1284
  const missingPaths = Object.keys(tpl.paths || {})
1285
1285
  .filter((k) => !(k in (cur2.paths || {})));
1286
+ // `git.*` has no type filter — ALL new keys surface regardless of
1287
+ // type, so scalars (trunk_branch, merge_strategy) AND ARRAYS
1288
+ // (git.auto_deploy, the allowlist since v4.59.0) are both caught.
1286
1289
  const missingGit = Object.keys(tpl.git || {})
1287
1290
  .filter((k) => !(k in (cur2.git || {})));
1288
1291
  // Scalar top-level stack.* keys — e.g. stack.database,