@mutmutco/hub 4.5.14 → 4.5.16

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 +46 -152
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -26,7 +26,6 @@ __export(index_exports, {
26
26
  buildWatcherCommand: () => buildWatcherCommand,
27
27
  checkAtomicity: () => checkAtomicity,
28
28
  claudeArm: () => claudeArm,
29
- claudeHostEvidence: () => claudeHostEvidence,
30
29
  clearLaunchTarget: () => clearLaunchTarget,
31
30
  clearPending: () => clearPending,
32
31
  createInstallerRun: () => createInstallerRun,
@@ -37,7 +36,6 @@ __export(index_exports, {
37
36
  hermesHome: () => hermesHome,
38
37
  hermesHomes: () => hermesHomes,
39
38
  hermesHostCommand: () => hermesHostCommand,
40
- hermesHostEvidence: () => hermesHostEvidence,
41
39
  hermesHostPresent: () => hermesHostPresent,
42
40
  hubStatus: () => hubStatus,
43
41
  hubStatusReport: () => hubStatusReport,
@@ -88,7 +86,7 @@ __export(index_exports, {
88
86
  writePending: () => writePending
89
87
  });
90
88
  module.exports = __toCommonJS(index_exports);
91
- var import_node_child_process11 = require("node:child_process");
89
+ var import_node_child_process9 = require("node:child_process");
92
90
  var import_node_fs24 = require("node:fs");
93
91
  var import_node_path16 = require("node:path");
94
92
 
@@ -305,35 +303,17 @@ var plainText = (text) => String(text).replaceAll("\u2192", "->").replaceAll("\x
305
303
 
306
304
  // ../installer/face/src/spinner.ts
307
305
  var import_node_fs2 = require("node:fs");
306
+ var import_node_tty = require("node:tty");
308
307
  var import_node_worker_threads = require("node:worker_threads");
309
308
 
310
309
  // ../installer/face/src/encoding.ts
311
- var import_node_child_process = require("node:child_process");
312
310
  var UNICODE_SPINNER_FRAMES = Object.freeze(["\u25D2", "\u25D0", "\u25D3", "\u25D1"]);
313
311
  var ASCII_SPINNER_FRAMES = Object.freeze(["-", "\\", "|", "/"]);
314
- var cachedCodePage;
315
- function consoleOutputCodePage() {
316
- if (cachedCodePage !== void 0) return cachedCodePage;
317
- cachedCodePage = null;
318
- try {
319
- const out = (0, import_node_child_process.execFileSync)("chcp.com", { windowsHide: true, encoding: "utf8", timeout: 5e3 });
320
- const pages = [...String(out).matchAll(/(\d{3,5})/gu)].map((m) => Number(m[1]));
321
- cachedCodePage = pages.length ? pages[pages.length - 1] : null;
322
- } catch {
323
- cachedCodePage = null;
324
- }
325
- return cachedCodePage;
326
- }
327
- function consoleRendersUnicode(env = process.env, platform = process.platform, codePage = platform === "win32" ? consoleOutputCodePage() : null) {
312
+ function consoleRendersUnicode(env = process.env, _platform = process.platform) {
328
313
  if (env.MM_FACE_ASCII === "1" || env.NO_UNICODE === "1") return false;
329
314
  const locale = env.LC_ALL || env.LC_CTYPE || env.LANG || "";
330
315
  if (locale === "C" || locale === "POSIX" || /^C\./u.test(locale) || /^POSIX\./u.test(locale)) return false;
331
316
  if (/cp437|ibm437|\b437\b/iu.test(locale)) return false;
332
- if (/utf-?8/iu.test(locale)) return true;
333
- if (platform === "win32") {
334
- if (env.WT_SESSION || env.ConEmuANSI === "ON") return true;
335
- return codePage === 65001;
336
- }
337
317
  return true;
338
318
  }
339
319
  function spinnerFramesFor(env = process.env, platform = process.platform) {
@@ -344,6 +324,8 @@ function spinnerFramesFor(env = process.env, platform = process.platform) {
344
324
  var WORKER_SOURCE = `
345
325
  const { parentPort, workerData } = require('node:worker_threads');
346
326
  const { writeSync, appendFileSync } = require('node:fs');
327
+ const wide = workerData.wide ? new (require('node:tty').WriteStream)(2) : null;
328
+ const put = (text) => wide ? wide.write(text) : writeSync(2, text);
347
329
  const control = new Int32Array(workerData.control);
348
330
  let frames = workerData.frames, frame = workerData.frame;
349
331
  function draw() {
@@ -351,7 +333,7 @@ function draw() {
351
333
  try {
352
334
  if (Atomics.load(control, 0) || Atomics.load(control, 2) || !frames.length) return;
353
335
  const text = frames[frame++ % frames.length].replace('__elapsed__', Math.floor((Date.now() - workerData.started) / 1000) + 's');
354
- writeSync(2, text);
336
+ put(text);
355
337
  if (workerData.transcriptPath) appendFileSync(workerData.transcriptPath, JSON.stringify({ channel: 'spinner', text }) + '\\n');
356
338
  } finally {
357
339
  Atomics.store(control, 1, 0);
@@ -376,10 +358,12 @@ function createSpinner(face, { animate, stream, intervalMs = 90, transcriptPath,
376
358
  let frame = 0;
377
359
  let started = 0;
378
360
  let suspended = false;
361
+ const wide = process.platform === "win32" && (0, import_node_tty.isatty)(2);
379
362
  const write = (text) => {
380
363
  if (stream) stream.write(text);
381
364
  else {
382
- (0, import_node_fs2.writeSync)(2, text);
365
+ if (wide) process.stderr.write(`\x1B[1G${text}`);
366
+ else (0, import_node_fs2.writeSync)(2, text);
383
367
  if (transcriptPath) (0, import_node_fs2.appendFileSync)(transcriptPath, `${JSON.stringify({ channel: "spinner", text })}
384
368
  `);
385
369
  }
@@ -426,7 +410,8 @@ function createSpinner(face, { animate, stream, intervalMs = 90, transcriptPath,
426
410
  frame,
427
411
  intervalMs,
428
412
  transcriptPath,
429
- started
413
+ started,
414
+ wide
430
415
  } });
431
416
  const active = worker;
432
417
  worker.on("error", () => {
@@ -1276,7 +1261,7 @@ async function runMaintenance(product, args, dependencies) {
1276
1261
  }
1277
1262
 
1278
1263
  // ../installer/launcher/src/refresh.ts
1279
- var import_node_child_process2 = require("node:child_process");
1264
+ var import_node_child_process = require("node:child_process");
1280
1265
  var import_node_fs6 = require("node:fs");
1281
1266
  var import_node_os2 = require("node:os");
1282
1267
  var import_node_path3 = require("node:path");
@@ -1515,7 +1500,7 @@ function parseLauncherVersion(stdout, bin) {
1515
1500
  }
1516
1501
  function runVersion(path, bin) {
1517
1502
  return new Promise((resolve2) => {
1518
- (0, import_node_child_process2.execFile)(path, ["--version"], { timeout: 3e4, windowsHide: true, encoding: "utf8" }, (error, stdout) => {
1503
+ (0, import_node_child_process.execFile)(path, ["--version"], { timeout: 3e4, windowsHide: true, encoding: "utf8" }, (error, stdout) => {
1519
1504
  resolve2(error ? null : parseLauncherVersion(stdout, bin));
1520
1505
  });
1521
1506
  });
@@ -1783,7 +1768,7 @@ function fileExists(path) {
1783
1768
  var import_node_perf_hooks2 = require("node:perf_hooks");
1784
1769
 
1785
1770
  // src/npm.ts
1786
- var import_node_child_process3 = require("node:child_process");
1771
+ var import_node_child_process2 = require("node:child_process");
1787
1772
  var import_node_fs8 = require("node:fs");
1788
1773
  var import_node_path5 = require("node:path");
1789
1774
  var cachedNpm = null;
@@ -1791,7 +1776,7 @@ function resolveNpm(env = process.env) {
1791
1776
  if (env.MMI_UPDATER_NPM) return { kind: "command", command: env.MMI_UPDATER_NPM };
1792
1777
  if (cachedNpm) return cachedNpm;
1793
1778
  if (process.platform === "win32") {
1794
- const where = (0, import_node_child_process3.spawnSync)("where.exe", ["npm.cmd"], { encoding: "utf8", windowsHide: true });
1779
+ const where = (0, import_node_child_process2.spawnSync)("where.exe", ["npm.cmd"], { encoding: "utf8", windowsHide: true });
1795
1780
  const first = where.stdout.split("\n").map((l) => l.trim()).find(Boolean);
1796
1781
  if (where.status === 0 && first) {
1797
1782
  const script = (0, import_node_path5.join)((0, import_node_path5.dirname)(first), "node_modules", "npm", "bin", "npm-cli.js");
@@ -1808,7 +1793,7 @@ function resolveNpm(env = process.env) {
1808
1793
  cachedNpm = { kind: "node-script", script: bundled };
1809
1794
  return cachedNpm;
1810
1795
  }
1811
- const located = (0, import_node_child_process3.spawnSync)("/bin/sh", ["-lc", "command -v npm"], { encoding: "utf8", windowsHide: true });
1796
+ const located = (0, import_node_child_process2.spawnSync)("/bin/sh", ["-lc", "command -v npm"], { encoding: "utf8", windowsHide: true });
1812
1797
  const resolved = (located.stdout ?? "").trim().split("\n").map((line) => line.trim()).find(Boolean);
1813
1798
  if (located.status === 0 && resolved && (0, import_node_fs8.existsSync)(resolved)) {
1814
1799
  cachedNpm = { kind: "command", command: resolved };
@@ -1819,7 +1804,7 @@ function resolveNpm(env = process.env) {
1819
1804
  }
1820
1805
  function runNpm(args, env = process.env, options = {}) {
1821
1806
  const npm = resolveNpm(env);
1822
- const result = npm.kind === "node-script" ? (0, import_node_child_process3.spawnSync)(process.execPath, [npm.script, ...args], { encoding: "utf8", env, cwd: options.cwd, windowsHide: true }) : (0, import_node_child_process3.spawnSync)(npm.command, args, { encoding: "utf8", env, cwd: options.cwd, shell: process.platform === "win32", windowsHide: true });
1807
+ const result = npm.kind === "node-script" ? (0, import_node_child_process2.spawnSync)(process.execPath, [npm.script, ...args], { encoding: "utf8", env, cwd: options.cwd, windowsHide: true }) : (0, import_node_child_process2.spawnSync)(npm.command, args, { encoding: "utf8", env, cwd: options.cwd, shell: process.platform === "win32", windowsHide: true });
1823
1808
  return { status: result.status, stdout: result.stdout ?? "", stderr: result.stderr ?? "" };
1824
1809
  }
1825
1810
  function runNpmAsync(args, env = process.env, options = {}) {
@@ -1830,7 +1815,7 @@ function runNpmAsync(args, env = process.env, options = {}) {
1830
1815
  let stderr = "";
1831
1816
  let child;
1832
1817
  try {
1833
- child = (0, import_node_child_process3.spawn)(file, argv, { env, cwd: options.cwd, windowsHide: true, shell });
1818
+ child = (0, import_node_child_process2.spawn)(file, argv, { env, cwd: options.cwd, windowsHide: true, shell });
1834
1819
  } catch (error) {
1835
1820
  resolve2({ status: null, stdout, stderr: String(error?.message ?? error) });
1836
1821
  return;
@@ -1891,7 +1876,7 @@ function npmVersions(packageName, env = process.env) {
1891
1876
  }
1892
1877
 
1893
1878
  // src/gate.ts
1894
- var import_node_child_process4 = require("node:child_process");
1879
+ var import_node_child_process3 = require("node:child_process");
1895
1880
  var import_node_fs9 = require("node:fs");
1896
1881
  function parseBom(text) {
1897
1882
  const bom = JSON.parse(text);
@@ -1906,16 +1891,16 @@ function npmPackRows(bom) {
1906
1891
  var GateEnvError = class extends Error {
1907
1892
  };
1908
1893
  function git(cachePath, args) {
1909
- const result = (0, import_node_child_process4.spawnSync)("git", ["-C", cachePath, ...args], { encoding: "utf8", windowsHide: true });
1894
+ const result = (0, import_node_child_process3.spawnSync)("git", ["-C", cachePath, ...args], { encoding: "utf8", windowsHide: true });
1910
1895
  return { status: result.status, stdout: (result.stdout ?? "").trim(), stderr: result.stderr ?? "" };
1911
1896
  }
1912
1897
  function ensureBareCache(cachePath, repoUrl) {
1913
- const probe = (0, import_node_child_process4.spawnSync)("git", ["--version"], { encoding: "utf8", windowsHide: true });
1898
+ const probe = (0, import_node_child_process3.spawnSync)("git", ["--version"], { encoding: "utf8", windowsHide: true });
1914
1899
  if (probe.status !== 0) {
1915
1900
  throw new GateEnvError("git is not available \u2014 the release gate needs a git client");
1916
1901
  }
1917
1902
  if (!(0, import_node_fs9.existsSync)(cachePath)) {
1918
- const init = (0, import_node_child_process4.spawnSync)("git", ["init", "--bare", cachePath], { encoding: "utf8", windowsHide: true });
1903
+ const init = (0, import_node_child_process3.spawnSync)("git", ["init", "--bare", cachePath], { encoding: "utf8", windowsHide: true });
1919
1904
  if (init.status !== 0) throw new GateEnvError(`cannot create bare cache at ${cachePath}: ${init.stderr}`);
1920
1905
  }
1921
1906
  }
@@ -2026,18 +2011,18 @@ var import_node_os5 = require("node:os");
2026
2011
  var import_node_path10 = require("node:path");
2027
2012
 
2028
2013
  // src/arm-host-plugins.ts
2029
- var import_node_child_process7 = require("node:child_process");
2014
+ var import_node_child_process6 = require("node:child_process");
2030
2015
  var import_node_fs13 = require("node:fs");
2031
2016
  var import_node_os4 = require("node:os");
2032
2017
  var import_node_path9 = require("node:path");
2033
2018
 
2034
2019
  // src/arm-npm-global.ts
2035
2020
  var import_node_fs11 = require("node:fs");
2036
- var import_node_child_process6 = require("node:child_process");
2021
+ var import_node_child_process5 = require("node:child_process");
2037
2022
  var import_node_path7 = require("node:path");
2038
2023
 
2039
2024
  // src/pending.ts
2040
- var import_node_child_process5 = require("node:child_process");
2025
+ var import_node_child_process4 = require("node:child_process");
2041
2026
  var import_node_fs10 = require("node:fs");
2042
2027
  var import_node_path6 = require("node:path");
2043
2028
  function hubDistPath(env) {
@@ -2118,7 +2103,7 @@ function buildWatcherCommand(opts) {
2118
2103
  return { file: "sh", args: ["-c", `${testBusy}; ${wait}; ${lock}; ${run}`] };
2119
2104
  }
2120
2105
  function defaultDetachSpawn(file, args) {
2121
- const child = (0, import_node_child_process5.spawn)(file, [...args], {
2106
+ const child = (0, import_node_child_process4.spawn)(file, [...args], {
2122
2107
  detached: process.platform !== "win32",
2123
2108
  stdio: "ignore",
2124
2109
  windowsHide: true,
@@ -2185,7 +2170,7 @@ function globalDist(env, packageName, distRel) {
2185
2170
  }
2186
2171
  function probeVersion(distPath) {
2187
2172
  if (!fileExists(distPath)) return null;
2188
- const probe = (0, import_node_child_process6.spawnSync)(process.execPath, [distPath, "--version"], { encoding: "utf8", windowsHide: true });
2173
+ const probe = (0, import_node_child_process5.spawnSync)(process.execPath, [distPath, "--version"], { encoding: "utf8", windowsHide: true });
2189
2174
  const version = (probe.stdout || "").trim();
2190
2175
  return probe.status === 0 && /^\d+\.\d+\.\d+/.test(version) ? version : null;
2191
2176
  }
@@ -2331,13 +2316,13 @@ function cmdArg(value) {
2331
2316
  return /^[A-Za-z0-9_@./:\\=+-]+$/.test(value) ? value : `"${value.replaceAll('"', '""')}"`;
2332
2317
  }
2333
2318
  var runHostCommand = (command, args, env) => {
2334
- const result = process.platform === "win32" ? (0, import_node_child_process7.spawnSync)("cmd.exe", ["/d", "/s", "/c", [command, ...args].map(cmdArg).join(" ")], {
2319
+ const result = process.platform === "win32" ? (0, import_node_child_process6.spawnSync)("cmd.exe", ["/d", "/s", "/c", [command, ...args].map(cmdArg).join(" ")], {
2335
2320
  encoding: "utf8",
2336
2321
  env,
2337
2322
  input: "",
2338
2323
  timeout: 12e4,
2339
2324
  windowsHide: true
2340
- }) : (0, import_node_child_process7.spawnSync)(command, args, {
2325
+ }) : (0, import_node_child_process6.spawnSync)(command, args, {
2341
2326
  encoding: "utf8",
2342
2327
  env,
2343
2328
  input: "",
@@ -2411,32 +2396,8 @@ function claudeMarkerVersion(root) {
2411
2396
  function claudeTreeHealthy(root) {
2412
2397
  return CLAUDE_TREE_MARKERS.every((rel) => fileExists((0, import_node_path9.join)(root, ...rel.split("/"))));
2413
2398
  }
2414
- var CLAUDE_PROCESS_SEGMENT = /^claude(-code|-cli)?(\.(exe|cmd|bat|ps1|js|mjs|cjs|py))?$/i;
2415
- var HUB_UPDATE_COMMAND = /(?:\bmmi-hub(?:\.(?:cmd|exe|bat|ps1))?\b|@mutmutco[/\\]hub[/\\]dist[/\\]index\.(?:cjs|mjs|js))[\s'"]+update\b/i;
2416
- function claudeProcessToken(line) {
2417
- if (HUB_UPDATE_COMMAND.test(line)) return null;
2418
- for (const token of line.replace(/["']/g, " ").split(/\s+/)) {
2419
- for (const segment of token.split(/[/\\]/)) {
2420
- if (CLAUDE_PROCESS_SEGMENT.test(segment)) return segment;
2421
- }
2422
- }
2423
- return null;
2424
- }
2425
- function realClaudeProcessListing() {
2426
- const result = process.platform === "win32" ? (0, import_node_child_process7.spawnSync)("powershell.exe", ["-NoProfile", "-Command", "Get-CimInstance Win32_Process | ForEach-Object { $_.Name + ' ' + $_.CommandLine }"], { encoding: "utf8", windowsHide: true, timeout: 15e3 }) : (0, import_node_child_process7.spawnSync)("ps", ["-eo", "args="], { encoding: "utf8", windowsHide: true, timeout: 15e3 });
2427
- return result.status === 0 ? result.stdout ?? "" : null;
2428
- }
2429
- function claudeHostEvidence(env, processListProvider) {
2430
- for (const marker of ["CLAUDE_CODE_SESSION_ID", "CLAUDECODE", "CLAUDE_PLUGIN_ROOT"]) {
2431
- if (env[marker]?.trim()) return `env marker ${marker}`;
2432
- }
2433
- const listing = processListProvider ? processListProvider() : realClaudeProcessListing();
2434
- if (listing === null || !listing.trim()) return "the process list is unreadable (unsafe to write)";
2435
- for (const line of listing.split(/\r?\n/)) {
2436
- const token = claudeProcessToken(line);
2437
- if (token) return `a live process names claude (${token})`;
2438
- }
2439
- return null;
2399
+ function claudeNpmEnv(env) {
2400
+ return { ...env, npm_config_allow_remote: "all" };
2440
2401
  }
2441
2402
  function probeClaudeLaunchStaging(env = process.env) {
2442
2403
  return probeLaunchTargetVersion((0, import_node_path9.join)(claudePluginsRoot(env), "staging", "launch-target.json"), claudeMarkerVersion);
@@ -2447,14 +2408,12 @@ function claudeArm(options) {
2447
2408
  const paths = options.paths ?? ensureState(env);
2448
2409
  const target = options.target;
2449
2410
  const repoUrl = options.repoUrl ?? (env.MMI_UPDATER_REPO || REPO_URL_DEFAULT);
2450
- const home = claudeHomeDir(env);
2451
- const result = (from2, to, verdict, detail, launchStaged = false) => ({
2411
+ const result = (from2, to, verdict, detail) => ({
2452
2412
  surface: "claude",
2453
2413
  from: from2,
2454
2414
  to,
2455
2415
  verdict,
2456
- detail,
2457
- launchStaged: launchStaged || void 0
2416
+ detail
2458
2417
  });
2459
2418
  const before = claudeMmi(runner, env);
2460
2419
  if (before.error) return result(null, target, "defer", before.error);
@@ -2510,32 +2469,6 @@ function claudeArm(options) {
2510
2469
  return result(from, target, "defer", "incoming Claude generation did not reproduce the verified payload");
2511
2470
  }
2512
2471
  }
2513
- const busy = claudeHostEvidence(env, options.processListProvider);
2514
- if (busy) {
2515
- const pending = noteLaunchStaged(paths, env, {
2516
- surface: "claude",
2517
- target,
2518
- reason: busy,
2519
- launchTargetPath,
2520
- incoming,
2521
- images: ["claude"],
2522
- dirs: [home]
2523
- });
2524
- return result(from, target, "ok", `staged ${target} for next launch while Claude Code is running (${busy}) \u2014 ${pending}`, true);
2525
- }
2526
- const started = claudeHostEvidence(env, options.processListProvider);
2527
- if (started) {
2528
- const pending = noteLaunchStaged(paths, env, {
2529
- surface: "claude",
2530
- target,
2531
- reason: started,
2532
- launchTargetPath,
2533
- incoming,
2534
- images: ["claude"],
2535
- dirs: [home]
2536
- });
2537
- return result(from, target, "ok", `staged ${target} for next launch \u2014 Claude Code started during staging (${started}) \u2014 ${pending}`, true);
2538
- }
2539
2472
  const cacheTarget = (0, import_node_path9.join)(pluginsRoot, "cache", "mutmutco", "mmi", target);
2540
2473
  try {
2541
2474
  if (!(0, import_node_fs13.existsSync)(cacheTarget) || claudeMarkerVersion(cacheTarget) !== target || !claudeTreeHealthy(cacheTarget)) {
@@ -2548,7 +2481,7 @@ function claudeArm(options) {
2548
2481
  }
2549
2482
  const scope = observed.row?.scope || before.row?.scope || "user";
2550
2483
  const command = observed.row ? ["plugin", "update", "mmi@mutmutco", "--scope", scope] : ["plugin", "install", "mmi@mutmutco", "--scope", scope];
2551
- const converge = runner("claude", command, env);
2484
+ const converge = runner("claude", command, claudeNpmEnv(env));
2552
2485
  if (converge.status !== 0) {
2553
2486
  return result(from, target, "defer", `${observed.row ? "plugin update" : "plugin install"} failed: ${failure(converge)}`);
2554
2487
  }
@@ -2688,7 +2621,7 @@ function enumerateSurfaces(env = process.env) {
2688
2621
 
2689
2622
  // src/arm-cursor.ts
2690
2623
  var import_node_fs17 = require("node:fs");
2691
- var import_node_child_process8 = require("node:child_process");
2624
+ var import_node_child_process7 = require("node:child_process");
2692
2625
  var import_node_os7 = require("node:os");
2693
2626
  var import_node_path11 = require("node:path");
2694
2627
 
@@ -2871,7 +2804,7 @@ function cursorHostEvidence(env) {
2871
2804
  if (env[marker]?.trim()) return `env marker ${marker}`;
2872
2805
  }
2873
2806
  if (env.CURSOR_AGENT === "1") return "env marker CURSOR_AGENT=1";
2874
- const result = process.platform === "win32" ? (0, import_node_child_process8.spawnSync)("powershell.exe", ["-NoProfile", "-Command", "Get-CimInstance Win32_Process | ForEach-Object { $_.CommandLine }"], { encoding: "utf8", windowsHide: true, timeout: 15e3 }) : (0, import_node_child_process8.spawnSync)("ps", ["-eo", "args="], { encoding: "utf8", windowsHide: true, timeout: 15e3 });
2807
+ const result = process.platform === "win32" ? (0, import_node_child_process7.spawnSync)("powershell.exe", ["-NoProfile", "-Command", "Get-CimInstance Win32_Process | ForEach-Object { $_.CommandLine }"], { encoding: "utf8", windowsHide: true, timeout: 15e3 }) : (0, import_node_child_process7.spawnSync)("ps", ["-eo", "args="], { encoding: "utf8", windowsHide: true, timeout: 15e3 });
2875
2808
  if (result.status !== 0 || !(result.stdout ?? "").trim()) return "the process table is unreadable (unsafe to write)";
2876
2809
  for (const line of result.stdout.split(/\r?\n/)) {
2877
2810
  const executable = cursorExecutable(line);
@@ -3268,7 +3201,6 @@ function jervcodeArm(options) {
3268
3201
 
3269
3202
  // src/arm-hermes.ts
3270
3203
  var import_node_fs19 = require("node:fs");
3271
- var import_node_child_process9 = require("node:child_process");
3272
3204
  var import_node_path13 = require("node:path");
3273
3205
  var PACKAGE2 = "@mutmutco/hermes-plugin";
3274
3206
  var MANIFEST2 = "plugin.yaml";
@@ -3342,30 +3274,6 @@ function discard2(path) {
3342
3274
  function message2(error) {
3343
3275
  return String(error?.message ?? error).replace(/\s+/g, " ").slice(0, 200);
3344
3276
  }
3345
- var HERMES_PROCESS_SEGMENT = /^hermes(-cli|-code)?(\.(exe|cmd|bat|ps1|js|mjs|cjs|py))?$/i;
3346
- var HUB_UPDATE_COMMAND2 = /(?:\bmmi-hub(?:\.(?:cmd|exe|bat|ps1))?\b|@mutmutco[/\\]hub[/\\]dist[/\\]index\.(?:cjs|mjs|js))[\s'"]+update\b/i;
3347
- function hermesProcessToken(line, home) {
3348
- const normalized = line.replace(/["']/g, " ");
3349
- const tokens = normalized.split(/\s+/);
3350
- const hermesToken = (candidates) => candidates.find((token) => token && token.split(/[/\\]/).some((segment) => HERMES_PROCESS_SEGMENT.test(segment))) ?? null;
3351
- const direct = hermesToken(tokens.slice(0, 2));
3352
- if (direct) return direct;
3353
- if (HUB_UPDATE_COMMAND2.test(line)) return null;
3354
- return hermesToken(tokens) ?? (home && normalized.toLowerCase().includes(home.toLowerCase()) ? home : null);
3355
- }
3356
- function realProcessListing() {
3357
- const result = process.platform === "win32" ? (0, import_node_child_process9.spawnSync)("powershell.exe", ["-NoProfile", "-Command", "Get-CimInstance Win32_Process | ForEach-Object { $_.Name + ' ' + $_.CommandLine }"], { encoding: "utf8", windowsHide: true, timeout: 15e3 }) : (0, import_node_child_process9.spawnSync)("ps", ["-eo", "args="], { encoding: "utf8", windowsHide: true, timeout: 15e3 });
3358
- return result.status === 0 ? result.stdout ?? "" : null;
3359
- }
3360
- function hermesHostEvidence(env, home, processListProvider) {
3361
- const listing = processListProvider ? processListProvider() : realProcessListing();
3362
- if (listing === null || !listing.trim()) return "the process list is unreadable (unsafe to write)";
3363
- for (const line of listing.split(/\r?\n/)) {
3364
- const token = hermesProcessToken(line, home);
3365
- if (token) return `a live process names hermes (${token})`;
3366
- }
3367
- return null;
3368
- }
3369
3277
  function materializeHermesSkills(home) {
3370
3278
  const pluginSkills = (0, import_node_path13.join)(home, "plugins", "mmi", "skills");
3371
3279
  const skillsRoot = (0, import_node_path13.join)(home, "skills");
@@ -3501,20 +3409,8 @@ function armHermesHome(home, env, options, primary) {
3501
3409
  }
3502
3410
  }
3503
3411
  const displaced = (0, import_node_fs19.existsSync)(live);
3504
- const busy = displaced ? hermesHostEvidence(env, home, options.processListProvider) : null;
3505
- if (busy) {
3506
- const pending = noteLaunchStaged(options.paths, env, {
3507
- surface: "hermes",
3508
- target: options.target,
3509
- reason: busy,
3510
- launchTargetPath,
3511
- incoming,
3512
- images: ["hermes"],
3513
- dirs: [home]
3514
- });
3515
- return result(installed, options.target, "ok", `staged ${options.target} for next launch while Hermes is running (${busy}) \u2014 ${pending}`, true);
3516
- }
3517
3412
  try {
3413
+ (0, import_node_fs19.mkdirSync)((0, import_node_path13.join)(scratch, "quarantine"), { recursive: true });
3518
3414
  if (displaced) (0, import_node_fs19.renameSync)(live, quarantine);
3519
3415
  (0, import_node_fs19.renameSync)(incoming, live);
3520
3416
  } catch (error) {
@@ -3547,7 +3443,7 @@ function armHermesHome(home, env, options, primary) {
3547
3443
  if (!skills.ok) return result(installed, options.target, "fail", `plugin converged to ${options.target}, but skills provisioning failed: ${skills.detail}`);
3548
3444
  const enabled = enableHermesPlugin(env, hostRunner);
3549
3445
  if (!enabled.ok) return result(installed, options.target, "fail", `plugin converged to ${options.target}, but ${enabled.detail}`);
3550
- return result(installed, options.target, "ok", `converged ${installed ?? "absent"} -> ${options.target} (staged, verified, atomically switched${displaced ? `; previous generation quarantined at ${quarantine}` : ""}); ${skills.detail}; ${enabled.detail}`);
3446
+ return result(installed, options.target, "ok", `converged ${installed ?? "absent"} -> ${options.target} (staged, verified, switched${displaced ? `; previous generation quarantined at ${quarantine}` : ""}); ${skills.detail}; ${enabled.detail}`);
3551
3447
  }
3552
3448
  function probeHermesLaunchStaging(env = process.env) {
3553
3449
  return probeLaunchTargetVersion((0, import_node_path13.join)(hermesHome(env), ".mmi-updater", "launch-target.json"), yamlVersion);
@@ -3869,7 +3765,7 @@ async function reconcile(options) {
3869
3765
  }
3870
3766
 
3871
3767
  // src/scheduler.ts
3872
- var import_node_child_process10 = require("node:child_process");
3768
+ var import_node_child_process8 = require("node:child_process");
3873
3769
  var import_node_fs21 = require("node:fs");
3874
3770
  var import_node_os8 = require("node:os");
3875
3771
  var import_node_path15 = require("node:path");
@@ -3888,15 +3784,15 @@ var SYSTEMD_UNIT = "mmi-hub-updater";
3888
3784
  var SYSTEMD_SERVICE_NAME = `${SYSTEMD_UNIT}.service`;
3889
3785
  var SYSTEMD_TIMER_NAME = `${SYSTEMD_UNIT}.timer`;
3890
3786
  function schtasks(args) {
3891
- const result = (0, import_node_child_process10.spawnSync)("schtasks.exe", args, { encoding: "utf8", windowsHide: true });
3787
+ const result = (0, import_node_child_process8.spawnSync)("schtasks.exe", args, { encoding: "utf8", windowsHide: true });
3892
3788
  return { status: result.status, stdout: result.stdout ?? "", stderr: result.stderr ?? "" };
3893
3789
  }
3894
3790
  function launchctl(args) {
3895
- const result = (0, import_node_child_process10.spawnSync)("launchctl", args, { encoding: "utf8", windowsHide: true });
3791
+ const result = (0, import_node_child_process8.spawnSync)("launchctl", args, { encoding: "utf8", windowsHide: true });
3896
3792
  return { status: result.status, stdout: result.stdout ?? "", stderr: result.stderr ?? "" };
3897
3793
  }
3898
3794
  function systemctlUser(args) {
3899
- const result = (0, import_node_child_process10.spawnSync)("systemctl", ["--user", ...args], { encoding: "utf8", windowsHide: true });
3795
+ const result = (0, import_node_child_process8.spawnSync)("systemctl", ["--user", ...args], { encoding: "utf8", windowsHide: true });
3900
3796
  return { status: result.status, stdout: result.stdout ?? "", stderr: result.stderr ?? "" };
3901
3797
  }
3902
3798
  function uid() {
@@ -3921,7 +3817,7 @@ WScript.Quit code
3921
3817
  `;
3922
3818
  }
3923
3819
  function loginPath(fallback = process.env.PATH ?? "") {
3924
- const probe = (0, import_node_child_process10.spawnSync)("/bin/sh", ["-lc", 'printf %s "$PATH"'], { encoding: "utf8", windowsHide: true, timeout: 1e4 });
3820
+ const probe = (0, import_node_child_process8.spawnSync)("/bin/sh", ["-lc", 'printf %s "$PATH"'], { encoding: "utf8", windowsHide: true, timeout: 1e4 });
3925
3821
  const captured = (probe.status === 0 ? probe.stdout ?? "" : "").trim();
3926
3822
  const source = captured || fallback;
3927
3823
  const durable = source.split(":").filter((entry) => entry && !/^\/(?:private\/)?(?:tmp|var\/folders)\//.test(entry));
@@ -4042,7 +3938,7 @@ function elevatedRelaunch(mode, env) {
4042
3938
  if (env.MMI_UPDATER_ELEVATED_RETRY === "1") return false;
4043
3939
  const self = process.argv[1];
4044
3940
  const command = self ? `"${process.execPath}" "${self}" autoupdate ${mode}` : `mmi-hub autoupdate ${mode}`;
4045
- const relaunch = (0, import_node_child_process10.spawnSync)(
3941
+ const relaunch = (0, import_node_child_process8.spawnSync)(
4046
3942
  "powershell.exe",
4047
3943
  ["-NoProfile", "-Command", `Start-Process -Verb RunAs -Wait -WindowStyle Hidden -FilePath 'cmd.exe' -ArgumentList '/c',${psQuote(`set MMI_UPDATER_ELEVATED_RETRY=1&& ${command}`)}`],
4048
3944
  { encoding: "utf8", windowsHide: true }
@@ -4053,7 +3949,7 @@ var NEVER_RUN_RESULT = 267011;
4053
3949
  var NEVER_RUN_YEAR = 1999;
4054
3950
  var EMPTY_RUN_INFO = { lastRunTime: null, lastTaskResult: null, nextRunTime: null };
4055
3951
  function taskRunInfo() {
4056
- const result = (0, import_node_child_process10.spawnSync)(
3952
+ const result = (0, import_node_child_process8.spawnSync)(
4057
3953
  "powershell.exe",
4058
3954
  ["-NoProfile", "-Command", `$stamp = { param($t) if ($t) { $t.ToString('yyyy-MM-dd HH:mm:ss') } }; Get-ScheduledTaskInfo -TaskName '${TASK_NAME}' | Select-Object @{n='LastRunTime';e={& $stamp $_.LastRunTime}},LastTaskResult,@{n='NextRunTime';e={& $stamp $_.NextRunTime}} | ConvertTo-Json -Compress`],
4059
3955
  { encoding: "utf8", windowsHide: true, timeout: 3e4 }
@@ -4624,7 +4520,7 @@ function notice(screen, render) {
4624
4520
  printScreen(renderNotice(FACE, screen, render), screen.state === "fail" ? "stderr" : "stdout");
4625
4521
  }
4626
4522
  function handOff(reexec, args, env) {
4627
- const child = (0, import_node_child_process11.spawnSync)(process.execPath, [reexec.dist, ...args], {
4523
+ const child = (0, import_node_child_process9.spawnSync)(process.execPath, [reexec.dist, ...args], {
4628
4524
  stdio: "inherit",
4629
4525
  windowsHide: true,
4630
4526
  env: { ...env, MMI_UPDATER_REEXEC: "1" }
@@ -4714,7 +4610,6 @@ if (typeof require !== "undefined" && require.main === module) {
4714
4610
  buildWatcherCommand,
4715
4611
  checkAtomicity,
4716
4612
  claudeArm,
4717
- claudeHostEvidence,
4718
4613
  clearLaunchTarget,
4719
4614
  clearPending,
4720
4615
  createInstallerRun,
@@ -4725,7 +4620,6 @@ if (typeof require !== "undefined" && require.main === module) {
4725
4620
  hermesHome,
4726
4621
  hermesHomes,
4727
4622
  hermesHostCommand,
4728
- hermesHostEvidence,
4729
4623
  hermesHostPresent,
4730
4624
  hubStatus,
4731
4625
  hubStatusReport,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mutmutco/hub",
3
- "version": "4.5.14",
3
+ "version": "4.5.16",
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",