@mutmutco/hub 4.0.4 → 4.0.6

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/index.cjs +58 -8
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -212,6 +212,17 @@ function resolveNpm(env = process.env) {
212
212
  return cachedNpm;
213
213
  }
214
214
  }
215
+ const bundled = (0, import_node_path2.join)((0, import_node_path2.dirname)(process.execPath), "..", "lib", "node_modules", "npm", "bin", "npm-cli.js");
216
+ if ((0, import_node_fs2.existsSync)(bundled)) {
217
+ cachedNpm = { kind: "node-script", script: bundled };
218
+ return cachedNpm;
219
+ }
220
+ const located = (0, import_node_child_process.spawnSync)("/bin/sh", ["-lc", "command -v npm"], { encoding: "utf8", windowsHide: true });
221
+ const resolved = (located.stdout ?? "").trim().split("\n").map((line) => line.trim()).find(Boolean);
222
+ if (located.status === 0 && resolved && (0, import_node_fs2.existsSync)(resolved)) {
223
+ cachedNpm = { kind: "command", command: resolved };
224
+ return cachedNpm;
225
+ }
215
226
  cachedNpm = { kind: "command", command: "npm" };
216
227
  return cachedNpm;
217
228
  }
@@ -339,11 +350,12 @@ function checkAtomicity(cachePath, tagCommit, bom, candidate, npm) {
339
350
  rows.push({ id: row.id, name, ok: false, detail: `${name}@${candidate} not on npm` });
340
351
  continue;
341
352
  }
342
- if (integrity !== row.identity.value) {
353
+ const legacySsri = /^sha\d+-/.test(row.identity.value ?? "");
354
+ if (legacySsri && integrity !== row.identity.value) {
343
355
  rows.push({ id: row.id, name, ok: false, detail: `${name}@${candidate} dist.integrity differs from BOM identity` });
344
356
  continue;
345
357
  }
346
- rows.push({ id: row.id, name, ok: true, detail: `${name}@${candidate} published, integrity matches` });
358
+ rows.push({ id: row.id, name, ok: true, detail: legacySsri ? `${name}@${candidate} published, integrity matches` : `${name}@${candidate} published` });
347
359
  }
348
360
  return { ok: rows.length > 0 && rows.every((row) => row.ok), rows };
349
361
  }
@@ -548,6 +560,9 @@ var import_node_child_process5 = require("node:child_process");
548
560
  var import_node_fs7 = require("node:fs");
549
561
  var import_node_os3 = require("node:os");
550
562
  var import_node_path6 = require("node:path");
563
+ function convergedAtOrAbove(installed, target, healthy) {
564
+ return healthy && typeof installed === "string" && compareSemver(installed, target) >= 0;
565
+ }
551
566
  function cmdArg(value) {
552
567
  return /^[A-Za-z0-9_@./:\\=+-]+$/.test(value) ? value : `"${value.replaceAll('"', '""')}"`;
553
568
  }
@@ -671,9 +686,12 @@ function claudeArm(options) {
671
686
  }
672
687
  observed = claudeMmi(runner, env);
673
688
  }
674
- if (observed.row?.version !== options.target || observed.row.enabled !== true) {
689
+ if (!convergedAtOrAbove(observed.row?.version, options.target, observed.row?.enabled === true)) {
675
690
  return { surface: "claude", from, to: observed.row?.version ?? "unknown", verdict: "fail", detail: `post-update evidence is version ${observed.row?.version ?? "missing"}, enabled=${String(observed.row?.enabled)}, expected ${options.target}/true` };
676
691
  }
692
+ if (observed.row.version !== options.target) {
693
+ return { surface: "claude", from, to: observed.row.version, verdict: "skip", detail: `installed ${observed.row.version} is above candidate ${options.target} (monotonic)` };
694
+ }
677
695
  return { surface: "claude", from, to: options.target, verdict: "ok", detail: `catalog refreshed; converged and verified ${from ?? "absent"} -> ${options.target}` };
678
696
  }
679
697
  var SNAPSHOT_MISSING = /marketplace snapshot|marketplace root does not contain/i;
@@ -713,9 +731,12 @@ function codexArm(options) {
713
731
  }
714
732
  observed = codexMmi(runner, env);
715
733
  }
716
- if (observed.row?.version !== options.target || observed.row.installed !== true || observed.row.enabled !== true) {
734
+ if (!convergedAtOrAbove(observed.row?.version, options.target, observed.row?.installed === true && observed.row?.enabled === true)) {
717
735
  return { surface: "codex", from, to: observed.row?.version ?? "unknown", verdict: "fail", detail: `post-upgrade evidence is version ${observed.row?.version ?? "missing"}, installed=${String(observed.row?.installed)}, enabled=${String(observed.row?.enabled)}, expected ${options.target}/true/true` };
718
736
  }
737
+ if (observed.row.version !== options.target) {
738
+ return { surface: "codex", from, to: observed.row.version, verdict: "skip", detail: `installed ${observed.row.version} is above candidate ${options.target} (monotonic)` };
739
+ }
719
740
  return { surface: "codex", from, to: options.target, verdict: "ok", detail: `marketplace upgraded; payload refresh and native evidence verified at ${options.target}` };
720
741
  }
721
742
  var KILO_PACKAGE = "@mutmutco/kilo-plugin";
@@ -1965,12 +1986,24 @@ code = shell.Run("""${vbsQuote(nodeExe)}"" ""${vbsQuote(hubDist)}"" update", 0,
1965
1986
  WScript.Quit code
1966
1987
  `;
1967
1988
  }
1968
- function launcherSh(nodeExe, hubDist) {
1989
+ function loginPath(fallback = process.env.PATH ?? "") {
1990
+ const probe = (0, import_node_child_process9.spawnSync)("/bin/sh", ["-lc", 'printf %s "$PATH"'], { encoding: "utf8", windowsHide: true, timeout: 1e4 });
1991
+ const captured = (probe.status === 0 ? probe.stdout ?? "" : "").trim();
1992
+ const source = captured || fallback;
1993
+ const durable = source.split(":").filter((entry) => entry && !/^\/(?:private\/)?(?:tmp|var\/folders)\//.test(entry));
1994
+ return [...new Set(durable)].join(":");
1995
+ }
1996
+ function launcherSh(nodeExe, hubDist, capturedPath = loginPath()) {
1969
1997
  const shQuote = (value) => `'${value.replaceAll("'", `'\\''`)}'`;
1998
+ const pathLine = capturedPath ? `PATH=${shQuote(capturedPath)}:"$PATH"
1999
+ export PATH
2000
+ ` : "";
1970
2001
  return `#!/bin/sh
1971
2002
  # MMI Hub maintenance launcher \u2014 generated by \`mmi-hub autoupdate on\`.
1972
2003
  # The exit code is propagated and reported by \`mmi-hub status\`.
1973
- exec ${shQuote(nodeExe)} ${shQuote(hubDist)} update
2004
+ # PATH is the one captured when autoupdate was enabled: a scheduler's PATH is not the interactive
2005
+ # one, and every surface below is reached through a command that lives outside it (#5278).
2006
+ ${pathLine}exec ${shQuote(nodeExe)} ${shQuote(hubDist)} update
1974
2007
  `;
1975
2008
  }
1976
2009
  function taskXml(launcherPath, workDir, userId, startBoundary) {
@@ -2225,9 +2258,23 @@ function installWindowsTask(env) {
2225
2258
  }
2226
2259
  return { ok: true, detail: `enabled "${TASK_NAME}" \u2014 ${CADENCE} \u2192 ${hubDist}` };
2227
2260
  }
2261
+ function refreshPosixLauncher(env) {
2262
+ const hubDist = globalDist(env, "@mutmutco/hub", "dist/index.cjs");
2263
+ if (!hubDist) return null;
2264
+ const paths = ensureState(env);
2265
+ const launcherPath = (0, import_node_path12.join)(paths.root, POSIX_LAUNCHER_FILE);
2266
+ const desired = launcherSh(process.execPath, hubDist);
2267
+ if (readFileOrNull(launcherPath) === desired) return null;
2268
+ (0, import_node_fs14.writeFileSync)(launcherPath, desired, "utf8");
2269
+ (0, import_node_fs14.chmodSync)(launcherPath, 493);
2270
+ return launcherPath;
2271
+ }
2228
2272
  function installLaunchd(env) {
2229
2273
  const current = darwinSchedulerStatus(env);
2230
- if (current.ok) return { ok: true, detail: `already enabled \u2014 ${current.detail}` };
2274
+ if (current.ok) {
2275
+ const refreshed = refreshPosixLauncher(env);
2276
+ return { ok: true, detail: refreshed ? `already enabled; launcher refreshed \u2014 ${current.detail}` : `already enabled \u2014 ${current.detail}` };
2277
+ }
2231
2278
  const hubDist = globalDist(env, "@mutmutco/hub", "dist/index.cjs");
2232
2279
  if (!hubDist) return { ok: false, detail: "cannot resolve the global @mutmutco/hub dist \u2014 run `npm install -g @mutmutco/hub` first" };
2233
2280
  const paths = ensureState(env);
@@ -2248,7 +2295,10 @@ function installLaunchd(env) {
2248
2295
  }
2249
2296
  function installSystemdTimer(env) {
2250
2297
  const current = linuxSchedulerStatus(env);
2251
- if (current.ok) return { ok: true, detail: `already enabled \u2014 ${current.detail}` };
2298
+ if (current.ok) {
2299
+ const refreshed = refreshPosixLauncher(env);
2300
+ return { ok: true, detail: refreshed ? `already enabled; launcher refreshed \u2014 ${current.detail}` : `already enabled \u2014 ${current.detail}` };
2301
+ }
2252
2302
  const hubDist = globalDist(env, "@mutmutco/hub", "dist/index.cjs");
2253
2303
  if (!hubDist) return { ok: false, detail: "cannot resolve the global @mutmutco/hub dist \u2014 run `npm install -g @mutmutco/hub` first" };
2254
2304
  const paths = ensureState(env);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mutmutco/hub",
3
- "version": "4.0.4",
3
+ "version": "4.0.6",
4
4
  "description": "Install and maintain the MMI CLI and every present host surface from one release-gated Hub command.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",