@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.
Files changed (2) hide show
  1. package/dist/main.cjs +36 -13
  2. 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.9",
15454
- tag: "v4.3.9",
15455
- commit: "64fc1be95e37",
15456
- npm: "@mutmutco/cli@4.3.9"
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.9"
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.9 and redeploy the Hub Lambda from tag v4.3.9 (64fc1be95e37); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
15480
- v3Target: "v4.3.9 (@mutmutco/cli@4.3.9, tag commit 64fc1be95e37 \u2014 last known-good release carrying the repo-index v4-only contract)"
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 defaultGitHubClient().rest("GET", `repos/${repoForPostCleanup}`);
39647
- assertRemoteBranchPreservedOnMerge(repoForPostCleanup, repoSettings.delete_branch_on_merge);
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mutmutco/cli",
3
- "version": "4.3.9",
3
+ "version": "4.3.11",
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",