@mutmutco/codex-plugin 4.5.152 → 4.5.153
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.
package/cli/dist/main.cjs
CHANGED
|
@@ -7081,6 +7081,12 @@ var APP_ELIGIBLE_COMMANDS = /* @__PURE__ */ new Set([
|
|
|
7081
7081
|
"read run watch",
|
|
7082
7082
|
"read run log",
|
|
7083
7083
|
// #8136: bounded jobs/logs REST read, same polling credential.
|
|
7084
|
+
"read pr list",
|
|
7085
|
+
// #8347: stored-field PR list; author/viewer-dependent filters refused.
|
|
7086
|
+
"read pr diff",
|
|
7087
|
+
// #8347: fixed PR diff read; no viewer fields.
|
|
7088
|
+
"read pr queue",
|
|
7089
|
+
// #8347: fixed mergeQueueEntry query; no generic GraphQL or viewer resolution.
|
|
7084
7090
|
"read pr view",
|
|
7085
7091
|
"read pr checks",
|
|
7086
7092
|
"read issue view",
|
|
@@ -16415,6 +16421,33 @@ function defaultTrackedFirstSegments(root, firstSegments, exec3 = import_node_ch
|
|
|
16415
16421
|
throw error;
|
|
16416
16422
|
}
|
|
16417
16423
|
}
|
|
16424
|
+
function mergeGroupRunbookMessages(root, deps, readFile10, warnings) {
|
|
16425
|
+
const env = deps.env ?? process.env;
|
|
16426
|
+
if (env.GITHUB_EVENT_NAME !== "merge_group") return "";
|
|
16427
|
+
let source = "merge_group event payload";
|
|
16428
|
+
try {
|
|
16429
|
+
const event = JSON.parse(readFile10(env.GITHUB_EVENT_PATH ?? "") ?? "");
|
|
16430
|
+
const match = /^refs\/heads\/gh-readonly-queue\/.+\/pr-([1-9]\d*)-[a-f0-9]+$/.exec(event.merge_group?.head_ref ?? "");
|
|
16431
|
+
const repo = env.GITHUB_REPOSITORY;
|
|
16432
|
+
if (!match || !repo || !/^[\w.-]+\/[\w.-]+$/.test(repo)) throw new Error("invalid queue source");
|
|
16433
|
+
source = `repos/${repo}/pulls/${match[1]}/commits`;
|
|
16434
|
+
const gh2 = deps.gh ?? ((args) => (0, import_node_child_process6.execFileSync)("gh", args, {
|
|
16435
|
+
cwd: root,
|
|
16436
|
+
encoding: "utf8",
|
|
16437
|
+
windowsHide: true,
|
|
16438
|
+
timeout: 3e4,
|
|
16439
|
+
maxBuffer: CHECK_IGNORE_MAX_BUFFER,
|
|
16440
|
+
env: { ...env, GH_TOKEN: env.GH_TOKEN || env.GITHUB_TOKEN },
|
|
16441
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
16442
|
+
}));
|
|
16443
|
+
const pages = JSON.parse(gh2(["api", source, "--paginate", "--slurp"]));
|
|
16444
|
+
if (!Array.isArray(pages) || !pages.every((page) => Array.isArray(page) && page.every((commit) => typeof commit?.commit?.message === "string"))) throw new Error("invalid commit response");
|
|
16445
|
+
return pages.flat().map((commit) => commit.commit.message).join("\n");
|
|
16446
|
+
} catch {
|
|
16447
|
+
warnings.push({ kind: "runbook-source-unverified", doc: source, line: 0, detail: `failed to read ${source}; using git-log Runbook-Unaffected declarations only` });
|
|
16448
|
+
return "";
|
|
16449
|
+
}
|
|
16450
|
+
}
|
|
16418
16451
|
function runDocRefs(root, deps = {}) {
|
|
16419
16452
|
const readFile10 = deps.readFile ?? readFileOrNull;
|
|
16420
16453
|
const exists = deps.exists ?? import_node_fs17.existsSync;
|
|
@@ -16451,7 +16484,10 @@ function runDocRefs(root, deps = {}) {
|
|
|
16451
16484
|
if (deps.base) {
|
|
16452
16485
|
const git3 = deps.git ?? ((args) => (0, import_node_child_process6.execFileSync)("git", args, { cwd: root, encoding: "utf8", maxBuffer: CHECK_IGNORE_MAX_BUFFER, windowsHide: true }));
|
|
16453
16486
|
const stale = checkRunbookCoverage(runbooks, deps.base, git3);
|
|
16454
|
-
const
|
|
16487
|
+
const messages = git3(["log", "--format=%B", `${deps.base}..HEAD`]);
|
|
16488
|
+
const sourceMessages = stale.length ? mergeGroupRunbookMessages(root, deps, readFile10, warnings) : "";
|
|
16489
|
+
const override = /^Runbook-Unaffected:[ \t]*\S.*$/m.test(`${messages}
|
|
16490
|
+
${sourceMessages}`);
|
|
16455
16491
|
(override ? warnings : findings).push(...stale);
|
|
16456
16492
|
}
|
|
16457
16493
|
return {
|
|
@@ -18684,10 +18720,10 @@ var rollout_plan_default = {
|
|
|
18684
18720
|
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)."
|
|
18685
18721
|
},
|
|
18686
18722
|
baseline: {
|
|
18687
|
-
version: "4.5.
|
|
18688
|
-
tag: "v4.5.
|
|
18689
|
-
commit: "
|
|
18690
|
-
npm: "@mutmutco/cli@4.5.
|
|
18723
|
+
version: "4.5.153",
|
|
18724
|
+
tag: "v4.5.153",
|
|
18725
|
+
commit: "57b23d8d7d5f",
|
|
18726
|
+
npm: "@mutmutco/cli@4.5.153"
|
|
18691
18727
|
},
|
|
18692
18728
|
exitCriterion: "fleet-n-of-n",
|
|
18693
18729
|
hubOnlyShortcut: "forbidden",
|
|
@@ -18704,14 +18740,14 @@ var rollout_plan_default = {
|
|
|
18704
18740
|
repo: "mutmutco/mmi-hub",
|
|
18705
18741
|
role: "canary",
|
|
18706
18742
|
schedule: "train",
|
|
18707
|
-
v3Target: "v4.5.
|
|
18743
|
+
v3Target: "v4.5.153"
|
|
18708
18744
|
}
|
|
18709
18745
|
],
|
|
18710
18746
|
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.",
|
|
18711
18747
|
rollback: {
|
|
18712
18748
|
independent: true,
|
|
18713
|
-
mechanism: "npm dist-tag latest -> 4.5.
|
|
18714
|
-
v3Target: "v4.5.
|
|
18749
|
+
mechanism: "npm dist-tag latest -> 4.5.153 and redeploy the Hub Lambda from tag v4.5.153 (57b23d8d7d5f); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
|
|
18750
|
+
v3Target: "v4.5.153 (@mutmutco/cli@4.5.153, tag commit 57b23d8d7d5f \u2014 last known-good release carrying the repo-index v4-only contract)"
|
|
18715
18751
|
}
|
|
18716
18752
|
},
|
|
18717
18753
|
{
|
|
@@ -53140,6 +53176,46 @@ function parseBrokerAssignee(raw) {
|
|
|
53140
53176
|
return v;
|
|
53141
53177
|
}
|
|
53142
53178
|
var SINGLE_SHOT_TIMEOUT_MS = 6e4;
|
|
53179
|
+
var BROKER_MAX_BUFFER = 64 * 1024 * 1024;
|
|
53180
|
+
var PR_QUEUE_QUERY = "query($owner:String!,$name:String!,$number:Int!){repository(owner:$owner,name:$name){pullRequest(number:$number){mergeQueueEntry{state position enqueuedAt estimatedTimeToMerge headCommit{oid}}}}}";
|
|
53181
|
+
function buildPrQueueSpec(number, o) {
|
|
53182
|
+
const repo = parseBrokerRepo(o.repo, "--repo");
|
|
53183
|
+
if (!repo) throw new Error("read pr queue: --repo is required");
|
|
53184
|
+
const [owner, name] = repo.split("/");
|
|
53185
|
+
return { program: "gh", args: ["api", "graphql", "-f", `query=${PR_QUEUE_QUERY}`, "-f", `owner=${owner}`, "-f", `name=${name}`, "-F", `number=${parseBrokerId(number, "PR number")}`], timeoutMs: SINGLE_SHOT_TIMEOUT_MS };
|
|
53186
|
+
}
|
|
53187
|
+
function buildPrDiffSpec(number, o) {
|
|
53188
|
+
const args = withRepo(["pr", "diff", parseBrokerId(number, "PR number")], parseBrokerRepo(o.repo, "--repo"));
|
|
53189
|
+
if (o.nameOnly) args.push("--name-only");
|
|
53190
|
+
return { program: "gh", args, timeoutMs: SINGLE_SHOT_TIMEOUT_MS };
|
|
53191
|
+
}
|
|
53192
|
+
function parseBrokerPrSearch(raw) {
|
|
53193
|
+
const search = parseBrokerSearch(raw);
|
|
53194
|
+
if (search && /@me/i.test(search)) throw new Error("read: --search resolves the viewer \u2014 viewer-scoped reads stay personal");
|
|
53195
|
+
return search;
|
|
53196
|
+
}
|
|
53197
|
+
function parseBrokerPrState(raw) {
|
|
53198
|
+
if (raw === void 0) return void 0;
|
|
53199
|
+
if (!["open", "closed", "merged", "all"].includes(raw)) throw new Error("read: --state must be one of: open, closed, merged, all");
|
|
53200
|
+
return raw;
|
|
53201
|
+
}
|
|
53202
|
+
function buildPrListSpec(o) {
|
|
53203
|
+
const args = withJson(withRepo(["pr", "list"], parseBrokerRepo(o.repo, "--repo")), parseBrokerJsonFields(o.json), o.json);
|
|
53204
|
+
const state = parseBrokerPrState(o.state);
|
|
53205
|
+
if (state) args.push("--state", state);
|
|
53206
|
+
for (const flag of ["base", "head"]) {
|
|
53207
|
+
const branch = parseBrokerBranch(o[flag]);
|
|
53208
|
+
if (branch) args.push(`--${flag}`, branch);
|
|
53209
|
+
}
|
|
53210
|
+
const label = parseBrokerLabel(o.label);
|
|
53211
|
+
if (label !== void 0) args.push("--label", label);
|
|
53212
|
+
const search = parseBrokerPrSearch(o.search);
|
|
53213
|
+
if (search !== void 0) args.push("--search", search);
|
|
53214
|
+
const assignee = parseBrokerAssignee(o.assignee);
|
|
53215
|
+
if (assignee) args.push("--assignee", assignee);
|
|
53216
|
+
if (o.limit !== void 0) args.push("--limit", String(parseBrokerInt(o.limit, "--limit", 1, 100)));
|
|
53217
|
+
return { program: "gh", args, timeoutMs: SINGLE_SHOT_TIMEOUT_MS };
|
|
53218
|
+
}
|
|
53143
53219
|
function withRepo(args, repo) {
|
|
53144
53220
|
return repo ? [...args, "--repo", repo] : args;
|
|
53145
53221
|
}
|
|
@@ -53332,7 +53408,7 @@ async function dispatchRestChecksRead(deps, resolveRepo2, label, spec, json) {
|
|
|
53332
53408
|
process.exitCode = result.exitCode;
|
|
53333
53409
|
}
|
|
53334
53410
|
function registerAppReadBrokerCommands(program3, resolveRepo2, overrides) {
|
|
53335
|
-
const ghRun = overrides?.ghRunner ?? (async (args, opts) => (await execFileP("gh", args, { timeout: opts.timeoutMs, env: opts.env })).stdout);
|
|
53411
|
+
const ghRun = overrides?.ghRunner ?? (async (args, opts) => (await execFileP("gh", args, { timeout: opts.timeoutMs, env: opts.env, maxBuffer: BROKER_MAX_BUFFER })).stdout);
|
|
53336
53412
|
const restGhApi = overrides?.restGhApi ?? ((env) => ghApiWithEnv(env));
|
|
53337
53413
|
const deps = { readRequired: readRequiredCheckRows, fetchSnapshot: fetchRestPrSnapshot, fetchRows: fetchHeadCheckRows, restGhApi };
|
|
53338
53414
|
const dispatchGh = (spec, label) => (async () => {
|
|
@@ -53385,7 +53461,28 @@ function registerAppReadBrokerCommands(program3, resolveRepo2, overrides) {
|
|
|
53385
53461
|
}
|
|
53386
53462
|
await dispatchGh(spec, "read run watch");
|
|
53387
53463
|
});
|
|
53388
|
-
const pr = read.command("pr").description("pull-request reads \u2014 view
|
|
53464
|
+
const pr = read.command("pr").description("pull-request reads \u2014 view/list/diff ride gh; queue uses fixed GraphQL; checks is REST-backed (deterministic closed-custody adapter; native was EMPTY only on the historical #3035 fixture)");
|
|
53465
|
+
pr.command("list").description("list viewer-free PRs (author/viewer filters stay personal)").requiredOption("--repo <owner/repo>", "target repo", repoOpt).option("--json [fields]", "native gh JSON fields", jsonOpt).addOption(new Option("--state <state>", "open|closed|merged|all").choices(["open", "closed", "merged", "all"])).option("--base <branch>", "base branch", branchOpt).option("--head <branch>", "head branch", branchOpt).option("--label <label>", "filter by label", labelOpt).option("--search <query>", "viewer-free search", (v) => parseBrokerPrSearch(v)).option("--assignee <login>", "explicit assignee (viewer refused)", assigneeOpt).option("--limit <n>", "maximum PRs (1-100)", intOpt("--limit", 1, 100)).action(async (o) => {
|
|
53466
|
+
await dispatchGh(buildPrListSpec(o), "read pr list");
|
|
53467
|
+
});
|
|
53468
|
+
pr.command("diff").description("read a bounded PR diff on the App pool").requiredOption("--repo <owner/repo>", "target repo", repoOpt).option("--name-only", "only changed file names").argument("<number>", "PR number", idOpt("PR number")).action(async (number, o) => {
|
|
53469
|
+
await dispatchGh(buildPrDiffSpec(number, o), "read pr diff");
|
|
53470
|
+
});
|
|
53471
|
+
pr.command("queue").description("read one PR mergeQueueEntry (fixed GraphQL query, no permission widening)").requiredOption("--repo <owner/repo>", "target repo", repoOpt).option("--json", "machine-readable mergeQueueEntry (null when not queued)").argument("<number>", "PR number", idOpt("PR number")).action(async (number, o) => {
|
|
53472
|
+
const spec = buildPrQueueSpec(number, o);
|
|
53473
|
+
requireBrokerApp("read pr queue");
|
|
53474
|
+
try {
|
|
53475
|
+
process.exitCode = await runBrokerGh(async (args, opts) => {
|
|
53476
|
+
const result = JSON.parse(await ghRun(args, opts));
|
|
53477
|
+
if (result.errors?.length) throw new Error(JSON.stringify(result.errors));
|
|
53478
|
+
const pr2 = result.data?.repository?.pullRequest;
|
|
53479
|
+
if (!pr2) throw new Error("PR not found or not accessible on the App pool");
|
|
53480
|
+
return JSON.stringify(pr2.mergeQueueEntry) + "\n";
|
|
53481
|
+
}, spec);
|
|
53482
|
+
} catch (e) {
|
|
53483
|
+
return fail(`read pr queue: ${e.message}`);
|
|
53484
|
+
}
|
|
53485
|
+
});
|
|
53389
53486
|
pr.command("view").description("read a PR as gh JSON (comments/json; --json supports statusCheckRollup selection; formatters refused)").option("--repo <owner/repo>", "target repo (defaults to the current repo)", repoOpt).option("--json [fields]", "machine-readable output (comma-separated gh fields)", jsonOpt).option("--comments", "include PR comments").argument("<number>", "PR number", idOpt("PR number")).action(async (number, o) => {
|
|
53390
53487
|
let spec;
|
|
53391
53488
|
try {
|
|
@@ -53456,14 +53553,14 @@ var RUNS_QUERY_VALUE = {
|
|
|
53456
53553
|
created: /^[0-9:TZ.<>=-]+$/,
|
|
53457
53554
|
actor: /^[A-Za-z0-9_.\[\]-]+$/
|
|
53458
53555
|
};
|
|
53459
|
-
function validRunsQuery(query) {
|
|
53556
|
+
function validRunsQuery(query, allowed = RUNS_QUERY_VALUE) {
|
|
53460
53557
|
const seen = /* @__PURE__ */ new Set();
|
|
53461
53558
|
for (const pair of query.split("&")) {
|
|
53462
53559
|
const eq = pair.indexOf("=");
|
|
53463
53560
|
if (eq < 1) return false;
|
|
53464
53561
|
const key = pair.slice(0, eq);
|
|
53465
53562
|
const value = pair.slice(eq + 1);
|
|
53466
|
-
const re = Object.prototype.hasOwnProperty.call(
|
|
53563
|
+
const re = Object.prototype.hasOwnProperty.call(allowed, key) ? allowed[key] : void 0;
|
|
53467
53564
|
if (!re || seen.has(key) || !re.test(value)) return false;
|
|
53468
53565
|
seen.add(key);
|
|
53469
53566
|
}
|
|
@@ -53475,10 +53572,12 @@ var ACTIONS_JOBS_RE = new RegExp(`^repos/${NAME}/${NAME}/actions/runs/\\d+(?:/at
|
|
|
53475
53572
|
var ACTIONS_ARTIFACTS_RE = new RegExp(`^repos/${NAME}/${NAME}/actions/runs/\\d+/artifacts$`);
|
|
53476
53573
|
var ACTIONS_ARTIFACT_ZIP_RE = new RegExp(`^repos/${NAME}/${NAME}/actions/artifacts/\\d+/zip$`);
|
|
53477
53574
|
var ACTIONS_JOB_LOGS_RE = new RegExp(`^repos/${NAME}/${NAME}/actions/jobs/\\d+/logs$`);
|
|
53575
|
+
var RELEASE_LIST_RE = new RegExp(`^repos/${NAME}/${NAME}/releases$`);
|
|
53576
|
+
var RELEASE_LIST_QUERY_VALUE = { per_page: RUNS_QUERY_VALUE.per_page, page: RUNS_QUERY_VALUE.page };
|
|
53478
53577
|
var RELEASE_LATEST_RE = new RegExp(`^repos/${NAME}/${NAME}/releases/latest$`);
|
|
53479
53578
|
var RELEASE_TAG_RE = new RegExp(`^repos/${NAME}/${NAME}/releases/tags/(${NAME})$`);
|
|
53480
53579
|
var RELEASE_ASSET_RE = new RegExp(`^repos/${NAME}/${NAME}/releases/assets/\\d+$`);
|
|
53481
|
-
var API_GET_ALLOWED_SHAPES = "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, repos/{owner}/{repo}/actions/runs/{id}/attempts/{n}/jobs, repos/{owner}/{repo}/actions/runs/{id}/artifacts, repos/{owner}/{repo}/actions/artifacts/{id}/zip (needs --out <file>), repos/{owner}/{repo}/actions/jobs/{id}/logs (needs --out <file>), repos/{owner}/{repo}/releases/latest, repos/{owner}/{repo}/releases/tags/{tag}, repos/{owner}/{repo}/releases/assets/{id} (needs --out <file>)";
|
|
53580
|
+
var API_GET_ALLOWED_SHAPES = "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, repos/{owner}/{repo}/actions/runs/{id}/attempts/{n}/jobs, repos/{owner}/{repo}/actions/runs/{id}/artifacts, 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>)";
|
|
53482
53581
|
function parseApiGetPath(rawPath) {
|
|
53483
53582
|
const path2 = rawPath.trim();
|
|
53484
53583
|
const refuse = () => new Error(`api get: refusing '${rawPath}' \u2014 only these GET reads are allowed (#7219): ${API_GET_ALLOWED_SHAPES}`);
|
|
@@ -53494,6 +53593,7 @@ function parseApiGetPath(rawPath) {
|
|
|
53494
53593
|
if (ACTIONS_ARTIFACTS_RE.test(path2)) return { kind: "actions-artifacts", path: path2, paginate: true };
|
|
53495
53594
|
if (ACTIONS_ARTIFACT_ZIP_RE.test(path2)) return { kind: "actions-artifact-zip", path: path2, paginate: false };
|
|
53496
53595
|
if (ACTIONS_JOB_LOGS_RE.test(path2)) return { kind: "actions-job-logs", path: path2, paginate: false };
|
|
53596
|
+
if (RELEASE_LIST_RE.test(base) && (q === -1 || validRunsQuery(query, RELEASE_LIST_QUERY_VALUE))) return { kind: "release-list", path: path2, paginate: false };
|
|
53497
53597
|
if (RELEASE_LATEST_RE.test(path2)) return { kind: "release-latest", path: path2, paginate: false };
|
|
53498
53598
|
const tag = RELEASE_TAG_RE.exec(path2)?.[1];
|
|
53499
53599
|
if (tag && !tag.includes("..")) return { kind: "release-tag", path: path2, paginate: false };
|
package/cli/package.json
CHANGED
package/package.json
CHANGED
|
@@ -54,6 +54,7 @@ concurrency:
|
|
|
54
54
|
permissions:
|
|
55
55
|
actions: read # #8206: exact-SHA development workflow verdict
|
|
56
56
|
contents: read
|
|
57
|
+
pull-requests: read # #8343: source commit declarations omitted by queue squashes
|
|
57
58
|
# MMI-Hub#7542: the product image build below reads org private packages with the workflow's
|
|
58
59
|
# own ephemeral token (NODE_AUTH_TOKEN) — the same reader the central deploy uses.
|
|
59
60
|
packages: read
|