@mutmutco/cli 4.6.18 → 4.6.19

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 +54 -10
  2. package/package.json +1 -1
package/dist/main.cjs CHANGED
@@ -28089,10 +28089,10 @@ var rollout_plan_default = {
28089
28089
  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)."
28090
28090
  },
28091
28091
  baseline: {
28092
- version: "4.6.18",
28093
- tag: "v4.6.18",
28094
- commit: "24b7f2455176",
28095
- npm: "@mutmutco/cli@4.6.18"
28092
+ version: "4.6.19",
28093
+ tag: "v4.6.19",
28094
+ commit: "4dce08ee7823",
28095
+ npm: "@mutmutco/cli@4.6.19"
28096
28096
  },
28097
28097
  exitCriterion: "fleet-n-of-n",
28098
28098
  hubOnlyShortcut: "forbidden",
@@ -28109,14 +28109,14 @@ var rollout_plan_default = {
28109
28109
  repo: "mutmutco/mmi-hub",
28110
28110
  role: "canary",
28111
28111
  schedule: "train",
28112
- v3Target: "v4.6.18"
28112
+ v3Target: "v4.6.19"
28113
28113
  }
28114
28114
  ],
28115
28115
  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.",
28116
28116
  rollback: {
28117
28117
  independent: true,
28118
- mechanism: "npm dist-tag latest -> 4.6.18 and redeploy the Hub Lambda from tag v4.6.18 (24b7f2455176); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
28119
- v3Target: "v4.6.18 (@mutmutco/cli@4.6.18, tag commit 24b7f2455176 \u2014 last known-good release carrying the repo-index v4-only contract)"
28118
+ mechanism: "npm dist-tag latest -> 4.6.19 and redeploy the Hub Lambda from tag v4.6.19 (4dce08ee7823); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
28119
+ v3Target: "v4.6.19 (@mutmutco/cli@4.6.19, tag commit 4dce08ee7823 \u2014 last known-good release carrying the repo-index v4-only contract)"
28120
28120
  }
28121
28121
  },
28122
28122
  {
@@ -56804,6 +56804,32 @@ var COMPARE_RE = new RegExp(`^repos/${NAME}/${NAME}/compare/${FREE}\\.\\.\\.${FR
56804
56804
  var CONTENTS_BASE_RE = new RegExp(`^repos/${NAME}/${NAME}/contents/${FREE}$`);
56805
56805
  var CONTENTS_QUERY_RE = /^ref=[^&\s]+$/;
56806
56806
  var ACTIONS_RUNS_RE = new RegExp(`^repos/(${NAME})/(${NAME})/actions/runs$`);
56807
+ var ACTIONS_WORKFLOW_RUNS_RE = new RegExp(`^repos/(${NAME})/(${NAME})/actions/workflows/([A-Za-z0-9][A-Za-z0-9_.-]*\\.ya?ml)/runs$`);
56808
+ var WORKFLOW_RUNS_CANONICAL_DIR = ".github/workflows/";
56809
+ function workflowRunsAliasRequest(owner, repo, file, query) {
56810
+ let page = "1";
56811
+ let perPage = 30;
56812
+ const filters = [];
56813
+ for (const pair of query.split("&")) {
56814
+ if (!pair) continue;
56815
+ const eq = pair.indexOf("=");
56816
+ if (pair.slice(0, eq) === "page") {
56817
+ page = pair.slice(eq + 1);
56818
+ continue;
56819
+ }
56820
+ if (pair.slice(0, eq) === "per_page") {
56821
+ perPage = Number(pair.slice(eq + 1));
56822
+ continue;
56823
+ }
56824
+ filters.push(pair);
56825
+ }
56826
+ return {
56827
+ kind: "actions-workflow-runs",
56828
+ path: `repos/${owner}/${repo}/actions/runs?per_page=100&page=${page}${filters.map((pair) => `&${pair}`).join("")}`,
56829
+ paginate: false,
56830
+ workflowRuns: { file, page: Number(page), perPage }
56831
+ };
56832
+ }
56807
56833
  var RUNS_QUERY_VALUE = {
56808
56834
  per_page: /^(?:[1-9]\d?|100)$/,
56809
56835
  page: /^[1-9]\d{0,5}$/,
@@ -56840,7 +56866,7 @@ var RELEASE_LIST_QUERY_VALUE = { per_page: RUNS_QUERY_VALUE.per_page, page: RUNS
56840
56866
  var RELEASE_LATEST_RE = new RegExp(`^repos/${NAME}/${NAME}/releases/latest$`);
56841
56867
  var RELEASE_TAG_RE = new RegExp(`^repos/${NAME}/${NAME}/releases/tags/(${NAME})$`);
56842
56868
  var RELEASE_ASSET_RE = new RegExp(`^repos/${NAME}/${NAME}/releases/assets/\\d+$`);
56843
- var API_GET_ALLOWED_SHAPES = "repos/{owner}/{repo}/issues/comments/{id}, repos/{owner}/{repo}/issues/{n}/comments[?per_page=1-100&page=<n>, each key at most once], repos/{owner}/{repo}/pulls/{n}/files, repos/{owner}/{repo}/compare/{a}...{b}, repos/{owner}/{repo}/contents/{path}[?ref=<branch>], repos/{owner}/{repo}/actions/runs[?per_page=1-100&page=<n>&status=&branch=&event=&head_sha=<40-hex>&created=<date-range>&actor=, each key at most once], repos/{owner}/{repo}/actions/runs/{id}, repos/{owner}/{repo}/actions/runs/{id}/jobs[?per_page=1-100&page=<n>, each key at most once], repos/{owner}/{repo}/actions/runs/{id}/attempts/{n}/jobs[?per_page=1-100&page=<n>, each key at most once], repos/{owner}/{repo}/actions/runs/{id}/artifacts[?per_page=1-100&page=<n>, each key at most once], repos/{owner}/{repo}/actions/artifacts/{id}/zip (needs --out <file>), repos/{owner}/{repo}/actions/jobs/{id}/logs (needs --out <file>), repos/{owner}/{repo}/releases[?per_page=1-100&page=<n>, each key at most once], repos/{owner}/{repo}/releases/latest, repos/{owner}/{repo}/releases/tags/{tag}, repos/{owner}/{repo}/releases/assets/{id} (needs --out <file>)";
56869
+ var API_GET_ALLOWED_SHAPES = "repos/{owner}/{repo}/issues/comments/{id}, repos/{owner}/{repo}/issues/{n}/comments[?per_page=1-100&page=<n>, each key at most once], repos/{owner}/{repo}/pulls/{n}/files, repos/{owner}/{repo}/compare/{a}...{b}, repos/{owner}/{repo}/contents/{path}[?ref=<branch>], repos/{owner}/{repo}/actions/runs[?per_page=1-100&page=<n>&status=&branch=&event=&head_sha=<40-hex>&created=<date-range>&actor=, each key at most once], repos/{owner}/{repo}/actions/workflows/<file>.yml|.yaml/runs[?same keys, each at most once \u2014 #9762 alias: ONE repository page (per_page=100 upstream) with workflow_runs sliced to exact .github/workflows/<file> path matches], repos/{owner}/{repo}/actions/runs/{id}, repos/{owner}/{repo}/actions/runs/{id}/jobs[?per_page=1-100&page=<n>, each key at most once], repos/{owner}/{repo}/actions/runs/{id}/attempts/{n}/jobs[?per_page=1-100&page=<n>, each key at most once], repos/{owner}/{repo}/actions/runs/{id}/artifacts[?per_page=1-100&page=<n>, each key at most once], repos/{owner}/{repo}/actions/artifacts/{id}/zip (needs --out <file>), repos/{owner}/{repo}/actions/jobs/{id}/logs (needs --out <file>), repos/{owner}/{repo}/releases[?per_page=1-100&page=<n>, each key at most once], repos/{owner}/{repo}/releases/latest, repos/{owner}/{repo}/releases/tags/{tag}, repos/{owner}/{repo}/releases/assets/{id} (needs --out <file>)";
56844
56870
  var API_GET_RECOVERY = " No other GET read exists \u2014 do not retry path variants; use a dedicated mmi-cli subcommand or ask a human token holder. This refusal exits 1 on stderr with nothing on stdout: check the exit code and never merge stderr into stdout (2>&1) before JSON-parsing. Piping empty stdout into JSON.parse hides the stderr refusal; check the exit code before parsing.";
56845
56871
  var TYPED_READ_ROUTE_RE = new RegExp(`^repos/(${NAME})/(${NAME})/(issues|pulls)(?:/(comments/\\d+|\\d+)(?:/([a-z_]+))?)?$`);
56846
56872
  function typedReadHint(path2) {
@@ -56912,7 +56938,7 @@ function workflowRunsReadHint(path2) {
56912
56938
  if (!match) return "";
56913
56939
  const [, owner, repo, workflow] = match;
56914
56940
  const slug = `${owner}/${repo}`;
56915
- return ` Workflow routes are outside the App allowlist \u2014 use the typed workflow runs read \`MMI_ACTOR=app mmi-cli devops read run list --repo ${slug} --workflow ${workflow ?? "<workflow.yml>"} --branch <branch> --limit <n> --json databaseId,workflowName,event,status,conclusion\`, or the allowlisted REST runs list \`MMI_ACTOR=app mmi-cli devops api get "repos/${slug}/actions/runs?branch=<branch>&per_page=<n>"\`.`;
56941
+ return ` Workflow routes are outside the App allowlist \u2014 use the typed workflow runs read \`MMI_ACTOR=app mmi-cli devops read run list --repo ${slug} --workflow ${workflow ?? "<workflow.yml>"} --branch <branch> --limit <n> --json databaseId,workflowName,event,status,conclusion\`, or the allowlisted REST runs list \`MMI_ACTOR=app mmi-cli devops api get "repos/${slug}/actions/runs?branch=<branch>&per_page=<n>"\`. A canonical workflow FILENAME at \`repos/${slug}/actions/workflows/<file>.yml|.yaml/runs\` IS the allowlisted alias (#9762: one repository page, runs sliced to exact .github/workflows/<file> path matches); numeric ids and display names are not.`;
56916
56942
  }
56917
56943
  function normalizeApiGetPath(raw) {
56918
56944
  const trimmed = raw.trim();
@@ -56935,6 +56961,8 @@ function parseApiGetPath(rawPath) {
56935
56961
  if (PULL_FILES_RE.test(path2)) return { kind: "pull-files", path: path2, paginate: true };
56936
56962
  if (COMPARE_RE.test(path2)) return { kind: "compare", path: path2, paginate: false };
56937
56963
  if (ACTIONS_RUNS_RE.test(base) && (q === -1 || validRunsQuery(query))) return { kind: "actions-runs", path: path2, paginate: false };
56964
+ const wfRuns = ACTIONS_WORKFLOW_RUNS_RE.exec(base);
56965
+ if (wfRuns && (q === -1 || validRunsQuery(query))) return workflowRunsAliasRequest(wfRuns[1], wfRuns[2], wfRuns[3], query);
56938
56966
  if (ACTIONS_RUN_RE.test(path2)) return { kind: "actions-run", path: path2, paginate: false };
56939
56967
  if (ACTIONS_JOBS_RE.test(base) && (q === -1 || validRunsQuery(query, RELEASE_LIST_QUERY_VALUE))) return { kind: "actions-jobs", path: path2, paginate: q === -1 };
56940
56968
  if (ACTIONS_ARTIFACTS_RE.test(base) && (q === -1 || validRunsQuery(query, RELEASE_LIST_QUERY_VALUE))) return { kind: "actions-artifacts", path: path2, paginate: q === -1 };
@@ -56950,6 +56978,20 @@ function parseApiGetPath(rawPath) {
56950
56978
  }
56951
56979
  throw refuse();
56952
56980
  }
56981
+ function sliceWorkflowRunsPage(body, selector) {
56982
+ const parsed = JSON.parse(body);
56983
+ if (!Array.isArray(parsed.workflow_runs)) throw new Error("api get: upstream repository runs page has no workflow_runs array");
56984
+ const matched = parsed.workflow_runs.filter((run) => run?.path === `${WORKFLOW_RUNS_CANONICAL_DIR}${selector.file}`).slice(0, selector.perPage);
56985
+ return JSON.stringify({
56986
+ workflow_runs: matched,
56987
+ matched_count: matched.length,
56988
+ repository_total_count: parsed.total_count,
56989
+ scope: "repository-page",
56990
+ incomplete_results: true,
56991
+ repository_page: selector.page,
56992
+ repository_per_page: 100
56993
+ });
56994
+ }
56953
56995
  var ZIP_TIMEOUT_MS = 12e4;
56954
56996
  var ZIP_MAX_BUFFER = 512 * 1024 * 1024;
56955
56997
  function buildApiGetArgs(path2, accept) {
@@ -56970,7 +57012,8 @@ async function readAppApi(path2, runner = apiReadRunner) {
56970
57012
  requireBrokerApp("read run log");
56971
57013
  const log = req.kind === "actions-job-logs";
56972
57014
  const body = await runApiGet((args, timeout) => runner(req.kind === "actions-jobs" ? [...args, "--slurp"] : args, log ? ZIP_TIMEOUT_MS : timeout, brokerChildEnv(), log || void 0), path2);
56973
- return log ? Buffer.from(body, "latin1").toString("utf8") : body;
57015
+ const out = req.workflowRuns ? sliceWorkflowRunsPage(body, req.workflowRuns) : body;
57016
+ return log ? Buffer.from(body, "latin1").toString("utf8") : out;
56974
57017
  }
56975
57018
  function registerApiReadCommands(program3, overrides) {
56976
57019
  const spawn7 = overrides?.runner ?? apiReadRunner;
@@ -56996,6 +57039,7 @@ function registerApiReadCommands(program3, overrides) {
56996
57039
  req.path,
56997
57040
  o.accept
56998
57041
  );
57042
+ if (req.workflowRuns) body = sliceWorkflowRunsPage(body, req.workflowRuns);
56999
57043
  if (o.jq !== void 0) body = await jqRun(o.jq, body, localJqEnv(), ...bindings.length ? [bindings] : []);
57000
57044
  if (zip) {
57001
57045
  (0, import_node_fs46.writeFileSync)(o.out, body, "latin1");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mutmutco/cli",
3
- "version": "4.6.18",
3
+ "version": "4.6.19",
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",