@mutmutco/cli 4.3.9 → 4.3.11
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 +36 -13
- package/package.json +1 -1
package/dist/main.cjs
CHANGED
|
@@ -10515,7 +10515,14 @@ var SESSION_ID_ENV_VARS = [
|
|
|
10515
10515
|
"CODEX_THREAD_ID",
|
|
10516
10516
|
"CURSOR_SESSION_ID",
|
|
10517
10517
|
"HERMES_SESSION_ID",
|
|
10518
|
-
"PI_SESSION_ID"
|
|
10518
|
+
"PI_SESSION_ID",
|
|
10519
|
+
// #6193: lane runners spawn the CLI through the host's extension shell operations, which strip
|
|
10520
|
+
// the PI_* session variables; the JervCode launcher's durable lane id (JERV_SESSION_ID) is what
|
|
10521
|
+
// survives in that env. Read it LAST so interactive invocations keep their own PI_SESSION_ID and
|
|
10522
|
+
// a stripped spawn still resolves to its owning lane — otherwise the actor degrades to a
|
|
10523
|
+
// synth/shell identity and the claim guard contests the caller's OWN lane (the #3414/#3438
|
|
10524
|
+
// refusals of jerv_worktree_land's `devops pr create` from the claimed task worktree).
|
|
10525
|
+
"JERV_SESSION_ID"
|
|
10519
10526
|
];
|
|
10520
10527
|
var SYNTH_SESSION_PREFIX = "synth-";
|
|
10521
10528
|
function isHostSessionId(session) {
|
|
@@ -12048,6 +12055,11 @@ async function postIssueComment(client, input) {
|
|
|
12048
12055
|
|
|
12049
12056
|
// src/board-claim-move.ts
|
|
12050
12057
|
var CLAIM_CONCURRENCY = 5;
|
|
12058
|
+
function withPowerShellChainHint(message2, platform2 = process.platform) {
|
|
12059
|
+
if (platform2 !== "win32") return message2;
|
|
12060
|
+
return `${message2}
|
|
12061
|
+
note: in PowerShell a ';' chain runs every statement regardless of the previous exit code, so the chain ran past this refusal \u2014 rerun the refused write solo or chain gated writes with '&&'`;
|
|
12062
|
+
}
|
|
12051
12063
|
async function moveBoardItem(options, deps = {}) {
|
|
12052
12064
|
if (!BOARD_STATUSES.includes(options.status)) {
|
|
12053
12065
|
throw new Error(`unknown status '${options.status}'; expected one of ${BOARD_STATUSES.join(", ")}`);
|
|
@@ -12209,7 +12221,7 @@ async function claimOneBoardItem(ctx, selector, options) {
|
|
|
12209
12221
|
}
|
|
12210
12222
|
return;
|
|
12211
12223
|
}
|
|
12212
|
-
if (!options.force) throw new Error(laneContestMessage(item.ref, contest, "claim"));
|
|
12224
|
+
if (!options.force) throw new Error(withPowerShellChainHint(laneContestMessage(item.ref, contest, "claim")));
|
|
12213
12225
|
previousHolder = displaced();
|
|
12214
12226
|
};
|
|
12215
12227
|
await refuseIfContested();
|
|
@@ -12392,7 +12404,7 @@ async function unclaimBoardIssue(options, deps = {}) {
|
|
|
12392
12404
|
const toStatus = options.toStatus ?? "Todo";
|
|
12393
12405
|
if (!options.force && item.contentType === "Issue") {
|
|
12394
12406
|
const contest = await checkLaneContest(client, item);
|
|
12395
|
-
if (contest.contested) throw new Error(laneContestMessage(item.ref, contest, "unclaim"));
|
|
12407
|
+
if (contest.contested) throw new Error(withPowerShellChainHint(laneContestMessage(item.ref, contest, "unclaim")));
|
|
12396
12408
|
}
|
|
12397
12409
|
try {
|
|
12398
12410
|
await client.rest("DELETE", `repos/${item.repository}/issues/${item.number}/assignees`, {
|
|
@@ -15450,10 +15462,10 @@ var rollout_plan_default = {
|
|
|
15450
15462
|
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)."
|
|
15451
15463
|
},
|
|
15452
15464
|
baseline: {
|
|
15453
|
-
version: "4.3.
|
|
15454
|
-
tag: "v4.3.
|
|
15455
|
-
commit: "
|
|
15456
|
-
npm: "@mutmutco/cli@4.3.
|
|
15465
|
+
version: "4.3.11",
|
|
15466
|
+
tag: "v4.3.11",
|
|
15467
|
+
commit: "c898259b41c3",
|
|
15468
|
+
npm: "@mutmutco/cli@4.3.11"
|
|
15457
15469
|
},
|
|
15458
15470
|
exitCriterion: "fleet-n-of-n",
|
|
15459
15471
|
hubOnlyShortcut: "forbidden",
|
|
@@ -15470,14 +15482,14 @@ var rollout_plan_default = {
|
|
|
15470
15482
|
repo: "mutmutco/mmi-hub",
|
|
15471
15483
|
role: "canary",
|
|
15472
15484
|
schedule: "train",
|
|
15473
|
-
v3Target: "v4.3.
|
|
15485
|
+
v3Target: "v4.3.11"
|
|
15474
15486
|
}
|
|
15475
15487
|
],
|
|
15476
15488
|
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.",
|
|
15477
15489
|
rollback: {
|
|
15478
15490
|
independent: true,
|
|
15479
|
-
mechanism: "npm dist-tag latest -> 4.3.
|
|
15480
|
-
v3Target: "v4.3.
|
|
15491
|
+
mechanism: "npm dist-tag latest -> 4.3.11 and redeploy the Hub Lambda from tag v4.3.11 (c898259b41c3); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
|
|
15492
|
+
v3Target: "v4.3.11 (@mutmutco/cli@4.3.11, tag commit c898259b41c3 \u2014 last known-good release carrying the repo-index v4-only contract)"
|
|
15481
15493
|
}
|
|
15482
15494
|
},
|
|
15483
15495
|
{
|
|
@@ -21139,6 +21151,11 @@ async function probeRegistryWhoami(train) {
|
|
|
21139
21151
|
(0, import_node_fs23.rmSync)(dir, { recursive: true, force: true });
|
|
21140
21152
|
}
|
|
21141
21153
|
}
|
|
21154
|
+
var REGISTRY_TOKEN_ENV = /\b(NODE_AUTH_TOKEN|NPM_TOKEN)\b/;
|
|
21155
|
+
function publishesViaTrustedPublisher(workflows) {
|
|
21156
|
+
if (!workflows?.length) return false;
|
|
21157
|
+
return workflows.some((f) => /\bid-token:\s*write\b/.test(f.body)) && !workflows.some((f) => REGISTRY_TOKEN_ENV.test(f.body));
|
|
21158
|
+
}
|
|
21142
21159
|
var defaultDeps2 = {
|
|
21143
21160
|
cliVersion: resolveClientVersion,
|
|
21144
21161
|
fetchReleasedVersion: fetchNpmReleasedVersion,
|
|
@@ -21443,7 +21460,9 @@ async function runTrainDoctor(input) {
|
|
|
21443
21460
|
}
|
|
21444
21461
|
if (/"publishVisibility"\s*:\s*"private"/.test(deps.readSurfacesRaw(cwd) ?? "")) {
|
|
21445
21462
|
const probe = await deps.registryWhoami(train);
|
|
21446
|
-
if (probe.kind === "rejected") {
|
|
21463
|
+
if (probe.kind === "rejected" && publishesViaTrustedPublisher(workflows)) {
|
|
21464
|
+
add({ code: "npm-token-rejected", severity: "info", source: "origin", title: `the vault npm token (_org npm/NPM_TOKEN) is REJECTED by registry.npmjs.org \u2014 ${probe.detail}; no lane of this repo consumes it (its workflows publish through OIDC Trusted Publishing and name no registry token)`, remedy: "nothing on the release path. It affects only a manual `npm view` of a restricted package made through the `_org` hop, which 404s exactly like an absent one until the token is rotated (`mmi-cli vault secrets set npm/NPM_TOKEN --slug _org`). If this repo verifies through a different vault entry, this row does not describe that hop (#6187)" });
|
|
21465
|
+
} else if (probe.kind === "rejected") {
|
|
21447
21466
|
add({ code: "npm-token-rejected", severity: "warning", source: "origin", title: `the vault npm token (_org npm/NPM_TOKEN) is REJECTED by registry.npmjs.org \u2014 ${probe.detail}; every authenticated \`npm view\` of a restricted package will 404 exactly like an absent one`, remedy: 'rotate the org token: mint a fresh npm automation token, store it with `mmi-cli vault secrets set npm/NPM_TOKEN --slug _org` (master or an exact grant), and rerun. Until whoami answers a login, a restricted-package 404 proves nothing \u2014 never read it as "not published" (#6184)' });
|
|
21448
21467
|
} else if (probe.kind === "unprobed") {
|
|
21449
21468
|
add({ code: "npm-token-rejected", severity: "info", source: "origin", title: `the vault npm token was not probed (no _org npm/NPM_TOKEN grant, or a vault error): ${probe.detail}`, remedy: "nothing here \u2014 the release does not depend on it (CI publishes through OIDC Trusted Publishing). Before verifying a private publish by hand, run the whoami probe from an account holding the `_org` npm/NPM_TOKEN grant" });
|
|
@@ -33475,6 +33494,10 @@ async function fetchBranchTipSha(repo, ref, gh = defaultGhApi) {
|
|
|
33475
33494
|
async function fetchRestPrSnapshot(prNumber, repo, gh = defaultGhApi) {
|
|
33476
33495
|
return parseRestPrSnapshot(JSON.parse(await gh([`repos/${repo}/pulls/${prNumber}`])));
|
|
33477
33496
|
}
|
|
33497
|
+
async function fetchRestRepoMergeSettings(repo, gh = defaultGhApi) {
|
|
33498
|
+
const payload = JSON.parse(await gh([`repos/${repo}`]));
|
|
33499
|
+
return typeof payload.delete_branch_on_merge === "boolean" ? { deleteBranchOnMerge: payload.delete_branch_on_merge } : {};
|
|
33500
|
+
}
|
|
33478
33501
|
var PR_SNAPSHOT_READ_RETRIES = 3;
|
|
33479
33502
|
var PR_SNAPSHOT_READ_DELAY_MS = 2e3;
|
|
33480
33503
|
async function readRestPrSnapshotWithRetry(prNumber, repo, gh = defaultGhApi, options) {
|
|
@@ -39643,8 +39666,8 @@ ${list}`);
|
|
|
39643
39666
|
if (closingGuardVerdict.message) console.warn(closingGuardVerdict.message);
|
|
39644
39667
|
if (prMeta.state !== "MERGED" && !o.preserveWorktree) {
|
|
39645
39668
|
if (!repoForPostCleanup) throw new Error("pr merge: repository is unreadable; cannot prove remote branch preservation");
|
|
39646
|
-
const repoSettings = await
|
|
39647
|
-
assertRemoteBranchPreservedOnMerge(repoForPostCleanup, repoSettings.
|
|
39669
|
+
const repoSettings = await fetchRestRepoMergeSettings(repoForPostCleanup);
|
|
39670
|
+
assertRemoteBranchPreservedOnMerge(repoForPostCleanup, repoSettings.deleteBranchOnMerge);
|
|
39648
39671
|
}
|
|
39649
39672
|
const startingPath = (await execFileP("git", ["rev-parse", "--show-toplevel"], { timeout: GIT_TIMEOUT_MS }).catch(() => ({ stdout: "" }))).stdout.trim();
|
|
39650
39673
|
const housekeeping = assertPrMergeHousekeepingClean(startingPath || process.cwd(), "pr merge", { force: o.force });
|
package/package.json
CHANGED