@mutmutco/cli 4.5.84 → 4.5.85

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 +105 -18
  2. package/package.json +1 -1
package/dist/main.cjs CHANGED
@@ -17268,10 +17268,10 @@ var rollout_plan_default = {
17268
17268
  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)."
17269
17269
  },
17270
17270
  baseline: {
17271
- version: "4.5.84",
17272
- tag: "v4.5.84",
17273
- commit: "86b566fd9857",
17274
- npm: "@mutmutco/cli@4.5.84"
17271
+ version: "4.5.85",
17272
+ tag: "v4.5.85",
17273
+ commit: "a1ce2f136846",
17274
+ npm: "@mutmutco/cli@4.5.85"
17275
17275
  },
17276
17276
  exitCriterion: "fleet-n-of-n",
17277
17277
  hubOnlyShortcut: "forbidden",
@@ -17288,14 +17288,14 @@ var rollout_plan_default = {
17288
17288
  repo: "mutmutco/mmi-hub",
17289
17289
  role: "canary",
17290
17290
  schedule: "train",
17291
- v3Target: "v4.5.84"
17291
+ v3Target: "v4.5.85"
17292
17292
  }
17293
17293
  ],
17294
17294
  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.",
17295
17295
  rollback: {
17296
17296
  independent: true,
17297
- mechanism: "npm dist-tag latest -> 4.5.84 and redeploy the Hub Lambda from tag v4.5.84 (86b566fd9857); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
17298
- v3Target: "v4.5.84 (@mutmutco/cli@4.5.84, tag commit 86b566fd9857 \u2014 last known-good release carrying the repo-index v4-only contract)"
17297
+ mechanism: "npm dist-tag latest -> 4.5.85 and redeploy the Hub Lambda from tag v4.5.85 (a1ce2f136846); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
17298
+ v3Target: "v4.5.85 (@mutmutco/cli@4.5.85, tag commit a1ce2f136846 \u2014 last known-good release carrying the repo-index v4-only contract)"
17299
17299
  }
17300
17300
  },
17301
17301
  {
@@ -19607,6 +19607,7 @@ var TRAIN_COMMIT_STATUS_JQ = "[.statuses[]|{context:.context,state:.state,id:.id
19607
19607
  var TRAIN_PROTECTION_CONTEXTS_JQ = "[.contexts[]]";
19608
19608
  var TRAIN_RULES_CONTEXTS_JQ = '[.[]|select(.type=="required_status_checks")|.parameters.required_status_checks[].context]';
19609
19609
  var TRAIN_CHECK_ATTEMPTS = 40;
19610
+ var TRAIN_QUEUED_CHECK_ATTEMPTS = 80;
19610
19611
  var TRAIN_CHECK_DELAY_MS = 15e3;
19611
19612
  var TRAIN_PR_ONLY_CONTEXTS = /* @__PURE__ */ new Set(["add-to-project", "mark-merged-pr-done", "guard", "verdict"]);
19612
19613
  var TRAIN_PR_AUTOMATION_GRACE_ATTEMPTS = 3;
@@ -20011,10 +20012,14 @@ async function waitForRequiredTrainChecks(deps, ctx, sha, required, freshSince)
20011
20012
  const sleep2 = resolveSleep(deps);
20012
20013
  let lastStatus = "not checked";
20013
20014
  let lastError;
20015
+ let workflowRunRead = "not-read";
20016
+ let workflowRunNote = "";
20017
+ let workflowRunEverSeen = false;
20018
+ let hadQueuedWorkflowRun = false;
20014
20019
  const everObserved = /* @__PURE__ */ new Set();
20015
20020
  const autoSatisfied = /* @__PURE__ */ new Set();
20016
20021
  let fleetForeignStreak = 0;
20017
- for (let attempt = 0; attempt < TRAIN_CHECK_ATTEMPTS; attempt++) {
20022
+ for (let attempt = 0; attempt < TRAIN_CHECK_ATTEMPTS || hadQueuedWorkflowRun && attempt < TRAIN_QUEUED_CHECK_ATTEMPTS; attempt++) {
20018
20023
  if (attempt > 0) await sleep2(TRAIN_CHECK_DELAY_MS);
20019
20024
  let checkRuns;
20020
20025
  let statuses;
@@ -20032,6 +20037,40 @@ async function waitForRequiredTrainChecks(deps, ctx, sha, required, freshSince)
20032
20037
  lastError = e.message || String(e);
20033
20038
  continue;
20034
20039
  }
20040
+ try {
20041
+ const workflowOut = await deps.run("gh", [
20042
+ "run",
20043
+ "list",
20044
+ "--repo",
20045
+ ctx.repo,
20046
+ "--commit",
20047
+ sha,
20048
+ "--limit",
20049
+ "100",
20050
+ "--json",
20051
+ "databaseId,status,conclusion,headSha"
20052
+ ]);
20053
+ const parsedWorkflowRuns = JSON.parse(workflowOut);
20054
+ if (!Array.isArray(parsedWorkflowRuns)) throw new Error("workflow-runs response was not an array");
20055
+ const matchingRuns = parsedWorkflowRuns.filter((run) => !run.headSha || run.headSha === sha);
20056
+ if (matchingRuns.length) {
20057
+ workflowRunRead = "found";
20058
+ workflowRunEverSeen = true;
20059
+ const activeRun = matchingRuns.find((run) => run.status === "queued" || run.status === "in_progress");
20060
+ if (activeRun) {
20061
+ if (activeRun.status === "queued") hadQueuedWorkflowRun = true;
20062
+ workflowRunNote = activeRun.status === "queued" ? "Actions run is queued behind busy runners" : "Actions run is in progress";
20063
+ } else {
20064
+ workflowRunNote = "Actions run exists but has not produced the required check-run";
20065
+ }
20066
+ } else {
20067
+ workflowRunRead = "empty";
20068
+ workflowRunNote = "";
20069
+ }
20070
+ } catch (e) {
20071
+ workflowRunRead = "failed";
20072
+ workflowRunNote = `workflow-run lookup failed: ${e.message || String(e)}`;
20073
+ }
20035
20074
  for (const c of required) {
20036
20075
  if (checkRuns.some((r) => r.name === c) || statuses.some((s) => s.context === c)) everObserved.add(c);
20037
20076
  }
@@ -20069,11 +20108,14 @@ async function waitForRequiredTrainChecks(deps, ctx, sha, required, freshSince)
20069
20108
  return `required checks passed: ${pending.join(", ") || "(none pending)"}${satisfiedNote}${fleetNote}`;
20070
20109
  }
20071
20110
  }
20072
- const waitedMin = Math.round((TRAIN_CHECK_ATTEMPTS - 1) * TRAIN_CHECK_DELAY_MS / 6e4);
20111
+ const attempts = hadQueuedWorkflowRun ? TRAIN_QUEUED_CHECK_ATTEMPTS : TRAIN_CHECK_ATTEMPTS;
20112
+ const waitedMin = Math.round((attempts - 1) * TRAIN_CHECK_DELAY_MS / 6e4);
20073
20113
  const neverMaterialized = required.filter((c) => !everObserved.has(c) && !autoSatisfied.has(c));
20074
- const neverNote = neverMaterialized.length ? ` Never materialized on ${sha} (no check-run or commit status ever appeared \u2014 the workflow that produces them was likely not triggered by the tag event): ${neverMaterialized.join(", ")}.` : "";
20114
+ const noWorkflowRun = workflowRunRead === "empty" && !workflowRunEverSeen;
20115
+ const neverNote = neverMaterialized.length && noWorkflowRun ? ` No workflow run was found on ${sha} after a successful lookup, and no check-run or commit status appeared: ${neverMaterialized.join(", ")}.` : "";
20116
+ const runNote = workflowRunNote ? ` ${workflowRunNote}.` : "";
20075
20117
  throw new Error(
20076
- `timed out after ~${waitedMin}m (${TRAIN_CHECK_ATTEMPTS} attempts) waiting for required train checks on ${sha}.${neverNote} Last observed: ${lastError ? `error: ${lastError}` : lastStatus}`
20118
+ `timed out after ~${waitedMin}m (${attempts} attempts) waiting for required train checks on ${sha}.${neverNote}${runNote}${lastError ? ` Last read error: ${lastError}` : ` Last observed: ${lastStatus}`}`
20077
20119
  );
20078
20120
  }
20079
20121
  async function probeRemoteTag(deps, tag) {
@@ -21747,7 +21789,7 @@ function partialTrainRecoveryError(cause, input) {
21747
21789
  const causeMessage = cause instanceof Error ? cause.message : String(cause);
21748
21790
  const branch = input.stage;
21749
21791
  const releaseState = input.stage === "rc" ? "GitHub Release n/a" : "GitHub Release not created";
21750
- const resumeCommand = input.stage === "rc" ? "mmi-cli devops rcand --resume" : "mmi-cli devops release --resume";
21792
+ const resumeCommand = input.stage === "rc" ? "mmi-cli devops rcand --resume" : `mmi-cli devops release --resume${input.suiteSolo ? " --suite-solo --owner-go" : ""}`;
21751
21793
  const tenant2 = input.deployModel === "tenant-container";
21752
21794
  const deployLine = tenant2 ? ` - deploy: dispatched by the train after the branch push; recover with \`mmi-cli devops runtime tenant redeploy ${input.repo} ${input.stage} --watch\` once the branch and release exist.` : ` - deploy: this repo is \`${input.deployModel ?? "not tenant-container"}\` \u2014 it has NO tenant runtime. Its own release/main-push workflows publish and deploy once the branch and Release exist. Do NOT run the tenant redeployer.`;
21753
21795
  const stateBlock = `partial train state for ${input.tag}:
@@ -26154,7 +26196,7 @@ async function completeMainRelease(deps, ctx, meta, deployModel, watch, options,
26154
26196
  }
26155
26197
  let tagPush;
26156
26198
  let tagLedgerStarted = false;
26157
- const recoveryInput = { repo: ctx.repo, tag, stage: "main", deployModel, meta, branchHints };
26199
+ const recoveryInput = { repo: ctx.repo, tag, stage: "main", deployModel, suiteSolo: options.suiteSolo, meta, branchHints };
26158
26200
  try {
26159
26201
  await assertComputedReleaseTagStillNext(deps, tag, preOneZeroInForce(meta));
26160
26202
  if (deployModel === "hub-serverless") {
@@ -26745,7 +26787,7 @@ Nothing was written. Inspect ${ledger.path} (or clear it only after proving the
26745
26787
  }
26746
26788
  const steps = [];
26747
26789
  let requiredChecks;
26748
- const recoveryInput = { repo: ctx.repo, tag, stage: "main", deployModel, meta, branchHints };
26790
+ const recoveryInput = { repo: ctx.repo, tag, stage: "main", deployModel, suiteSolo: options.suiteSolo, meta, branchHints };
26749
26791
  try {
26750
26792
  requiredChecks = await discoverRequiredCheckContexts(deps, ctx, "main");
26751
26793
  } catch (e) {
@@ -46729,6 +46771,17 @@ async function prepareLaneCheckout(git3, repo, branch, lane) {
46729
46771
  const [head, origin] = (await git3(["rev-parse", "HEAD", `origin/${branch}`])).trim().split(/\s+/);
46730
46772
  if (!head || head !== origin) throw new Error(`${repo}: local ${branch} ${head?.slice(0, 12)} is not origin/${branch} ${origin?.slice(0, 12)}; stop`);
46731
46773
  }
46774
+ async function refreshSuiteCheckout(git3) {
46775
+ await git3(["fetch", "--prune", "origin"]);
46776
+ if ((await git3(["branch", "--remotes", "--list", "origin/rc"])).trim()) return;
46777
+ if (!(await git3(["branch", "--list", "rc"])).trim()) return;
46778
+ const upstream = (await git3(["for-each-ref", "--format=%(upstream:short)", "refs/heads/rc"])).trim();
46779
+ if (upstream !== "origin/rc") return;
46780
+ const sha = (await git3(["rev-parse", "--short=12", "refs/heads/rc"])).trim();
46781
+ let stale = `stale-rc-${sha}`;
46782
+ for (let suffix = 1; (await git3(["branch", "--list", stale])).trim(); suffix++) stale = `stale-rc-${sha}-${suffix}`;
46783
+ await git3(["branch", "--move", "rc", stale]);
46784
+ }
46732
46785
  function rcRunCauseFromLog(log) {
46733
46786
  const causes = [...new Set([...log.matchAll(/##\[error\](?!Process completed with exit code)([^\r\n]+)/g)].map((m) => m[1].trim()).filter(Boolean))];
46734
46787
  return causes.length ? `: ${causes.join("; ")}` : "";
@@ -46750,6 +46803,7 @@ function suiteTrainIo(root, summaryFile, memberSummaryFiles = {}) {
46750
46803
  const origin = await exec("git", ["remote", "get-url", "origin"], target);
46751
46804
  if (!origin.toLowerCase().endsWith(`/${repo.toLowerCase()}.git`) && !origin.toLowerCase().endsWith(`/${repo.toLowerCase()}`))
46752
46805
  throw new Error(`${repo}: suite checkout origin mismatch at ${target}; stop`);
46806
+ await refreshSuiteCheckout((args) => exec("git", args, target, WATCH_TIMEOUT));
46753
46807
  return target;
46754
46808
  };
46755
46809
  const inTrain = async (repo, action, solo = false) => {
@@ -47766,6 +47820,16 @@ var surfaces_default = {
47766
47820
  "mmi-cli.cmd"
47767
47821
  ]
47768
47822
  },
47823
+ {
47824
+ mode: "files",
47825
+ sourcePath: "cli",
47826
+ targetPath: "packages/claude-plugin/cli",
47827
+ include: [
47828
+ "dist/index.cjs",
47829
+ "dist/main.cjs",
47830
+ "package.json"
47831
+ ]
47832
+ },
47769
47833
  {
47770
47834
  mode: "files",
47771
47835
  sourcePath: ".claude-plugin",
@@ -47841,6 +47905,16 @@ var surfaces_default = {
47841
47905
  "mmi-cli.cmd"
47842
47906
  ]
47843
47907
  },
47908
+ {
47909
+ mode: "files",
47910
+ sourcePath: "cli",
47911
+ targetPath: "packages/codex-plugin/cli",
47912
+ include: [
47913
+ "dist/index.cjs",
47914
+ "dist/main.cjs",
47915
+ "package.json"
47916
+ ]
47917
+ },
47844
47918
  {
47845
47919
  mode: "files",
47846
47920
  sourcePath: ".codex-plugin",
@@ -47916,6 +47990,16 @@ var surfaces_default = {
47916
47990
  "mmi-cli.cmd"
47917
47991
  ]
47918
47992
  },
47993
+ {
47994
+ mode: "files",
47995
+ sourcePath: "cli",
47996
+ targetPath: "packages/cursor-plugin/cli",
47997
+ include: [
47998
+ "dist/index.cjs",
47999
+ "dist/main.cjs",
48000
+ "package.json"
48001
+ ]
48002
+ },
47919
48003
  {
47920
48004
  mode: "files",
47921
48005
  sourcePath: ".cursor-plugin",
@@ -48132,7 +48216,7 @@ var surfaces_default = {
48132
48216
  ownerPath: "packages/claude-plugin/package.json",
48133
48217
  deliveryPath: "packages/claude-plugin/package.json",
48134
48218
  delivery: "npm",
48135
- applicability: "Claude Code plugin; npm package @mutmutco/claude-plugin carrying the plugin manifest, skills, hooks, gate scripts, and launchers. The thin git catalog stays in .claude-plugin/marketplace.json (#4945).",
48219
+ applicability: "Claude Code plugin; npm package @mutmutco/claude-plugin carrying the plugin manifest, skills, hooks, gate scripts, launchers, and the bundled mmi-cli engine the launchers run. The thin git catalog stays in .claude-plugin/marketplace.json (#4945).",
48136
48220
  versionCoordinated: true,
48137
48221
  surfaceToken: "claude",
48138
48222
  versionPaths: [
@@ -48148,7 +48232,8 @@ var surfaces_default = {
48148
48232
  additionalPaths: [
48149
48233
  "packages/claude-plugin/.claude-plugin",
48150
48234
  "packages/claude-plugin/skills",
48151
- "packages/claude-plugin/bin"
48235
+ "packages/claude-plugin/bin",
48236
+ "packages/claude-plugin/cli"
48152
48237
  ],
48153
48238
  artifactIdentity: {
48154
48239
  kind: "npm-pack",
@@ -48183,7 +48268,8 @@ var surfaces_default = {
48183
48268
  additionalPaths: [
48184
48269
  "packages/codex-plugin/.codex-plugin",
48185
48270
  "packages/codex-plugin/skills",
48186
- "packages/codex-plugin/bin"
48271
+ "packages/codex-plugin/bin",
48272
+ "packages/codex-plugin/cli"
48187
48273
  ],
48188
48274
  artifactIdentity: {
48189
48275
  kind: "npm-pack",
@@ -48214,7 +48300,8 @@ var surfaces_default = {
48214
48300
  additionalPaths: [
48215
48301
  "packages/cursor-plugin/.cursor-plugin",
48216
48302
  "packages/cursor-plugin/skills",
48217
- "packages/cursor-plugin/bin"
48303
+ "packages/cursor-plugin/bin",
48304
+ "packages/cursor-plugin/cli"
48218
48305
  ],
48219
48306
  artifactIdentity: {
48220
48307
  kind: "npm-pack",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mutmutco/cli",
3
- "version": "4.5.84",
3
+ "version": "4.5.85",
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",