@mutmutco/claude-plugin 4.5.164 → 4.5.166
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/.claude-plugin/plugin.json +1 -1
- package/cli/dist/main.cjs +35 -13
- package/cli/package.json +1 -1
- package/package.json +1 -1
package/cli/dist/main.cjs
CHANGED
|
@@ -14631,6 +14631,15 @@ function latestClaimMarker(comments) {
|
|
|
14631
14631
|
}
|
|
14632
14632
|
return void 0;
|
|
14633
14633
|
}
|
|
14634
|
+
function latestClaimRelease(comments) {
|
|
14635
|
+
for (let i = comments.length - 1; i >= 0; i -= 1) {
|
|
14636
|
+
const body = comments[i].body;
|
|
14637
|
+
const releases = parseClaimReleases(body);
|
|
14638
|
+
if (!parseClaimMarkers(body).length && !releases.length) continue;
|
|
14639
|
+
return latestClaimMarker([comments[i]]) ? void 0 : releases[releases.length - 1];
|
|
14640
|
+
}
|
|
14641
|
+
return void 0;
|
|
14642
|
+
}
|
|
14634
14643
|
function formatClaimAge(ageMs) {
|
|
14635
14644
|
if (ageMs === void 0 || !Number.isFinite(ageMs) || ageMs < 0) return "unknown age";
|
|
14636
14645
|
const minutes = Math.floor(ageMs / 6e4);
|
|
@@ -14838,6 +14847,7 @@ async function gatherClaimLiveness(client, repo, number, fetchOpenPulls) {
|
|
|
14838
14847
|
const comments = await client.restPaginate(`repos/${repo}/issues/${number}/comments`);
|
|
14839
14848
|
const rows = comments.map((comment) => ({ body: comment.body ?? "", login: comment.user?.login ?? void 0 }));
|
|
14840
14849
|
out.marker = latestClaimMarker(rows);
|
|
14850
|
+
if (!out.marker) out.releasedAt = latestClaimRelease(rows)?.ts;
|
|
14841
14851
|
for (let i = comments.length - 1; i >= 0; i -= 1) {
|
|
14842
14852
|
if (comments[i].created_at && !latestClaimMarker([rows[i]])) {
|
|
14843
14853
|
out.lastCommentAt = comments[i].created_at;
|
|
@@ -14919,8 +14929,9 @@ function liveEvidenceLines(evidence, repo) {
|
|
|
14919
14929
|
live.push(evidence.lastCommentAt && Date.parse(evidence.lastCommentAt) > Date.parse(evidence.marker.ts) ? `claim marker from ${marker} is ${formatClaimAge(evidence.markerAgeMs)} old but the issue was commented ${formatClaimAge(idleMs)} ago (session not locally probeable)` : `claim marker from ${marker} is only ${formatClaimAge(evidence.markerAgeMs)} old (session not locally probeable)`);
|
|
14920
14930
|
}
|
|
14921
14931
|
}
|
|
14922
|
-
|
|
14923
|
-
if (evidence.
|
|
14932
|
+
const sinceRelease = (at) => !evidence.releasedAt || at === void 0 || Date.parse(at) > Date.parse(evidence.releasedAt);
|
|
14933
|
+
if (evidence.openPr && workIsLive(evidence.openPrAt) && sinceRelease(evidence.openPrAt)) live.push(evidence.openPr);
|
|
14934
|
+
if (evidence.branch && workIsLive(evidence.branchAt) && sinceRelease(evidence.branchAt)) live.push(`live branch ${evidence.branch} on ${repo}`);
|
|
14924
14935
|
return live;
|
|
14925
14936
|
}
|
|
14926
14937
|
function staleWorkLines(evidence) {
|
|
@@ -16613,6 +16624,15 @@ function localRunbookBase(refExists) {
|
|
|
16613
16624
|
function checkRunbookCoverage(docs, base, git3) {
|
|
16614
16625
|
const changed = git3(["diff", "--name-only", `${base}...HEAD`]).split(/\r?\n/).filter(Boolean);
|
|
16615
16626
|
const findings = [];
|
|
16627
|
+
const usesOnly = /* @__PURE__ */ new Map();
|
|
16628
|
+
const changesOnlyUses = (path2) => {
|
|
16629
|
+
if (!usesOnly.has(path2)) {
|
|
16630
|
+
const diff = git3(["diff", "-U0", `${base}...HEAD`, "--", path2]);
|
|
16631
|
+
const content = diff.split(/\r?\n/).filter((line) => /^[+-]/.test(line) && !/^(\+\+\+|---)/.test(line));
|
|
16632
|
+
usesOnly.set(path2, content.length > 0 && content.every((line) => /^[+-]\s*(-\s+)?uses:\s*\S/.test(line)));
|
|
16633
|
+
}
|
|
16634
|
+
return usesOnly.get(path2);
|
|
16635
|
+
};
|
|
16616
16636
|
const matches = (glob, path2) => {
|
|
16617
16637
|
const pattern = glob.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*\//g, "\0").replace(/\*\*/g, "").replace(/\*/g, "[^/]*").replace(/\?/g, "[^/]").replaceAll("\0", "(?:.*/)?").replaceAll("", ".*");
|
|
16618
16638
|
return new RegExp(`^${pattern}$`).test(path2);
|
|
@@ -16630,7 +16650,7 @@ function checkRunbookCoverage(docs, base, git3) {
|
|
|
16630
16650
|
const end = headings.slice(i + 1).find((h) => h.level <= heading.level)?.start ?? lines2.length + 1;
|
|
16631
16651
|
const markerEnd = headings[i + 1]?.start ?? end;
|
|
16632
16652
|
const globs = lines2.slice(heading.start, markerEnd - 1).flatMap((text) => /<!--\s*runbook-covers:\s*(.*?)\s*-->/.exec(text)?.[1].split(",").map((s) => s.trim()) ?? []);
|
|
16633
|
-
const affected = changed.filter((path2) => globs.some((glob) => matches(glob, path2)));
|
|
16653
|
+
const affected = changed.filter((path2) => globs.some((glob) => matches(glob, path2)) && !changesOnlyUses(path2));
|
|
16634
16654
|
if (affected.length && !ranges.some((r) => r.count > 0 && r.start < end && r.start + r.count > heading.start)) {
|
|
16635
16655
|
findings.push({ kind: "runbook-section-stale", doc, line: heading.start, detail: `${heading.title}: changed ${affected.join(", ")}; update this section or declare Runbook-Unaffected: <reason>`, section: { heading: heading.title, level: heading.level, startLine: heading.start, endLine: end - 1, covers: globs }, sources: affected });
|
|
16636
16656
|
}
|
|
@@ -19051,10 +19071,10 @@ var rollout_plan_default = {
|
|
|
19051
19071
|
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)."
|
|
19052
19072
|
},
|
|
19053
19073
|
baseline: {
|
|
19054
|
-
version: "4.5.
|
|
19055
|
-
tag: "v4.5.
|
|
19056
|
-
commit: "
|
|
19057
|
-
npm: "@mutmutco/cli@4.5.
|
|
19074
|
+
version: "4.5.166",
|
|
19075
|
+
tag: "v4.5.166",
|
|
19076
|
+
commit: "4dbaaf17ac67",
|
|
19077
|
+
npm: "@mutmutco/cli@4.5.166"
|
|
19058
19078
|
},
|
|
19059
19079
|
exitCriterion: "fleet-n-of-n",
|
|
19060
19080
|
hubOnlyShortcut: "forbidden",
|
|
@@ -19071,14 +19091,14 @@ var rollout_plan_default = {
|
|
|
19071
19091
|
repo: "mutmutco/mmi-hub",
|
|
19072
19092
|
role: "canary",
|
|
19073
19093
|
schedule: "train",
|
|
19074
|
-
v3Target: "v4.5.
|
|
19094
|
+
v3Target: "v4.5.166"
|
|
19075
19095
|
}
|
|
19076
19096
|
],
|
|
19077
19097
|
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.",
|
|
19078
19098
|
rollback: {
|
|
19079
19099
|
independent: true,
|
|
19080
|
-
mechanism: "npm dist-tag latest -> 4.5.
|
|
19081
|
-
v3Target: "v4.5.
|
|
19100
|
+
mechanism: "npm dist-tag latest -> 4.5.166 and redeploy the Hub Lambda from tag v4.5.166 (4dbaaf17ac67); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
|
|
19101
|
+
v3Target: "v4.5.166 (@mutmutco/cli@4.5.166, tag commit 4dbaaf17ac67 \u2014 last known-good release carrying the repo-index v4-only contract)"
|
|
19082
19102
|
}
|
|
19083
19103
|
},
|
|
19084
19104
|
{
|
|
@@ -33317,7 +33337,7 @@ function parseGateVar(raw) {
|
|
|
33317
33337
|
}
|
|
33318
33338
|
var SECRET_OUTPUT_PATH_RE = /^\/[A-Za-z0-9._/-]+$/;
|
|
33319
33339
|
var SECRET_OUTPUT_REPO_RE = /^[A-Za-z0-9][A-Za-z0-9._-]*\/[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
33320
|
-
var SECRET_OUTPUT_KEY_RE = /^[A-Z][A-Z0-9_]*$/;
|
|
33340
|
+
var SECRET_OUTPUT_KEY_RE = /^(?:(?:dev|rc|main)\/)?[A-Z][A-Z0-9_]*$/;
|
|
33321
33341
|
function parseTenantTaskSecretOutput(raw, label) {
|
|
33322
33342
|
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
33323
33343
|
throw new Error(`org project set: ${label} must be an object {path,vault:{repo,key},overwrite?}`);
|
|
@@ -33341,7 +33361,7 @@ function parseTenantTaskSecretOutput(raw, label) {
|
|
|
33341
33361
|
throw new Error(`org project set: ${label}.vault.repo must be owner/name`);
|
|
33342
33362
|
}
|
|
33343
33363
|
if (typeof vaultMap.key !== "string" || !SECRET_OUTPUT_KEY_RE.test(vaultMap.key)) {
|
|
33344
|
-
throw new Error(`org project set: ${label}.vault.key must be UPPER_SNAKE`);
|
|
33364
|
+
throw new Error(`org project set: ${label}.vault.key must be UPPER_SNAKE or <dev|rc|main>/UPPER_SNAKE`);
|
|
33345
33365
|
}
|
|
33346
33366
|
if (value.overwrite !== void 0 && typeof value.overwrite !== "boolean") {
|
|
33347
33367
|
throw new Error(`org project set: ${label}.overwrite must be true or false`);
|
|
@@ -40981,11 +41001,12 @@ async function runPrLand(prNumber, options, deps) {
|
|
|
40981
41001
|
if (drift) return drift;
|
|
40982
41002
|
const hasQueue = await deps.hasMergeQueue?.(repo, resolved.base) ?? false;
|
|
40983
41003
|
let queueSnapshot;
|
|
41004
|
+
const queued = { base: resolved.base, state: "queued" };
|
|
40984
41005
|
if (hasQueue) {
|
|
40985
|
-
base.mergeQueue = { base: resolved.base, state: "queued" };
|
|
40986
41006
|
if (!deps.readMergeQueue) throw new Error("merge queue reader unavailable");
|
|
40987
41007
|
queueSnapshot = await deps.readMergeQueue(prNumber, repo);
|
|
40988
41008
|
if (queueSnapshot.isInMergeQueue || queueSnapshot.state === "MERGED") {
|
|
41009
|
+
base.mergeQueue = queued;
|
|
40989
41010
|
base.mergeStatus = "auto-merge-enqueued";
|
|
40990
41011
|
return pollPrMergeQueue(prNumber, options, deps, base, queueSnapshot);
|
|
40991
41012
|
}
|
|
@@ -41035,6 +41056,7 @@ async function runPrLand(prNumber, options, deps) {
|
|
|
41035
41056
|
return { ...base, error: merge.error ?? "merge failed" };
|
|
41036
41057
|
}
|
|
41037
41058
|
if (hasQueue) {
|
|
41059
|
+
base.mergeQueue = queued;
|
|
41038
41060
|
if (merge.mergeStatus === "merged") {
|
|
41039
41061
|
return queueMerged(base, deps);
|
|
41040
41062
|
}
|
package/cli/package.json
CHANGED