@mutmutco/cli 4.3.50 → 4.3.52

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/main.cjs +133 -13
  2. package/package.json +1 -1
package/dist/main.cjs CHANGED
@@ -14756,7 +14756,7 @@ function deriveTrainFollowUpStatus(f) {
14756
14756
  return worst === "failure" ? "failed" : worst === "unresolved" ? "pending" : "complete";
14757
14757
  }
14758
14758
  function trainFollowUpExitCode(status) {
14759
- return status === "failed" ? 1 : status === "pending" ? 2 : 0;
14759
+ return status === "failed" ? 1 : 0;
14760
14760
  }
14761
14761
  function trainFollowUpNote(status) {
14762
14762
  if (status === "complete") return void 0;
@@ -15858,10 +15858,10 @@ var rollout_plan_default = {
15858
15858
  note: "The v4.0.0 stamp happens at cut time (D6e #4463); until then the candidate is the origin/development head artifacts (built cli/dist + npm pack), identity proven by dist content hash (D6a)."
15859
15859
  },
15860
15860
  baseline: {
15861
- version: "4.3.50",
15862
- tag: "v4.3.50",
15863
- commit: "d24d7fd0aaca",
15864
- npm: "@mutmutco/cli@4.3.50"
15861
+ version: "4.3.52",
15862
+ tag: "v4.3.52",
15863
+ commit: "6219f52caf87",
15864
+ npm: "@mutmutco/cli@4.3.52"
15865
15865
  },
15866
15866
  exitCriterion: "fleet-n-of-n",
15867
15867
  hubOnlyShortcut: "forbidden",
@@ -15878,14 +15878,14 @@ var rollout_plan_default = {
15878
15878
  repo: "mutmutco/mmi-hub",
15879
15879
  role: "canary",
15880
15880
  schedule: "train",
15881
- v3Target: "v4.3.50"
15881
+ v3Target: "v4.3.52"
15882
15882
  }
15883
15883
  ],
15884
15884
  rollbackTrigger: "Any red inside the post-contract soak window: `devops train gate` FAIL attributable to the v4 doors, Hub endpoint health probe failure, a pre-v4 client admitted instead of receiving actionable HTTP 426, or npm consumer install/doctor failure on the v4-only dist.",
15885
15885
  rollback: {
15886
15886
  independent: true,
15887
- mechanism: "npm dist-tag latest -> 4.3.50 and redeploy the Hub Lambda from tag v4.3.50 (d24d7fd0aaca); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
15888
- v3Target: "v4.3.50 (@mutmutco/cli@4.3.50, tag commit d24d7fd0aaca \u2014 last known-good release carrying the repo-index v4-only contract)"
15887
+ mechanism: "npm dist-tag latest -> 4.3.52 and redeploy the Hub Lambda from tag v4.3.52 (6219f52caf87); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
15888
+ v3Target: "v4.3.52 (@mutmutco/cli@4.3.52, tag commit 6219f52caf87 \u2014 last known-good release carrying the repo-index v4-only contract)"
15889
15889
  }
15890
15890
  },
15891
15891
  {
@@ -20543,6 +20543,9 @@ function validatePhaseRecord(phase, raw) {
20543
20543
  throw new ReleaseLedgerError("invalid-record", `release ledger: phase ${phase} has a malformed ${key}`);
20544
20544
  }
20545
20545
  }
20546
+ if (rec.superseded !== void 0 && typeof rec.superseded !== "boolean") {
20547
+ throw new ReleaseLedgerError("invalid-record", `release ledger: phase ${phase} has a malformed superseded marker`);
20548
+ }
20546
20549
  if (rec.retries !== void 0 && (typeof rec.retries !== "number" || !Number.isSafeInteger(rec.retries) || rec.retries < 0 || rec.retries > 9)) {
20547
20550
  throw new ReleaseLedgerError("invalid-record", `release ledger: phase ${phase} has a malformed retries value`);
20548
20551
  }
@@ -21429,6 +21432,69 @@ async function healStaleAlignmentLeg(deps, cwd, expected) {
21429
21432
  return prior.tag;
21430
21433
  });
21431
21434
  }
21435
+ function supersedeableDeployLegShape(rec) {
21436
+ return rec.state === "failed" || rec.state === "pending" && rec.runId == null;
21437
+ }
21438
+ async function supersedeContentCausedDeployLeg(deps, cwd) {
21439
+ const path2 = releaseLedgerPath(cwd);
21440
+ return withFileLock(`${path2}.lock`, { label: "release ledger" }, async () => {
21441
+ let prior;
21442
+ try {
21443
+ prior = parseReleaseLedger((0, import_node_fs21.readFileSync)(path2, "utf8"));
21444
+ } catch (e) {
21445
+ throw new ReleaseLedgerError(
21446
+ "unreadable",
21447
+ `release --supersede-deploy: the active release ledger at ${path2} could not be read (${e instanceof Error ? e.message : String(e)}) \u2014 resolve it by hand before any train; nothing was written (#6553)`
21448
+ );
21449
+ }
21450
+ if (prior.phases.deploy.superseded === true) {
21451
+ throw new Error(`release --supersede-deploy: the ${prior.tag} deploy leg is already superseded \u2014 nothing to do; the next train runs normally`);
21452
+ }
21453
+ if (!supersedeableDeployLegShape(prior.phases.deploy)) {
21454
+ throw new Error(
21455
+ `release --supersede-deploy: the ${prior.tag} deploy leg is ${prior.phases.deploy.state}` + (prior.phases.deploy.runId != null ? ` with run ${prior.phases.deploy.runId} \u2014 a run-backed leg is resolved by watching/reverifying its run, never superseded` : "") + "; the supersession closes only a FAILED deploy leg, or a PENDING one no run correlates (the uncorrelatable historical shape); nothing was written (#6553)"
21456
+ );
21457
+ }
21458
+ const phases = { ...prior.phases };
21459
+ if (phases.alignment.state === "pending") {
21460
+ const closed = await alignmentLegClosedLive(deps, prior);
21461
+ if (closed) phases.alignment = closed;
21462
+ }
21463
+ const unresolved = ["promotion", "ordinaryCi", "githubRelease", "publish", "alignment"].filter((phase) => phases[phase].state === "pending" || phases[phase].state === "failed");
21464
+ if (unresolved.length > 0) {
21465
+ throw new Error(
21466
+ `release --supersede-deploy: ${prior.tag} has unresolved legs besides deploy (${unresolved.map((p) => `${p}=${phases[p].state}`).join(", ")}) \u2014 the supersession closes only the deploy leg of an otherwise-complete release; resolve those first, nothing was written (#6553)`
21467
+ );
21468
+ }
21469
+ let liveSha = "";
21470
+ try {
21471
+ liveSha = (await deps.run("git", ["ls-remote", "origin", `refs/tags/${prior.tag}`])).trim().split(/\s+/)[0] ?? "";
21472
+ } catch (e) {
21473
+ throw new Error(`release --supersede-deploy: could not prove ${prior.tag} live on origin (${e instanceof Error ? e.message : String(e)}) \u2014 refusing to close the leg on an unproven state; retry when origin answers (#6553)`);
21474
+ }
21475
+ if (liveSha.toLowerCase() !== prior.tagSha.toLowerCase()) {
21476
+ throw new Error(
21477
+ `release --supersede-deploy: origin reports ${prior.tag} at ${liveSha.slice(0, 12) || "no tag"} but the ledger anchors ${prior.tagSha.slice(0, 12)} \u2014 an absent or divergent release is NOT supersedeable (release --abort --apply is the unpublished candidate's own exit); nothing was written (#6553)`
21478
+ );
21479
+ }
21480
+ const note = `superseded: content-caused deploy failure on the immutable promoted ${prior.tag} \u2014 the cause fix rides the next patch train (master-approved closure, #6553)`;
21481
+ atomicWriteJson(path2, {
21482
+ ...prior,
21483
+ phases: {
21484
+ ...phases,
21485
+ deploy: { state: "skipped", sha: prior.tagSha, superseded: true, note, updatedAt: (/* @__PURE__ */ new Date()).toISOString() }
21486
+ },
21487
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
21488
+ });
21489
+ return {
21490
+ command: "release-supersede-deploy",
21491
+ repo: prior.repo,
21492
+ tag: prior.tag,
21493
+ tagSha: prior.tagSha,
21494
+ note: `closed the ${prior.tag} deploy leg as superseded (skipped) \u2014 the ledger is phases-green; rerun the train doctor to confirm, then run the next patch train (hotfix or release) to carry the cause fix`
21495
+ };
21496
+ });
21497
+ }
21432
21498
  async function reverifyPriorRunLegs(deps, path2, targetTag) {
21433
21499
  let prior;
21434
21500
  try {
@@ -21895,10 +21961,12 @@ async function runTrainDoctor(input) {
21895
21961
  ledgerTag = void 0;
21896
21962
  }
21897
21963
  let remoteTags;
21964
+ let newestRemoteReleaseTag;
21898
21965
  try {
21899
21966
  remoteTags = tagNames(await runGitRemoteRead(train, ["ls-remote", "--tags", "origin", "refs/tags/v*"]));
21900
21967
  const releaseTags = await listRemoteReleaseTags(train);
21901
21968
  const latest = releaseTags[releaseTags.length - 1];
21969
+ newestRemoteReleaseTag = latest;
21902
21970
  if (latest) {
21903
21971
  const remoteSha = await probeRemoteTag(train, latest);
21904
21972
  if (remoteSha && await isStrayUnreleasedTag(train, latest, remoteSha, repo)) {
@@ -22007,8 +22075,11 @@ async function runTrainDoctor(input) {
22007
22075
  }
22008
22076
  }
22009
22077
  if (derived.phaseStatus !== "phases-green") {
22010
- const open2 = derived.legs.filter((l) => l.state === "pending" || l.state === "failed").map((l) => `${l.phase}=${l.state}`).join(", ");
22078
+ const openLegs = derived.legs.filter((l) => l.state === "pending" || l.state === "failed");
22079
+ const open2 = openLegs.map((l) => `${l.phase}=${l.state}`).join(", ");
22011
22080
  const failed = derived.phaseStatus === "phases-failed";
22081
+ const deployOnlyDeadlock = openLegs.length > 0 && openLegs.every((l) => l.phase === "deploy" && supersedeableDeployLegShape(l));
22082
+ const supersession = deployOnlyDeadlock ? `; when the deploy failure is content-caused on the already-published ${ledger.tag} (the immutable tag can never deploy green), the sanctioned exit is \`mmi-cli devops release --supersede-deploy --apply\` after explicit master approval \u2014 the next patch train carries the cause fix (#6553)` : "";
22012
22083
  add({
22013
22084
  code: failed ? "ledger-failed" : "ledger-pending",
22014
22085
  severity: "blocker",
@@ -22016,7 +22087,15 @@ async function runTrainDoctor(input) {
22016
22087
  // #6429: each lane finishes its own run (#6068) — an rcand-lane ledger named as a release
22017
22088
  // ledger, with `release --resume` as its remedy, sends the operator to a verb that refuses it.
22018
22089
  title: `a prior ${ledger.lane ?? "release"} ledger for ${ledger.tag} is ${derived.phaseStatus} (${open2}) \u2014 a new train must not stack on it (#5987)`,
22019
- remedy: failed ? `diagnose the failed leg, then ${ledgerLaneResumeCommand(ledger)} once its cause is fixed (an abort only with fresh approval)` : `finish it first: ${ledgerLaneResumeCommand(ledger)} (alignment-only pending legs close themselves with \`train doctor --heal\` once the PR merges)`
22090
+ remedy: failed ? `diagnose the failed leg, then ${ledgerLaneResumeCommand(ledger)} once its cause is fixed (an abort only with fresh approval)${supersession}` : `finish it first: ${ledgerLaneResumeCommand(ledger)} (alignment-only pending legs close themselves with \`train doctor --heal\` once the PR merges)${supersession}`
22091
+ });
22092
+ } else if (newestRemoteReleaseTag && newestRemoteReleaseTag !== ledger.tag) {
22093
+ add({
22094
+ code: "ledger-stale",
22095
+ severity: "info",
22096
+ source: "origin",
22097
+ title: `the active ledger describes the PRIOR release ${ledger.tag} \u2014 origin's newest release tag is ${newestRemoteReleaseTag}`,
22098
+ remedy: "nothing \u2014 the next train live-proves and archives it aside; never cite a prior-release ledger or its runs as the current release's deploy state \u2014 a clearance cites runs proven to belong to the active tag"
22020
22099
  });
22021
22100
  }
22022
22101
  } catch (e) {
@@ -23185,7 +23264,9 @@ Nothing was written. Inspect ${ledger.path} (or clear it only after proving the
23185
23264
  });
23186
23265
  if (persisted) {
23187
23266
  const phaseInputs = phaseInputsFromRunRows(deployModel, dispatch2.workflowRuns ?? historicalRows, tagSha, { repo: ctx.repo });
23188
- await recordPhase(ledger, deps, anchors, "deploy", phaseEntry(phaseInputs.deploy), { strict: true, landed: "the verified GitHub Release and origin/main at the immutable tag SHA" });
23267
+ if (persisted.phases.deploy.superseded !== true) {
23268
+ await recordPhase(ledger, deps, anchors, "deploy", phaseEntry(phaseInputs.deploy), { strict: true, landed: "the verified GitHub Release and origin/main at the immutable tag SHA" });
23269
+ }
23189
23270
  await recordPhase(ledger, deps, anchors, "publish", phaseEntry(phaseInputs.publish), { strict: true, landed: "the verified GitHub Release and origin/main at the immutable tag SHA" });
23190
23271
  await recordPhase(ledger, deps, anchors, "githubRelease", phaseEntry({ state: "complete", sha: tagSha, note: "re-verified live: the GitHub Release exists at the immutable tag SHA" }), { strict: true, landed: "the promotion (verified live)" });
23191
23272
  await recordPhase(ledger, deps, anchors, "promotion", phaseEntry({ state: "complete", sha: tagSha, note: "re-verified live: origin/main contains the immutable tag SHA" }), { strict: true, landed: "nothing beyond the already-public release" });
@@ -23437,6 +23518,17 @@ async function runReleaseAbort(deps, options = {}) {
23437
23518
  note: `removed the unpublished ${tag} candidate and restored local main; repair development before recutting` + (clearedLedgerNote ? `; ${clearedLedgerNote}` : "")
23438
23519
  };
23439
23520
  }
23521
+ async function runReleaseSupersedeDeploy(deps, options = {}) {
23522
+ if (!options.approved) {
23523
+ throw new Error("release --supersede-deploy requires --apply after explicit master approval; nothing was written");
23524
+ }
23525
+ try {
23526
+ return await supersedeContentCausedDeployLeg(deps, process.cwd());
23527
+ } catch (e) {
23528
+ const message2 = e instanceof Error ? e.message : String(e);
23529
+ throw new Error(message2.includes("nothing was written") || message2.includes("nothing to do") ? message2 : `${message2}; nothing was written`);
23530
+ }
23531
+ }
23440
23532
  async function runReleasePublishRetry(deps, runId, options = {}) {
23441
23533
  if (!options.approved) {
23442
23534
  throw new Error("release --retry-publish requires --apply after explicit approval; nothing was written");
@@ -43888,7 +43980,7 @@ function readRepoVersion() {
43888
43980
  }
43889
43981
  function registerTrainCommands(program3, trainDeps) {
43890
43982
  const train = program3.command("train").description("release-train observability \u2014 track position, version lag, and the shared preflight-and-heal doctor (#2688, #6067)");
43891
- train.command("doctor").description("one shared preflight-and-heal verdict for the release, rcand and hotfix lanes; read-only unless --heal (#6067)").addOption(new Option("--lane <lane>", "train lane to check (defaults from the release track: direct \u2192 release)").choices([...TRAIN_LANES])).option("--dev", "judge the `release --dev` lane (development -> main, skipping rc): the lane starts from development and is read on development's workflows (#6318)").option("--heal", "repair safe local reconstructible state (scratch gitignore, churn, stray local tags, ff-only branch lag, finished scratch branches, stale alignment ledger leg); it never clears a ledger-pending, ledger-failed or branch-mismatch blocker (#6404, #6401, #6399) \u2014 those need `mmi-cli devops release --resume` (or, with fresh approval, `--abort --apply`) and `git checkout <start branch>`, so exit 1 after --heal is the gate working, not a failed heal").option("--repo <owner/repo>", "target repo (defaults to the current checkout)").option("--json", "machine-readable output").addHelpText("after", "\nExit codes:\n 0 ready \u2014 no blocker and origin verified\n 1 a blocker remains, or origin could not be verified (never green on an unread origin)\n\nEvery finding carries code, severity (blocker|warning|healed|info), source (local|origin), remedy and a\ndocs/Guides/train-troubleshooting.md#<code> anchor. `release --apply` and `rcand --apply` run this at step 0 with --heal.\n").action(async (o) => {
43983
+ train.command("doctor").description("one shared preflight-and-heal verdict for the release, rcand and hotfix lanes; read-only unless --heal (#6067)").addOption(new Option("--lane <lane>", "train lane to check (defaults from the release track: direct \u2192 release)").choices([...TRAIN_LANES])).option("--dev", "judge the `release --dev` lane (development -> main, skipping rc): the lane starts from development and is read on development's workflows (#6318)").option("--heal", "repair safe local reconstructible state (scratch gitignore, churn, stray local tags, ff-only branch lag, finished scratch branches, stale alignment ledger leg); it never clears a ledger-pending, ledger-failed or branch-mismatch blocker (#6404, #6401, #6399) \u2014 those need `mmi-cli devops release --resume` (or, with fresh approval, `--abort --apply`) and `git checkout <start branch>`, so exit 1 after --heal is the gate working, not a failed heal").option("--repo <owner/repo>", "target repo (defaults to the current checkout)").option("--json", "machine-readable output").option("--out <path>", "write the verdict to this file as UTF-8 (no BOM) instead of stdout \u2014 the shell-free receipt path (#5802/#6563); pair with --json for a machine-readable file (e.g. `--json --out .jerv/tmp/train-doctor.json`); the file is written even when the verdict is NOT READY").addHelpText("after", "\nExit codes:\n 0 ready \u2014 no blocker and origin verified\n 1 a blocker remains, or origin could not be verified (never green on an unread origin)\n\nEvery finding carries code, severity (blocker|warning|healed|info), source (local|origin), remedy and a\ndocs/Guides/train-troubleshooting.md#<code> anchor. `release --apply` and `rcand --apply` run this at step 0 with --heal.\n").action(async (o) => {
43892
43984
  try {
43893
43985
  if (o.dev && o.lane && o.lane !== "release") {
43894
43986
  return failGraceful(`train doctor: --dev applies only to the release lane \u2014 it names the development -> main variant that skips rc, which the ${o.lane} lane does not have`);
@@ -43912,7 +44004,9 @@ function registerTrainCommands(program3, trainDeps) {
43912
44004
  };
43913
44005
  const verdict = await runTrainDoctor({ lane: o.lane, dev: o.dev === true, heal: o.heal === true, train: deps, repo: o.repo, cwd: root, argv: INVOKED_ARGV });
43914
44006
  if (verdict.reexecCode !== void 0) return process.exit(verdict.reexecCode);
43915
- console.log(o.json ? JSON.stringify(verdict, null, 2) : formatTrainDoctor(verdict));
44007
+ const output = o.json ? JSON.stringify(verdict, null, 2) : formatTrainDoctor(verdict);
44008
+ if (!o.out) console.log(output);
44009
+ else console.log(`Wrote train doctor verdict to ${o.out} (UTF-8, ${writeUtf8Receipt(o.out, output)} bytes)`);
43916
44010
  if (!verdict.ready) process.exitCode = 1;
43917
44011
  } catch (e) {
43918
44012
  return failGraceful(`train doctor: ${e.message}`);
@@ -44138,6 +44232,9 @@ function renderReleaseResume(r) {
44138
44232
  function renderReleaseAbort(r) {
44139
44233
  return `mmi-cli devops release --abort --apply: ${r.repo} ${r.tag} (${r.tagSha.slice(0, 12)}) \u2014 ${r.note}`;
44140
44234
  }
44235
+ function renderReleaseSupersedeDeploy(r) {
44236
+ return `mmi-cli devops release --supersede-deploy --apply: ${r.repo} ${r.tag} (${r.tagSha.slice(0, 12)}) \u2014 ${r.note}`;
44237
+ }
44141
44238
  function renderReleasePublishRetry(r) {
44142
44239
  return `mmi-cli devops release --retry-publish: ${r.repo} ${r.tag} (${r.tagSha.slice(0, 12)}) \u2014 ${r.note}; ${r.runUrl}`;
44143
44240
  }
@@ -44331,6 +44428,7 @@ function registerTrainOperationsCommands(program3, runProjectInfoSyncCallback) {
44331
44428
  { flags: "--ack <shas>", description: "comma-separated dev shas a human verified are in the candidate, overriding the hotfix-coverage guard for a conflicted port whose -x trailer was lost (#958)" },
44332
44429
  { flags: "--dev", description: "full-track repos release development -> main directly, skipping rc (refuses if rc carries content not in development; no-op on direct-track repos) (#1062)" },
44333
44430
  { flags: "--abort", description: "with --apply, delete only a proven unpublished failed release candidate on any registered deploy model and restore local main for a same-version recut (#3944/#5650/#5657)" },
44431
+ { flags: "--supersede-deploy", description: "with --apply, master-approved closure of a content-caused failed deploy leg on a PUBLISHED release whose immutable tag can never deploy green \u2014 the next patch train then carries the fix (#6553)" },
44334
44432
  { flags: "--retry-publish <run-id>", description: "with --apply, retry one proven failed or cancelled Hub publish release run (#3949/#5797)" }
44335
44433
  ];
44336
44434
  for (const f of RELEASE_ONLY_FLAGS) {
@@ -44358,6 +44456,9 @@ function registerTrainOperationsCommands(program3, runProjectInfoSyncCallback) {
44358
44456
  if (o.abort && commandName !== "release") {
44359
44457
  return fail(`${commandName}: --abort applies only to release \u2014 it rolls back a proven unpublished release tag. Run: mmi-cli devops release --abort --apply`);
44360
44458
  }
44459
+ if (o.supersedeDeploy && commandName !== "release") {
44460
+ return fail(`${commandName}: --supersede-deploy applies only to release \u2014 it closes a content-caused failed deploy leg on a published release's ledger. Run: mmi-cli devops release --supersede-deploy --apply`);
44461
+ }
44361
44462
  if (o.retryPublish && commandName !== "release") {
44362
44463
  return fail(`${commandName}: --retry-publish applies only to release. Run: mmi-cli devops release --retry-publish <run-id> --apply --watch`);
44363
44464
  }
@@ -44405,6 +44506,25 @@ function registerTrainOperationsCommands(program3, runProjectInfoSyncCallback) {
44405
44506
  return failGraceful(`release --abort: ${e.message}`);
44406
44507
  }
44407
44508
  }
44509
+ if (o.supersedeDeploy) {
44510
+ if (o.resume) return fail("release: --supersede-deploy and --resume are mutually exclusive \u2014 the closure settles the ledger so a NEW train can run, resume re-derives the very leg it closes");
44511
+ if (o.abort) return fail("release: --supersede-deploy and --abort are mutually exclusive \u2014 the closure is for a PUBLISHED release, abort only ever deletes a proven unpublished candidate");
44512
+ if (o.retryPublish) return fail("release: --supersede-deploy cannot be combined with --retry-publish");
44513
+ if (!o.apply) return fail("release: --supersede-deploy requires --apply after explicit master approval; nothing was written");
44514
+ if (o.watch || o.announceSummaryFile || o.ack || o.dev) {
44515
+ return fail("release: --supersede-deploy accepts only --apply, --repo, --json and --out; it closes a ledger leg and dispatches nothing");
44516
+ }
44517
+ if (o.repo) {
44518
+ const guard = planTrainApplyRepoGuard(o.repo, await resolveRepo(), "mmi-cli devops release --supersede-deploy --apply");
44519
+ if (!guard.ok) return fail(`release: ${guard.message}`);
44520
+ }
44521
+ try {
44522
+ const result = await runReleaseSupersedeDeploy(trainApplyDeps(), { approved: true });
44523
+ return emitTrainResult("release --supersede-deploy", o.json ? JSON.stringify(result, null, 2) : renderReleaseSupersedeDeploy(result), o.out);
44524
+ } catch (e) {
44525
+ return failGraceful(`release --supersede-deploy: ${e.message}`);
44526
+ }
44527
+ }
44408
44528
  if (o.resume) {
44409
44529
  if (o.apply) return fail(`${commandName}: --resume and --apply are mutually exclusive \u2014 --apply cuts the NEXT version, --resume finishes the immutable tag already on origin`);
44410
44530
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mutmutco/cli",
3
- "version": "4.3.50",
3
+ "version": "4.3.52",
4
4
  "description": "MMI Future CLI — the org dev toolbox and shared cross-IDE engine for every registry-declared MMI coding surface.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",