@mutmutco/cli 3.68.0 → 3.69.0
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/dist/main.cjs +134 -61
- package/package.json +1 -1
package/dist/main.cjs
CHANGED
|
@@ -5003,6 +5003,7 @@ function buildPrMergeResultPayload(input) {
|
|
|
5003
5003
|
function buildPrMergeArgs(input) {
|
|
5004
5004
|
const args = ["pr", "merge", input.number, ...input.repoArgs, input.method];
|
|
5005
5005
|
if (input.deleteBranch !== false) args.push("--delete-branch");
|
|
5006
|
+
if (input.bodyFile) args.push("--body-file", input.bodyFile);
|
|
5006
5007
|
if (input.auto) args.push("--auto");
|
|
5007
5008
|
return args;
|
|
5008
5009
|
}
|
|
@@ -7235,7 +7236,7 @@ function checkGateBudget(files, opts = {}) {
|
|
|
7235
7236
|
}
|
|
7236
7237
|
|
|
7237
7238
|
// src/project-model.ts
|
|
7238
|
-
var PROJECT_TYPES = ["web-app", "hub-service", "content", "desktop-app", "desktop-game", "non-deployable", "cli-tool", "worker"];
|
|
7239
|
+
var PROJECT_TYPES = ["web-app", "hub-service", "content", "desktop-app", "desktop-game", "mobile-app", "non-deployable", "cli-tool", "worker"];
|
|
7239
7240
|
var DEPLOY_MODELS = ["hub-serverless", "serverless", "tenant-container", "solo-container", "registry-publish", "content", "none"];
|
|
7240
7241
|
var RELEASE_TRACKS = ["full", "direct", "trunk"];
|
|
7241
7242
|
var PROJECT_TYPE_SET = new Set(PROJECT_TYPES);
|
|
@@ -7272,7 +7273,7 @@ function resolveDeployModel(meta, repo) {
|
|
|
7272
7273
|
const projectType = resolveProjectType(meta, repo);
|
|
7273
7274
|
if (projectType === "content" || meta?.class === "content") return "content";
|
|
7274
7275
|
if (projectType === "hub-service" || repoIsHub(repo)) return "hub-serverless";
|
|
7275
|
-
if (projectType === "desktop-app" || projectType === "desktop-game" || projectType === "non-deployable") return "none";
|
|
7276
|
+
if (projectType === "desktop-app" || projectType === "desktop-game" || projectType === "mobile-app" || projectType === "non-deployable") return "none";
|
|
7276
7277
|
if (projectType === "cli-tool") return "registry-publish";
|
|
7277
7278
|
return "tenant-container";
|
|
7278
7279
|
}
|
|
@@ -8970,7 +8971,7 @@ async function executeWaveLand(plan, deps, opts = { preserveWorktree: true }) {
|
|
|
8970
8971
|
}
|
|
8971
8972
|
|
|
8972
8973
|
// src/index.ts
|
|
8973
|
-
var
|
|
8974
|
+
var import_node_os11 = require("node:os");
|
|
8974
8975
|
|
|
8975
8976
|
// src/board.ts
|
|
8976
8977
|
var import_node_child_process7 = require("node:child_process");
|
|
@@ -16548,6 +16549,43 @@ function evaluate(changed, policy, present = () => false) {
|
|
|
16548
16549
|
function git(args, cwd) {
|
|
16549
16550
|
return (0, import_node_child_process10.execFileSync)("git", args, { cwd, encoding: "utf8", maxBuffer: 32 * 1024 * 1024 });
|
|
16550
16551
|
}
|
|
16552
|
+
var COAUTHOR_KEY = "Co-authored-by";
|
|
16553
|
+
var GH_MESSAGE_SEPARATOR = /^-{5,}$/;
|
|
16554
|
+
var LIFTED_KEYS = new RegExp(`^(?:${TRAILER_KEY}|${COAUTHOR_KEY}):`, "i");
|
|
16555
|
+
function parseTrailers(message, cwd) {
|
|
16556
|
+
try {
|
|
16557
|
+
return (0, import_node_child_process10.execFileSync)("git", ["interpret-trailers", "--parse", "--unfold"], {
|
|
16558
|
+
cwd,
|
|
16559
|
+
input: message,
|
|
16560
|
+
encoding: "utf8",
|
|
16561
|
+
maxBuffer: 4 * 1024 * 1024
|
|
16562
|
+
}).split("\n").map((l) => l.trim()).filter(Boolean);
|
|
16563
|
+
} catch {
|
|
16564
|
+
return [];
|
|
16565
|
+
}
|
|
16566
|
+
}
|
|
16567
|
+
function squashBodyWithOverride(commits, cwd) {
|
|
16568
|
+
const overrides = [];
|
|
16569
|
+
const coauthors = [];
|
|
16570
|
+
const bodies = [];
|
|
16571
|
+
for (const commit of commits) {
|
|
16572
|
+
const message = `${commit.headline}
|
|
16573
|
+
|
|
16574
|
+
${commit.body}`.trim();
|
|
16575
|
+
for (const trailer of parseTrailers(message, cwd)) {
|
|
16576
|
+
if (trailer.toLowerCase().startsWith(`${TRAILER_KEY.toLowerCase()}:`)) {
|
|
16577
|
+
if (!overrides.includes(trailer)) overrides.push(trailer);
|
|
16578
|
+
} else if (trailer.toLowerCase().startsWith(`${COAUTHOR_KEY.toLowerCase()}:`)) {
|
|
16579
|
+
if (!coauthors.some((c) => c.toLowerCase() === trailer.toLowerCase())) coauthors.push(trailer);
|
|
16580
|
+
}
|
|
16581
|
+
}
|
|
16582
|
+
const source = commits.length > 1 ? message : commit.body;
|
|
16583
|
+
const kept = source.split("\n").filter((line) => !LIFTED_KEYS.test(line.trim()) && !GH_MESSAGE_SEPARATOR.test(line.trim())).join("\n").trim();
|
|
16584
|
+
if (kept) bodies.push(kept);
|
|
16585
|
+
}
|
|
16586
|
+
if (!overrides.length) return null;
|
|
16587
|
+
return [...bodies, [...overrides, ...coauthors].join("\n")].join("\n\n");
|
|
16588
|
+
}
|
|
16551
16589
|
function resolveBase(cwd, explicit) {
|
|
16552
16590
|
const candidates = [explicit, process.env.TEST_POLICY_BASE, "origin/development", "origin/main"].filter(Boolean);
|
|
16553
16591
|
for (const ref of candidates) {
|
|
@@ -21350,6 +21388,7 @@ function registerBoardCommands(program3) {
|
|
|
21350
21388
|
var import_node_fs27 = require("node:fs");
|
|
21351
21389
|
var import_promises6 = require("node:fs/promises");
|
|
21352
21390
|
var import_node_path26 = require("node:path");
|
|
21391
|
+
var import_node_os8 = require("node:os");
|
|
21353
21392
|
var import_node_child_process12 = require("node:child_process");
|
|
21354
21393
|
|
|
21355
21394
|
// src/board-advance.ts
|
|
@@ -22258,8 +22297,36 @@ ${err?.stdout ?? ""}`.split("\n").map((line) => line.trim()).find((line) => line
|
|
|
22258
22297
|
var defaultGhMergeAutoIo = {
|
|
22259
22298
|
gh: async (args, timeoutMs) => (await execFileP2("gh", args, { timeout: timeoutMs })).stdout
|
|
22260
22299
|
};
|
|
22300
|
+
async function composeOverrideBodyFile(prNumber, repoArgs, gh) {
|
|
22301
|
+
try {
|
|
22302
|
+
const raw = await gh(["pr", "view", prNumber, ...repoArgs, "--json", "commits"], GC_GH_TIMEOUT_MS2);
|
|
22303
|
+
const commits = JSON.parse(raw).commits ?? [];
|
|
22304
|
+
const body = squashBodyWithOverride(commits.map((c) => ({ headline: c.messageHeadline ?? "", body: c.messageBody ?? "" })), process.cwd());
|
|
22305
|
+
if (!body) return void 0;
|
|
22306
|
+
const dir = (0, import_node_fs27.mkdtempSync)((0, import_node_path26.join)((0, import_node_os8.tmpdir)(), "mmi-squash-body-"));
|
|
22307
|
+
const path2 = (0, import_node_path26.join)(dir, "body.txt");
|
|
22308
|
+
(0, import_node_fs27.writeFileSync)(path2, `${body}
|
|
22309
|
+
`, "utf8");
|
|
22310
|
+
return { path: path2, cleanup: () => {
|
|
22311
|
+
try {
|
|
22312
|
+
(0, import_node_fs27.rmSync)(dir, { recursive: true, force: true });
|
|
22313
|
+
} catch {
|
|
22314
|
+
}
|
|
22315
|
+
} };
|
|
22316
|
+
} catch {
|
|
22317
|
+
return void 0;
|
|
22318
|
+
}
|
|
22319
|
+
}
|
|
22261
22320
|
async function ghMergeAutoEnqueue(prNumber, repo, method, io = defaultGhMergeAutoIo) {
|
|
22262
22321
|
const args = repo ? ["--repo", repo] : [];
|
|
22322
|
+
const overrideBody = await composeOverrideBodyFile(prNumber, args, io.gh);
|
|
22323
|
+
try {
|
|
22324
|
+
return await mergeAutoEnqueueWithBody(prNumber, args, method, io, overrideBody?.path);
|
|
22325
|
+
} finally {
|
|
22326
|
+
overrideBody?.cleanup();
|
|
22327
|
+
}
|
|
22328
|
+
}
|
|
22329
|
+
async function mergeAutoEnqueueWithBody(prNumber, args, method, io, bodyFile) {
|
|
22263
22330
|
const headRef = (await io.gh(["pr", "view", prNumber, ...args, "--json", "headRefName", "--jq", ".headRefName"], GC_GH_TIMEOUT_MS2).catch(() => "")).trim();
|
|
22264
22331
|
const deleteBranch = !isProtectedBranch(headRef);
|
|
22265
22332
|
const readMergeState = () => readGhPrStateWithRetry(
|
|
@@ -22278,7 +22345,7 @@ async function ghMergeAutoEnqueue(prNumber, repo, method, io = defaultGhMergeAut
|
|
|
22278
22345
|
return s.ok && s.state === "MERGED";
|
|
22279
22346
|
},
|
|
22280
22347
|
reEnqueue: async () => {
|
|
22281
|
-
await io.gh(buildPrMergeArgs({ number: prNumber, repoArgs: args, method, auto: true, deleteBranch }), GH_MUTATION_TIMEOUT_MS);
|
|
22348
|
+
await io.gh(buildPrMergeArgs({ number: prNumber, repoArgs: args, method, auto: true, deleteBranch, bodyFile }), GH_MUTATION_TIMEOUT_MS);
|
|
22282
22349
|
}
|
|
22283
22350
|
});
|
|
22284
22351
|
if (confirmation === "merged") return { mergeStatus: "merged" };
|
|
@@ -22286,7 +22353,7 @@ async function ghMergeAutoEnqueue(prNumber, repo, method, io = defaultGhMergeAut
|
|
|
22286
22353
|
return { mergeStatus: "failed", error: "auto-merge did not stick \u2014 GitHub reported no autoMergeRequest after enqueue; retry once the PR has a pending check" };
|
|
22287
22354
|
};
|
|
22288
22355
|
try {
|
|
22289
|
-
await io.gh(buildPrMergeArgs({ number: prNumber, repoArgs: args, method, auto: true, deleteBranch }), GH_MUTATION_TIMEOUT_MS);
|
|
22356
|
+
await io.gh(buildPrMergeArgs({ number: prNumber, repoArgs: args, method, auto: true, deleteBranch, bodyFile }), GH_MUTATION_TIMEOUT_MS);
|
|
22290
22357
|
} catch (e) {
|
|
22291
22358
|
const message = String(e.message || "");
|
|
22292
22359
|
if (/already been merged/i.test(message)) return { mergeStatus: "merged" };
|
|
@@ -22294,7 +22361,7 @@ async function ghMergeAutoEnqueue(prNumber, repo, method, io = defaultGhMergeAut
|
|
|
22294
22361
|
if (note) return { mergeStatus: "failed", error: note };
|
|
22295
22362
|
if (mergeAutoRejectedPrAlreadyClean(message)) {
|
|
22296
22363
|
try {
|
|
22297
|
-
await io.gh(buildPrMergeArgs({ number: prNumber, repoArgs: args, method, auto: false, deleteBranch }), GH_MUTATION_TIMEOUT_MS);
|
|
22364
|
+
await io.gh(buildPrMergeArgs({ number: prNumber, repoArgs: args, method, auto: false, deleteBranch, bodyFile }), GH_MUTATION_TIMEOUT_MS);
|
|
22298
22365
|
} catch (e2) {
|
|
22299
22366
|
const m2 = String(e2.message || "");
|
|
22300
22367
|
if (/already been merged/i.test(m2)) return { mergeStatus: "merged" };
|
|
@@ -22305,7 +22372,7 @@ async function ghMergeAutoEnqueue(prNumber, repo, method, io = defaultGhMergeAut
|
|
|
22305
22372
|
return { mergeStatus: "failed", error: `could not confirm PR state after clean-status fallback: ${afterDirect.error}` };
|
|
22306
22373
|
}
|
|
22307
22374
|
try {
|
|
22308
|
-
await io.gh(buildPrMergeArgs({ number: prNumber, repoArgs: args, method, auto: true, deleteBranch }), GH_MUTATION_TIMEOUT_MS);
|
|
22375
|
+
await io.gh(buildPrMergeArgs({ number: prNumber, repoArgs: args, method, auto: true, deleteBranch, bodyFile }), GH_MUTATION_TIMEOUT_MS);
|
|
22309
22376
|
} catch (e3) {
|
|
22310
22377
|
const m3 = String(e3.message || "");
|
|
22311
22378
|
if (/already been merged/i.test(m3)) return { mergeStatus: "merged" };
|
|
@@ -23829,7 +23896,7 @@ function registerDeployCommands(program3) {
|
|
|
23829
23896
|
|
|
23830
23897
|
// src/discovery-commands.ts
|
|
23831
23898
|
var import_node_fs31 = require("node:fs");
|
|
23832
|
-
var
|
|
23899
|
+
var import_node_os9 = require("node:os");
|
|
23833
23900
|
var import_node_path29 = require("node:path");
|
|
23834
23901
|
var GC_GH_TIMEOUT_MS3 = 2e4;
|
|
23835
23902
|
async function collectStatus() {
|
|
@@ -24005,7 +24072,7 @@ async function collectOnboardStatus() {
|
|
|
24005
24072
|
else if (top) nextCommand = `mmi-cli board claim ${top.number} # ${top.title}`;
|
|
24006
24073
|
else nextCommand = "mmi-cli board read \u2014 no claimable items found";
|
|
24007
24074
|
}
|
|
24008
|
-
const home = (0,
|
|
24075
|
+
const home = (0, import_node_os9.homedir)();
|
|
24009
24076
|
const plugin = onboardPluginGate({
|
|
24010
24077
|
readKnown: () => readFileSyncSafe((0, import_node_path29.join)(home, ...KNOWN_MARKETPLACES_RELATIVE), import_node_fs31.readFileSync),
|
|
24011
24078
|
readSettings: () => readFileSyncSafe((0, import_node_path29.join)(home, ".claude", "settings.json"), import_node_fs31.readFileSync)
|
|
@@ -25388,17 +25455,17 @@ function parseOriginRepo(remoteUrl) {
|
|
|
25388
25455
|
}
|
|
25389
25456
|
function ghHostsConfigPath(env, platform2) {
|
|
25390
25457
|
const sep2 = platform2 === "win32" ? "\\" : "/";
|
|
25391
|
-
const
|
|
25458
|
+
const join27 = (...parts) => parts.join(sep2);
|
|
25392
25459
|
const explicit = env.GH_CONFIG_DIR?.trim();
|
|
25393
|
-
if (explicit) return
|
|
25460
|
+
if (explicit) return join27(explicit, "hosts.yml");
|
|
25394
25461
|
if (platform2 === "win32") {
|
|
25395
25462
|
const appData = (env.AppData ?? env.APPDATA)?.trim();
|
|
25396
|
-
return appData ?
|
|
25463
|
+
return appData ? join27(appData, "GitHub CLI", "hosts.yml") : void 0;
|
|
25397
25464
|
}
|
|
25398
25465
|
const xdg = env.XDG_CONFIG_HOME?.trim();
|
|
25399
|
-
if (xdg) return
|
|
25466
|
+
if (xdg) return join27(xdg, "gh", "hosts.yml");
|
|
25400
25467
|
const home = env.HOME?.trim();
|
|
25401
|
-
return home ?
|
|
25468
|
+
return home ? join27(home, ".config", "gh", "hosts.yml") : void 0;
|
|
25402
25469
|
}
|
|
25403
25470
|
function parseGhHostsAccounts(yaml, host = "github.com") {
|
|
25404
25471
|
let hostIndent = null;
|
|
@@ -25449,7 +25516,7 @@ function ghAccountCaveat(announcedLogin, accounts) {
|
|
|
25449
25516
|
|
|
25450
25517
|
// src/doctor-io.ts
|
|
25451
25518
|
var import_node_fs32 = require("node:fs");
|
|
25452
|
-
var
|
|
25519
|
+
var import_node_os10 = require("node:os");
|
|
25453
25520
|
var import_node_path30 = require("node:path");
|
|
25454
25521
|
var import_node_child_process13 = require("node:child_process");
|
|
25455
25522
|
var import_node_util8 = require("node:util");
|
|
@@ -25458,7 +25525,7 @@ var MMI_PLUGIN_ID2 = "mmi@mutmutco";
|
|
|
25458
25525
|
function installedClaudePluginVersion() {
|
|
25459
25526
|
try {
|
|
25460
25527
|
const file = JSON.parse(
|
|
25461
|
-
(0, import_node_fs32.readFileSync)((0, import_node_path30.join)((0,
|
|
25528
|
+
(0, import_node_fs32.readFileSync)((0, import_node_path30.join)((0, import_node_os10.homedir)(), ".claude", "plugins", "installed_plugins.json"), "utf8")
|
|
25462
25529
|
);
|
|
25463
25530
|
const versions = (file.plugins?.[MMI_PLUGIN_ID2] ?? []).map((r) => r.version).filter((v) => Boolean(v));
|
|
25464
25531
|
if (versions.length === 0) return void 0;
|
|
@@ -25567,7 +25634,7 @@ function envHealLockPath(home) {
|
|
|
25567
25634
|
async function withEnvHealLock(what, run) {
|
|
25568
25635
|
try {
|
|
25569
25636
|
return await withFileLock(
|
|
25570
|
-
envHealLockPath((0,
|
|
25637
|
+
envHealLockPath((0, import_node_os11.homedir)()),
|
|
25571
25638
|
{ staleMs: ENV_HEAL_LOCK_STALE_MS, maxWaitMs: ENV_HEAL_LOCK_MAX_WAIT_MS, label: "mmi env-heal lock" },
|
|
25572
25639
|
run
|
|
25573
25640
|
);
|
|
@@ -25662,9 +25729,9 @@ function mmiDoctorDeps(opts = {}) {
|
|
|
25662
25729
|
},
|
|
25663
25730
|
pluginCache: () => {
|
|
25664
25731
|
const plan = buildPluginCachePlan(
|
|
25665
|
-
(0,
|
|
25732
|
+
(0, import_node_os11.homedir)(),
|
|
25666
25733
|
runningPluginVersion(process.env, resolveClientVersion()),
|
|
25667
|
-
pluginCacheFsDeps((0,
|
|
25734
|
+
pluginCacheFsDeps((0, import_node_os11.homedir)(), () => 0)
|
|
25668
25735
|
);
|
|
25669
25736
|
return {
|
|
25670
25737
|
stale: plan.prune,
|
|
@@ -25713,7 +25780,7 @@ function mmiDoctorDeps(opts = {}) {
|
|
|
25713
25780
|
// which branch it would pick one up from. Two local file reads, no network, fail-soft to no rows.
|
|
25714
25781
|
marketplaceRows: () => {
|
|
25715
25782
|
try {
|
|
25716
|
-
const home = (0,
|
|
25783
|
+
const home = (0, import_node_os11.homedir)();
|
|
25717
25784
|
return marketplaceRows(
|
|
25718
25785
|
MMI_MARKETPLACE_NAME,
|
|
25719
25786
|
readFileSyncSafe((0, import_node_path31.join)(home, ...KNOWN_MARKETPLACES_RELATIVE), import_node_fs33.readFileSync),
|
|
@@ -27527,44 +27594,50 @@ jsonParity(pr.command("merge <number>").description("merge a PR (squash by defau
|
|
|
27527
27594
|
let remoteDeleteAttempted = false;
|
|
27528
27595
|
let upgradedToAuto = false;
|
|
27529
27596
|
let remoteNotAttemptedReason = headIsProtected ? "protected-branch" : void 0;
|
|
27530
|
-
await
|
|
27531
|
-
|
|
27532
|
-
|
|
27533
|
-
|
|
27534
|
-
|
|
27535
|
-
|
|
27536
|
-
|
|
27537
|
-
|
|
27538
|
-
|
|
27539
|
-
|
|
27540
|
-
|
|
27541
|
-
|
|
27542
|
-
|
|
27543
|
-
|
|
27544
|
-
|
|
27545
|
-
|
|
27546
|
-
|
|
27547
|
-
|
|
27548
|
-
|
|
27549
|
-
|
|
27550
|
-
|
|
27551
|
-
|
|
27552
|
-
|
|
27553
|
-
|
|
27554
|
-
|
|
27555
|
-
|
|
27556
|
-
|
|
27557
|
-
|
|
27558
|
-
|
|
27559
|
-
|
|
27560
|
-
|
|
27561
|
-
|
|
27562
|
-
|
|
27563
|
-
|
|
27564
|
-
|
|
27565
|
-
|
|
27566
|
-
|
|
27567
|
-
|
|
27597
|
+
const overrideBody = await composeOverrideBodyFile(number, repoArgs, async (a, t) => (await execFileP2("gh", a, { timeout: t })).stdout);
|
|
27598
|
+
const bodyFile = overrideBody?.path;
|
|
27599
|
+
try {
|
|
27600
|
+
await execFileP2("gh", buildPrMergeArgs({ number, repoArgs, method, auto: o.auto, deleteBranch: !headIsProtected, bodyFile }), { timeout: GH_MUTATION_TIMEOUT_MS }).catch(async (e) => {
|
|
27601
|
+
const message = String(e.message || "");
|
|
27602
|
+
if (/already been merged/i.test(message)) {
|
|
27603
|
+
remoteNotAttemptedReason = "pr-already-merged";
|
|
27604
|
+
return;
|
|
27605
|
+
}
|
|
27606
|
+
const note = timeoutKillNote(e, GH_MUTATION_TIMEOUT_MS);
|
|
27607
|
+
if (note) throw new Error(`gh pr merge ${number}: ${note}`);
|
|
27608
|
+
if (o.auto && mergeAutoRejectedPrAlreadyClean(message)) {
|
|
27609
|
+
await execFileP2("gh", buildPrMergeArgs({ number, repoArgs, method, auto: false, deleteBranch: !headIsProtected, bodyFile }), { timeout: GH_MUTATION_TIMEOUT_MS }).catch((e2) => {
|
|
27610
|
+
const m2 = String(e2.message || "");
|
|
27611
|
+
if (/already been merged/i.test(m2)) {
|
|
27612
|
+
remoteNotAttemptedReason = "pr-already-merged";
|
|
27613
|
+
return;
|
|
27614
|
+
}
|
|
27615
|
+
const note2 = timeoutKillNote(e2, GH_MUTATION_TIMEOUT_MS);
|
|
27616
|
+
if (note2) throw new Error(`gh pr merge ${number}: ${note2}`);
|
|
27617
|
+
if (!ghPrMergeLocalBranchDeleteWarning(m2)) throw e2;
|
|
27618
|
+
});
|
|
27619
|
+
return;
|
|
27620
|
+
}
|
|
27621
|
+
if (!o.auto && basePolicyBlocksImmediateMerge(message)) {
|
|
27622
|
+
console.warn(`pr merge: the base-branch policy blocks an immediate merge \u2014 upgrading to --auto (merges once required checks pass).`);
|
|
27623
|
+
upgradedToAuto = true;
|
|
27624
|
+
await execFileP2("gh", buildPrMergeArgs({ number, repoArgs, method, auto: true, deleteBranch: !headIsProtected, bodyFile }), { timeout: GH_MUTATION_TIMEOUT_MS }).catch((e2) => {
|
|
27625
|
+
const m2 = String(e2.message || "");
|
|
27626
|
+
if (/already been merged/i.test(m2)) {
|
|
27627
|
+
remoteNotAttemptedReason = "pr-already-merged";
|
|
27628
|
+
return;
|
|
27629
|
+
}
|
|
27630
|
+
const note2 = timeoutKillNote(e2, GH_MUTATION_TIMEOUT_MS);
|
|
27631
|
+
if (note2) throw new Error(`gh pr merge ${number}: ${note2}`);
|
|
27632
|
+
if (!ghPrMergeLocalBranchDeleteWarning(m2)) throw e2;
|
|
27633
|
+
});
|
|
27634
|
+
return;
|
|
27635
|
+
}
|
|
27636
|
+
if (!ghPrMergeLocalBranchDeleteWarning(message)) throw e;
|
|
27637
|
+
});
|
|
27638
|
+
} finally {
|
|
27639
|
+
overrideBody?.cleanup();
|
|
27640
|
+
}
|
|
27568
27641
|
const stateRead = await readGhPrStateWithRetry(
|
|
27569
27642
|
() => execFileP2("gh", ["pr", "view", number, ...repoArgs, "--json", "state", "--jq", ".state"], { timeout: GC_GH_TIMEOUT_MS2 }).then((r) => r.stdout)
|
|
27570
27643
|
);
|
|
@@ -28052,13 +28125,13 @@ function stagingApplyFsGuard(home) {
|
|
|
28052
28125
|
}
|
|
28053
28126
|
program2.command("plugin-prune").description(`prune stale cached MMI plugin versions (keeps running + newest, ${PLUGIN_CACHE_KEEP} total) and orphaned temp_git_* staging dirs; dry-run unless --apply (#2903, #2990)`).option("--apply", "actually delete the stale version dirs + orphaned staging dirs (default: report only)").option("--json", "machine-readable output").action((o) => {
|
|
28054
28127
|
const plan = buildPluginCachePlan(
|
|
28055
|
-
(0,
|
|
28128
|
+
(0, import_node_os11.homedir)(),
|
|
28056
28129
|
runningPluginVersion(process.env, resolveClientVersion()),
|
|
28057
|
-
pluginCacheFsDeps((0,
|
|
28130
|
+
pluginCacheFsDeps((0, import_node_os11.homedir)(), directoryBytes),
|
|
28058
28131
|
{ withBytes: true }
|
|
28059
28132
|
);
|
|
28060
28133
|
const anythingToDelete = plan.prune.length > 0 || plan.staging.length > 0;
|
|
28061
|
-
const result = o.apply && anythingToDelete ? applyPluginCachePlan(plan, (p) => (0, import_node_fs33.rmSync)(p, { recursive: true, force: true }), stagingApplyFsGuard((0,
|
|
28134
|
+
const result = o.apply && anythingToDelete ? applyPluginCachePlan(plan, (p) => (0, import_node_fs33.rmSync)(p, { recursive: true, force: true }), stagingApplyFsGuard((0, import_node_os11.homedir)())) : void 0;
|
|
28062
28135
|
const warnings = plan.prune.length > 0 ? [CONCURRENT_SESSION_WARNING] : [];
|
|
28063
28136
|
if (o.json) console.log(JSON.stringify({ ...plan, warnings, applied: result ?? null }));
|
|
28064
28137
|
else console.log(renderPluginCachePlan(plan, result));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mutmutco/cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.69.0",
|
|
4
4
|
"description": "MMI Future CLI — the org dev toolbox (board, registry, keyless secrets, release train, bootstrap, doctor) and the cross-IDE engine the plugin's session-start hook drives.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "UNLICENSED",
|