@mutmutco/claude-plugin 4.5.193 → 4.5.195

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mmi",
3
3
  "displayName": "MMI",
4
- "version": "4.5.193",
4
+ "version": "4.5.195",
5
5
  "mmiCompat": "4.x",
6
6
  "description": "MMI workflow skills and org gates delivery.",
7
7
  "author": {
package/cli/dist/main.cjs CHANGED
@@ -365,7 +365,35 @@ var init_error_codes = __esm({
365
365
  function isAppFilingWrite(args) {
366
366
  if (args.some((a) => VIEWER.test(a))) return false;
367
367
  const [group, verb] = args;
368
- return (group === "issue" || group === "label") && verb === "create";
368
+ if ((group === "issue" || group === "label" || group === "pr") && verb === "create") return true;
369
+ if (group === "pr" && verb === "merge") return true;
370
+ if (group === "api") return isFilingWriteApi(args.slice(1));
371
+ return false;
372
+ }
373
+ function isFilingWriteApi(rest) {
374
+ let method = "GET";
375
+ let path2;
376
+ for (let i = 0; i < rest.length; i++) {
377
+ const a = rest[i];
378
+ if (a === "-X" || a === "--method") {
379
+ method = (rest[i + 1] ?? "").toUpperCase();
380
+ i++;
381
+ } else if (/^--method=/.test(a)) {
382
+ method = a.slice(9).toUpperCase();
383
+ } else if (a === "-f" || a === "-F" || a === "--field" || a === "--raw-field" || a === "--input" || a === "-H" || a === "--header" || a === "-q" || a === "--jq" || a === "-t" || a === "--template" || a === "--hostname") {
384
+ if (a === "-f" || a === "-F" || a === "--field" || a === "--raw-field" || a === "--input") {
385
+ if (method === "GET") method = "POST";
386
+ }
387
+ i++;
388
+ } else if (a.startsWith("--input=")) {
389
+ if (method === "GET") method = "POST";
390
+ } else if (!a.startsWith("-") && path2 === void 0) {
391
+ path2 = a.replace(/^\//, "");
392
+ }
393
+ }
394
+ if (method === "POST" && path2 && /^repos\/[^/]+\/[^/]+\/(issues|pulls)$/.test(path2)) return true;
395
+ if (method === "PUT" && path2 && /^repos\/[^/]+\/[^/]+\/pulls\/\d+\/merge$/.test(path2)) return true;
396
+ return false;
369
397
  }
370
398
  function isViewerFreeGhRead(args) {
371
399
  if (args.some((a) => VIEWER.test(a))) return false;
@@ -1254,8 +1282,13 @@ __export(cli_shared_exports, {
1254
1282
  repoProject: () => repoProject,
1255
1283
  setGhReadTokenProvider: () => setGhReadTokenProvider,
1256
1284
  setGhWriteTokenProvider: () => setGhWriteTokenProvider,
1257
- setInjectedStdin: () => setInjectedStdin
1285
+ setInjectedStdin: () => setInjectedStdin,
1286
+ shouldRetryIntegrationRefusalOnAmbient: () => shouldRetryIntegrationRefusalOnAmbient
1258
1287
  });
1288
+ function shouldRetryIntegrationRefusalOnAmbient(err, env = process.env) {
1289
+ if (env.MMI_ACTOR?.trim() === "app") return false;
1290
+ return /Resource not accessible by integration/i.test(String(err?.stderr ?? ""));
1291
+ }
1259
1292
  function setGhReadTokenProvider(provider) {
1260
1293
  ghReadTokenProvider = provider;
1261
1294
  }
@@ -1265,8 +1298,18 @@ function setGhWriteTokenProvider(provider) {
1265
1298
  async function ghFilingAppEnv(file, args) {
1266
1299
  if (!ghWriteTokenProvider || !/(^|[\\/])gh(\.exe)?$/i.test(file) || process.env.MMI_ACTOR?.trim() === "personal") return void 0;
1267
1300
  if (!isAppFilingWrite(args)) return void 0;
1268
- const token = await ghWriteTokenProvider().catch(() => void 0);
1269
- return token ? { ...process.env, GH_TOKEN: token } : void 0;
1301
+ const explicitApp = process.env.MMI_ACTOR?.trim() === "app";
1302
+ let token;
1303
+ try {
1304
+ token = await ghWriteTokenProvider();
1305
+ } catch (e) {
1306
+ if (explicitApp) throw e;
1307
+ return void 0;
1308
+ }
1309
+ if (!token && explicitApp) {
1310
+ throw new Error("app actor: filing write token unavailable \u2014 refusing personal-token fallback under MMI_ACTOR=app");
1311
+ }
1312
+ return token ? { ...process.env, GH_TOKEN: token, MMI_GH_POOL: "app" } : void 0;
1270
1313
  }
1271
1314
  async function ghReadAppEnv(file, args) {
1272
1315
  if (!ghReadTokenProvider || !/(^|[\\/])gh(\.exe)?$/i.test(file) || process.env.MMI_ACTOR?.trim() === "personal") return void 0;
@@ -1477,7 +1520,7 @@ var init_cli_shared = __esm({
1477
1520
  try {
1478
1521
  return await run(appEnv);
1479
1522
  } catch (e) {
1480
- if (/Resource not accessible by integration/i.test(String(e.stderr ?? ""))) return run();
1523
+ if (shouldRetryIntegrationRefusalOnAmbient(e)) return run();
1481
1524
  throw e;
1482
1525
  }
1483
1526
  };
@@ -7385,7 +7428,11 @@ async function mintCommandWriteToken(deps, commandPath4) {
7385
7428
  }
7386
7429
  async function mintFilingWriteToken(deps) {
7387
7430
  try {
7388
- return await mintFromMember(deps, { metadata: "read", issues: "write" }, APP_VAULT_KEYS);
7431
+ return await mintFromMember(
7432
+ deps,
7433
+ { metadata: "read", contents: "write", issues: "write", pull_requests: "write" },
7434
+ APP_VAULT_KEYS
7435
+ );
7389
7436
  } catch (e) {
7390
7437
  if (e instanceof AppActorError) throw e;
7391
7438
  throw new AppActorError(`app actor: filing token mint failed (${e?.constructor?.name ?? "Error"})`);
@@ -7512,6 +7559,11 @@ async function pollTokenOrUndefined(deps, env = process.env) {
7512
7559
  }
7513
7560
  var notedIneligibleCommand = false;
7514
7561
  var notedVaultDenied = false;
7562
+ var APP_SUBPROCESS_ROUTED_COMMANDS = /* @__PURE__ */ new Set([
7563
+ "issue create",
7564
+ "pr create",
7565
+ "pr merge"
7566
+ ]);
7515
7567
  async function activateAppActor(commandPath4, env, mint, note = (line) => process.stderr.write(`${line}
7516
7568
  `)) {
7517
7569
  activeQuotaScope = void 0;
@@ -7522,7 +7574,7 @@ async function activateAppActor(commandPath4, env, mint, note = (line) => proces
7522
7574
  throw new AppActorError(`app actor: unknown ${APP_ACTOR_ENV} value \u2014 only 'app' and 'personal' are supported; refusing to guess an identity`);
7523
7575
  }
7524
7576
  if (!APP_ELIGIBLE_COMMANDS.has(commandPath4) && !APP_WRITE_COMMANDS.has(commandPath4)) {
7525
- if (requested === "app" && !notedIneligibleCommand) {
7577
+ if (requested === "app" && !notedIneligibleCommand && !APP_SUBPROCESS_ROUTED_COMMANDS.has(commandPath4)) {
7526
7578
  notedIneligibleCommand = true;
7527
7579
  note(`app actor: '${commandPath4}' is personal-only (viewer/@me/authorship) \u2014 running on the personal token despite ${APP_ACTOR_ENV}=app`);
7528
7580
  }
@@ -14003,6 +14055,11 @@ mutation($projectId: ID!, $itemId: ID!) {
14003
14055
  }
14004
14056
  }`;
14005
14057
  async function updateItemSingleSelect(client, projectId, itemId, fieldId, optionId) {
14058
+ if (process.env.MMI_ACTOR?.trim() === "app") {
14059
+ const { writeHubBoardField: writeHubBoardField2 } = await Promise.resolve().then(() => (init_board_write(), board_write_exports));
14060
+ await writeHubBoardField2({ projectId, itemId, fieldId, optionId });
14061
+ return { credential: "app_installation" };
14062
+ }
14006
14063
  try {
14007
14064
  await client.graphql(UPDATE_ITEM_FIELD_MUTATION, { projectId, itemId, fieldId, optionId });
14008
14065
  return { credential: "user" };
@@ -19193,10 +19250,10 @@ var rollout_plan_default = {
19193
19250
  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)."
19194
19251
  },
19195
19252
  baseline: {
19196
- version: "4.5.193",
19197
- tag: "v4.5.193",
19198
- commit: "8a9085b5492f",
19199
- npm: "@mutmutco/cli@4.5.193"
19253
+ version: "4.5.195",
19254
+ tag: "v4.5.195",
19255
+ commit: "ecbc0826abbe",
19256
+ npm: "@mutmutco/cli@4.5.195"
19200
19257
  },
19201
19258
  exitCriterion: "fleet-n-of-n",
19202
19259
  hubOnlyShortcut: "forbidden",
@@ -19213,14 +19270,14 @@ var rollout_plan_default = {
19213
19270
  repo: "mutmutco/mmi-hub",
19214
19271
  role: "canary",
19215
19272
  schedule: "train",
19216
- v3Target: "v4.5.193"
19273
+ v3Target: "v4.5.195"
19217
19274
  }
19218
19275
  ],
19219
19276
  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.",
19220
19277
  rollback: {
19221
19278
  independent: true,
19222
- mechanism: "npm dist-tag latest -> 4.5.193 and redeploy the Hub Lambda from tag v4.5.193 (8a9085b5492f); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
19223
- v3Target: "v4.5.193 (@mutmutco/cli@4.5.193, tag commit 8a9085b5492f \u2014 last known-good release carrying the repo-index v4-only contract)"
19279
+ mechanism: "npm dist-tag latest -> 4.5.195 and redeploy the Hub Lambda from tag v4.5.195 (ecbc0826abbe); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
19280
+ v3Target: "v4.5.195 (@mutmutco/cli@4.5.195, tag commit ecbc0826abbe \u2014 last known-good release carrying the repo-index v4-only contract)"
19224
19281
  }
19225
19282
  },
19226
19283
  {
@@ -33385,9 +33442,13 @@ function parseAlerts(output) {
33385
33442
  if (name === "runner-private-key") {
33386
33443
  const pm = /^(\d+)( private key file\(s\) readable by every CI job on this box \(#7535\): )(.+)$/.exec(message2);
33387
33444
  if (pm) {
33388
- const kept = pm[3].trim().split(/\s+/).filter((p) => p && !isSuppressedRunnerPrivateKeyPath(p));
33389
- if (kept.length === 0) continue;
33390
- message2 = `${kept.length}${pm[2]}${kept.join(" ")}`;
33445
+ const advertisedCount = Number(pm[1]);
33446
+ const paths = pm[3].trim().split(/\s+/).filter(Boolean);
33447
+ if (paths.length === advertisedCount) {
33448
+ const kept = paths.filter((p) => !isSuppressedRunnerPrivateKeyPath(p));
33449
+ if (kept.length === 0) continue;
33450
+ message2 = `${kept.length}${pm[2]}${kept.join(" ")}`;
33451
+ }
33391
33452
  }
33392
33453
  }
33393
33454
  out.push({ name, message: message2 });
@@ -47571,6 +47632,19 @@ async function attachToProject(issueNumber, repo, priority) {
47571
47632
  defaultGitHubClient()
47572
47633
  );
47573
47634
  if (!contentId) throw new Error("could not resolve issue node id");
47635
+ if (process.env.MMI_ACTOR?.trim() === "app") {
47636
+ const projectItemId2 = await attachViaHubApp(cfg, contentId);
47637
+ if (projectItemId2 && priority) {
47638
+ try {
47639
+ await setBoardItemPriority(defaultGitHubClient(), cfg, projectItemId2, priority);
47640
+ } catch (e) {
47641
+ const err = e;
47642
+ process.stderr.write(`warning: issue #${issueNumber} board Priority not set: ${(err.stderr || err.message || String(e)).trim()}
47643
+ `);
47644
+ }
47645
+ }
47646
+ return { projectItemId: projectItemId2, onBoard: true, credential: "app_installation" };
47647
+ }
47574
47648
  const { stdout } = await execFileP("gh", buildAddToProjectArgs(cfg.projectId, contentId), { timeout: GH_MUTATION_TIMEOUT_MS });
47575
47649
  const projectItemId = parseAddedItemId(stdout);
47576
47650
  if (projectItemId && priority) {
@@ -58026,7 +58100,12 @@ setPollTokenProvider(async () => activeAppToken() ?? pollTokenOrUndefined(appAct
58026
58100
  setGhReadTokenProvider(pollToken);
58027
58101
  setGitHubReadTokenProvider(pollToken);
58028
58102
  var filingToken;
58029
- setGhWriteTokenProvider(() => filingToken ??= mintFilingWriteToken(appActorDeps()).then((t) => t.token, () => void 0));
58103
+ setGhWriteTokenProvider(() => {
58104
+ if (process.env.MMI_ACTOR?.trim() === "app") {
58105
+ return mintFilingWriteToken(appActorDeps()).then((t) => t.token);
58106
+ }
58107
+ return filingToken ??= mintFilingWriteToken(appActorDeps()).then((t) => t.token, () => void 0);
58108
+ });
58030
58109
  setStatusWriteTokenProvider(() => mintStatusWriteToken(appActorDeps()));
58031
58110
  var registerPreAction = Reflect.get(program2, ["h", "ook"].join(""));
58032
58111
  registerPreAction.call(program2, "preAction", async (_thisCommand, actionCommand) => {
package/cli/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mutmutco/cli",
3
- "version": "4.5.193",
3
+ "version": "4.5.195",
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",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mutmutco/claude-plugin",
3
- "version": "4.5.193",
3
+ "version": "4.5.195",
4
4
  "description": "MMI workflow skills and org gates delivery.",
5
5
  "author": {
6
6
  "name": "MMI Future",