@mutmutco/cli 3.105.2 → 3.105.3

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 +275 -146
  2. package/package.json +1 -1
package/dist/main.cjs CHANGED
@@ -5000,7 +5000,7 @@ var program = new Command();
5000
5000
 
5001
5001
  // src/index.ts
5002
5002
  var import_promises11 = require("node:fs/promises");
5003
- var import_node_fs41 = require("node:fs");
5003
+ var import_node_fs42 = require("node:fs");
5004
5004
  var import_node_child_process19 = require("node:child_process");
5005
5005
 
5006
5006
  // src/cli-shared.ts
@@ -8590,7 +8590,7 @@ function commandLadderHint() {
8590
8590
  }
8591
8591
 
8592
8592
  // src/index.ts
8593
- var import_node_path39 = require("node:path");
8593
+ var import_node_path40 = require("node:path");
8594
8594
 
8595
8595
  // src/merge-ci-policy.ts
8596
8596
  function resolveMergeCiPolicy(input) {
@@ -15206,7 +15206,7 @@ async function executeWaveLand(plan, deps, opts = { preserveWorktree: true }) {
15206
15206
  }
15207
15207
 
15208
15208
  // src/index.ts
15209
- var import_node_os16 = require("node:os");
15209
+ var import_node_os17 = require("node:os");
15210
15210
 
15211
15211
  // src/board.ts
15212
15212
  var import_node_child_process9 = require("node:child_process");
@@ -18832,13 +18832,25 @@ function liveEvidenceLines(evidence, repo) {
18832
18832
  if (evidence.branch) live.push(`live branch ${evidence.branch} on ${repo}`);
18833
18833
  return live;
18834
18834
  }
18835
- function laneOwnership(marker, currentSession) {
18836
- if (marker?.session && currentSession) return marker.session === currentSession ? "mine" : "other";
18835
+ function sameClaimHost(a, b) {
18836
+ return Boolean(a && b && a.toLowerCase() === b.toLowerCase());
18837
+ }
18838
+ function laneOwnership(marker, current) {
18839
+ if (!marker) return "unknown";
18840
+ if (marker.session && current.session) {
18841
+ return marker.session === current.session ? "mine" : "other";
18842
+ }
18843
+ if (marker.surface && current.surface && marker.surface !== current.surface) return "other";
18844
+ if (marker.host && current.host && !sameClaimHost(marker.host, current.host)) return "other";
18845
+ if (marker.surface && current.surface && marker.surface === current.surface && marker.host && current.host && sameClaimHost(marker.host, current.host)) {
18846
+ return "mine";
18847
+ }
18837
18848
  return "unknown";
18838
18849
  }
18839
18850
  async function checkLaneContest(client, item) {
18840
18851
  const evidence = await gatherClaimLiveness(client, item.repository, item.number, openPullsFetcher(client));
18841
- const ownership = laneOwnership(evidence.marker, readSessionId(process.env));
18852
+ const actor = describeActor({ env: process.env, surface: detectSurface(process.env), cwd: process.cwd() });
18853
+ const ownership = laneOwnership(evidence.marker, actor);
18842
18854
  const live = ownership === "mine" ? [] : liveEvidenceLines(evidence, item.repository);
18843
18855
  const unverifiable = ownership === "mine" ? [] : evidence.failed;
18844
18856
  return {
@@ -28179,10 +28191,10 @@ function registerBoardCommands(program3) {
28179
28191
  }
28180
28192
 
28181
28193
  // src/merge-cleanup.ts
28182
- var import_node_fs34 = require("node:fs");
28194
+ var import_node_fs35 = require("node:fs");
28183
28195
  var import_promises8 = require("node:fs/promises");
28184
- var import_node_path33 = require("node:path");
28185
- var import_node_os12 = require("node:os");
28196
+ var import_node_path34 = require("node:path");
28197
+ var import_node_os13 = require("node:os");
28186
28198
  var import_node_child_process17 = require("node:child_process");
28187
28199
 
28188
28200
  // src/board-advance.ts
@@ -28348,6 +28360,117 @@ function makeDeferredWorktreeStore(registryPath, lockOpts = {}) {
28348
28360
  };
28349
28361
  }
28350
28362
 
28363
+ // src/jerv-cli-spawn.ts
28364
+ var import_node_fs34 = require("node:fs");
28365
+ var import_node_os12 = require("node:os");
28366
+ var import_node_path33 = require("node:path");
28367
+ var WIN_NAMES = ["jerv-cli.cmd", "jerv-cli.exe", "jerv-cli"];
28368
+ var POSIX_NAMES = ["jerv-cli"];
28369
+ var JERV_CLI_ENTRY = (0, import_node_path33.join)("node_modules", "@jervaise", "jerv-cli", "dist", "index.cjs");
28370
+ function pathEnvEntries(pathEnv, platform2 = process.platform) {
28371
+ if (platform2 !== "win32") {
28372
+ return pathEnv.split(import_node_path33.delimiter).map((e) => e.trim()).filter(Boolean);
28373
+ }
28374
+ if (pathEnv.includes(";")) {
28375
+ return pathEnv.split(";").map((e) => e.trim()).filter(Boolean);
28376
+ }
28377
+ const looksUnix = pathEnv.startsWith("/") || /(?:^|:)\/[a-zA-Z]\//.test(pathEnv);
28378
+ if (looksUnix && pathEnv.includes(":")) {
28379
+ return pathEnv.split(":").map((e) => e.trim()).filter(Boolean);
28380
+ }
28381
+ return pathEnv.trim() ? [pathEnv.trim()] : [];
28382
+ }
28383
+ function normalizeSpawnPathEntry(entry, platform2 = process.platform) {
28384
+ const trimmed = entry.trim();
28385
+ if (!trimmed) return void 0;
28386
+ if (platform2 !== "win32") return trimmed;
28387
+ const msys = /^\/([a-zA-Z])\/(.*)$/.exec(trimmed.replace(/\\/g, "/"));
28388
+ if (msys) return `${msys[1].toUpperCase()}:\\${msys[2].replace(/\//g, "\\")}`;
28389
+ return trimmed;
28390
+ }
28391
+ function jervCliCandidateDirs(env = process.env, home = (0, import_node_os12.homedir)(), platform2 = process.platform) {
28392
+ const seen = /* @__PURE__ */ new Set();
28393
+ const out = [];
28394
+ const push = (dir) => {
28395
+ if (!dir) return;
28396
+ const key = platform2 === "win32" ? dir.toLowerCase() : dir;
28397
+ if (seen.has(key)) return;
28398
+ seen.add(key);
28399
+ out.push(dir);
28400
+ };
28401
+ for (const entry of pathEnvEntries(env.PATH ?? "", platform2)) {
28402
+ push(normalizeSpawnPathEntry(entry, platform2));
28403
+ }
28404
+ if (platform2 === "win32") {
28405
+ if (env.APPDATA) push((0, import_node_path33.join)(env.APPDATA, "npm"));
28406
+ if (env.LOCALAPPDATA) push((0, import_node_path33.join)(env.LOCALAPPDATA, "npm"));
28407
+ } else {
28408
+ push((0, import_node_path33.join)(home, ".local", "bin"));
28409
+ }
28410
+ return out;
28411
+ }
28412
+ function jervCliCandidatePaths(env = process.env, home = (0, import_node_os12.homedir)(), platform2 = process.platform) {
28413
+ const names = platform2 === "win32" ? WIN_NAMES : POSIX_NAMES;
28414
+ const out = [];
28415
+ for (const dir of jervCliCandidateDirs(env, home, platform2)) {
28416
+ for (const name of names) out.push((0, import_node_path33.join)(dir, name));
28417
+ }
28418
+ return out;
28419
+ }
28420
+ function resolveJervCliPath(env = process.env, home = (0, import_node_os12.homedir)(), platform2 = process.platform, exists = import_node_fs34.existsSync) {
28421
+ for (const candidate of jervCliCandidatePaths(env, home, platform2)) {
28422
+ if (exists(candidate)) return candidate;
28423
+ }
28424
+ return void 0;
28425
+ }
28426
+ function resolveJervCliNodeEntry(shimPath, exists = import_node_fs34.existsSync) {
28427
+ const entry = (0, import_node_path33.join)((0, import_node_path33.dirname)(shimPath), JERV_CLI_ENTRY);
28428
+ return exists(entry) ? entry : void 0;
28429
+ }
28430
+ function jervCliExecFileArgs(args, opts = {}) {
28431
+ const platform2 = opts.platform ?? process.platform;
28432
+ const exists = opts.exists ?? import_node_fs34.existsSync;
28433
+ const resolved = resolveJervCliPath(opts.env ?? process.env, opts.home ?? (0, import_node_os12.homedir)(), platform2, exists);
28434
+ if (resolved) {
28435
+ const entry = resolveJervCliNodeEntry(resolved, exists);
28436
+ if (entry) {
28437
+ return { file: opts.execPath ?? process.execPath, args: [entry, ...args], via: "node-entry" };
28438
+ }
28439
+ }
28440
+ const bin = resolved ?? "jerv-cli";
28441
+ if (platform2 === "win32") {
28442
+ return { file: "cmd.exe", args: ["/c", bin, ...args], via: resolved ? "cmd-shim" : "bare" };
28443
+ }
28444
+ return { file: bin, args: [...args], via: resolved ? "posix" : "bare" };
28445
+ }
28446
+ function formatJervCliSpawnFailure(err, plan, candidates) {
28447
+ const base = (err.stderr?.trim() || err.message.trim()).split("\n")[0] || "spawn failed";
28448
+ const code = err.code;
28449
+ if (code !== "ENOENT" && !/\bENOENT\b/i.test(base)) return base;
28450
+ const tried = candidates.length > 0 ? candidates.join(" | ") : "(no candidates)";
28451
+ return `${base} [via=${plan.via} file=${plan.file}; tried: ${tried}]`;
28452
+ }
28453
+ function isEnoent(err) {
28454
+ const code = err.code;
28455
+ if (code === "ENOENT") return true;
28456
+ return /\bENOENT\b/i.test(err.message ?? "");
28457
+ }
28458
+ function execJervCli(args, options = {}) {
28459
+ const env = options.env ?? process.env;
28460
+ const candidates = jervCliCandidatePaths(env);
28461
+ const plan = jervCliExecFileArgs(args, { env });
28462
+ return execFileP2(plan.file, plan.args, options).catch((err) => {
28463
+ if (!isEnoent(err)) throw err;
28464
+ const wrapped = new Error(formatJervCliSpawnFailure(err, plan, candidates));
28465
+ Object.assign(wrapped, {
28466
+ code: "ENOENT",
28467
+ stderr: err.stderr,
28468
+ cause: err
28469
+ });
28470
+ throw wrapped;
28471
+ });
28472
+ }
28473
+
28351
28474
  // src/merge-cleanup.ts
28352
28475
  var GC_GH_TIMEOUT_MS2 = 2e4;
28353
28476
  async function advanceClosedIssuesToDone2(prNumber, repoOption) {
@@ -28466,7 +28589,8 @@ function assertPrMergeHousekeepingClean(startingPath, context, options = {}) {
28466
28589
  if (verdict.blocked) throw new Error(verdict.reason);
28467
28590
  return housekeeping;
28468
28591
  }
28469
- async function bestEffortLeaseClose(wtPath, exec = (cmd, args) => execFileP2(cmd, args, { timeout: GIT_TIMEOUT_MS })) {
28592
+ var defaultLeaseCloseExec = (_cmd, args) => execJervCli(args, { timeout: GIT_TIMEOUT_MS });
28593
+ async function bestEffortLeaseClose(wtPath, exec = defaultLeaseCloseExec) {
28470
28594
  const step = "close jerv worktree lease";
28471
28595
  try {
28472
28596
  await exec("jerv-cli", ["lease", "close", "--ref", wtPath]);
@@ -28489,7 +28613,7 @@ async function applyGcPlan(plan, remote, opts = {}) {
28489
28613
  );
28490
28614
  const repoRoot2 = (await execFileP2("git", ["rev-parse", "--show-toplevel"], { timeout: GIT_TIMEOUT_MS }).catch(() => ({ stdout: "" }))).stdout.trim() || process.cwd();
28491
28615
  const worktreeGitRoot = await currentRepoWorktreeGitRoot(repoRoot2);
28492
- const primaryRepoRoot = worktreeGitRoot ? (0, import_node_path33.dirname)((0, import_node_path33.dirname)(worktreeGitRoot)) : repoRoot2;
28616
+ const primaryRepoRoot = worktreeGitRoot ? (0, import_node_path34.dirname)((0, import_node_path34.dirname)(worktreeGitRoot)) : repoRoot2;
28493
28617
  const gcActor = describeActor({ env: process.env, surface: detectSurface(process.env), cwd: process.cwd() });
28494
28618
  const owners = readWorktreeOwners(primaryRepoRoot);
28495
28619
  const removalNow = Date.now();
@@ -28520,7 +28644,7 @@ async function applyGcPlan(plan, remote, opts = {}) {
28520
28644
  const cleanup = await cleanupPrMergeLocalBranch(branch.branch, {
28521
28645
  beforeWorktrees,
28522
28646
  startingPath: branch.worktreePath,
28523
- pathExists: (p) => (0, import_node_fs34.existsSync)(p),
28647
+ pathExists: (p) => (0, import_node_fs35.existsSync)(p),
28524
28648
  execGit: async (args) => (await execFileP2("git", args, { timeout: GIT_TIMEOUT_MS })).stdout,
28525
28649
  teardownWorktreeStage,
28526
28650
  deferredStore,
@@ -28549,7 +28673,7 @@ async function applyGcPlan(plan, remote, opts = {}) {
28549
28673
  let removalAttempted = false;
28550
28674
  try {
28551
28675
  const cleanupTarget = resolveSafeSiblingWorktreeCleanupTarget(wt.path, siblingRoot, {
28552
- realpath: (path2) => (0, import_node_fs34.realpathSync)(path2)
28676
+ realpath: (path2) => (0, import_node_fs35.realpathSync)(path2)
28553
28677
  });
28554
28678
  if (!cleanupTarget.ok) {
28555
28679
  result.failed.push(`${wt.path}: ${cleanupTarget.reason}`);
@@ -28636,13 +28760,13 @@ async function composeOverrideBodyFile(prNumber, repoArgs, gh) {
28636
28760
  const commits = JSON.parse(raw).commits ?? [];
28637
28761
  const body = squashBodyWithOverride(commits.map((c) => ({ headline: c.messageHeadline ?? "", body: c.messageBody ?? "" })), process.cwd());
28638
28762
  if (!body) return void 0;
28639
- const dir = (0, import_node_fs34.mkdtempSync)((0, import_node_path33.join)((0, import_node_os12.tmpdir)(), "mmi-squash-body-"));
28640
- const path2 = (0, import_node_path33.join)(dir, "body.txt");
28641
- (0, import_node_fs34.writeFileSync)(path2, `${body}
28763
+ const dir = (0, import_node_fs35.mkdtempSync)((0, import_node_path34.join)((0, import_node_os13.tmpdir)(), "mmi-squash-body-"));
28764
+ const path2 = (0, import_node_path34.join)(dir, "body.txt");
28765
+ (0, import_node_fs35.writeFileSync)(path2, `${body}
28642
28766
  `, "utf8");
28643
28767
  return { path: path2, cleanup: () => {
28644
28768
  try {
28645
- (0, import_node_fs34.rmSync)(dir, { recursive: true, force: true });
28769
+ (0, import_node_fs35.rmSync)(dir, { recursive: true, force: true });
28646
28770
  } catch {
28647
28771
  }
28648
28772
  } };
@@ -28764,13 +28888,13 @@ var realWorktreeDirRemover = {
28764
28888
  probe: (p) => {
28765
28889
  let st;
28766
28890
  try {
28767
- st = (0, import_node_fs34.lstatSync)(p);
28891
+ st = (0, import_node_fs35.lstatSync)(p);
28768
28892
  } catch {
28769
28893
  return null;
28770
28894
  }
28771
28895
  if (st.isSymbolicLink()) return "link";
28772
28896
  try {
28773
- (0, import_node_fs34.readlinkSync)(p);
28897
+ (0, import_node_fs35.readlinkSync)(p);
28774
28898
  return "link";
28775
28899
  } catch {
28776
28900
  }
@@ -28778,7 +28902,7 @@ var realWorktreeDirRemover = {
28778
28902
  },
28779
28903
  readdir: (p) => {
28780
28904
  try {
28781
- return (0, import_node_fs34.readdirSync)(p);
28905
+ return (0, import_node_fs35.readdirSync)(p);
28782
28906
  } catch {
28783
28907
  return [];
28784
28908
  }
@@ -28787,9 +28911,9 @@ var realWorktreeDirRemover = {
28787
28911
  // leaving the target); a file symlink with unlink. rmdir first, fall back to unlink.
28788
28912
  detachLink: (p) => {
28789
28913
  try {
28790
- (0, import_node_fs34.rmdirSync)(p);
28914
+ (0, import_node_fs35.rmdirSync)(p);
28791
28915
  } catch {
28792
- (0, import_node_fs34.unlinkSync)(p);
28916
+ (0, import_node_fs35.unlinkSync)(p);
28793
28917
  }
28794
28918
  },
28795
28919
  removeTree: (p) => (0, import_promises8.rm)(p, { recursive: true, force: true, maxRetries: 5, retryDelay: 200 })
@@ -28822,9 +28946,9 @@ async function worktreeHasStageState(worktreePath) {
28822
28946
  }
28823
28947
  }
28824
28948
  function stageStateFileBelongsToWorktree(statePath, worktreePath) {
28825
- if (!(0, import_node_fs34.existsSync)(statePath)) return false;
28949
+ if (!(0, import_node_fs35.existsSync)(statePath)) return false;
28826
28950
  try {
28827
- const state = JSON.parse((0, import_node_fs34.readFileSync)(statePath, "utf8"));
28951
+ const state = JSON.parse((0, import_node_fs35.readFileSync)(statePath, "utf8"));
28828
28952
  const recordedCwd = typeof state.identity?.cwd === "string" ? state.identity.cwd : typeof state.cwd === "string" ? state.cwd : "";
28829
28953
  return Boolean(recordedCwd && isPathUnderDirectory(recordedCwd, worktreePath));
28830
28954
  } catch {
@@ -29155,9 +29279,9 @@ async function checkDocsIndexAtHead(opts, deps) {
29155
29279
  }
29156
29280
 
29157
29281
  // src/worktree-lifecycle-commands.ts
29158
- var import_node_fs35 = require("node:fs");
29282
+ var import_node_fs36 = require("node:fs");
29159
29283
  var import_promises9 = require("node:fs/promises");
29160
- var import_node_path34 = require("node:path");
29284
+ var import_node_path35 = require("node:path");
29161
29285
  var GH_TIMEOUT_MS = 2e4;
29162
29286
  var STALE_PR_LOOKUP_LIMIT = 20;
29163
29287
  var DEFAULT_BASE = "origin/development";
@@ -29304,7 +29428,7 @@ function classifyStaleLeaks(input) {
29304
29428
  var defaultOrphanDirScanDeps = {
29305
29429
  listDirs: (root) => {
29306
29430
  try {
29307
- return (0, import_node_fs35.readdirSync)(root, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => (0, import_node_path34.join)(root, e.name));
29431
+ return (0, import_node_fs36.readdirSync)(root, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => (0, import_node_path35.join)(root, e.name));
29308
29432
  } catch {
29309
29433
  return [];
29310
29434
  }
@@ -29460,13 +29584,13 @@ function registerWorktreeCommands(program3) {
29460
29584
  const detached = headBorn && !symbolicBranch;
29461
29585
  const branch = symbolicBranch || (detached ? "HEAD" : "");
29462
29586
  if (!wtPath || !branch) return fail("worktree land: not inside a git worktree");
29463
- const gitFile = (0, import_node_path34.join)(wtPath, ".git");
29464
- const isLinked = (0, import_node_fs35.existsSync)(gitFile) && (0, import_node_fs35.statSync)(gitFile).isFile();
29587
+ const gitFile = (0, import_node_path35.join)(wtPath, ".git");
29588
+ const isLinked = (0, import_node_fs36.existsSync)(gitFile) && (0, import_node_fs36.statSync)(gitFile).isFile();
29465
29589
  if (apply && !isLinked) {
29466
29590
  return fail("worktree land: run from inside the linked worktree you want to land (this is the primary checkout)");
29467
29591
  }
29468
29592
  const commonDir = (await execFileP2("git", ["rev-parse", "--git-common-dir"], { timeout: GIT_TIMEOUT_MS }).catch(() => ({ stdout: "" }))).stdout.trim();
29469
- const primaryCheckout = commonDir ? (0, import_node_path34.dirname)(commonDir) : wtPath;
29593
+ const primaryCheckout = commonDir ? (0, import_node_path35.dirname)(commonDir) : wtPath;
29470
29594
  const localBranchNames = await execFileP2("git", ["-C", primaryCheckout, "for-each-ref", "--format=%(refname:short)", "refs/heads"], { timeout: GIT_TIMEOUT_MS }).then(({ stdout }) => new Set((stdout || "").split("\n").map((l) => l.trim()).filter(Boolean))).catch(() => void 0);
29471
29595
  const orphan = classifyOrphanedWorktree({
29472
29596
  branch,
@@ -29675,10 +29799,10 @@ async function gatherWorktreeContext() {
29675
29799
  if (s) stages.push({ path: wt.path, port: s.port });
29676
29800
  }
29677
29801
  const worktreeGitRoot = await currentRepoWorktreeGitRoot(repoRoot2);
29678
- const primaryRepoRoot = worktreeGitRoot ? (0, import_node_path34.dirname)((0, import_node_path34.dirname)(worktreeGitRoot)) : repoRoot2;
29802
+ const primaryRepoRoot = worktreeGitRoot ? (0, import_node_path35.dirname)((0, import_node_path35.dirname)(worktreeGitRoot)) : repoRoot2;
29679
29803
  const wtRoot = siblingMmiWorktreesRoot(primaryRepoRoot);
29680
29804
  let orphanDirs = [];
29681
- if ((0, import_node_fs35.existsSync)(wtRoot)) {
29805
+ if ((0, import_node_fs36.existsSync)(wtRoot)) {
29682
29806
  orphanDirs = scanOrphanDirs(wtRoot, worktreeGitRoot, {
29683
29807
  ...defaultOrphanDirScanDeps,
29684
29808
  listDirs: (root) => worktreeScanDirs(root, primaryRepoRoot, defaultOrphanDirScanDeps.listDirs, isRepoCheckoutDir)
@@ -29704,7 +29828,7 @@ ${err.stderr ?? ""}`;
29704
29828
  }
29705
29829
 
29706
29830
  // src/issue-commands.ts
29707
- var import_node_fs36 = require("node:fs");
29831
+ var import_node_fs37 = require("node:fs");
29708
29832
  var import_node_crypto7 = require("node:crypto");
29709
29833
  var ghRunner = async (args, timeoutMs) => (await execFileP2("gh", args, { timeout: timeoutMs })).stdout;
29710
29834
  var ReparentConflictError = class extends Error {
@@ -29722,7 +29846,7 @@ async function editIssue(client, options, deps = {}) {
29722
29846
  const url = `https://github.com/${repo}/issues/${parsed.number}`;
29723
29847
  const patch = {};
29724
29848
  let bodyChanged = false;
29725
- const textDeps = () => deps.textDeps ?? { readFile: (p, e) => Promise.resolve((0, import_node_fs36.readFileSync)(p, e)), readStdin: () => Promise.resolve("") };
29849
+ const textDeps = () => deps.textDeps ?? { readFile: (p, e) => Promise.resolve((0, import_node_fs37.readFileSync)(p, e)), readStdin: () => Promise.resolve("") };
29726
29850
  if (options.titleFile !== void 0) {
29727
29851
  patch.title = await resolveIssueTitle({ title: options.title, titleFile: options.titleFile }, textDeps());
29728
29852
  } else if (options.title !== void 0) {
@@ -30327,7 +30451,7 @@ function extendCreateCommand(issue2, batchAttach) {
30327
30451
  if (opts.batch) {
30328
30452
  let specs;
30329
30453
  try {
30330
- const raw = (0, import_node_fs36.readFileSync)(opts.batch, "utf8");
30454
+ const raw = (0, import_node_fs37.readFileSync)(opts.batch, "utf8");
30331
30455
  specs = JSON.parse(raw);
30332
30456
  if (!Array.isArray(specs)) throw new Error("batch file must contain a JSON array");
30333
30457
  } catch (e) {
@@ -30402,8 +30526,8 @@ ${lines}`, {
30402
30526
  }
30403
30527
 
30404
30528
  // src/train-commands.ts
30405
- var import_node_fs37 = require("node:fs");
30406
- var import_node_path35 = require("node:path");
30529
+ var import_node_fs38 = require("node:fs");
30530
+ var import_node_path36 = require("node:path");
30407
30531
 
30408
30532
  // src/train-status.ts
30409
30533
  function buildTrainStatusReport(input) {
@@ -30443,7 +30567,7 @@ function formatTrainStatus(r) {
30443
30567
  // src/train-commands.ts
30444
30568
  function readRepoVersion() {
30445
30569
  try {
30446
- return JSON.parse((0, import_node_fs37.readFileSync)((0, import_node_path35.join)(process.cwd(), ".claude-plugin", "plugin.json"), "utf8")).version || void 0;
30570
+ return JSON.parse((0, import_node_fs38.readFileSync)((0, import_node_path36.join)(process.cwd(), ".claude-plugin", "plugin.json"), "utf8")).version || void 0;
30447
30571
  } catch {
30448
30572
  return void 0;
30449
30573
  }
@@ -30589,9 +30713,9 @@ function registerDeployCommands(program3) {
30589
30713
  }
30590
30714
 
30591
30715
  // src/discovery-commands.ts
30592
- var import_node_fs38 = require("node:fs");
30593
- var import_node_os13 = require("node:os");
30594
- var import_node_path36 = require("node:path");
30716
+ var import_node_fs39 = require("node:fs");
30717
+ var import_node_os14 = require("node:os");
30718
+ var import_node_path37 = require("node:path");
30595
30719
  var GC_GH_TIMEOUT_MS3 = 2e4;
30596
30720
  async function collectStatus() {
30597
30721
  const repo = await resolveRepo();
@@ -30779,10 +30903,10 @@ async function collectOnboardStatus(opts = {}) {
30779
30903
  else if (top) nextCommand = `mmi-cli board claim ${top.number} # ${top.title}`;
30780
30904
  else nextCommand = "mmi-cli board read \u2014 no claimable items found";
30781
30905
  }
30782
- const home = (0, import_node_os13.homedir)();
30906
+ const home = (0, import_node_os14.homedir)();
30783
30907
  const plugin = onboardPluginGate({
30784
- readKnown: () => readFileSyncSafe((0, import_node_path36.join)(home, ...KNOWN_MARKETPLACES_RELATIVE), import_node_fs38.readFileSync),
30785
- readSettings: () => readFileSyncSafe((0, import_node_path36.join)(home, ".claude", "settings.json"), import_node_fs38.readFileSync)
30908
+ readKnown: () => readFileSyncSafe((0, import_node_path37.join)(home, ...KNOWN_MARKETPLACES_RELATIVE), import_node_fs39.readFileSync),
30909
+ readSettings: () => readFileSyncSafe((0, import_node_path37.join)(home, ".claude", "settings.json"), import_node_fs39.readFileSync)
30786
30910
  });
30787
30911
  return { track, board, registry: registry2, secrets, plugin, estateCli, nextCommand };
30788
30912
  }
@@ -31686,19 +31810,19 @@ function registerSessionReport(program3) {
31686
31810
  }
31687
31811
 
31688
31812
  // src/plugin-release-catchup.ts
31689
- var import_node_fs39 = require("node:fs");
31690
- var import_node_path37 = require("node:path");
31691
- var import_node_os14 = require("node:os");
31813
+ var import_node_fs40 = require("node:fs");
31814
+ var import_node_path38 = require("node:path");
31815
+ var import_node_os15 = require("node:os");
31692
31816
  var RELEASE_CATCHUP_TTL_MS = 24 * 60 * 60 * 1e3;
31693
31817
  var RELEASE_CATCHUP_DISABLE_ENV = "MMI_NO_RELEASE_CATCHUP";
31694
31818
  function releaseCatchupStatePath(env = process.env) {
31695
31819
  if (env.MMI_RELEASE_CATCHUP_STATE) return env.MMI_RELEASE_CATCHUP_STATE;
31696
31820
  if (process.platform === "win32") {
31697
- const base2 = env.LOCALAPPDATA || (0, import_node_path37.join)((0, import_node_os14.homedir)(), "AppData", "Local");
31698
- return (0, import_node_path37.join)(base2, "MMI Future", "mmi-cli", "release-catchup.json");
31821
+ const base2 = env.LOCALAPPDATA || (0, import_node_path38.join)((0, import_node_os15.homedir)(), "AppData", "Local");
31822
+ return (0, import_node_path38.join)(base2, "MMI Future", "mmi-cli", "release-catchup.json");
31699
31823
  }
31700
- const base = env.XDG_STATE_HOME || (0, import_node_path37.join)((0, import_node_os14.homedir)(), ".local", "state");
31701
- return (0, import_node_path37.join)(base, "mmi-cli", "release-catchup.json");
31824
+ const base = env.XDG_STATE_HOME || (0, import_node_path38.join)((0, import_node_os15.homedir)(), ".local", "state");
31825
+ return (0, import_node_path38.join)(base, "mmi-cli", "release-catchup.json");
31702
31826
  }
31703
31827
  function releaseCatchupDue(state, now, force = false) {
31704
31828
  if (force) return true;
@@ -31708,7 +31832,7 @@ function releaseCatchupDue(state, now, force = false) {
31708
31832
  function newestCachedPluginVersion(home) {
31709
31833
  let names;
31710
31834
  try {
31711
- names = (0, import_node_fs39.readdirSync)(pluginCacheRoot(home));
31835
+ names = (0, import_node_fs40.readdirSync)(pluginCacheRoot(home));
31712
31836
  } catch {
31713
31837
  return void 0;
31714
31838
  }
@@ -31716,15 +31840,15 @@ function newestCachedPluginVersion(home) {
31716
31840
  }
31717
31841
  function marketplaceClonePath(home) {
31718
31842
  try {
31719
- const parsed = JSON.parse((0, import_node_fs39.readFileSync)((0, import_node_path37.join)(home, ".claude", "plugins", "known_marketplaces.json"), "utf8"));
31843
+ const parsed = JSON.parse((0, import_node_fs40.readFileSync)((0, import_node_path38.join)(home, ".claude", "plugins", "known_marketplaces.json"), "utf8"));
31720
31844
  if (parsed.mutmutco?.installLocation) return parsed.mutmutco.installLocation;
31721
31845
  } catch {
31722
31846
  }
31723
- return (0, import_node_path37.join)(home, ".claude", "plugins", "marketplaces", "mutmutco");
31847
+ return (0, import_node_path38.join)(home, ".claude", "plugins", "marketplaces", "mutmutco");
31724
31848
  }
31725
31849
  function readCatalogVersion(home) {
31726
31850
  try {
31727
- const parsed = JSON.parse((0, import_node_fs39.readFileSync)((0, import_node_path37.join)(marketplaceClonePath(home), ".claude-plugin", "marketplace.json"), "utf8"));
31851
+ const parsed = JSON.parse((0, import_node_fs40.readFileSync)((0, import_node_path38.join)(marketplaceClonePath(home), ".claude-plugin", "marketplace.json"), "utf8"));
31728
31852
  return parsed.plugins?.find((p) => p.name === "mmi")?.version;
31729
31853
  } catch {
31730
31854
  return void 0;
@@ -31732,7 +31856,7 @@ function readCatalogVersion(home) {
31732
31856
  }
31733
31857
  function readMmiInstallRecord(home) {
31734
31858
  try {
31735
- const parsed = JSON.parse((0, import_node_fs39.readFileSync)((0, import_node_path37.join)(home, ".claude", "plugins", "installed_plugins.json"), "utf8"));
31859
+ const parsed = JSON.parse((0, import_node_fs40.readFileSync)((0, import_node_path38.join)(home, ".claude", "plugins", "installed_plugins.json"), "utf8"));
31736
31860
  const record = parsed.plugins?.["mmi@mutmutco"]?.[0];
31737
31861
  return record?.version ? { version: record.version, gitCommitSha: record.gitCommitSha } : void 0;
31738
31862
  } catch {
@@ -31741,7 +31865,7 @@ function readMmiInstallRecord(home) {
31741
31865
  }
31742
31866
  async function runReleaseCatchup(home, env, deps, opts = {}) {
31743
31867
  if (env[RELEASE_CATCHUP_DISABLE_ENV]) return { ok: true, skipped: true, detail: `disabled via ${RELEASE_CATCHUP_DISABLE_ENV}` };
31744
- if (!(0, import_node_fs39.existsSync)(pluginCacheRoot(home))) return { ok: true, skipped: true, detail: "no mmi plugin cache on this machine \u2014 nothing to catch up" };
31868
+ if (!(0, import_node_fs40.existsSync)(pluginCacheRoot(home))) return { ok: true, skipped: true, detail: "no mmi plugin cache on this machine \u2014 nothing to catch up" };
31745
31869
  const statePath = releaseCatchupStatePath(env);
31746
31870
  const state = deps.readState(statePath);
31747
31871
  if (!releaseCatchupDue(state, deps.now(), opts.force)) {
@@ -31766,8 +31890,8 @@ async function runReleaseCatchup(home, env, deps, opts = {}) {
31766
31890
  return { ok: false, detail: `released ${latest} but the install record could not be cleared \u2014 nothing changed (record still ${prior.version})` };
31767
31891
  }
31768
31892
  const installed = await deps.runClaude(["plugin", "install", "mmi@mutmutco"], "claude plugin install mmi@mutmutco");
31769
- const payload = (0, import_node_path37.join)(pluginCacheRoot(home), latest, ".pi-plugin");
31770
- if (!installed || !(0, import_node_fs39.existsSync)(payload)) {
31893
+ const payload = (0, import_node_path38.join)(pluginCacheRoot(home), latest, ".pi-plugin");
31894
+ if (!installed || !(0, import_node_fs40.existsSync)(payload)) {
31771
31895
  const why = installed ? `install of ${latest} did not produce a verifiable .pi-plugin payload` : `install of ${latest} failed`;
31772
31896
  if (!prior) return { ok: false, detail: `${why}; no prior record to restore` };
31773
31897
  const rollback = await restorePriorRecord(home, prior, deps);
@@ -31795,7 +31919,7 @@ async function restorePriorRecord(home, prior, deps) {
31795
31919
  }
31796
31920
  function shouldSpawnReleaseCatchup(home, env, readState2, now = Date.now()) {
31797
31921
  if (env[RELEASE_CATCHUP_DISABLE_ENV]) return false;
31798
- if (!(0, import_node_fs39.existsSync)(pluginCacheRoot(home))) return false;
31922
+ if (!(0, import_node_fs40.existsSync)(pluginCacheRoot(home))) return false;
31799
31923
  return releaseCatchupDue(readState2(releaseCatchupStatePath(env)), now);
31800
31924
  }
31801
31925
  function defaultRegistrationHeal(home, env) {
@@ -33841,17 +33965,17 @@ function parseOriginRepo(remoteUrl) {
33841
33965
  }
33842
33966
  function ghHostsConfigPath(env, platform2) {
33843
33967
  const sep3 = platform2 === "win32" ? "\\" : "/";
33844
- const join35 = (...parts) => parts.join(sep3);
33968
+ const join36 = (...parts) => parts.join(sep3);
33845
33969
  const explicit = env.GH_CONFIG_DIR?.trim();
33846
- if (explicit) return join35(explicit, "hosts.yml");
33970
+ if (explicit) return join36(explicit, "hosts.yml");
33847
33971
  if (platform2 === "win32") {
33848
33972
  const appData = (env.AppData ?? env.APPDATA)?.trim();
33849
- return appData ? join35(appData, "GitHub CLI", "hosts.yml") : void 0;
33973
+ return appData ? join36(appData, "GitHub CLI", "hosts.yml") : void 0;
33850
33974
  }
33851
33975
  const xdg = env.XDG_CONFIG_HOME?.trim();
33852
- if (xdg) return join35(xdg, "gh", "hosts.yml");
33976
+ if (xdg) return join36(xdg, "gh", "hosts.yml");
33853
33977
  const home = env.HOME?.trim();
33854
- return home ? join35(home, ".config", "gh", "hosts.yml") : void 0;
33978
+ return home ? join36(home, ".config", "gh", "hosts.yml") : void 0;
33855
33979
  }
33856
33980
  function parseGhHostsAccounts(yaml, host = "github.com") {
33857
33981
  let hostIndent = null;
@@ -33901,9 +34025,9 @@ function ghAccountCaveat(announcedLogin, accounts) {
33901
34025
  }
33902
34026
 
33903
34027
  // src/doctor-io.ts
33904
- var import_node_fs40 = require("node:fs");
33905
- var import_node_os15 = require("node:os");
33906
- var import_node_path38 = require("node:path");
34028
+ var import_node_fs41 = require("node:fs");
34029
+ var import_node_os16 = require("node:os");
34030
+ var import_node_path39 = require("node:path");
33907
34031
  var import_node_child_process18 = require("node:child_process");
33908
34032
  var import_node_util8 = require("node:util");
33909
34033
  var execFileP6 = (0, import_node_util8.promisify)(import_node_child_process18.execFile);
@@ -33911,7 +34035,7 @@ var MMI_PLUGIN_ID2 = "mmi@mutmutco";
33911
34035
  function installedClaudePluginVersion() {
33912
34036
  try {
33913
34037
  const file = JSON.parse(
33914
- (0, import_node_fs40.readFileSync)((0, import_node_path38.join)((0, import_node_os15.homedir)(), ".claude", "plugins", "installed_plugins.json"), "utf8")
34038
+ (0, import_node_fs41.readFileSync)((0, import_node_path39.join)((0, import_node_os16.homedir)(), ".claude", "plugins", "installed_plugins.json"), "utf8")
33915
34039
  );
33916
34040
  const versions = (file.plugins?.[MMI_PLUGIN_ID2] ?? []).map((r) => r.version).filter((v) => Boolean(v));
33917
34041
  if (versions.length === 0) return void 0;
@@ -33922,7 +34046,7 @@ function installedClaudePluginVersion() {
33922
34046
  }
33923
34047
  function manifestVersion(path2) {
33924
34048
  try {
33925
- const manifest = JSON.parse((0, import_node_fs40.readFileSync)(path2, "utf8"));
34049
+ const manifest = JSON.parse((0, import_node_fs41.readFileSync)(path2, "utf8"));
33926
34050
  return typeof manifest.version === "string" && manifest.version.trim() ? manifest.version.trim() : void 0;
33927
34051
  } catch {
33928
34052
  return void 0;
@@ -33932,22 +34056,22 @@ function installedSurfacePluginVersion(surface) {
33932
34056
  const token = surfaceToken(surface);
33933
34057
  if (token === "kilo") {
33934
34058
  try {
33935
- const stamp = (0, import_node_fs40.readFileSync)((0, import_node_path38.join)((0, import_node_os15.homedir)(), ".kilo", ".mmi-kilo-version"), "utf8").trim();
34059
+ const stamp = (0, import_node_fs41.readFileSync)((0, import_node_path39.join)((0, import_node_os16.homedir)(), ".kilo", ".mmi-kilo-version"), "utf8").trim();
33936
34060
  return stamp || void 0;
33937
34061
  } catch {
33938
34062
  return void 0;
33939
34063
  }
33940
34064
  }
33941
34065
  if (token === "cursor") {
33942
- return manifestVersion((0, import_node_path38.join)(cursorLocalPluginRoot(), ".cursor-plugin", "plugin.json"));
34066
+ return manifestVersion((0, import_node_path39.join)(cursorLocalPluginRoot(), ".cursor-plugin", "plugin.json"));
33943
34067
  }
33944
34068
  if (token === "jervcode") {
33945
34069
  const entry = mmiPiWrapperEntry();
33946
34070
  if (!entry) return void 0;
33947
- return manifestVersion((0, import_node_path38.join)(decodeURIComponent(entry.replace(/^file:\/\/\/?/, "")), "package.json"));
34071
+ return manifestVersion((0, import_node_path39.join)(decodeURIComponent(entry.replace(/^file:\/\/\/?/, "")), "package.json"));
33948
34072
  }
33949
34073
  if (token === "kimi") {
33950
- return manifestVersion((0, import_node_path38.join)(surfaceConfigRoot(surface), "plugins", "managed", "mmi", ".kimi-plugin", "plugin.json"));
34074
+ return manifestVersion((0, import_node_path39.join)(surfaceConfigRoot(surface), "plugins", "managed", "mmi", ".kimi-plugin", "plugin.json"));
33951
34075
  }
33952
34076
  if (token === "claude") return installedClaudePluginVersion();
33953
34077
  if (token !== "codex") return void 0;
@@ -33985,13 +34109,13 @@ function worktreeRootSync() {
33985
34109
  }
33986
34110
  var gitignorePath = () => {
33987
34111
  const root = worktreeRootSync();
33988
- return root === null ? null : (0, import_node_path38.join)(root, ".gitignore");
34112
+ return root === null ? null : (0, import_node_path39.join)(root, ".gitignore");
33989
34113
  };
33990
34114
  function readGitignore() {
33991
34115
  const path2 = gitignorePath();
33992
34116
  if (path2 === null) return null;
33993
34117
  try {
33994
- return (0, import_node_fs40.readFileSync)(path2, "utf8");
34118
+ return (0, import_node_fs41.readFileSync)(path2, "utf8");
33995
34119
  } catch {
33996
34120
  return null;
33997
34121
  }
@@ -34000,7 +34124,7 @@ function writeGitignore(content) {
34000
34124
  const path2 = gitignorePath();
34001
34125
  if (path2 === null) return false;
34002
34126
  try {
34003
- (0, import_node_fs40.writeFileSync)(path2, content, "utf8");
34127
+ (0, import_node_fs41.writeFileSync)(path2, content, "utf8");
34004
34128
  return true;
34005
34129
  } catch {
34006
34130
  return false;
@@ -34024,7 +34148,7 @@ async function repoRoot() {
34024
34148
  }
34025
34149
  function hasRepoLocalWorktrees() {
34026
34150
  const root = worktreeRootSync();
34027
- return root !== null && (0, import_node_fs40.existsSync)((0, import_node_path38.join)(root, ".worktrees"));
34151
+ return root !== null && (0, import_node_fs41.existsSync)((0, import_node_path39.join)(root, ".worktrees"));
34028
34152
  }
34029
34153
 
34030
34154
  // src/index.ts
@@ -34043,8 +34167,8 @@ ${r.stderr ?? ""}`).catch(() => "");
34043
34167
  function ghMultiAccountCaveat(announcedLogin) {
34044
34168
  try {
34045
34169
  const hostsPath = ghHostsConfigPath(process.env, process.platform);
34046
- if (!hostsPath || !(0, import_node_fs41.existsSync)(hostsPath)) return void 0;
34047
- return ghAccountCaveat(announcedLogin, parseGhHostsAccounts((0, import_node_fs41.readFileSync)(hostsPath, "utf8")));
34170
+ if (!hostsPath || !(0, import_node_fs42.existsSync)(hostsPath)) return void 0;
34171
+ return ghAccountCaveat(announcedLogin, parseGhHostsAccounts((0, import_node_fs42.readFileSync)(hostsPath, "utf8")));
34048
34172
  } catch {
34049
34173
  return void 0;
34050
34174
  }
@@ -34052,12 +34176,12 @@ function ghMultiAccountCaveat(announcedLogin) {
34052
34176
  var ENV_HEAL_LOCK_STALE_MS = 10 * 6e4;
34053
34177
  var ENV_HEAL_LOCK_MAX_WAIT_MS = 2 * 6e4;
34054
34178
  function envHealLockPath(home) {
34055
- return (0, import_node_path39.join)(home, ".claude", "plugins", ".mmi-env-heal.lock");
34179
+ return (0, import_node_path40.join)(home, ".claude", "plugins", ".mmi-env-heal.lock");
34056
34180
  }
34057
34181
  async function withEnvHealLock(what, run) {
34058
34182
  try {
34059
34183
  return await withFileLock(
34060
- envHealLockPath((0, import_node_os16.homedir)()),
34184
+ envHealLockPath((0, import_node_os17.homedir)()),
34061
34185
  { staleMs: ENV_HEAL_LOCK_STALE_MS, maxWaitMs: ENV_HEAL_LOCK_MAX_WAIT_MS, label: "mmi env-heal lock" },
34062
34186
  run
34063
34187
  );
@@ -34154,7 +34278,7 @@ function mmiDoctorDeps(opts = {}) {
34154
34278
  const configRoot = surfaceConfigRoot(surface);
34155
34279
  const running = surface === "codex" ? installedActivePluginVersion(surface) : runningPluginVersion(process.env, resolveClientVersion());
34156
34280
  const plan = buildPluginCachePlan(
34157
- (0, import_node_os16.homedir)(),
34281
+ (0, import_node_os17.homedir)(),
34158
34282
  running,
34159
34283
  pluginCacheFsDeps(configRoot, () => 0),
34160
34284
  { configRoot, includeStaging: surface !== "codex" }
@@ -34178,14 +34302,14 @@ function mmiDoctorDeps(opts = {}) {
34178
34302
  const running = surface === "codex" ? installedActivePluginVersion(surface) : runningPluginVersion(process.env, resolveClientVersion());
34179
34303
  const installed = installedActivePluginVersion(surface);
34180
34304
  const plan = buildPluginCachePlan(
34181
- (0, import_node_os16.homedir)(),
34305
+ (0, import_node_os17.homedir)(),
34182
34306
  running,
34183
34307
  pluginCacheFsDeps(configRoot, () => 0),
34184
34308
  { configRoot, includeStaging: surface !== "codex", installedVersion: installed }
34185
34309
  );
34186
34310
  const result = applyPluginCachePlan(
34187
34311
  plan,
34188
- (p) => (0, import_node_fs41.rmSync)(p, { recursive: true }),
34312
+ (p) => (0, import_node_fs42.rmSync)(p, { recursive: true }),
34189
34313
  stagingApplyFsGuard(configRoot)
34190
34314
  );
34191
34315
  return {
@@ -34213,12 +34337,12 @@ function mmiDoctorDeps(opts = {}) {
34213
34337
  piPluginState: () => {
34214
34338
  const env = { ...process.env };
34215
34339
  delete env.CLAUDE_PLUGIN_ROOT;
34216
- return readPiPluginState((0, import_node_os16.homedir)(), env);
34340
+ return readPiPluginState((0, import_node_os17.homedir)(), env);
34217
34341
  },
34218
34342
  healPiPlugin: () => {
34219
34343
  const env = { ...process.env };
34220
34344
  delete env.CLAUDE_PLUGIN_ROOT;
34221
- return healPiPluginRegistration((0, import_node_os16.homedir)(), env);
34345
+ return healPiPluginRegistration((0, import_node_os17.homedir)(), env);
34222
34346
  },
34223
34347
  // #3470: what the SessionStart hook LAST emitted, measured at emission by the session-start verb below.
34224
34348
  // A local record read ? cheap enough for every lane, including the banner.
@@ -34228,17 +34352,17 @@ function mmiDoctorDeps(opts = {}) {
34228
34352
  marketplaceRows: () => {
34229
34353
  try {
34230
34354
  if (detectSurface(process.env) === "codex") return [];
34231
- const home = (0, import_node_os16.homedir)();
34355
+ const home = (0, import_node_os17.homedir)();
34232
34356
  const rows = marketplaceRows(
34233
34357
  MMI_MARKETPLACE_NAME,
34234
- readFileSyncSafe((0, import_node_path39.join)(home, ...KNOWN_MARKETPLACES_RELATIVE), import_node_fs41.readFileSync),
34235
- readFileSyncSafe((0, import_node_path39.join)(home, ".claude", "settings.json"), import_node_fs41.readFileSync),
34358
+ readFileSyncSafe((0, import_node_path40.join)(home, ...KNOWN_MARKETPLACES_RELATIVE), import_node_fs42.readFileSync),
34359
+ readFileSyncSafe((0, import_node_path40.join)(home, ".claude", "settings.json"), import_node_fs42.readFileSync),
34236
34360
  // #3974: this CLI heals these rows, so report mode names the doctor run rather than the hand
34237
34361
  // edit. Unconditional ? it is a fact about mmi-cli, not about the lane this run is on.
34238
34362
  true
34239
34363
  );
34240
34364
  const pending = readMarketplacePinPending(
34241
- (0, import_node_path39.join)(home, ".claude", "plugins", ".mmi-marketplace-pin-pending.json"),
34365
+ (0, import_node_path40.join)(home, ".claude", "plugins", ".mmi-marketplace-pin-pending.json"),
34242
34366
  MMI_MARKETPLACE_NAME
34243
34367
  );
34244
34368
  if (!pending) return rows;
@@ -34262,11 +34386,11 @@ function mmiDoctorDeps(opts = {}) {
34262
34386
  healMarketplacePins: () => {
34263
34387
  try {
34264
34388
  if (detectSurface(process.env) === "codex") return void 0;
34265
- const home = (0, import_node_os16.homedir)();
34389
+ const home = (0, import_node_os17.homedir)();
34266
34390
  const names = [MMI_MARKETPLACE_NAME];
34267
- const result = applyOrgMarketplacePins((0, import_node_path39.join)(home, ...KNOWN_MARKETPLACES_RELATIVE), names);
34391
+ const result = applyOrgMarketplacePins((0, import_node_path40.join)(home, ...KNOWN_MARKETPLACES_RELATIVE), names);
34268
34392
  if (result?.wrote) {
34269
- writeMarketplacePinPending((0, import_node_path39.join)(home, ".claude", "plugins", ".mmi-marketplace-pin-pending.json"), names);
34393
+ writeMarketplacePinPending((0, import_node_path40.join)(home, ".claude", "plugins", ".mmi-marketplace-pin-pending.json"), names);
34270
34394
  }
34271
34395
  return result;
34272
34396
  } catch {
@@ -34282,7 +34406,7 @@ function mmiDoctorDeps(opts = {}) {
34282
34406
  // adopted the generated routing index (MMG-Unlive: `docs/Archive/**` only, no index, no gate.yml) would
34283
34407
  // get a permanent ? demanding an artifact it never asked for.
34284
34408
  docsIndexState: (root) => {
34285
- if (!(0, import_node_fs41.existsSync)((0, import_node_path39.join)(root, DOCS_INDEX_PATH))) return void 0;
34409
+ if (!(0, import_node_fs42.existsSync)((0, import_node_path40.join)(root, DOCS_INDEX_PATH))) return void 0;
34286
34410
  const real = createDocsIndexDeps(root);
34287
34411
  let docs2;
34288
34412
  const listDocs = () => docs2 ??= real.listDocs();
@@ -34291,7 +34415,7 @@ function mmiDoctorDeps(opts = {}) {
34291
34415
  },
34292
34416
  // #4168: working-tree heal — write if drifted, then re-check. Commit remains the operator's step.
34293
34417
  healDocsIndex: (root) => {
34294
- if (!(0, import_node_fs41.existsSync)((0, import_node_path39.join)(root, DOCS_INDEX_PATH))) return { drift: false, docCount: 0 };
34418
+ if (!(0, import_node_fs42.existsSync)((0, import_node_path40.join)(root, DOCS_INDEX_PATH))) return { drift: false, docCount: 0 };
34295
34419
  const real = createDocsIndexDeps(root);
34296
34420
  let docs2;
34297
34421
  const listDocs = () => docs2 ??= real.listDocs();
@@ -34626,19 +34750,19 @@ program2.hook("preAction", async (_thisCommand, actionCommand) => {
34626
34750
  });
34627
34751
  var rules = program2.command("rules").description("org-managed .gitignore delivery");
34628
34752
  rules.command("gitignore").option("--write", "upsert the managed block into .gitignore (default: check only, non-zero exit on drift)").option("--json", "machine-readable output").description("verify (or --write) this repo's org-managed .gitignore block matches the SSOT").action((opts) => {
34629
- const path2 = (0, import_node_path39.join)(process.cwd(), ".gitignore");
34630
- const current = (0, import_node_fs41.existsSync)(path2) ? (0, import_node_fs41.readFileSync)(path2, "utf8") : null;
34753
+ const path2 = (0, import_node_path40.join)(process.cwd(), ".gitignore");
34754
+ const current = (0, import_node_fs42.existsSync)(path2) ? (0, import_node_fs42.readFileSync)(path2, "utf8") : null;
34631
34755
  const plan = planManagedGitignore(current);
34632
34756
  const drift = [...plan.added.map((l) => `+${l}`), ...plan.removed.map((l) => `-${l}`)].join(", ") || "block normalize";
34633
34757
  if (opts.json) {
34634
- if (opts.write && plan.changed) (0, import_node_fs41.writeFileSync)(path2, plan.content, "utf8");
34758
+ if (opts.write && plan.changed) (0, import_node_fs42.writeFileSync)(path2, plan.content, "utf8");
34635
34759
  console.log(JSON.stringify(plan, null, 2));
34636
34760
  if (!opts.write && plan.changed) process.exitCode = 1;
34637
34761
  return;
34638
34762
  }
34639
34763
  if (opts.write) {
34640
34764
  if (plan.changed) {
34641
- (0, import_node_fs41.writeFileSync)(path2, plan.content, "utf8");
34765
+ (0, import_node_fs42.writeFileSync)(path2, plan.content, "utf8");
34642
34766
  console.log(`mmi-cli org rules gitignore: updated .gitignore (${drift})`);
34643
34767
  } else {
34644
34768
  console.log("mmi-cli org rules gitignore: up to date");
@@ -34796,8 +34920,8 @@ gcCmd.option("--dry-run", "show what would be deleted (default)").option("--appl
34796
34920
  if (!Number.isFinite(limit) || limit < 1) return fail("worktree gc: --limit must be a positive integer");
34797
34921
  let root;
34798
34922
  if (o.root !== void 0) {
34799
- root = (0, import_node_path39.resolve)(o.root);
34800
- if (!(0, import_node_fs41.existsSync)(root) || !(0, import_node_fs41.statSync)(root).isDirectory()) return fail(`worktree gc: --root ${o.root} is not a directory`);
34923
+ root = (0, import_node_path40.resolve)(o.root);
34924
+ if (!(0, import_node_fs42.existsSync)(root) || !(0, import_node_fs42.statSync)(root).isDirectory()) return fail(`worktree gc: --root ${o.root} is not a directory`);
34801
34925
  const gcRepoRoot = (await execFileP2("git", ["rev-parse", "--show-toplevel"], { timeout: GIT_TIMEOUT_MS }).catch(() => ({ stdout: "" }))).stdout.trim() || process.cwd();
34802
34926
  if (isPathUnderDirectory(gcRepoRoot, root)) {
34803
34927
  return fail(`worktree gc: --root ${root} contains this checkout ? name a worktrees root, not the repo or an ancestor of it`);
@@ -34877,7 +35001,7 @@ async function currentWorktreeRemovalContext(command, force) {
34877
35001
  };
34878
35002
  }
34879
35003
  async function unprovenWorktreeReason(wtPath, repoRoot2) {
34880
- if (!(0, import_node_fs41.existsSync)(wtPath)) return `${wtPath} does not exist on disk`;
35004
+ if (!(0, import_node_fs42.existsSync)(wtPath)) return `${wtPath} does not exist on disk`;
34881
35005
  const porcelain = (await execFileP2("git", ["-C", repoRoot2, "worktree", "list", "--porcelain"], { timeout: GIT_TIMEOUT_MS }).catch(() => ({ stdout: "" }))).stdout;
34882
35006
  const registered = parseWorktreePorcelainEntries(porcelain);
34883
35007
  if (!registered.length) {
@@ -34899,26 +35023,26 @@ function makeProvisionDeps(worktreeRoot, quiet, log) {
34899
35023
  function acquireWorktreeSetupLock(worktreeRoot) {
34900
35024
  const lockPath = repoRuntimeStatePath(worktreeRoot, "worktree-setup.lock");
34901
35025
  const take = () => {
34902
- const fd = (0, import_node_fs41.openSync)(lockPath, "wx");
35026
+ const fd = (0, import_node_fs42.openSync)(lockPath, "wx");
34903
35027
  try {
34904
- (0, import_node_fs41.writeSync)(fd, String(Date.now()));
35028
+ (0, import_node_fs42.writeSync)(fd, String(Date.now()));
34905
35029
  } finally {
34906
- (0, import_node_fs41.closeSync)(fd);
35030
+ (0, import_node_fs42.closeSync)(fd);
34907
35031
  }
34908
35032
  return () => {
34909
35033
  try {
34910
- (0, import_node_fs41.rmSync)(lockPath, { force: true });
35034
+ (0, import_node_fs42.rmSync)(lockPath, { force: true });
34911
35035
  } catch {
34912
35036
  }
34913
35037
  };
34914
35038
  };
34915
35039
  try {
34916
- (0, import_node_fs41.mkdirSync)((0, import_node_path39.dirname)(lockPath), { recursive: true });
35040
+ (0, import_node_fs42.mkdirSync)((0, import_node_path40.dirname)(lockPath), { recursive: true });
34917
35041
  return take();
34918
35042
  } catch {
34919
35043
  try {
34920
- if (Date.now() - (0, import_node_fs41.statSync)(lockPath).mtimeMs > WORKTREE_SETUP_LOCK_TTL_MS) {
34921
- (0, import_node_fs41.rmSync)(lockPath, { force: true });
35044
+ if (Date.now() - (0, import_node_fs42.statSync)(lockPath).mtimeMs > WORKTREE_SETUP_LOCK_TTL_MS) {
35045
+ (0, import_node_fs42.rmSync)(lockPath, { force: true });
34922
35046
  return take();
34923
35047
  }
34924
35048
  } catch {
@@ -34944,6 +35068,11 @@ withExamples(mutating(
34944
35068
  const resolvedRepo = await resolveRepo();
34945
35069
  if (!resolvedRepo) return fail("worktree create: could not resolve the repo for the issue ref (run from a repo checkout)");
34946
35070
  selector = parseIssueSelector(target, resolvedRepo);
35071
+ if (selector.repo.toLowerCase() !== resolvedRepo.toLowerCase()) {
35072
+ return fail(
35073
+ `worktree create: issue ${selector.repo}#${selector.number} belongs to ${selector.repo}, but this checkout is ${resolvedRepo} \u2014 re-run from ${selector.repo}'s primary checkout. Refusing to attach a foreign issue branch here (MMI-Hub#4351).`
35074
+ );
35075
+ }
34947
35076
  const slug = o.slug ?? await fetchIssueTitle(selector.repo, selector.number).then((t) => t ? slugifyIssueTitle(t) : "");
34948
35077
  branch = buildNewBranchName(selector.number, slug ?? "");
34949
35078
  if (PROTECTED_BRANCHES2.has(branch)) {
@@ -35057,7 +35186,7 @@ withExamples(mutating(
35057
35186
  appendWorktreeEvent(repoRoot2, { action: "created", command: "worktree create", target: wtPath, branch, actor: owner.actor });
35058
35187
  let lease;
35059
35188
  try {
35060
- await execFileP2("jerv-cli", [
35189
+ await execJervCli([
35061
35190
  "lease",
35062
35191
  "open",
35063
35192
  "--kind",
@@ -35766,7 +35895,7 @@ project.command("set [owner/repo]").description("upsert project META (idempotent
35766
35895
  if (dupe) return fail(`org project set: KEY "${dupe}" was passed to both --var and --set; --set is an alias of --var, so pass each KEY once`);
35767
35896
  if (o.secretsFile) {
35768
35897
  try {
35769
- vars.push(`secrets=${(0, import_node_fs41.readFileSync)(o.secretsFile, "utf8")}`);
35898
+ vars.push(`secrets=${(0, import_node_fs42.readFileSync)(o.secretsFile, "utf8")}`);
35770
35899
  } catch (e) {
35771
35900
  return fail(`org project set: cannot read --secrets-file ${o.secretsFile}: ${e.message}`);
35772
35901
  }
@@ -36520,11 +36649,11 @@ pr.command("view <number>").description("read a PR as structured JSON (merged st
36520
36649
  }
36521
36650
  });
36522
36651
  async function listCiWorkflowPaths(cwd = process.cwd()) {
36523
- const wfDir = (0, import_node_path39.join)(cwd, ".github", "workflows");
36524
- if (!(0, import_node_fs41.existsSync)(wfDir)) return [];
36525
- return (0, import_node_fs41.readdirSync)(wfDir).filter((name) => /\.(ya?ml)$/i.test(name)).filter((name) => {
36652
+ const wfDir = (0, import_node_path40.join)(cwd, ".github", "workflows");
36653
+ if (!(0, import_node_fs42.existsSync)(wfDir)) return [];
36654
+ return (0, import_node_fs42.readdirSync)(wfDir).filter((name) => /\.(ya?ml)$/i.test(name)).filter((name) => {
36526
36655
  try {
36527
- return workflowReportsPrChecks((0, import_node_fs41.readFileSync)((0, import_node_path39.join)(wfDir, name), "utf8"));
36656
+ return workflowReportsPrChecks((0, import_node_fs42.readFileSync)((0, import_node_path40.join)(wfDir, name), "utf8"));
36528
36657
  } catch {
36529
36658
  return true;
36530
36659
  }
@@ -36556,16 +36685,16 @@ function ciAuditDeps() {
36556
36685
  // gate re-seed step is skipped gracefully rather than failing mid-run.
36557
36686
  readSeedFile: (path2) => {
36558
36687
  if (!root) return null;
36559
- const fullPath = (0, import_node_path39.join)(root, path2);
36560
- return (0, import_node_fs41.existsSync)(fullPath) ? (0, import_node_fs41.readFileSync)(fullPath, "utf8") : null;
36688
+ const fullPath = (0, import_node_path40.join)(root, path2);
36689
+ return (0, import_node_fs42.existsSync)(fullPath) ? (0, import_node_fs42.readFileSync)(fullPath, "utf8") : null;
36561
36690
  }
36562
36691
  };
36563
36692
  }
36564
36693
  function hubRoot() {
36565
- const fromPkg = (0, import_node_path39.join)(__dirname, "..", "..");
36694
+ const fromPkg = (0, import_node_path40.join)(__dirname, "..", "..");
36566
36695
  const marker = "skills/bootstrap/seeds/manifest.json";
36567
- if ((0, import_node_fs41.existsSync)((0, import_node_path39.join)(fromPkg, marker))) return fromPkg;
36568
- if ((0, import_node_fs41.existsSync)((0, import_node_path39.join)(process.cwd(), marker))) return process.cwd();
36696
+ if ((0, import_node_fs42.existsSync)((0, import_node_path40.join)(fromPkg, marker))) return fromPkg;
36697
+ if ((0, import_node_fs42.existsSync)((0, import_node_path40.join)(process.cwd(), marker))) return process.cwd();
36569
36698
  return null;
36570
36699
  }
36571
36700
  pr.command("ci-policy").description("report merge CI policy: wait-for-checks vs no-ci (for grind/build agents)").option("--json", "machine-readable output").option("--repo <owner/repo>", "target repo (defaults to the current checkout)").action(async (o) => {
@@ -36877,7 +37006,7 @@ jsonParity(pr.command("merge <number>").description("merge a PR (squash by defau
36877
37006
  localCleanup = await cleanupPrMergeLocalBranch(headRef, {
36878
37007
  beforeWorktrees,
36879
37008
  startingPath,
36880
- pathExists: (p) => (0, import_node_fs41.existsSync)(p),
37009
+ pathExists: (p) => (0, import_node_fs42.existsSync)(p),
36881
37010
  execGit: async (args) => (await execFileP2("git", args, { timeout: GIT_TIMEOUT_MS })).stdout,
36882
37011
  teardownWorktreeStage,
36883
37012
  deferredStore,
@@ -37373,12 +37502,12 @@ access.command("audit").description("audit collaborator roles + train-branch pus
37373
37502
  targets = resolution.targets;
37374
37503
  }
37375
37504
  const derivedMatrix = registryProjects ? accessMatrixFromProjects(registryProjects) : {};
37376
- const fileMatrix = (0, import_node_fs41.existsSync)("access-matrix.json") ? loadAccessMatrix((0, import_node_fs41.readFileSync)("access-matrix.json", "utf8")) : {};
37505
+ const fileMatrix = (0, import_node_fs42.existsSync)("access-matrix.json") ? loadAccessMatrix((0, import_node_fs42.readFileSync)("access-matrix.json", "utf8")) : {};
37377
37506
  const matrix = mergeAccessMatrix(fileMatrix, derivedMatrix);
37378
37507
  const derivedContracts = registryProjects ? dataAccessContractsFromProjects(registryProjects) : { consumers: {} };
37379
- const fileContracts = (0, import_node_fs41.existsSync)("data-access-contracts.json") ? loadDataAccessContracts((0, import_node_fs41.readFileSync)("data-access-contracts.json", "utf8")) : { consumers: {} };
37508
+ const fileContracts = (0, import_node_fs42.existsSync)("data-access-contracts.json") ? loadDataAccessContracts((0, import_node_fs42.readFileSync)("data-access-contracts.json", "utf8")) : { consumers: {} };
37380
37509
  const dataAccess = mergeDataAccessContracts(fileContracts, derivedContracts);
37381
- const sanctioned = (0, import_node_fs41.existsSync)("access-matrix.json") ? loadSanctionedAdmins((0, import_node_fs41.readFileSync)("access-matrix.json", "utf8")) : {};
37510
+ const sanctioned = (0, import_node_fs42.existsSync)("access-matrix.json") ? loadSanctionedAdmins((0, import_node_fs42.readFileSync)("access-matrix.json", "utf8")) : {};
37382
37511
  const report = await auditOrgAccess(targets, deps, matrix, dataAccess, sanctioned);
37383
37512
  console.log(o.json ? JSON.stringify(report, null, 2) : renderAccessReport(report));
37384
37513
  if (!report.ok) process.exitCode = 1;
@@ -37410,16 +37539,16 @@ function directoryBytes(path2) {
37410
37539
  let total = 0;
37411
37540
  let entries;
37412
37541
  try {
37413
- entries = (0, import_node_fs41.readdirSync)(path2, { withFileTypes: true });
37542
+ entries = (0, import_node_fs42.readdirSync)(path2, { withFileTypes: true });
37414
37543
  } catch {
37415
37544
  return 0;
37416
37545
  }
37417
37546
  for (const entry of entries) {
37418
- const child2 = (0, import_node_path39.join)(path2, entry.name);
37547
+ const child2 = (0, import_node_path40.join)(path2, entry.name);
37419
37548
  if (entry.isDirectory()) total += directoryBytes(child2);
37420
37549
  else {
37421
37550
  try {
37422
- total += (0, import_node_fs41.statSync)(child2).size;
37551
+ total += (0, import_node_fs42.statSync)(child2).size;
37423
37552
  } catch {
37424
37553
  }
37425
37554
  }
@@ -37427,25 +37556,25 @@ function directoryBytes(path2) {
37427
37556
  return total;
37428
37557
  }
37429
37558
  function listDirEntries(dir) {
37430
- return (0, import_node_fs41.readdirSync)(dir, { withFileTypes: true }).map((d) => ({ name: d.name, isDirectory: d.isDirectory() }));
37559
+ return (0, import_node_fs42.readdirSync)(dir, { withFileTypes: true }).map((d) => ({ name: d.name, isDirectory: d.isDirectory() }));
37431
37560
  }
37432
37561
  function readInstalledPluginRefs(configRoot) {
37433
37562
  const p = installedPluginsPathForConfig(configRoot);
37434
- if (!(0, import_node_fs41.existsSync)(p)) return [];
37563
+ if (!(0, import_node_fs42.existsSync)(p)) return [];
37435
37564
  try {
37436
- return installedPluginPaths((0, import_node_fs41.readFileSync)(p, "utf8"));
37565
+ return installedPluginPaths((0, import_node_fs42.readFileSync)(p, "utf8"));
37437
37566
  } catch {
37438
37567
  return null;
37439
37568
  }
37440
37569
  }
37441
37570
  function pluginCacheFsDeps(configRoot, dirBytes) {
37442
37571
  return {
37443
- exists: (p) => (0, import_node_fs41.existsSync)(p),
37444
- listVersionDirs: (root) => (0, import_node_fs41.readdirSync)(root, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name),
37572
+ exists: (p) => (0, import_node_fs42.existsSync)(p),
37573
+ listVersionDirs: (root) => (0, import_node_fs42.readdirSync)(root, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name),
37445
37574
  dirBytes,
37446
- listStagingDirs: (root) => (0, import_node_fs41.readdirSync)(root, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => {
37575
+ listStagingDirs: (root) => (0, import_node_fs42.readdirSync)(root, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => {
37447
37576
  try {
37448
- return { name: d.name, mtimeMs: newestMtimeMs((0, import_node_path39.join)(root, d.name), listDirEntries, (p) => (0, import_node_fs41.statSync)(p).mtimeMs) };
37577
+ return { name: d.name, mtimeMs: newestMtimeMs((0, import_node_path40.join)(root, d.name), listDirEntries, (p) => (0, import_node_fs42.statSync)(p).mtimeMs) };
37449
37578
  } catch {
37450
37579
  return { name: d.name, mtimeMs: Date.now() };
37451
37580
  }
@@ -37459,10 +37588,10 @@ function stagingApplyFsGuard(configRoot) {
37459
37588
  return {
37460
37589
  referencedPaths: () => readInstalledPluginRefs(configRoot),
37461
37590
  mtimeMs: (name) => {
37462
- const p = (0, import_node_path39.join)(stagingRoot, name);
37463
- if (!(0, import_node_fs41.existsSync)(p)) return null;
37591
+ const p = (0, import_node_path40.join)(stagingRoot, name);
37592
+ if (!(0, import_node_fs42.existsSync)(p)) return null;
37464
37593
  try {
37465
- return newestMtimeMs(p, listDirEntries, (q) => (0, import_node_fs41.statSync)(q).mtimeMs);
37594
+ return newestMtimeMs(p, listDirEntries, (q) => (0, import_node_fs42.statSync)(q).mtimeMs);
37466
37595
  } catch {
37467
37596
  return null;
37468
37597
  }
@@ -37482,13 +37611,13 @@ program2.command("plugin-prune").description(`prune stale cached MMI plugin vers
37482
37611
  return;
37483
37612
  }
37484
37613
  const plan = buildPluginCachePlan(
37485
- (0, import_node_os16.homedir)(),
37614
+ (0, import_node_os17.homedir)(),
37486
37615
  running,
37487
37616
  pluginCacheFsDeps(configRoot, directoryBytes),
37488
37617
  { withBytes: true, configRoot, includeStaging: surface !== "codex" }
37489
37618
  );
37490
37619
  const anythingToDelete = plan.prune.length > 0 || plan.staging.length > 0;
37491
- const result = o.apply && anythingToDelete ? applyPluginCachePlan(plan, (p) => (0, import_node_fs41.rmSync)(p, { recursive: true, force: true }), stagingApplyFsGuard(configRoot)) : void 0;
37620
+ const result = o.apply && anythingToDelete ? applyPluginCachePlan(plan, (p) => (0, import_node_fs42.rmSync)(p, { recursive: true, force: true }), stagingApplyFsGuard(configRoot)) : void 0;
37492
37621
  const warnings = plan.prune.length > 0 ? [CONCURRENT_SESSION_WARNING] : [];
37493
37622
  if (o.json) console.log(JSON.stringify({ ...plan, warnings, applied: result ?? null }));
37494
37623
  else console.log(renderPluginCachePlan(plan, result));
@@ -37496,7 +37625,7 @@ program2.command("plugin-prune").description(`prune stale cached MMI plugin vers
37496
37625
  });
37497
37626
  function readReleaseCatchupState(path2) {
37498
37627
  try {
37499
- const parsed = JSON.parse((0, import_node_fs41.readFileSync)(path2, "utf8"));
37628
+ const parsed = JSON.parse((0, import_node_fs42.readFileSync)(path2, "utf8"));
37500
37629
  return typeof parsed?.checkedAt === "number" ? parsed : void 0;
37501
37630
  } catch {
37502
37631
  return void 0;
@@ -37504,8 +37633,8 @@ function readReleaseCatchupState(path2) {
37504
37633
  }
37505
37634
  function writeReleaseCatchupState(path2, state) {
37506
37635
  try {
37507
- (0, import_node_fs41.mkdirSync)((0, import_node_path39.dirname)(path2), { recursive: true });
37508
- (0, import_node_fs41.writeFileSync)(path2, `${JSON.stringify(state)}
37636
+ (0, import_node_fs42.mkdirSync)((0, import_node_path40.dirname)(path2), { recursive: true });
37637
+ (0, import_node_fs42.writeFileSync)(path2, `${JSON.stringify(state)}
37509
37638
  `);
37510
37639
  } catch {
37511
37640
  }
@@ -37513,7 +37642,7 @@ function writeReleaseCatchupState(path2, state) {
37513
37642
  program2.command("plugin-release-catchup").description("install a newer released MMI plugin clone non-destructively and re-point the Pi registration (#4297); TTL-gated no-op when current").option("--force", "skip the 24h TTL (acceptance proof / manual run)").option("--quiet", "print only failures (the detached session-start lane)").option("--json", "machine-readable output").action(async (o) => {
37514
37643
  const outcome = await withEnvHealLock(
37515
37644
  "plugin release catch-up",
37516
- () => runReleaseCatchup((0, import_node_os16.homedir)(), process.env, {
37645
+ () => runReleaseCatchup((0, import_node_os17.homedir)(), process.env, {
37517
37646
  fetchReleased: fetchNpmReleasedVersion,
37518
37647
  runClaude: (args, step) => runPluginCli("claude", args, (msg) => {
37519
37648
  if (!o.quiet && !o.json) console.log(msg);
@@ -37529,7 +37658,7 @@ program2.command("plugin-release-catchup").description("install a newer released
37529
37658
  },
37530
37659
  readState: readReleaseCatchupState,
37531
37660
  writeState: writeReleaseCatchupState,
37532
- healRegistration: defaultRegistrationHeal((0, import_node_os16.homedir)(), process.env),
37661
+ healRegistration: defaultRegistrationHeal((0, import_node_os17.homedir)(), process.env),
37533
37662
  now: () => Date.now()
37534
37663
  }, { force: o.force })
37535
37664
  );
@@ -37597,7 +37726,7 @@ program2.command("session-start").description("run the SessionStart verbs (whoam
37597
37726
  spawnDetachedSelf(["worktree", "setup", "--quiet"], { spawn: import_node_child_process19.spawn, execPath: process.execPath, scriptPath: process.argv[1] });
37598
37727
  bannerIo.log(worktreeBanner);
37599
37728
  }
37600
- if (shouldSpawnReleaseCatchup((0, import_node_os16.homedir)(), process.env, readReleaseCatchupState)) {
37729
+ if (shouldSpawnReleaseCatchup((0, import_node_os17.homedir)(), process.env, readReleaseCatchupState)) {
37601
37730
  spawnDetachedSelf(["plugin", "release-catchup", "--quiet"], { spawn: import_node_child_process19.spawn, execPath: process.execPath, scriptPath: process.argv[1] });
37602
37731
  }
37603
37732
  if (isLinkedWorktree(process.cwd())) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mutmutco/cli",
3
- "version": "3.105.2",
3
+ "version": "3.105.3",
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",