@mutmutco/cli 4.4.2 → 4.4.4

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 +70 -21
  2. package/package.json +1 -1
package/dist/main.cjs CHANGED
@@ -15870,10 +15870,10 @@ var rollout_plan_default = {
15870
15870
  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)."
15871
15871
  },
15872
15872
  baseline: {
15873
- version: "4.4.2",
15874
- tag: "v4.4.2",
15875
- commit: "678e071c6859",
15876
- npm: "@mutmutco/cli@4.4.2"
15873
+ version: "4.4.4",
15874
+ tag: "v4.4.4",
15875
+ commit: "d35da22e2e0b",
15876
+ npm: "@mutmutco/cli@4.4.4"
15877
15877
  },
15878
15878
  exitCriterion: "fleet-n-of-n",
15879
15879
  hubOnlyShortcut: "forbidden",
@@ -15890,14 +15890,14 @@ var rollout_plan_default = {
15890
15890
  repo: "mutmutco/mmi-hub",
15891
15891
  role: "canary",
15892
15892
  schedule: "train",
15893
- v3Target: "v4.4.2"
15893
+ v3Target: "v4.4.4"
15894
15894
  }
15895
15895
  ],
15896
15896
  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.",
15897
15897
  rollback: {
15898
15898
  independent: true,
15899
- mechanism: "npm dist-tag latest -> 4.4.2 and redeploy the Hub Lambda from tag v4.4.2 (678e071c6859); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
15900
- v3Target: "v4.4.2 (@mutmutco/cli@4.4.2, tag commit 678e071c6859 \u2014 last known-good release carrying the repo-index v4-only contract)"
15899
+ mechanism: "npm dist-tag latest -> 4.4.4 and redeploy the Hub Lambda from tag v4.4.4 (d35da22e2e0b); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
15900
+ v3Target: "v4.4.4 (@mutmutco/cli@4.4.4, tag commit d35da22e2e0b \u2014 last known-good release carrying the repo-index v4-only contract)"
15901
15901
  }
15902
15902
  },
15903
15903
  {
@@ -18813,20 +18813,64 @@ function tenantPublishRecoveryCommand(slug, repo, ref, stage, publishDir) {
18813
18813
  if (publishDir && publishDir !== ".") parts.push(`-f publishDir=${publishDir}`);
18814
18814
  return parts.join(" ");
18815
18815
  }
18816
- var PUBLISH_IDEMPOTENT_MARKER = /already on npm/i;
18816
+ var PUBLISH_CONFLICT_SIGNAL = /E409|cannot publish over|previously published|\b(?:HTTP|status|code)\s*[:=]?\s*409\b|\b409\s+Conflict\b/i;
18817
18817
  var PUBLISH_LOG_RETRY_ATTEMPTS = 4;
18818
18818
  var PUBLISH_LOG_RETRY_DELAY_MS = 6e3;
18819
- async function reconcilePublishFailure(deps, runId) {
18820
- if (runId == null) return "failure";
18819
+ function publishRegistryTarget(meta, repo, publishRef) {
18820
+ const version = publishRef.replace(/^v/, "");
18821
+ if (!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(version)) return void 0;
18822
+ try {
18823
+ return { name: resolveReleaseAbortNpmPackage(meta, repo), version };
18824
+ } catch {
18825
+ return void 0;
18826
+ }
18827
+ }
18828
+ async function provePublishedVersion(deps, target) {
18829
+ try {
18830
+ return clean2(await deps.run("npm", ["view", `${target.name}@${target.version}`, "version"])) === target.version;
18831
+ } catch {
18832
+ return false;
18833
+ }
18834
+ }
18835
+ function publishReconcileFailureNote(input) {
18836
+ if (input.signal && input.target) {
18837
+ return `run FAILED and its log shows a publish conflict (${input.signal}) but the registry does not report ${input.target.name}@${input.target.version} live \u2014 the failure stands (verify with an authenticated registry read, never a bare npm view \u2014 see docs/Guides/train-troubleshooting.md#publish-private-package)`;
18838
+ }
18839
+ if (input.signal) {
18840
+ return `run FAILED and its log shows a publish conflict (${input.signal}) but no npm package name could be resolved to prove the exact version live \u2014 the failure stands`;
18841
+ }
18842
+ if (input.readError) {
18843
+ return `run FAILED and its log could not be read (${input.readError}) \u2014 the failure stands`;
18844
+ }
18845
+ return 'run FAILED and its log shows no publish-conflict signal (E409, "cannot publish over", "previously published", or a 409 status) \u2014 the failure stands';
18846
+ }
18847
+ async function reconcilePublishFailure(deps, runId, target) {
18848
+ if (runId == null) {
18849
+ return { status: "failure", note: "the failed publish run had no run id to re-read \u2014 the failure stands" };
18850
+ }
18821
18851
  const sleep2 = resolveSleep(deps);
18852
+ let signal;
18853
+ let readError;
18822
18854
  for (let attempt = 0; attempt < PUBLISH_LOG_RETRY_ATTEMPTS; attempt++) {
18823
18855
  if (attempt > 0) await sleep2(PUBLISH_LOG_RETRY_DELAY_MS);
18824
18856
  const log = await fetchControlRunLog(deps, runId);
18825
- if (log.ok && PUBLISH_IDEMPOTENT_MARKER.test(log.log)) return "success";
18857
+ if (!log.ok) {
18858
+ readError = log.error;
18859
+ continue;
18860
+ }
18861
+ const match = log.log.match(PUBLISH_CONFLICT_SIGNAL);
18862
+ if (!match) continue;
18863
+ signal = match[0];
18864
+ if (target && await provePublishedVersion(deps, target)) {
18865
+ return {
18866
+ status: "success",
18867
+ note: `registry reports ${target.name}@${target.version} live; run failed with a publish conflict (${signal}) \u2014 #2428/#6777`
18868
+ };
18869
+ }
18826
18870
  }
18827
- return "failure";
18871
+ return { status: "failure", note: publishReconcileFailureNote({ signal, readError, target }) };
18828
18872
  }
18829
- async function dispatchTenantPublish(deps, ctx, stage, ref, watch, dispatchFailure = "throw", publishDir) {
18873
+ async function dispatchTenantPublish(deps, ctx, stage, ref, watch, dispatchFailure = "throw", publishDir, publishTarget) {
18830
18874
  deps.warn?.("Release: Starting package publishing");
18831
18875
  const since = (deps.now ?? Date.now)();
18832
18876
  const dispatchArgs = [
@@ -18867,20 +18911,25 @@ async function dispatchTenantPublish(deps, ctx, stage, ref, watch, dispatchFailu
18867
18911
  let deployStatus = watch ? await watchTenantRun(deps, runId) : "pending";
18868
18912
  let note = `dispatched tenant-publish.yml (slug=${ctx.slug}, ref=${ref}, stage=${stage})`;
18869
18913
  if (deployStatus === "failure") {
18870
- const reconciled = await reconcilePublishFailure(deps, runId);
18871
- if (reconciled === "success") {
18872
- deployStatus = "success";
18873
- note = `${note}; run reported failure but its log confirms the version is already on npm (idempotent E409 \u2014 #2428)`;
18874
- } else {
18875
- note = `${note}; run FAILED and its log never confirmed the version landed \u2014 verify from the run log or an authenticated registry read, never a bare npm view \u2014 see docs/Guides/train-troubleshooting.md#publish-private-package`;
18876
- }
18914
+ const reconciled = await reconcilePublishFailure(deps, runId, publishTarget);
18915
+ deployStatus = reconciled.status;
18916
+ note = `${note}; ${reconciled.note}`;
18877
18917
  }
18878
18918
  return { note, runId, runUrl, deployStatus };
18879
18919
  }
18880
18920
  async function dispatchPublishIfRequired(deps, ctx, meta, model, stage, publishRef, watch, dispatchFailure) {
18881
18921
  if (!meta.publishRequired || stage !== "main") return null;
18882
18922
  if (model !== "tenant-container" && model !== "solo-container") return null;
18883
- return dispatchTenantPublish(deps, ctx, stage, publishRef, watch, dispatchFailure, meta.publishDir);
18923
+ return dispatchTenantPublish(
18924
+ deps,
18925
+ ctx,
18926
+ stage,
18927
+ publishRef,
18928
+ watch,
18929
+ dispatchFailure,
18930
+ meta.publishDir,
18931
+ publishRegistryTarget(meta, ctx.repo, publishRef)
18932
+ );
18884
18933
  }
18885
18934
  function appendPublishDispatch(deploy, publish) {
18886
18935
  if (!publish) return deploy;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mutmutco/cli",
3
- "version": "4.4.2",
3
+ "version": "4.4.4",
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",