@mutmutco/hub 4.5.29 → 4.5.31

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 +308 -611
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -66,7 +66,6 @@ __export(index_exports, {
66
66
  renderNotice: () => renderNotice,
67
67
  renderReport: () => renderReport,
68
68
  reportCounts: () => reportCounts,
69
- resolvePayloadTarball: () => resolvePayloadTarball,
70
69
  retiredSurfaces: () => retiredSurfaces,
71
70
  retryHint: () => retryHint,
72
71
  runMaintenance: () => runMaintenance2,
@@ -76,7 +75,6 @@ __export(index_exports, {
76
75
  sharedDocLockTimeoutReceipt: () => sharedDocLockTimeoutReceipt,
77
76
  shippedTargetFrom: () => shippedTargetFrom,
78
77
  shouldHandOff: () => shouldHandOff,
79
- stagePackage: () => stagePackage,
80
78
  statusScreen: () => statusScreen,
81
79
  surfaceArmPlan: () => surfaceArmPlan,
82
80
  systemdServiceUnit: () => systemdServiceUnit,
@@ -89,8 +87,8 @@ __export(index_exports, {
89
87
  });
90
88
  module.exports = __toCommonJS(index_exports);
91
89
  var import_node_child_process9 = require("node:child_process");
92
- var import_node_fs27 = require("node:fs");
93
- var import_node_path18 = require("node:path");
90
+ var import_node_fs24 = require("node:fs");
91
+ var import_node_path16 = require("node:path");
94
92
 
95
93
  // ../installer/face/src/face.ts
96
94
  var import_node_fs = require("node:fs");
@@ -1081,6 +1079,7 @@ async function runMaintenance(product, args, dependencies) {
1081
1079
  const quiet = args.includes("--quiet");
1082
1080
  const dryRun = args.includes("--dry-run");
1083
1081
  const installed = args.includes("install");
1082
+ const verbose = !quiet && !json && args.includes("--verbose");
1084
1083
  const render = dependencies.render;
1085
1084
  const env = render?.env ?? process.env;
1086
1085
  const tty = render?.tty ?? Boolean(process.stdout.isTTY);
@@ -1116,7 +1115,7 @@ async function runMaintenance(product, args, dependencies) {
1116
1115
  phaseStarted.delete(event.id);
1117
1116
  if (active === event.id) active = void 0;
1118
1117
  }
1119
- if (!quiet && event.state === "running" && event.detail) run?.relay(event.detail);
1118
+ if (verbose && event.state === "running" && event.detail) run?.relay(event.detail, "stderr", false);
1120
1119
  const measured = event.measured;
1121
1120
  const measure = measured?.kind === "percent" ? `${Math.max(0, Math.min(100, Math.round(measured.percent)))}%` : measured?.kind === "bytes" ? `${measured.done}/${measured.total} B` : measured?.kind === "count" ? `${measured.done}${measured.total === void 0 ? "" : `/${measured.total}`}` : event.measure;
1122
1121
  const facts = {
@@ -1264,14 +1263,14 @@ async function runMaintenance(product, args, dependencies) {
1264
1263
 
1265
1264
  // ../installer/launcher/src/refresh.ts
1266
1265
  var import_node_child_process = require("node:child_process");
1267
- var import_node_fs8 = require("node:fs");
1266
+ var import_node_fs6 = require("node:fs");
1268
1267
  var import_node_os2 = require("node:os");
1269
- var import_node_path4 = require("node:path");
1268
+ var import_node_path3 = require("node:path");
1270
1269
 
1271
1270
  // ../installer/launcher/src/acquisition.ts
1272
1271
  var import_node_crypto2 = require("node:crypto");
1273
- var import_node_fs7 = require("node:fs");
1274
- var import_node_path3 = require("node:path");
1272
+ var import_node_fs5 = require("node:fs");
1273
+ var import_node_path2 = require("node:path");
1275
1274
 
1276
1275
  // ../installer/launcher/src/download.ts
1277
1276
  async function readDownload(response, onProgress, expectedSize) {
@@ -1292,7 +1291,6 @@ async function readDownload(response, onProgress, expectedSize) {
1292
1291
  }
1293
1292
 
1294
1293
  // ../installer/launcher/src/store.ts
1295
- var import_node_fs5 = require("node:fs");
1296
1294
  var import_node_os = require("node:os");
1297
1295
  var import_node_path = require("node:path");
1298
1296
  function defaultProductDir(product) {
@@ -1303,40 +1301,9 @@ function defaultProductDir(product) {
1303
1301
  const home = process.env.HOME ?? (0, import_node_os.tmpdir)();
1304
1302
  return (0, import_node_path.join)(home, `.${product}`);
1305
1303
  }
1306
- function tokensPath(dir) {
1307
- return (0, import_node_path.join)(dir, "tokens.json");
1308
- }
1309
- function readTokens(dir) {
1310
- try {
1311
- const data = JSON.parse((0, import_node_fs5.readFileSync)(tokensPath(dir), "utf8"));
1312
- if (typeof data.accessToken !== "string" || !data.accessToken) return null;
1313
- if (typeof data.expiresAt !== "number" || !Number.isFinite(data.expiresAt)) return null;
1314
- const tokens = { accessToken: data.accessToken, expiresAt: data.expiresAt };
1315
- if (typeof data.refreshToken === "string" && data.refreshToken) tokens.refreshToken = data.refreshToken;
1316
- if (typeof data.clientId === "string" && data.clientId) tokens.clientId = data.clientId;
1317
- return tokens;
1318
- } catch {
1319
- return null;
1320
- }
1321
- }
1322
- function writeTokens(dir, tokens) {
1323
- (0, import_node_fs5.mkdirSync)(dir, { recursive: true });
1324
- try {
1325
- (0, import_node_fs5.writeFileSync)(tokensPath(dir), `${JSON.stringify(tokens)}
1326
- `, { mode: 384 });
1327
- } catch {
1328
- (0, import_node_fs5.writeFileSync)(tokensPath(dir), `${JSON.stringify(tokens)}
1329
- `);
1330
- }
1331
- }
1332
- function clearTokens(dir) {
1333
- (0, import_node_fs5.rmSync)(tokensPath(dir), { force: true });
1334
- }
1335
1304
 
1336
1305
  // ../installer/launcher/src/payload.ts
1337
1306
  var import_node_crypto = require("node:crypto");
1338
- var import_node_fs6 = require("node:fs");
1339
- var import_node_path2 = require("node:path");
1340
1307
 
1341
1308
  // ../installer/launcher/src/canonical.ts
1342
1309
  function canonicalJson(value) {
@@ -1374,18 +1341,6 @@ function publicKeyBytes(config) {
1374
1341
  }
1375
1342
 
1376
1343
  // ../installer/launcher/src/payload.ts
1377
- var NeedsLoginError = class extends Error {
1378
- constructor() {
1379
- super("signed out \u2014 run login first");
1380
- this.name = "NeedsLoginError";
1381
- }
1382
- };
1383
- var ForbiddenError = class extends Error {
1384
- constructor() {
1385
- super("this install is not allowed for your account \u2014 access was revoked or never granted.");
1386
- this.name = "ForbiddenError";
1387
- }
1388
- };
1389
1344
  function canonicalManifestBytes(manifest2) {
1390
1345
  return Buffer.from(
1391
1346
  canonicalJson({
@@ -1416,26 +1371,6 @@ function verifyFileBytes(entry, bytes) {
1416
1371
  if (entry.size !== bytes.length) return false;
1417
1372
  return (0, import_node_crypto.createHash)("sha256").update(bytes).digest("hex") === entry.sha256.toLowerCase();
1418
1373
  }
1419
- async function readErrorCode(response) {
1420
- try {
1421
- const data = await response.json();
1422
- return typeof data.error === "string" ? data.error : "";
1423
- } catch {
1424
- return "";
1425
- }
1426
- }
1427
- function throwForStatus(status, errorCode) {
1428
- if (status === 401) throw new NeedsLoginError();
1429
- if (status === 403) throw new ForbiddenError();
1430
- throw new Error(
1431
- errorCode ? `the release server refused the request (${status}: ${errorCode})` : `the release server refused the request (${status})`
1432
- );
1433
- }
1434
- async function getJson(url, accessToken, fetchImpl) {
1435
- const response = await fetchImpl(url, { headers: { authorization: `Bearer ${accessToken}` } });
1436
- if (!response.ok) throwForStatus(response.status, await readErrorCode(response));
1437
- return { status: response.status, json: await response.json() };
1438
- }
1439
1374
  function parseManifest(json) {
1440
1375
  if (typeof json !== "object" || json === null) throw new Error("the release manifest is not an object");
1441
1376
  const record = json;
@@ -1465,42 +1400,24 @@ function safeManifestPath(rawPath) {
1465
1400
  }
1466
1401
  return segments.join("/");
1467
1402
  }
1468
- async function fetchVerifiedManifest(config, accessToken, fetchImpl = fetch) {
1469
- const { json } = await getJson(`${config.host}/release/manifest`, accessToken, fetchImpl);
1470
- const manifest2 = parseManifest(json);
1471
- if (!verifyManifest(manifest2, manifest2.signature, config)) {
1472
- throw new Error("the release manifest signature is invalid \u2014 refusing to install anything.");
1473
- }
1474
- return manifest2;
1475
- }
1476
- var VERSION_CACHE_RE = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
1477
- function versionCacheRoot(dir, version) {
1478
- return VERSION_CACHE_RE.test(version) ? (0, import_node_path2.join)(dir, "payload-cache", version) : "";
1479
- }
1480
- function cachedPayloadForVersion(dir, version) {
1481
- const root = versionCacheRoot(dir, version);
1482
- if (!root) return null;
1483
- const payload = (0, import_node_path2.join)(root, "payload");
1484
- return (0, import_node_fs6.existsSync)(payload) ? payload : null;
1485
- }
1486
1403
 
1487
1404
  // ../installer/launcher/src/acquisition.ts
1488
1405
  function lockInstallation(dir) {
1489
- (0, import_node_fs7.mkdirSync)(dir, { recursive: true });
1490
- const path = (0, import_node_path3.join)(dir, "installation.lock");
1406
+ (0, import_node_fs5.mkdirSync)(dir, { recursive: true });
1407
+ const path = (0, import_node_path2.join)(dir, "installation.lock");
1491
1408
  const owner = `${process.pid}:${(0, import_node_crypto2.randomUUID)()}`;
1492
1409
  try {
1493
- (0, import_node_fs7.writeFileSync)(path, owner, { flag: "wx", mode: 384 });
1410
+ (0, import_node_fs5.writeFileSync)(path, owner, { flag: "wx", mode: 384 });
1494
1411
  } catch (error) {
1495
1412
  if (error.code !== "EEXIST") throw error;
1496
1413
  const recovery = `${path}.recovery`;
1497
1414
  try {
1498
- (0, import_node_fs7.writeFileSync)(recovery, owner, { flag: "wx", mode: 384, flush: true });
1415
+ (0, import_node_fs5.writeFileSync)(recovery, owner, { flag: "wx", mode: 384, flush: true });
1499
1416
  } catch {
1500
1417
  throw new Error("installation lock recovery is already pending");
1501
1418
  }
1502
1419
  try {
1503
- const previous = (0, import_node_fs7.readFileSync)(path, "utf8");
1420
+ const previous = (0, import_node_fs5.readFileSync)(path, "utf8");
1504
1421
  const pid = Number(previous.split(":")[0]);
1505
1422
  if (!Number.isInteger(pid) || pid <= 0) throw new Error("installation lock is malformed; recovery required");
1506
1423
  try {
@@ -1509,15 +1426,15 @@ function lockInstallation(dir) {
1509
1426
  } catch (probe) {
1510
1427
  if (probe.code !== "ESRCH") throw probe;
1511
1428
  }
1512
- (0, import_node_fs7.unlinkSync)(path);
1513
- (0, import_node_fs7.writeFileSync)(path, owner, { flag: "wx", mode: 384, flush: true });
1429
+ (0, import_node_fs5.unlinkSync)(path);
1430
+ (0, import_node_fs5.writeFileSync)(path, owner, { flag: "wx", mode: 384, flush: true });
1514
1431
  } finally {
1515
- (0, import_node_fs7.unlinkSync)(recovery);
1432
+ (0, import_node_fs5.unlinkSync)(recovery);
1516
1433
  }
1517
1434
  }
1518
1435
  let released = false;
1519
1436
  return () => {
1520
- if (!released && (0, import_node_fs7.readFileSync)(path, "utf8") === owner) (0, import_node_fs7.unlinkSync)(path);
1437
+ if (!released && (0, import_node_fs5.readFileSync)(path, "utf8") === owner) (0, import_node_fs5.unlinkSync)(path);
1521
1438
  released = true;
1522
1439
  };
1523
1440
  }
@@ -1568,14 +1485,14 @@ function compareVersions(a, b) {
1568
1485
  }
1569
1486
  function recordedPath(productDir) {
1570
1487
  try {
1571
- const saved = JSON.parse((0, import_node_fs8.readFileSync)((0, import_node_path4.join)(productDir, LAUNCHER_RECORD_FILE), "utf8"));
1488
+ const saved = JSON.parse((0, import_node_fs6.readFileSync)((0, import_node_path3.join)(productDir, LAUNCHER_RECORD_FILE), "utf8"));
1572
1489
  return typeof saved.path === "string" && saved.path ? saved.path : null;
1573
1490
  } catch {
1574
1491
  return null;
1575
1492
  }
1576
1493
  }
1577
1494
  function installedPath(target, productDir, platform) {
1578
- return platform === "win32" ? (0, import_node_path4.join)(productDir, "bin", `${target.bin}.exe`) : (0, import_node_path4.join)((0, import_node_os2.homedir)(), ".local", "bin", target.bin);
1495
+ return platform === "win32" ? (0, import_node_path3.join)(productDir, "bin", `${target.bin}.exe`) : (0, import_node_path3.join)((0, import_node_os2.homedir)(), ".local", "bin", target.bin);
1579
1496
  }
1580
1497
  function parseLauncherVersion(stdout, bin) {
1581
1498
  const text = String(stdout).trim();
@@ -1590,17 +1507,17 @@ function runVersion(path, bin) {
1590
1507
  });
1591
1508
  }
1592
1509
  function removeStale(file) {
1593
- const prefix = `${(0, import_node_path4.basename)(file)}.old-`;
1510
+ const prefix = `${(0, import_node_path3.basename)(file)}.old-`;
1594
1511
  let names;
1595
1512
  try {
1596
- names = (0, import_node_fs8.readdirSync)((0, import_node_path4.dirname)(file));
1513
+ names = (0, import_node_fs6.readdirSync)((0, import_node_path3.dirname)(file));
1597
1514
  } catch {
1598
1515
  return;
1599
1516
  }
1600
1517
  for (const name of names) {
1601
1518
  if (!name.startsWith(prefix)) continue;
1602
1519
  try {
1603
- (0, import_node_fs8.rmSync)((0, import_node_path4.join)((0, import_node_path4.dirname)(file), name), { force: true });
1520
+ (0, import_node_fs6.rmSync)((0, import_node_path3.join)((0, import_node_path3.dirname)(file), name), { force: true });
1604
1521
  } catch {
1605
1522
  }
1606
1523
  }
@@ -1612,8 +1529,8 @@ async function refreshLauncher(target, options = {}) {
1612
1529
  if (!key) return null;
1613
1530
  const productDir = options.productDir ?? defaultProductDir(target.product);
1614
1531
  const recorded = recordedPath(productDir);
1615
- const file = options.path ?? (recorded && (0, import_node_fs8.existsSync)(recorded) ? recorded : installedPath(target, productDir, platform));
1616
- if (!(0, import_node_fs8.existsSync)(file) || (0, import_node_fs8.lstatSync)(file).isSymbolicLink()) return null;
1532
+ const file = options.path ?? (recorded && (0, import_node_fs6.existsSync)(recorded) ? recorded : installedPath(target, productDir, platform));
1533
+ if (!(0, import_node_fs6.existsSync)(file) || (0, import_node_fs6.lstatSync)(file).isSymbolicLink()) return null;
1617
1534
  if (!options.dryRun) removeStale(file);
1618
1535
  const from = await (options.readVersion ?? ((path) => runVersion(path, target.bin)))(file);
1619
1536
  if (!from) return null;
@@ -1649,19 +1566,19 @@ async function refreshLauncher(target, options = {}) {
1649
1566
  }
1650
1567
  if (!verifyFileBytes(entry, bytes)) return arm("fail", from, "The downloaded launcher failed its checksum.");
1651
1568
  try {
1652
- (0, import_node_fs8.writeFileSync)(next, bytes, { mode: 493 });
1653
- if (platform !== "win32") (0, import_node_fs8.chmodSync)(next, 493);
1569
+ (0, import_node_fs6.writeFileSync)(next, bytes, { mode: 493 });
1570
+ if (platform !== "win32") (0, import_node_fs6.chmodSync)(next, 493);
1654
1571
  if (platform === "win32") {
1655
1572
  moved = `${file}.old-${process.pid}-${Date.now()}`;
1656
- (0, import_node_fs8.renameSync)(file, moved);
1573
+ (0, import_node_fs6.renameSync)(file, moved);
1657
1574
  }
1658
- (0, import_node_fs8.renameSync)(next, file);
1575
+ (0, import_node_fs6.renameSync)(next, file);
1659
1576
  } catch {
1660
1577
  try {
1661
- if (moved && !(0, import_node_fs8.existsSync)(file)) (0, import_node_fs8.renameSync)(moved, file);
1578
+ if (moved && !(0, import_node_fs6.existsSync)(file)) (0, import_node_fs6.renameSync)(moved, file);
1662
1579
  } catch {
1663
1580
  }
1664
- (0, import_node_fs8.rmSync)(next, { force: true });
1581
+ (0, import_node_fs6.rmSync)(next, { force: true });
1665
1582
  return arm("fail", from, "The launcher could not be replaced.");
1666
1583
  }
1667
1584
  return arm("ok", record.version, "");
@@ -1688,22 +1605,22 @@ var installer_product_default = {
1688
1605
  };
1689
1606
 
1690
1607
  // src/state.ts
1691
- var import_node_fs9 = require("node:fs");
1608
+ var import_node_fs7 = require("node:fs");
1692
1609
  var import_node_os3 = require("node:os");
1693
- var import_node_path5 = require("node:path");
1610
+ var import_node_path4 = require("node:path");
1694
1611
  function stateRoot(env = process.env) {
1695
- return env.MMI_UPDATER_HOME || (0, import_node_path5.join)((0, import_node_os3.homedir)(), ".mmi", "updater");
1612
+ return env.MMI_UPDATER_HOME || (0, import_node_path4.join)((0, import_node_os3.homedir)(), ".mmi", "updater");
1696
1613
  }
1697
1614
  function statePaths(env = process.env) {
1698
1615
  const root = stateRoot(env);
1699
- const staging = (0, import_node_path5.join)(root, "staging");
1700
- const gitCache = (0, import_node_path5.join)(root, "git-cache", "mmi-hub.git");
1701
- return { root, staging, gitCache, journalPath: (0, import_node_path5.join)(root, "journal.jsonl"), leasePath: (0, import_node_path5.join)(root, "lease.lock") };
1616
+ const staging = (0, import_node_path4.join)(root, "staging");
1617
+ const gitCache = (0, import_node_path4.join)(root, "git-cache", "mmi-hub.git");
1618
+ return { root, staging, gitCache, journalPath: (0, import_node_path4.join)(root, "journal.jsonl"), leasePath: (0, import_node_path4.join)(root, "lease.lock") };
1702
1619
  }
1703
1620
  function ensureState(env = process.env) {
1704
1621
  const paths = statePaths(env);
1705
- (0, import_node_fs9.mkdirSync)(paths.staging, { recursive: true });
1706
- (0, import_node_fs9.mkdirSync)((0, import_node_path5.dirname)(paths.gitCache), { recursive: true });
1622
+ (0, import_node_fs7.mkdirSync)(paths.staging, { recursive: true });
1623
+ (0, import_node_fs7.mkdirSync)((0, import_node_path4.dirname)(paths.gitCache), { recursive: true });
1707
1624
  return paths;
1708
1625
  }
1709
1626
  var UpdaterBusy = class extends Error {
@@ -1713,15 +1630,15 @@ var LEASE_STALE_MS = 10 * 6e4;
1713
1630
  function tryAcquire(path) {
1714
1631
  const token = `${Date.now()}-${process.pid}-${Math.random().toString(36).slice(2, 10)}`;
1715
1632
  try {
1716
- const fd = (0, import_node_fs9.openSync)(path, "wx");
1717
- (0, import_node_fs9.writeFileSync)(fd, JSON.stringify({ token, pid: process.pid, ts: Date.now() }) + "\n");
1718
- (0, import_node_fs9.closeSync)(fd);
1633
+ const fd = (0, import_node_fs7.openSync)(path, "wx");
1634
+ (0, import_node_fs7.writeFileSync)(fd, JSON.stringify({ token, pid: process.pid, ts: Date.now() }) + "\n");
1635
+ (0, import_node_fs7.closeSync)(fd);
1719
1636
  return {
1720
1637
  token,
1721
1638
  release() {
1722
1639
  try {
1723
1640
  const current2 = readLease(path);
1724
- if (current2 && current2.token === token) (0, import_node_fs9.unlinkSync)(path);
1641
+ if (current2 && current2.token === token) (0, import_node_fs7.unlinkSync)(path);
1725
1642
  } catch {
1726
1643
  }
1727
1644
  }
@@ -1732,7 +1649,7 @@ function tryAcquire(path) {
1732
1649
  const current = readLease(path);
1733
1650
  if (current && Date.now() - current.ts > LEASE_STALE_MS) {
1734
1651
  try {
1735
- (0, import_node_fs9.renameSync)(path, `${path}.stale-${Date.now()}`);
1652
+ (0, import_node_fs7.renameSync)(path, `${path}.stale-${Date.now()}`);
1736
1653
  return "stolen-stale";
1737
1654
  } catch {
1738
1655
  }
@@ -1741,7 +1658,7 @@ function tryAcquire(path) {
1741
1658
  }
1742
1659
  function readLease(path) {
1743
1660
  try {
1744
- return JSON.parse((0, import_node_fs9.readFileSync)(path, "utf8"));
1661
+ return JSON.parse((0, import_node_fs7.readFileSync)(path, "utf8"));
1745
1662
  } catch {
1746
1663
  return null;
1747
1664
  }
@@ -1766,10 +1683,10 @@ function withLease(path, fn, waitMs = LEASE_WAIT_MS) {
1766
1683
  }
1767
1684
  function appendJournal(path, event) {
1768
1685
  try {
1769
- (0, import_node_fs9.mkdirSync)((0, import_node_path5.dirname)(path), { recursive: true });
1770
- const fd = (0, import_node_fs9.openSync)(path, "a");
1771
- (0, import_node_fs9.writeFileSync)(fd, JSON.stringify(event) + "\n");
1772
- (0, import_node_fs9.closeSync)(fd);
1686
+ (0, import_node_fs7.mkdirSync)((0, import_node_path4.dirname)(path), { recursive: true });
1687
+ const fd = (0, import_node_fs7.openSync)(path, "a");
1688
+ (0, import_node_fs7.writeFileSync)(fd, JSON.stringify(event) + "\n");
1689
+ (0, import_node_fs7.closeSync)(fd);
1773
1690
  return true;
1774
1691
  } catch {
1775
1692
  return false;
@@ -1788,7 +1705,7 @@ function journalHighWater(path, surface, events) {
1788
1705
  function parseJournal(path) {
1789
1706
  const events = [];
1790
1707
  try {
1791
- for (const line of (0, import_node_fs9.readFileSync)(path, "utf8").split("\n")) {
1708
+ for (const line of (0, import_node_fs7.readFileSync)(path, "utf8").split("\n")) {
1792
1709
  if (!line.trim()) continue;
1793
1710
  try {
1794
1711
  events.push(JSON.parse(line));
@@ -1802,7 +1719,7 @@ function parseJournal(path) {
1802
1719
  function journalSurfaceRepeatedFail(path, surface, currentRun) {
1803
1720
  let lastVerdict = null;
1804
1721
  try {
1805
- for (const line of (0, import_node_fs9.readFileSync)(path, "utf8").split("\n")) {
1722
+ for (const line of (0, import_node_fs7.readFileSync)(path, "utf8").split("\n")) {
1806
1723
  if (!line.trim()) continue;
1807
1724
  try {
1808
1725
  const event = JSON.parse(line);
@@ -1845,7 +1762,7 @@ function compareSemver(a, b) {
1845
1762
  return va.pre.join(".") < vb.pre.join(".") ? -1 : va.pre.join(".") > vb.pre.join(".") ? 1 : 0;
1846
1763
  }
1847
1764
  function fileExists(path) {
1848
- return (0, import_node_fs9.existsSync)(path);
1765
+ return (0, import_node_fs7.existsSync)(path);
1849
1766
  }
1850
1767
 
1851
1768
  // src/reconcile.ts
@@ -1853,8 +1770,8 @@ var import_node_perf_hooks2 = require("node:perf_hooks");
1853
1770
 
1854
1771
  // src/npm.ts
1855
1772
  var import_node_child_process2 = require("node:child_process");
1856
- var import_node_fs10 = require("node:fs");
1857
- var import_node_path6 = require("node:path");
1773
+ var import_node_fs8 = require("node:fs");
1774
+ var import_node_path5 = require("node:path");
1858
1775
  var cachedNpm = null;
1859
1776
  function resolveNpm(env = process.env) {
1860
1777
  if (env.MMI_UPDATER_NPM) return { kind: "command", command: env.MMI_UPDATER_NPM };
@@ -1863,8 +1780,8 @@ function resolveNpm(env = process.env) {
1863
1780
  const where = (0, import_node_child_process2.spawnSync)("where.exe", ["npm.cmd"], { encoding: "utf8", windowsHide: true });
1864
1781
  const first = where.stdout.split("\n").map((l) => l.trim()).find(Boolean);
1865
1782
  if (where.status === 0 && first) {
1866
- const script = (0, import_node_path6.join)((0, import_node_path6.dirname)(first), "node_modules", "npm", "bin", "npm-cli.js");
1867
- if ((0, import_node_fs10.existsSync)(script)) {
1783
+ const script = (0, import_node_path5.join)((0, import_node_path5.dirname)(first), "node_modules", "npm", "bin", "npm-cli.js");
1784
+ if ((0, import_node_fs8.existsSync)(script)) {
1868
1785
  cachedNpm = { kind: "node-script", script };
1869
1786
  return cachedNpm;
1870
1787
  }
@@ -1872,14 +1789,14 @@ function resolveNpm(env = process.env) {
1872
1789
  return cachedNpm;
1873
1790
  }
1874
1791
  }
1875
- const bundled = (0, import_node_path6.join)((0, import_node_path6.dirname)(process.execPath), "..", "lib", "node_modules", "npm", "bin", "npm-cli.js");
1876
- if ((0, import_node_fs10.existsSync)(bundled)) {
1792
+ const bundled = (0, import_node_path5.join)((0, import_node_path5.dirname)(process.execPath), "..", "lib", "node_modules", "npm", "bin", "npm-cli.js");
1793
+ if ((0, import_node_fs8.existsSync)(bundled)) {
1877
1794
  cachedNpm = { kind: "node-script", script: bundled };
1878
1795
  return cachedNpm;
1879
1796
  }
1880
1797
  const located = (0, import_node_child_process2.spawnSync)("/bin/sh", ["-lc", "command -v npm"], { encoding: "utf8", windowsHide: true });
1881
1798
  const resolved = (located.stdout ?? "").trim().split("\n").map((line) => line.trim()).find(Boolean);
1882
- if (located.status === 0 && resolved && (0, import_node_fs10.existsSync)(resolved)) {
1799
+ if (located.status === 0 && resolved && (0, import_node_fs8.existsSync)(resolved)) {
1883
1800
  cachedNpm = { kind: "command", command: resolved };
1884
1801
  return cachedNpm;
1885
1802
  }
@@ -1961,7 +1878,7 @@ function npmVersions(packageName, env = process.env) {
1961
1878
 
1962
1879
  // src/gate.ts
1963
1880
  var import_node_child_process3 = require("node:child_process");
1964
- var import_node_fs11 = require("node:fs");
1881
+ var import_node_fs9 = require("node:fs");
1965
1882
  function parseBom(text) {
1966
1883
  const bom = JSON.parse(text);
1967
1884
  if (typeof bom?.version !== "string" || typeof bom?.sourceCommit !== "string" || !Array.isArray(bom?.artifacts)) {
@@ -1983,7 +1900,7 @@ function ensureBareCache(cachePath, repoUrl) {
1983
1900
  if (probe.status !== 0) {
1984
1901
  throw new GateEnvError("git is not available \u2014 the release gate needs a git client");
1985
1902
  }
1986
- if (!(0, import_node_fs11.existsSync)(cachePath)) {
1903
+ if (!(0, import_node_fs9.existsSync)(cachePath)) {
1987
1904
  const init = (0, import_node_child_process3.spawnSync)("git", ["init", "--bare", cachePath], { encoding: "utf8", windowsHide: true });
1988
1905
  if (init.status !== 0) throw new GateEnvError(`cannot create bare cache at ${cachePath}: ${init.stderr}`);
1989
1906
  }
@@ -2090,39 +2007,39 @@ async function checkAtomicity(cachePath, tagCommit, bom, candidate, npm) {
2090
2007
  }
2091
2008
 
2092
2009
  // src/surfaces.ts
2093
- var import_node_fs16 = require("node:fs");
2010
+ var import_node_fs14 = require("node:fs");
2094
2011
  var import_node_os5 = require("node:os");
2095
- var import_node_path11 = require("node:path");
2012
+ var import_node_path10 = require("node:path");
2096
2013
 
2097
2014
  // src/arm-host-plugins.ts
2098
2015
  var import_node_child_process6 = require("node:child_process");
2099
- var import_node_fs15 = require("node:fs");
2016
+ var import_node_fs13 = require("node:fs");
2100
2017
  var import_node_os4 = require("node:os");
2101
- var import_node_path10 = require("node:path");
2018
+ var import_node_path9 = require("node:path");
2102
2019
 
2103
2020
  // src/arm-npm-global.ts
2104
- var import_node_fs13 = require("node:fs");
2021
+ var import_node_fs11 = require("node:fs");
2105
2022
  var import_node_child_process5 = require("node:child_process");
2106
- var import_node_path8 = require("node:path");
2023
+ var import_node_path7 = require("node:path");
2107
2024
 
2108
2025
  // src/pending.ts
2109
2026
  var import_node_child_process4 = require("node:child_process");
2110
- var import_node_fs12 = require("node:fs");
2111
- var import_node_path7 = require("node:path");
2027
+ var import_node_fs10 = require("node:fs");
2028
+ var import_node_path6 = require("node:path");
2112
2029
  function hubDistPath(env) {
2113
2030
  const root = globalRoot(env);
2114
- return root ? (0, import_node_path7.join)(root, "@mutmutco", "hub", "dist", "index.cjs") : null;
2031
+ return root ? (0, import_node_path6.join)(root, "@mutmutco", "hub", "dist", "index.cjs") : null;
2115
2032
  }
2116
2033
  var WATCHER_MAX_WAIT_MS = 4 * 60 * 60 * 1e3;
2117
2034
  function pendingPath(paths) {
2118
- return (0, import_node_path7.join)(paths.root, "pending.json");
2035
+ return (0, import_node_path6.join)(paths.root, "pending.json");
2119
2036
  }
2120
2037
  function watcherLockPath(paths) {
2121
- return (0, import_node_path7.join)(paths.root, "pending-watcher.lock.d");
2038
+ return (0, import_node_path6.join)(paths.root, "pending-watcher.lock.d");
2122
2039
  }
2123
2040
  function readPending(paths) {
2124
2041
  try {
2125
- const parsed = JSON.parse((0, import_node_fs12.readFileSync)(pendingPath(paths), "utf8"));
2042
+ const parsed = JSON.parse((0, import_node_fs10.readFileSync)(pendingPath(paths), "utf8"));
2126
2043
  if (!Array.isArray(parsed)) return [];
2127
2044
  return parsed.filter((row) => Boolean(row) && typeof row === "object" && typeof row.surface === "string" && typeof row.target === "string" && Array.isArray(row.images) && Array.isArray(row.dirs));
2128
2045
  } catch {
@@ -2130,12 +2047,12 @@ function readPending(paths) {
2130
2047
  }
2131
2048
  }
2132
2049
  function writePending(paths, records) {
2133
- (0, import_node_fs12.mkdirSync)(paths.root, { recursive: true });
2050
+ (0, import_node_fs10.mkdirSync)(paths.root, { recursive: true });
2134
2051
  const path = pendingPath(paths);
2135
2052
  const tmp = `${path}.${process.pid}.${Math.random().toString(36).slice(2)}.tmp`;
2136
- (0, import_node_fs12.writeFileSync)(tmp, `${JSON.stringify(records, null, 2)}
2053
+ (0, import_node_fs10.writeFileSync)(tmp, `${JSON.stringify(records, null, 2)}
2137
2054
  `, "utf8");
2138
- (0, import_node_fs12.renameSync)(tmp, path);
2055
+ (0, import_node_fs10.renameSync)(tmp, path);
2139
2056
  }
2140
2057
  function clearPending(paths, surface) {
2141
2058
  const records = readPending(paths);
@@ -2204,14 +2121,14 @@ function schedulePendingWatcher(paths, env = process.env, seam = {}) {
2204
2121
  const live = records.find((row) => row.watcherPid && pidAlive(row.watcherPid));
2205
2122
  if (live) return { scheduled: false, reason: `watcher pid ${live.watcherPid} is already waiting` };
2206
2123
  const hubDist = seam.hubDist ?? hubDistPath(env);
2207
- if (!hubDist || !(0, import_node_fs12.existsSync)(hubDist)) return { scheduled: false, reason: "the installed hub bundle is unresolvable \u2014 the hourly tick remains the retry" };
2124
+ if (!hubDist || !(0, import_node_fs10.existsSync)(hubDist)) return { scheduled: false, reason: "the installed hub bundle is unresolvable \u2014 the hourly tick remains the retry" };
2208
2125
  const command = buildWatcherCommand({
2209
2126
  images: [...new Set(records.flatMap((row) => row.images))],
2210
2127
  dirs: [...new Set(records.flatMap((row) => row.dirs))],
2211
2128
  node: process.execPath,
2212
2129
  hubDist,
2213
- codePath: (0, import_node_path7.join)(paths.root, "pending-result.code"),
2214
- logPath: (0, import_node_path7.join)(paths.root, "pending-result.log"),
2130
+ codePath: (0, import_node_path6.join)(paths.root, "pending-result.code"),
2131
+ logPath: (0, import_node_path6.join)(paths.root, "pending-result.log"),
2215
2132
  lockPath: watcherLockPath(paths)
2216
2133
  });
2217
2134
  try {
@@ -2250,7 +2167,7 @@ function resumePendingWatcher(paths, env = process.env) {
2250
2167
  // src/arm-npm-global.ts
2251
2168
  function globalDist(env, packageName, distRel) {
2252
2169
  const root = globalRoot(env);
2253
- return root ? (0, import_node_path8.join)(root, ...packageName.split("/"), ...distRel.split("/")) : null;
2170
+ return root ? (0, import_node_path7.join)(root, ...packageName.split("/"), ...distRel.split("/")) : null;
2254
2171
  }
2255
2172
  function probeVersion(distPath) {
2256
2173
  if (!fileExists(distPath)) return null;
@@ -2264,7 +2181,7 @@ function tail(output) {
2264
2181
  function manifestVersion(packageRoot) {
2265
2182
  if (!packageRoot) return null;
2266
2183
  try {
2267
- const version = JSON.parse((0, import_node_fs13.readFileSync)((0, import_node_path8.join)(packageRoot, "package.json"), "utf8")).version;
2184
+ const version = JSON.parse((0, import_node_fs11.readFileSync)((0, import_node_path7.join)(packageRoot, "package.json"), "utf8")).version;
2268
2185
  return typeof version === "string" ? version : null;
2269
2186
  } catch {
2270
2187
  return null;
@@ -2272,40 +2189,34 @@ function manifestVersion(packageRoot) {
2272
2189
  }
2273
2190
  function stagePackage(options) {
2274
2191
  const { surface, packageName, target, witness, paths, env } = options;
2275
- const stageRoot = (0, import_node_path8.join)(paths.staging, surface, target);
2276
- const packageRoot = (0, import_node_path8.join)(stageRoot, "node_modules", ...packageName.split("/"));
2277
- const sourceTarball = (0, import_node_path8.join)(stageRoot, "source.tgz");
2278
- const staged = fileExists((0, import_node_path8.join)(packageRoot, ...witness.split("/")));
2279
- if (options.payload && typeof options.payload !== "string") return options.payload;
2280
- if (!staged) {
2281
- (0, import_node_fs13.mkdirSync)(stageRoot, { recursive: true });
2282
- (0, import_node_fs13.writeFileSync)((0, import_node_path8.join)(stageRoot, "package.json"), JSON.stringify({ name: "mmi-updater-stage", private: true }) + "\n");
2283
- (0, import_node_fs13.rmSync)(sourceTarball, { force: true });
2284
- if (typeof options.payload === "string") (0, import_node_fs13.copyFileSync)(options.payload, sourceTarball);
2285
- const install = runNpm(["install", "--prefix", stageRoot, "--no-audit", "--no-fund", "--no-package-lock", typeof options.payload === "string" ? sourceTarball : `${packageName}@${target}`], env);
2192
+ const stageRoot = (0, import_node_path7.join)(paths.staging, surface, target);
2193
+ const packageRoot = (0, import_node_path7.join)(stageRoot, "node_modules", ...packageName.split("/"));
2194
+ if (!fileExists((0, import_node_path7.join)(packageRoot, ...witness.split("/")))) {
2195
+ (0, import_node_fs11.mkdirSync)(stageRoot, { recursive: true });
2196
+ (0, import_node_fs11.writeFileSync)((0, import_node_path7.join)(stageRoot, "package.json"), JSON.stringify({ name: "mmi-updater-stage", private: true }) + "\n");
2197
+ const install = runNpm(["install", "--prefix", stageRoot, "--no-audit", "--no-fund", "--no-package-lock", `${packageName}@${target}`], env);
2286
2198
  if (install.status !== 0) {
2287
2199
  return { defer: `staging install failed: ${tail(install.stderr || install.stdout)}` };
2288
2200
  }
2289
2201
  }
2290
2202
  let stagedManifestVersion;
2291
2203
  try {
2292
- stagedManifestVersion = JSON.parse((0, import_node_fs13.readFileSync)((0, import_node_path8.join)(packageRoot, "package.json"), "utf8")).version;
2204
+ stagedManifestVersion = JSON.parse((0, import_node_fs11.readFileSync)((0, import_node_path7.join)(packageRoot, "package.json"), "utf8")).version;
2293
2205
  } catch {
2294
2206
  }
2295
2207
  if (stagedManifestVersion !== target) {
2296
2208
  return { defer: `staged manifest is ${stagedManifestVersion ?? "unreadable"}, expected ${target}` };
2297
2209
  }
2298
- return { packageRoot, source: fileExists(sourceTarball) ? "payload" : "npm", ...fileExists(sourceTarball) ? { tarball: sourceTarball } : {} };
2210
+ return { packageRoot };
2299
2211
  }
2300
2212
  function npmGlobalArm(options) {
2301
2213
  const env = options.env ?? process.env;
2302
2214
  const { surface, packageName, distRel, target, dryRun, paths } = options;
2303
2215
  const spec = `${packageName}@${target}`;
2304
- let source;
2305
- const result = (from, to, verdict, detail) => ({ surface, from, to, verdict, detail, ...source ? { source } : {} });
2216
+ const result = (from, to, verdict, detail) => ({ surface, from, to, verdict, detail });
2306
2217
  const highWater = journalHighWater(paths.journalPath, surface, options.journalEvents);
2307
2218
  const localRoot = globalRoot(env);
2308
- const localVersion = localRoot ? manifestVersion((0, import_node_path8.join)(localRoot, ...packageName.split("/"))) : null;
2219
+ const localVersion = localRoot ? manifestVersion((0, import_node_path7.join)(localRoot, ...packageName.split("/"))) : null;
2309
2220
  if (localVersion === target && highWater === target) {
2310
2221
  return result(localVersion, target, "ok", `already at target ${target} (installed manifest + journal high-water)`);
2311
2222
  }
@@ -2323,17 +2234,16 @@ function npmGlobalArm(options) {
2323
2234
  if (dryRun) {
2324
2235
  return result(installed, target, "ok", `dry-run: would converge ${installed ?? "absent"} -> ${target}`);
2325
2236
  }
2326
- const staged = stagePackage({ surface, packageName, target, witness: distRel, paths, env, payload: options.payload });
2237
+ const staged = stagePackage({ surface, packageName, target, witness: distRel, paths, env });
2327
2238
  if ("defer" in staged) {
2328
2239
  return result(installed, target, "defer", staged.defer);
2329
2240
  }
2330
- source = staged.source;
2331
- const stageDist = (0, import_node_path8.join)(staged.packageRoot, ...distRel.split("/"));
2241
+ const stageDist = (0, import_node_path7.join)(staged.packageRoot, ...distRel.split("/"));
2332
2242
  const stagedVersion = probeVersion(stageDist);
2333
2243
  if (stagedVersion !== target) {
2334
2244
  return result(installed, target, "defer", `staged binary probed ${stagedVersion ?? "dead"}, expected ${target}`);
2335
2245
  }
2336
- const globalInstall = runNpm(["install", "-g", "--no-audit", "--no-fund", staged.tarball ?? spec], env);
2246
+ const globalInstall = runNpm(["install", "-g", "--no-audit", "--no-fund", spec], env);
2337
2247
  if (globalInstall.status !== 0) {
2338
2248
  const reason = `global install failed: ${tail(globalInstall.stderr || globalInstall.stdout)}`;
2339
2249
  const root = globalRoot(env);
@@ -2349,11 +2259,11 @@ function npmGlobalArm(options) {
2349
2259
  }
2350
2260
 
2351
2261
  // src/launch-staging.ts
2352
- var import_node_fs14 = require("node:fs");
2353
- var import_node_path9 = require("node:path");
2262
+ var import_node_fs12 = require("node:fs");
2263
+ var import_node_path8 = require("node:path");
2354
2264
  function readLaunchTarget(path) {
2355
2265
  try {
2356
- const parsed = JSON.parse((0, import_node_fs14.readFileSync)(path, "utf8"));
2266
+ const parsed = JSON.parse((0, import_node_fs12.readFileSync)(path, "utf8"));
2357
2267
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
2358
2268
  const row = parsed;
2359
2269
  if (typeof row.surface !== "string" || typeof row.target !== "string" || typeof row.since !== "string" || typeof row.incoming !== "string") return null;
@@ -2363,15 +2273,15 @@ function readLaunchTarget(path) {
2363
2273
  }
2364
2274
  }
2365
2275
  function writeLaunchTarget(path, record) {
2366
- (0, import_node_fs14.mkdirSync)((0, import_node_path9.join)(path, ".."), { recursive: true });
2276
+ (0, import_node_fs12.mkdirSync)((0, import_node_path8.join)(path, ".."), { recursive: true });
2367
2277
  const tmp = `${path}.tmp-${process.pid}-${Math.random().toString(36).slice(2)}`;
2368
- (0, import_node_fs14.writeFileSync)(tmp, `${JSON.stringify(record, null, 2)}
2278
+ (0, import_node_fs12.writeFileSync)(tmp, `${JSON.stringify(record, null, 2)}
2369
2279
  `, "utf8");
2370
- (0, import_node_fs14.renameSync)(tmp, path);
2280
+ (0, import_node_fs12.renameSync)(tmp, path);
2371
2281
  }
2372
2282
  function clearLaunchTarget(path) {
2373
2283
  try {
2374
- (0, import_node_fs14.rmSync)(path, { force: true });
2284
+ (0, import_node_fs12.rmSync)(path, { force: true });
2375
2285
  } catch {
2376
2286
  }
2377
2287
  }
@@ -2392,7 +2302,7 @@ function noteLaunchStaged(paths, env, options, seam = {}) {
2392
2302
  }
2393
2303
  function probeLaunchTargetVersion(launchTargetPath, versionAt) {
2394
2304
  const record = readLaunchTarget(launchTargetPath);
2395
- if (!record || !(0, import_node_fs14.existsSync)(record.incoming)) return null;
2305
+ if (!record || !(0, import_node_fs12.existsSync)(record.incoming)) return null;
2396
2306
  const version = versionAt(record.incoming);
2397
2307
  return version === record.target ? record.target : null;
2398
2308
  }
@@ -2441,16 +2351,16 @@ function claudeMmi(runner, env) {
2441
2351
  }
2442
2352
  function claudeHomeDir(env) {
2443
2353
  const home = env.HOME?.trim() || env.USERPROFILE?.trim() || (0, import_node_os4.homedir)();
2444
- return (0, import_node_path10.join)(home, ".claude");
2354
+ return (0, import_node_path9.join)(home, ".claude");
2445
2355
  }
2446
2356
  function claudeMarketplacesPath(env) {
2447
- return env.MMI_UPDATER_CLAUDE_MARKETPLACES || (0, import_node_path10.join)(claudeHomeDir(env), "plugins", "known_marketplaces.json");
2357
+ return env.MMI_UPDATER_CLAUDE_MARKETPLACES || (0, import_node_path9.join)(claudeHomeDir(env), "plugins", "known_marketplaces.json");
2448
2358
  }
2449
2359
  function ensureClaudeMarketplace(env) {
2450
2360
  const path = claudeMarketplacesPath(env);
2451
2361
  let body;
2452
2362
  try {
2453
- body = JSON.parse((0, import_node_fs15.readFileSync)(path, "utf8"));
2363
+ body = JSON.parse((0, import_node_fs13.readFileSync)(path, "utf8"));
2454
2364
  } catch (error) {
2455
2365
  if (error?.code === "ENOENT") return { ok: false, detail: `${path} does not exist \u2014 mutmutco marketplace is not registered`, unregistered: true };
2456
2366
  return { ok: false, detail: `cannot read ${path}` };
@@ -2472,26 +2382,26 @@ function ensureClaudeMarketplace(env) {
2472
2382
  }
2473
2383
  var CLAUDE_PACKAGE = "@mutmutco/claude-plugin";
2474
2384
  var CLAUDE_MANIFEST = ".claude-plugin/plugin.json";
2475
- var CLAUDE_TREE_MARKERS = [".claude-plugin/plugin.json"];
2385
+ var CLAUDE_TREE_MARKERS = [".claude-plugin/plugin.json", "skills/bootstrap/SKILL.md"];
2476
2386
  function claudePluginsRoot(env) {
2477
- return (0, import_node_path10.join)(claudeHomeDir(env), "plugins");
2387
+ return (0, import_node_path9.join)(claudeHomeDir(env), "plugins");
2478
2388
  }
2479
2389
  function claudeMarkerVersion(root) {
2480
2390
  try {
2481
- const version = JSON.parse((0, import_node_fs15.readFileSync)((0, import_node_path10.join)(root, ...CLAUDE_MANIFEST.split("/")), "utf8")).version;
2391
+ const version = JSON.parse((0, import_node_fs13.readFileSync)((0, import_node_path9.join)(root, ...CLAUDE_MANIFEST.split("/")), "utf8")).version;
2482
2392
  return typeof version === "string" ? version : null;
2483
2393
  } catch {
2484
2394
  return null;
2485
2395
  }
2486
2396
  }
2487
2397
  function claudeTreeHealthy(root) {
2488
- return CLAUDE_TREE_MARKERS.every((rel) => fileExists((0, import_node_path10.join)(root, ...rel.split("/"))));
2398
+ return CLAUDE_TREE_MARKERS.every((rel) => fileExists((0, import_node_path9.join)(root, ...rel.split("/"))));
2489
2399
  }
2490
2400
  function claudeNpmEnv(env) {
2491
2401
  return { ...env, npm_config_allow_remote: "all" };
2492
2402
  }
2493
2403
  function probeClaudeLaunchStaging(env = process.env) {
2494
- return probeLaunchTargetVersion((0, import_node_path10.join)(claudePluginsRoot(env), "staging", "launch-target.json"), claudeMarkerVersion);
2404
+ return probeLaunchTargetVersion((0, import_node_path9.join)(claudePluginsRoot(env), "staging", "launch-target.json"), claudeMarkerVersion);
2495
2405
  }
2496
2406
  function claudeArm(options) {
2497
2407
  const env = options.env ?? process.env;
@@ -2499,14 +2409,12 @@ function claudeArm(options) {
2499
2409
  const paths = options.paths ?? ensureState(env);
2500
2410
  const target = options.target;
2501
2411
  const repoUrl = options.repoUrl ?? (env.MMI_UPDATER_REPO || REPO_URL_DEFAULT);
2502
- let source;
2503
2412
  const result = (from2, to, verdict, detail) => ({
2504
2413
  surface: "claude",
2505
2414
  from: from2,
2506
2415
  to,
2507
2416
  verdict,
2508
- detail,
2509
- ...source ? { source } : {}
2417
+ detail
2510
2418
  });
2511
2419
  const before = claudeMmi(runner, env);
2512
2420
  if (before.error) return result(null, target, "defer", before.error);
@@ -2526,7 +2434,7 @@ function claudeArm(options) {
2526
2434
  }
2527
2435
  if (!marketplaceTrust.ok) return result(from, target, "defer", marketplaceTrust.detail ?? "cannot trust the mutmutco marketplace registration");
2528
2436
  const pluginsRoot = claudePluginsRoot(env);
2529
- const launchTargetPath = (0, import_node_path10.join)(pluginsRoot, "staging", "launch-target.json");
2437
+ const launchTargetPath = (0, import_node_path9.join)(pluginsRoot, "staging", "launch-target.json");
2530
2438
  if (options.dryRun) {
2531
2439
  return result(from, target, "ok", `dry-run: would refresh mutmutco, stage ${target} on the Claude volume, and converge mmi@mutmutco ${from ?? "absent"} -> ${target}`);
2532
2440
  }
@@ -2540,35 +2448,34 @@ function claudeArm(options) {
2540
2448
  clearLaunchTarget(launchTargetPath);
2541
2449
  return result(from, target, "ok", `catalog refreshed; installed+enabled at target ${target}`);
2542
2450
  }
2543
- const incomingRoot = (0, import_node_path10.join)(pluginsRoot, "staging", "incoming");
2544
- const incoming = (0, import_node_path10.join)(incomingRoot, target);
2451
+ const incomingRoot = (0, import_node_path9.join)(pluginsRoot, "staging", "incoming");
2452
+ const incoming = (0, import_node_path9.join)(incomingRoot, target);
2545
2453
  const priorLaunch = readLaunchTarget(launchTargetPath);
2546
2454
  const reuseIncoming = priorLaunch?.target === target && priorLaunch.incoming === incoming && claudeMarkerVersion(incoming) === target && claudeTreeHealthy(incoming);
2547
2455
  if (!reuseIncoming) {
2548
- const staged = stagePackage({ surface: "claude", packageName: CLAUDE_PACKAGE, target, witness: CLAUDE_MANIFEST, paths, env, payload: options.payload });
2456
+ const staged = stagePackage({ surface: "claude", packageName: CLAUDE_PACKAGE, target, witness: CLAUDE_MANIFEST, paths, env });
2549
2457
  if ("defer" in staged) return result(from, target, "defer", staged.defer);
2550
- source = staged.source;
2551
2458
  if (claudeMarkerVersion(staged.packageRoot) !== target || !claudeTreeHealthy(staged.packageRoot)) {
2552
2459
  return result(from, target, "defer", `staged Claude manifest is ${claudeMarkerVersion(staged.packageRoot) ?? "unreadable"} or its tree is incomplete (expected ${target})`);
2553
2460
  }
2554
2461
  try {
2555
- (0, import_node_fs15.mkdirSync)((0, import_node_path10.join)(pluginsRoot, "staging"), { recursive: true });
2556
- (0, import_node_fs15.rmSync)(incomingRoot, { recursive: true, force: true });
2557
- (0, import_node_fs15.cpSync)(staged.packageRoot, incoming, { recursive: true });
2462
+ (0, import_node_fs13.mkdirSync)((0, import_node_path9.join)(pluginsRoot, "staging"), { recursive: true });
2463
+ (0, import_node_fs13.rmSync)(incomingRoot, { recursive: true, force: true });
2464
+ (0, import_node_fs13.cpSync)(staged.packageRoot, incoming, { recursive: true });
2558
2465
  } catch (error) {
2559
2466
  return result(from, target, "defer", `cannot place incoming Claude generation: ${error?.message ?? error}`);
2560
2467
  }
2561
2468
  if (claudeMarkerVersion(incoming) !== target || !claudeTreeHealthy(incoming)) {
2562
- (0, import_node_fs15.rmSync)(incomingRoot, { recursive: true, force: true });
2469
+ (0, import_node_fs13.rmSync)(incomingRoot, { recursive: true, force: true });
2563
2470
  return result(from, target, "defer", "incoming Claude generation did not reproduce the verified payload");
2564
2471
  }
2565
2472
  }
2566
- const cacheTarget = (0, import_node_path10.join)(pluginsRoot, "cache", "mutmutco", "mmi", target);
2473
+ const cacheTarget = (0, import_node_path9.join)(pluginsRoot, "cache", "mutmutco", "mmi", target);
2567
2474
  try {
2568
- if (!(0, import_node_fs15.existsSync)(cacheTarget) || claudeMarkerVersion(cacheTarget) !== target || !claudeTreeHealthy(cacheTarget)) {
2569
- (0, import_node_fs15.rmSync)(cacheTarget, { recursive: true, force: true });
2570
- (0, import_node_fs15.mkdirSync)((0, import_node_path10.join)(cacheTarget, ".."), { recursive: true });
2571
- (0, import_node_fs15.cpSync)(incoming, cacheTarget, { recursive: true });
2475
+ if (!(0, import_node_fs13.existsSync)(cacheTarget) || claudeMarkerVersion(cacheTarget) !== target || !claudeTreeHealthy(cacheTarget)) {
2476
+ (0, import_node_fs13.rmSync)(cacheTarget, { recursive: true, force: true });
2477
+ (0, import_node_fs13.mkdirSync)((0, import_node_path9.join)(cacheTarget, ".."), { recursive: true });
2478
+ (0, import_node_fs13.cpSync)(incoming, cacheTarget, { recursive: true });
2572
2479
  }
2573
2480
  } catch (error) {
2574
2481
  return result(from, target, "defer", `cannot populate Claude plugin cache: ${error?.message ?? error}`);
@@ -2596,7 +2503,7 @@ function claudeArm(options) {
2596
2503
  }
2597
2504
  clearLaunchTarget(launchTargetPath);
2598
2505
  try {
2599
- (0, import_node_fs15.rmSync)(incomingRoot, { recursive: true, force: true });
2506
+ (0, import_node_fs13.rmSync)(incomingRoot, { recursive: true, force: true });
2600
2507
  } catch {
2601
2508
  }
2602
2509
  return result(from, target, "ok", `catalog refreshed; converged and verified ${from ?? "absent"} -> ${target}`);
@@ -2675,12 +2582,12 @@ function probeNativeHostInstallation(surface, env = process.env, runner = runHos
2675
2582
 
2676
2583
  // src/surfaces.ts
2677
2584
  function jervcodeAgentDir(env = process.env) {
2678
- return env.MMI_UPDATER_JERVCODE_AGENT_DIR?.trim() || env.JERVCODE_CODING_AGENT_DIR?.trim() || env.PI_CODING_AGENT_DIR?.trim() || (0, import_node_path11.join)((0, import_node_os5.homedir)(), ".jerv", "agent");
2585
+ return env.MMI_UPDATER_JERVCODE_AGENT_DIR?.trim() || env.JERVCODE_CODING_AGENT_DIR?.trim() || env.PI_CODING_AGENT_DIR?.trim() || (0, import_node_path10.join)((0, import_node_os5.homedir)(), ".jerv", "agent");
2679
2586
  }
2680
2587
  function hermesHome(env = process.env, platform = process.platform) {
2681
2588
  if (env.HERMES_HOME?.trim()) return env.HERMES_HOME.trim();
2682
- if (platform === "win32") return (0, import_node_path11.join)(env.LOCALAPPDATA?.trim() || (0, import_node_path11.join)((0, import_node_os5.homedir)(), "AppData", "Local"), "hermes");
2683
- return (0, import_node_path11.join)((0, import_node_os5.homedir)(), ".hermes");
2589
+ if (platform === "win32") return (0, import_node_path10.join)(env.LOCALAPPDATA?.trim() || (0, import_node_path10.join)((0, import_node_os5.homedir)(), "AppData", "Local"), "hermes");
2590
+ return (0, import_node_path10.join)((0, import_node_os5.homedir)(), ".hermes");
2684
2591
  }
2685
2592
  function hermesHostCommand(env = process.env) {
2686
2593
  return env.MMI_UPDATER_HERMES?.trim() || "hermes";
@@ -2694,36 +2601,36 @@ function surfaceArmPlan(token, managedSurfaces) {
2694
2601
  }
2695
2602
  function enumerateSurfaces(env = process.env) {
2696
2603
  const home = env.HOME?.trim() || env.USERPROFILE?.trim() || (0, import_node_os5.homedir)();
2697
- const codexHome = env.CODEX_HOME || (0, import_node_path11.join)(home, ".codex");
2604
+ const codexHome = env.CODEX_HOME || (0, import_node_path10.join)(home, ".codex");
2698
2605
  return [
2699
- { id: "claude", marker: (0, import_node_path11.join)(home, ".claude", "plugins", "installed_plugins.json") },
2700
- { id: "codex", marker: (0, import_node_path11.join)(codexHome, "plugins", "installed_plugins.json") },
2606
+ { id: "claude", marker: (0, import_node_path10.join)(home, ".claude", "plugins", "installed_plugins.json") },
2607
+ { id: "codex", marker: (0, import_node_path10.join)(codexHome, "plugins", "installed_plugins.json") },
2701
2608
  // The host, not the payload (#4951, #5356): this marker used to be plugins/local/mmi — the MMI
2702
2609
  // plugin tree itself — so a machine running Cursor WITHOUT the plugin enumerated as "no Cursor"
2703
2610
  // and the arm could never make the first install. The plugin's absence is a converge action, not
2704
2611
  // a skip. The host root mirrors surfaceConfigRoot('cursor') in cli/src/plugin-guard-io.ts.
2705
- { id: "cursor", marker: (0, import_node_path11.join)(home, ".cursor") },
2706
- { id: "jervcode", marker: (0, import_node_path11.join)(jervcodeAgentDir(env), "settings.json") },
2612
+ { id: "cursor", marker: (0, import_node_path10.join)(home, ".cursor") },
2613
+ { id: "jervcode", marker: (0, import_node_path10.join)(jervcodeAgentDir(env), "settings.json") },
2707
2614
  // Host CLI, not HERMES_HOME (#5673): the config tree can survive an uninstall and still carry
2708
2615
  // leftover plugin manifests — that residue must not enumerate as an installed host.
2709
2616
  { id: "hermes", marker: `${hermesHostCommand(env)} --version` }
2710
2617
  ].map((probe) => ({
2711
2618
  ...probe,
2712
- present: probe.id === "hermes" ? hermesHostPresent(env) : (0, import_node_fs16.existsSync)(probe.marker)
2619
+ present: probe.id === "hermes" ? hermesHostPresent(env) : (0, import_node_fs14.existsSync)(probe.marker)
2713
2620
  }));
2714
2621
  }
2715
2622
 
2716
2623
  // src/arm-cursor.ts
2717
- var import_node_fs19 = require("node:fs");
2624
+ var import_node_fs17 = require("node:fs");
2718
2625
  var import_node_child_process7 = require("node:child_process");
2719
2626
  var import_node_os7 = require("node:os");
2720
- var import_node_path12 = require("node:path");
2627
+ var import_node_path11 = require("node:path");
2721
2628
 
2722
2629
  // src/compat.ts
2723
- var import_node_fs17 = require("node:fs");
2630
+ var import_node_fs15 = require("node:fs");
2724
2631
  function readManifestCompat(manifestPath) {
2725
2632
  try {
2726
- const parsed = JSON.parse((0, import_node_fs17.readFileSync)(manifestPath, "utf8"));
2633
+ const parsed = JSON.parse((0, import_node_fs15.readFileSync)(manifestPath, "utf8"));
2727
2634
  return typeof parsed.mmiCompat === "string" ? parsed.mmiCompat : void 0;
2728
2635
  } catch {
2729
2636
  return void 0;
@@ -2731,7 +2638,7 @@ function readManifestCompat(manifestPath) {
2731
2638
  }
2732
2639
 
2733
2640
  // src/host-doc-lock.ts
2734
- var import_node_fs18 = require("node:fs");
2641
+ var import_node_fs16 = require("node:fs");
2735
2642
  var import_node_os6 = require("node:os");
2736
2643
  var SHARED_DOC_LOCK_STALE_MS = 3e4;
2737
2644
  var SHARED_DOC_LOCK_ATTEMPTS = 50;
@@ -2745,7 +2652,7 @@ function lockContent(options) {
2745
2652
  }
2746
2653
  function readHolder(lockPath) {
2747
2654
  try {
2748
- const parsed = JSON.parse((0, import_node_fs18.readFileSync)(lockPath, "utf8"));
2655
+ const parsed = JSON.parse((0, import_node_fs16.readFileSync)(lockPath, "utf8"));
2749
2656
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return null;
2750
2657
  return parsed;
2751
2658
  } catch {
@@ -2757,7 +2664,7 @@ function lockAgeMs(lockPath, now) {
2757
2664
  const declared = typeof holder?.acquiredAt === "string" ? Date.parse(holder.acquiredAt) : Number.NaN;
2758
2665
  if (!Number.isNaN(declared)) return Math.max(0, now - declared);
2759
2666
  try {
2760
- return Math.max(0, now - (0, import_node_fs18.statSync)(lockPath).mtimeMs);
2667
+ return Math.max(0, now - (0, import_node_fs16.statSync)(lockPath).mtimeMs);
2761
2668
  } catch {
2762
2669
  return 0;
2763
2670
  }
@@ -2780,9 +2687,9 @@ function acquireSharedDocLock(documentPath, options) {
2780
2687
  for (let attempt = 0; attempt < attempts; attempt += 1) {
2781
2688
  let fd;
2782
2689
  try {
2783
- fd = (0, import_node_fs18.openSync)(lockPath, "wx");
2784
- (0, import_node_fs18.writeSync)(fd, content);
2785
- (0, import_node_fs18.closeSync)(fd);
2690
+ fd = (0, import_node_fs16.openSync)(lockPath, "wx");
2691
+ (0, import_node_fs16.writeSync)(fd, content);
2692
+ (0, import_node_fs16.closeSync)(fd);
2786
2693
  return {
2787
2694
  documentPath,
2788
2695
  lockPath,
@@ -2795,11 +2702,11 @@ function acquireSharedDocLock(documentPath, options) {
2795
2702
  } catch (error) {
2796
2703
  if (fd !== void 0) {
2797
2704
  try {
2798
- (0, import_node_fs18.closeSync)(fd);
2705
+ (0, import_node_fs16.closeSync)(fd);
2799
2706
  } catch {
2800
2707
  }
2801
2708
  try {
2802
- (0, import_node_fs18.unlinkSync)(lockPath);
2709
+ (0, import_node_fs16.unlinkSync)(lockPath);
2803
2710
  } catch {
2804
2711
  }
2805
2712
  }
@@ -2808,12 +2715,12 @@ function acquireSharedDocLock(documentPath, options) {
2808
2715
  if (lockAgeMs(lockPath, Date.now()) >= staleAfterMs) {
2809
2716
  const aside = `${lockPath}.stale-${Date.now()}`;
2810
2717
  try {
2811
- (0, import_node_fs18.renameSync)(lockPath, aside);
2718
+ (0, import_node_fs16.renameSync)(lockPath, aside);
2812
2719
  } catch {
2813
2720
  continue;
2814
2721
  }
2815
2722
  try {
2816
- (0, import_node_fs18.rmSync)(aside, { force: true });
2723
+ (0, import_node_fs16.rmSync)(aside, { force: true });
2817
2724
  } catch {
2818
2725
  }
2819
2726
  continue;
@@ -2826,7 +2733,7 @@ function releaseSharedDocLock(handle) {
2826
2733
  try {
2827
2734
  const holder = readHolder(handle.lockPath);
2828
2735
  if (holder && holder.owner === handle.owner && Number(holder.pid) === handle.pid) {
2829
- (0, import_node_fs18.unlinkSync)(handle.lockPath);
2736
+ (0, import_node_fs16.unlinkSync)(handle.lockPath);
2830
2737
  }
2831
2738
  } catch {
2832
2739
  }
@@ -2848,14 +2755,14 @@ var KEEP_GENERATIONS = 2;
2848
2755
  var STRANDED_TMP_AGE_MS = 24 * 60 * 6e4;
2849
2756
  var TREE_FILES = [MANIFEST, "skills/bootstrap/SKILL.md"];
2850
2757
  function cursorPluginsRoot() {
2851
- return (0, import_node_path12.join)((0, import_node_os7.homedir)(), ".cursor", "plugins");
2758
+ return (0, import_node_path11.join)((0, import_node_os7.homedir)(), ".cursor", "plugins");
2852
2759
  }
2853
2760
  function treeHealthy(root) {
2854
- return TREE_FILES.every((rel) => (0, import_node_fs19.existsSync)((0, import_node_path12.join)(root, ...rel.split("/"))));
2761
+ return TREE_FILES.every((rel) => (0, import_node_fs17.existsSync)((0, import_node_path11.join)(root, ...rel.split("/"))));
2855
2762
  }
2856
2763
  function readJson(root, rel) {
2857
2764
  try {
2858
- return JSON.parse((0, import_node_fs19.readFileSync)((0, import_node_path12.join)(root, ...rel.split("/")), "utf8"));
2765
+ return JSON.parse((0, import_node_fs17.readFileSync)((0, import_node_path11.join)(root, ...rel.split("/")), "utf8"));
2859
2766
  } catch {
2860
2767
  return null;
2861
2768
  }
@@ -2864,7 +2771,7 @@ function manifest(root) {
2864
2771
  return readJson(root, MANIFEST);
2865
2772
  }
2866
2773
  function probeCursorInstallation() {
2867
- const location = (0, import_node_path12.join)(cursorPluginsRoot(), "local", "mmi");
2774
+ const location = (0, import_node_path11.join)(cursorPluginsRoot(), "local", "mmi");
2868
2775
  const version = manifest(location)?.version ?? null;
2869
2776
  return { version, location, detail: version ? "installed Cursor plugin manifest" : "installed Cursor plugin manifest was unreadable" };
2870
2777
  }
@@ -2879,7 +2786,7 @@ function message(error) {
2879
2786
  }
2880
2787
  function discard(path) {
2881
2788
  try {
2882
- (0, import_node_fs19.rmSync)(path, { recursive: true, force: true });
2789
+ (0, import_node_fs17.rmSync)(path, { recursive: true, force: true });
2883
2790
  } catch {
2884
2791
  }
2885
2792
  }
@@ -2907,7 +2814,7 @@ function cursorHostEvidence(env) {
2907
2814
  return null;
2908
2815
  }
2909
2816
  function resolvedPluginRoot(root) {
2910
- return (0, import_node_path12.join)(root).replace(/\\/g, "/");
2817
+ return (0, import_node_path11.join)(root).replace(/\\/g, "/");
2911
2818
  }
2912
2819
  function isMmiEntry(entry, pluginRoot) {
2913
2820
  if (typeof entry !== "object" || entry === null || typeof entry.command !== "string") return false;
@@ -2931,12 +2838,12 @@ function stripUserHooks(existing, pluginRoot) {
2931
2838
  }
2932
2839
  var CURSOR_HOOKS_LOCK_OWNER = "mmi-hub:cursor-hooks";
2933
2840
  function reconcileCursorUserHooks(pluginRoot, homeDir, lock = {}) {
2934
- const path = (0, import_node_path12.join)(homeDir, ".cursor", USER_HOOKS_FILE);
2841
+ const path = (0, import_node_path11.join)(homeDir, ".cursor", USER_HOOKS_FILE);
2935
2842
  return withSharedDocLock(path, { owner: CURSOR_HOOKS_LOCK_OWNER, ...lock }, () => {
2936
- if (!(0, import_node_fs19.existsSync)(path)) return "current";
2843
+ if (!(0, import_node_fs17.existsSync)(path)) return "current";
2937
2844
  let existing;
2938
2845
  try {
2939
- existing = JSON.parse((0, import_node_fs19.readFileSync)(path, "utf8"));
2846
+ existing = JSON.parse((0, import_node_fs17.readFileSync)(path, "utf8"));
2940
2847
  } catch {
2941
2848
  return "user-conflict";
2942
2849
  }
@@ -2944,8 +2851,8 @@ function reconcileCursorUserHooks(pluginRoot, homeDir, lock = {}) {
2944
2851
  if (!stripped) return "user-conflict";
2945
2852
  if (JSON.stringify(stripped) === JSON.stringify(existing)) return "current";
2946
2853
  const tmp = `${path}.tmp-${process.pid}`;
2947
- (0, import_node_fs19.writeFileSync)(tmp, JSON.stringify(stripped, null, 2) + "\n", "utf8");
2948
- (0, import_node_fs19.renameSync)(tmp, path);
2854
+ (0, import_node_fs17.writeFileSync)(tmp, JSON.stringify(stripped, null, 2) + "\n", "utf8");
2855
+ (0, import_node_fs17.renameSync)(tmp, path);
2949
2856
  return "updated";
2950
2857
  });
2951
2858
  }
@@ -2960,41 +2867,41 @@ function userHooksDetail(pluginRoot, homeDir) {
2960
2867
  case "updated":
2961
2868
  return "; user hooks legacy entries stripped";
2962
2869
  case "user-conflict":
2963
- return `; USER HOOKS CONFLICT at ${(0, import_node_path12.join)(homeDir, ".cursor", USER_HOOKS_FILE)} \u2014 legacy entries were not changed`;
2870
+ return `; USER HOOKS CONFLICT at ${(0, import_node_path11.join)(homeDir, ".cursor", USER_HOOKS_FILE)} \u2014 legacy entries were not changed`;
2964
2871
  default:
2965
2872
  return "";
2966
2873
  }
2967
2874
  }
2968
2875
  function writeRollbackPointer(root, entry) {
2969
- const path = (0, import_node_path12.join)(root, "quarantine", "rollback.json");
2876
+ const path = (0, import_node_path11.join)(root, "quarantine", "rollback.json");
2970
2877
  const tmp = `${path}.tmp-${process.pid}`;
2971
2878
  try {
2972
- (0, import_node_fs19.writeFileSync)(tmp, JSON.stringify({ surface: "cursor", ts: (/* @__PURE__ */ new Date()).toISOString(), ...entry }, null, 2) + "\n", "utf8");
2973
- (0, import_node_fs19.renameSync)(tmp, path);
2879
+ (0, import_node_fs17.writeFileSync)(tmp, JSON.stringify({ surface: "cursor", ts: (/* @__PURE__ */ new Date()).toISOString(), ...entry }, null, 2) + "\n", "utf8");
2880
+ (0, import_node_fs17.renameSync)(tmp, path);
2974
2881
  } catch {
2975
2882
  discard(tmp);
2976
2883
  }
2977
2884
  }
2978
2885
  function mtimeMs(path) {
2979
2886
  try {
2980
- return (0, import_node_fs19.statSync)(path).mtimeMs;
2887
+ return (0, import_node_fs17.statSync)(path).mtimeMs;
2981
2888
  } catch {
2982
2889
  return 0;
2983
2890
  }
2984
2891
  }
2985
2892
  function pruneQuarantine(root, keep) {
2986
- const dir = (0, import_node_path12.join)(root, "quarantine");
2893
+ const dir = (0, import_node_path11.join)(root, "quarantine");
2987
2894
  let generations;
2988
2895
  try {
2989
- generations = (0, import_node_fs19.readdirSync)(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && entry.name.startsWith("mmi-")).map((entry) => (0, import_node_path12.join)(dir, entry.name)).sort((a, b) => mtimeMs(b) - mtimeMs(a));
2896
+ generations = (0, import_node_fs17.readdirSync)(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && entry.name.startsWith("mmi-")).map((entry) => (0, import_node_path11.join)(dir, entry.name)).sort((a, b) => mtimeMs(b) - mtimeMs(a));
2990
2897
  } catch {
2991
2898
  return 0;
2992
2899
  }
2993
2900
  let stranded = 0;
2994
2901
  try {
2995
- for (const entry of (0, import_node_fs19.readdirSync)(dir, { withFileTypes: true })) {
2902
+ for (const entry of (0, import_node_fs17.readdirSync)(dir, { withFileTypes: true })) {
2996
2903
  if (!entry.isFile() || !/^rollback\.json\.tmp-\d+$/.test(entry.name)) continue;
2997
- const path = (0, import_node_path12.join)(dir, entry.name);
2904
+ const path = (0, import_node_path11.join)(dir, entry.name);
2998
2905
  if (Date.now() - mtimeMs(path) < STRANDED_TMP_AGE_MS) continue;
2999
2906
  discard(path);
3000
2907
  stranded += 1;
@@ -3012,16 +2919,16 @@ function pruneQuarantine(root, keep) {
3012
2919
  }
3013
2920
  function restorePrevious(live, quarantined, broken) {
3014
2921
  try {
3015
- (0, import_node_fs19.renameSync)(live, broken);
2922
+ (0, import_node_fs17.renameSync)(live, broken);
3016
2923
  } catch {
3017
2924
  return "kept-broken";
3018
2925
  }
3019
2926
  try {
3020
- (0, import_node_fs19.renameSync)(quarantined, live);
2927
+ (0, import_node_fs17.renameSync)(quarantined, live);
3021
2928
  return "restored";
3022
2929
  } catch {
3023
2930
  try {
3024
- (0, import_node_fs19.renameSync)(broken, live);
2931
+ (0, import_node_fs17.renameSync)(broken, live);
3025
2932
  return "kept-broken";
3026
2933
  } catch {
3027
2934
  return "lost";
@@ -3032,11 +2939,9 @@ function cursorArm(options) {
3032
2939
  const env = options.env ?? process.env;
3033
2940
  const { target, dryRun, paths } = options;
3034
2941
  const root = cursorPluginsRoot();
3035
- const live = (0, import_node_path12.join)(root, "local", "mmi");
3036
- let source;
2942
+ const live = (0, import_node_path11.join)(root, "local", "mmi");
3037
2943
  const result = (from, to, verdict, detail, launchStaged = false) => ({
3038
2944
  surface: "cursor",
3039
- ...source ? { source } : {},
3040
2945
  from,
3041
2946
  to,
3042
2947
  verdict,
@@ -3044,7 +2949,7 @@ function cursorArm(options) {
3044
2949
  launchStaged: launchStaged || void 0,
3045
2950
  // C11: the constraint of the generation LEFT at `live` — read at result time, so a failed
3046
2951
  // switch reports the restored generation's declaration, not the rejected one's (#4973).
3047
- compat: readManifestCompat((0, import_node_path12.join)(live, MANIFEST))
2952
+ compat: readManifestCompat((0, import_node_path11.join)(live, MANIFEST))
3048
2953
  });
3049
2954
  const current = manifest(live);
3050
2955
  const installed = current?.version ?? null;
@@ -3058,31 +2963,30 @@ function cursorArm(options) {
3058
2963
  if (installed === target && treeHealthy(live)) {
3059
2964
  return result(installed, target, "ok", `already at target ${target}${userHooksDetail(live, (0, import_node_os7.homedir)())}`);
3060
2965
  }
3061
- if ((0, import_node_fs19.existsSync)(live) && !mmiOwned(live)) {
2966
+ if ((0, import_node_fs17.existsSync)(live) && !mmiOwned(live)) {
3062
2967
  return result(installed, target, "defer", `${live} carries no MMI ownership marker (plugin manifest name, or a ${PACKAGE} package.json) \u2014 refusing to displace an unmanaged directory (mmi-cli plugin heal adopts it)`);
3063
2968
  }
3064
2969
  if (dryRun) {
3065
2970
  return result(installed, target, "ok", `dry-run: would stage ${PACKAGE}@${target} and switch ${installed ?? "absent"} -> ${target} while Cursor is absent`);
3066
2971
  }
3067
- const staged = stagePackage({ surface: "cursor", packageName: PACKAGE, target, witness: MANIFEST, paths, env, payload: options.payload });
2972
+ const staged = stagePackage({ surface: "cursor", packageName: PACKAGE, target, witness: MANIFEST, paths, env });
3068
2973
  if ("defer" in staged) {
3069
2974
  return result(installed, target, "defer", staged.defer);
3070
2975
  }
3071
- source = staged.source;
3072
2976
  const stagedMarker = manifest(staged.packageRoot)?.version;
3073
2977
  if (stagedMarker !== target || !treeHealthy(staged.packageRoot)) {
3074
2978
  return result(installed, target, "defer", `staged tree marker is ${stagedMarker ?? "unreadable"} and the tree is ${treeHealthy(staged.packageRoot) ? "complete" : "incomplete"}, expected ${target} and complete`);
3075
2979
  }
3076
- const launchTargetPath = (0, import_node_path12.join)(root, "staging", "launch-target.json");
2980
+ const launchTargetPath = (0, import_node_path11.join)(root, "staging", "launch-target.json");
3077
2981
  const priorLaunch = readLaunchTarget(launchTargetPath);
3078
- let incoming = priorLaunch?.target === target && priorLaunch.incoming.startsWith((0, import_node_path12.join)(root, "staging")) && manifest(priorLaunch.incoming)?.version === target && treeHealthy(priorLaunch.incoming) ? priorLaunch.incoming : (0, import_node_path12.join)(root, "staging", `mmi-${safeSegment(target)}-${Date.now()}`);
2982
+ let incoming = priorLaunch?.target === target && priorLaunch.incoming.startsWith((0, import_node_path11.join)(root, "staging")) && manifest(priorLaunch.incoming)?.version === target && treeHealthy(priorLaunch.incoming) ? priorLaunch.incoming : (0, import_node_path11.join)(root, "staging", `mmi-${safeSegment(target)}-${Date.now()}`);
3079
2983
  const reuseIncoming = incoming === priorLaunch?.incoming;
3080
- if (!reuseIncoming || !(0, import_node_fs19.existsSync)(incoming)) {
3081
- incoming = (0, import_node_path12.join)(root, "staging", `mmi-${safeSegment(target)}-${Date.now()}`);
3082
- for (const dir of ["local", "staging", "quarantine"]) (0, import_node_fs19.mkdirSync)((0, import_node_path12.join)(root, dir), { recursive: true });
2984
+ if (!reuseIncoming || !(0, import_node_fs17.existsSync)(incoming)) {
2985
+ incoming = (0, import_node_path11.join)(root, "staging", `mmi-${safeSegment(target)}-${Date.now()}`);
2986
+ for (const dir of ["local", "staging", "quarantine"]) (0, import_node_fs17.mkdirSync)((0, import_node_path11.join)(root, dir), { recursive: true });
3083
2987
  try {
3084
2988
  discard(incoming);
3085
- (0, import_node_fs19.cpSync)(staged.packageRoot, incoming, { recursive: true });
2989
+ (0, import_node_fs17.cpSync)(staged.packageRoot, incoming, { recursive: true });
3086
2990
  } catch (error) {
3087
2991
  discard(incoming);
3088
2992
  return result(installed, target, "defer", `copy into ${root} failed: ${message(error)}`);
@@ -3105,8 +3009,8 @@ function cursorArm(options) {
3105
3009
  return result(installed, target, "ok", `staged ${target} for next launch while Cursor is running (${busy}) \u2014 ${pending}`, true);
3106
3010
  }
3107
3011
  const stamp = Date.now();
3108
- const quarantined = (0, import_node_path12.join)(root, "quarantine", `mmi-${safeSegment(installed ?? "unknown")}-${stamp}`);
3109
- for (const dir of ["local", "staging", "quarantine"]) (0, import_node_fs19.mkdirSync)((0, import_node_path12.join)(root, dir), { recursive: true });
3012
+ const quarantined = (0, import_node_path11.join)(root, "quarantine", `mmi-${safeSegment(installed ?? "unknown")}-${stamp}`);
3013
+ for (const dir of ["local", "staging", "quarantine"]) (0, import_node_fs17.mkdirSync)((0, import_node_path11.join)(root, dir), { recursive: true });
3110
3014
  const started = cursorHostEvidence(env);
3111
3015
  if (started) {
3112
3016
  const pending = noteLaunchStaged(paths, env, {
@@ -3121,15 +3025,15 @@ function cursorArm(options) {
3121
3025
  }
3122
3026
  let displaced = false;
3123
3027
  try {
3124
- if ((0, import_node_fs19.existsSync)(live)) {
3125
- (0, import_node_fs19.renameSync)(live, quarantined);
3028
+ if ((0, import_node_fs17.existsSync)(live)) {
3029
+ (0, import_node_fs17.renameSync)(live, quarantined);
3126
3030
  displaced = true;
3127
3031
  }
3128
- (0, import_node_fs19.renameSync)(incoming, live);
3032
+ (0, import_node_fs17.renameSync)(incoming, live);
3129
3033
  } catch (error) {
3130
- if (displaced && !(0, import_node_fs19.existsSync)(live)) {
3034
+ if (displaced && !(0, import_node_fs17.existsSync)(live)) {
3131
3035
  try {
3132
- (0, import_node_fs19.renameSync)(quarantined, live);
3036
+ (0, import_node_fs17.renameSync)(quarantined, live);
3133
3037
  } catch {
3134
3038
  }
3135
3039
  }
@@ -3140,7 +3044,7 @@ function cursorArm(options) {
3140
3044
  }
3141
3045
  const evidence = manifest(live)?.version;
3142
3046
  if (evidence !== target || !treeHealthy(live)) {
3143
- const broken = `${(0, import_node_path12.join)(root, "quarantine", `mmi-${safeSegment(evidence ?? "broken")}-${stamp}`)}-failed`;
3047
+ const broken = `${(0, import_node_path11.join)(root, "quarantine", `mmi-${safeSegment(evidence ?? "broken")}-${stamp}`)}-failed`;
3144
3048
  const outcome = displaced ? restorePrevious(live, quarantined, broken) : "none";
3145
3049
  const detail = outcome === "restored" ? `restored the previous generation ${installed ?? "unknown"}, unverified tree kept at ${broken}` : outcome === "lost" ? `restore failed and ${live} is missing \u2014 the previous generation is at ${quarantined}` : displaced ? `restore failed, the unverified tree is still live and the previous generation is at ${quarantined}` : "nothing was displaced \u2014 there is no previous generation to restore";
3146
3050
  writeRollbackPointer(root, outcome === "restored" ? { installed: installed ?? "unknown", previous: null, generation: null } : { installed: evidence ?? "unknown", previous: installed, generation: displaced ? quarantined : null });
@@ -3153,12 +3057,12 @@ function cursorArm(options) {
3153
3057
  return result(installed, target, "ok", `switched ${installed ?? "absent"} -> ${target}; ${previous}${pruned ? `; pruned ${pruned} older generation${pruned === 1 ? "" : "s"}` : ""}${userHooksDetail(live, (0, import_node_os7.homedir)())}`);
3154
3058
  }
3155
3059
  function probeCursorLaunchStaging() {
3156
- return probeLaunchTargetVersion((0, import_node_path12.join)(cursorPluginsRoot(), "staging", "launch-target.json"), (root) => manifest(root)?.version ?? null);
3060
+ return probeLaunchTargetVersion((0, import_node_path11.join)(cursorPluginsRoot(), "staging", "launch-target.json"), (root) => manifest(root)?.version ?? null);
3157
3061
  }
3158
3062
 
3159
3063
  // src/arm-jervcode.ts
3160
- var import_node_fs20 = require("node:fs");
3161
- var import_node_path13 = require("node:path");
3064
+ var import_node_fs18 = require("node:fs");
3065
+ var import_node_path12 = require("node:path");
3162
3066
  var PI_PACKAGE = "@mutmutco/pi-plugin";
3163
3067
  function hostEnv(env) {
3164
3068
  const dir = jervcodeAgentDir(env);
@@ -3169,7 +3073,7 @@ function hostCommands(_env) {
3169
3073
  }
3170
3074
  function readPackageSpecs(env) {
3171
3075
  try {
3172
- const settings = JSON.parse((0, import_node_fs20.readFileSync)((0, import_node_path13.join)(jervcodeAgentDir(env), "settings.json"), "utf8"));
3076
+ const settings = JSON.parse((0, import_node_fs18.readFileSync)((0, import_node_path12.join)(jervcodeAgentDir(env), "settings.json"), "utf8"));
3173
3077
  return Array.isArray(settings.packages) ? settings.packages.filter((entry) => typeof entry === "string") : [];
3174
3078
  } catch {
3175
3079
  return null;
@@ -3177,14 +3081,14 @@ function readPackageSpecs(env) {
3177
3081
  }
3178
3082
  function installedVersion(env) {
3179
3083
  try {
3180
- const manifest2 = JSON.parse((0, import_node_fs20.readFileSync)((0, import_node_path13.join)(jervcodeAgentDir(env), "npm", "node_modules", ...PI_PACKAGE.split("/"), "package.json"), "utf8"));
3084
+ const manifest2 = JSON.parse((0, import_node_fs18.readFileSync)((0, import_node_path12.join)(jervcodeAgentDir(env), "npm", "node_modules", ...PI_PACKAGE.split("/"), "package.json"), "utf8"));
3181
3085
  return typeof manifest2.version === "string" ? manifest2.version : null;
3182
3086
  } catch {
3183
3087
  return null;
3184
3088
  }
3185
3089
  }
3186
3090
  function materializedManifestLocation(env) {
3187
- return (0, import_node_path13.join)(jervcodeAgentDir(env), "npm", "node_modules", ...PI_PACKAGE.split("/"));
3091
+ return (0, import_node_path12.join)(jervcodeAgentDir(env), "npm", "node_modules", ...PI_PACKAGE.split("/"));
3188
3092
  }
3189
3093
  var PI_LIST_SPEC = new RegExp(`npm:${PI_PACKAGE.replace("/", "\\/")}@(\\S+)`);
3190
3094
  function parseListText(stdout) {
@@ -3243,32 +3147,32 @@ function jervcodeArm(options) {
3243
3147
  detail,
3244
3148
  // C11: the constraint of the package pi LEFT materialised — read at result time, so defer/fail
3245
3149
  // carry the previous payload's declaration (#4973 reconsult ruling).
3246
- compat: readManifestCompat((0, import_node_path13.join)(jervcodeAgentDir(env), "npm", "node_modules", ...PI_PACKAGE.split("/"), "package.json"))
3150
+ compat: readManifestCompat((0, import_node_path12.join)(jervcodeAgentDir(env), "npm", "node_modules", ...PI_PACKAGE.split("/"), "package.json"))
3247
3151
  });
3248
3152
  const before = readPackageSpecs(env);
3249
- if (!before) return result(null, options.target, "defer", `cannot read ${(0, import_node_path13.join)(jervcodeAgentDir(env), "settings.json")}`);
3153
+ if (!before) return result(null, options.target, "defer", `cannot read ${(0, import_node_path12.join)(jervcodeAgentDir(env), "settings.json")}`);
3250
3154
  const from = installedVersion(env);
3251
3155
  const legacy = before.filter(isLegacyMmiPiPath);
3252
3156
  const highWater = journalHighWater(options.paths.journalPath, "jervcode", options.journalEvents);
3253
3157
  const floor = from && compareSemver(from, options.target) > 0 ? `installed ${from} is above candidate ${options.target} (monotonic)` : highWater && compareSemver(highWater, options.target) > 0 ? `journal high-water ${highWater} is above candidate ${options.target} (monotonic)` : null;
3254
3158
  if (options.dryRun) {
3255
3159
  const action = floor ? `hold ${from ?? "the install"} and skip the install (${floor})` : before.includes(exact) && from === options.target ? "keep exact pin" : `install ${exact}`;
3256
- return { surface: "jervcode", from, to: options.target, verdict: "ok", detail: `dry-run: would ${action}${legacy.length ? ` and retire ${legacy.length} legacy claude-cache path registration${legacy.length === 1 ? "" : "s"}` : ""}`, compat: readManifestCompat((0, import_node_path13.join)(jervcodeAgentDir(env), "npm", "node_modules", ...PI_PACKAGE.split("/"), "package.json")) };
3160
+ return { surface: "jervcode", from, to: options.target, verdict: "ok", detail: `dry-run: would ${action}${legacy.length ? ` and retire ${legacy.length} legacy claude-cache path registration${legacy.length === 1 ? "" : "s"}` : ""}`, compat: readManifestCompat((0, import_node_path12.join)(jervcodeAgentDir(env), "npm", "node_modules", ...PI_PACKAGE.split("/"), "package.json")) };
3257
3161
  }
3258
3162
  const hosted = hostEnv(env);
3259
3163
  const commands = hostCommands(env);
3260
3164
  const command = commands.find((bin) => runner(bin, ["--version"], hosted).status === 0);
3261
- if (!command) return { surface: "jervcode", from, to: options.target, verdict: "defer", detail: "neither `jervcode` nor `pi` answered --version \u2014 the host CLI is not on PATH", compat: readManifestCompat((0, import_node_path13.join)(jervcodeAgentDir(env), "npm", "node_modules", ...PI_PACKAGE.split("/"), "package.json")) };
3165
+ if (!command) return { surface: "jervcode", from, to: options.target, verdict: "defer", detail: "neither `jervcode` nor `pi` answered --version \u2014 the host CLI is not on PATH", compat: readManifestCompat((0, import_node_path12.join)(jervcodeAgentDir(env), "npm", "node_modules", ...PI_PACKAGE.split("/"), "package.json")) };
3262
3166
  if (!floor && (!before.includes(exact) || from !== options.target)) {
3263
3167
  const install = runner(command, ["install", exact], hosted);
3264
3168
  if (install.status !== 0) {
3265
- return { surface: "jervcode", from, to: options.target, verdict: "defer", detail: `${command} install ${exact} failed: ${failure2(install)}`, compat: readManifestCompat((0, import_node_path13.join)(jervcodeAgentDir(env), "npm", "node_modules", ...PI_PACKAGE.split("/"), "package.json")) };
3169
+ return { surface: "jervcode", from, to: options.target, verdict: "defer", detail: `${command} install ${exact} failed: ${failure2(install)}`, compat: readManifestCompat((0, import_node_path12.join)(jervcodeAgentDir(env), "npm", "node_modules", ...PI_PACKAGE.split("/"), "package.json")) };
3266
3170
  }
3267
3171
  }
3268
3172
  for (const stale of legacy) {
3269
3173
  const removed = runner(command, ["remove", stale], hosted);
3270
3174
  if (removed.status !== 0) {
3271
- return { surface: "jervcode", from, to: options.target, verdict: "defer", detail: `${command} remove of the legacy registration failed: ${failure2(removed)}`, compat: readManifestCompat((0, import_node_path13.join)(jervcodeAgentDir(env), "npm", "node_modules", ...PI_PACKAGE.split("/"), "package.json")) };
3175
+ return { surface: "jervcode", from, to: options.target, verdict: "defer", detail: `${command} remove of the legacy registration failed: ${failure2(removed)}`, compat: readManifestCompat((0, import_node_path12.join)(jervcodeAgentDir(env), "npm", "node_modules", ...PI_PACKAGE.split("/"), "package.json")) };
3272
3176
  }
3273
3177
  }
3274
3178
  const after = readPackageSpecs(env);
@@ -3276,7 +3180,7 @@ function jervcodeArm(options) {
3276
3180
  const legacyAfter = after?.filter(isLegacyMmiPiPath) ?? [];
3277
3181
  const retired = legacy.length ? `; retired ${legacy.length} legacy claude-cache path registration${legacy.length === 1 ? "" : "s"}` : "";
3278
3182
  if (floor && !legacyAfter.length) {
3279
- return { surface: "jervcode", from, to: converged ?? highWater ?? options.target, verdict: "skip", detail: `${floor}${retired}`, compat: readManifestCompat((0, import_node_path13.join)(jervcodeAgentDir(env), "npm", "node_modules", ...PI_PACKAGE.split("/"), "package.json")) };
3183
+ return { surface: "jervcode", from, to: converged ?? highWater ?? options.target, verdict: "skip", detail: `${floor}${retired}`, compat: readManifestCompat((0, import_node_path12.join)(jervcodeAgentDir(env), "npm", "node_modules", ...PI_PACKAGE.split("/"), "package.json")) };
3280
3184
  }
3281
3185
  if (!after?.includes(exact) || converged !== options.target || legacyAfter.length) {
3282
3186
  return {
@@ -3297,14 +3201,14 @@ function jervcodeArm(options) {
3297
3201
  }
3298
3202
 
3299
3203
  // src/arm-hermes.ts
3300
- var import_node_fs21 = require("node:fs");
3301
- var import_node_path14 = require("node:path");
3204
+ var import_node_fs19 = require("node:fs");
3205
+ var import_node_path13 = require("node:path");
3302
3206
  var PACKAGE2 = "@mutmutco/hermes-plugin";
3303
3207
  var MANIFEST2 = "plugin.yaml";
3304
3208
  var TREE_MARKERS_FALLBACK = [MANIFEST2, "__init__.py", "skills"];
3305
3209
  function yamlVersion(root) {
3306
3210
  try {
3307
- const text = (0, import_node_fs21.readFileSync)((0, import_node_path14.join)(root, MANIFEST2), "utf8");
3211
+ const text = (0, import_node_fs19.readFileSync)((0, import_node_path13.join)(root, MANIFEST2), "utf8");
3308
3212
  try {
3309
3213
  const version = JSON.parse(text).version;
3310
3214
  if (typeof version === "string" && version.trim()) return version.trim();
@@ -3318,7 +3222,7 @@ function yamlVersion(root) {
3318
3222
  }
3319
3223
  function packageTreeMarkers(root) {
3320
3224
  try {
3321
- const files = JSON.parse((0, import_node_fs21.readFileSync)((0, import_node_path14.join)(root, "package.json"), "utf8")).files;
3225
+ const files = JSON.parse((0, import_node_fs19.readFileSync)((0, import_node_path13.join)(root, "package.json"), "utf8")).files;
3322
3226
  if (Array.isArray(files) && files.length && files.every((entry) => typeof entry === "string" && entry.trim())) {
3323
3227
  return files.map((entry) => entry.trim());
3324
3228
  }
@@ -3327,10 +3231,10 @@ function packageTreeMarkers(root) {
3327
3231
  return TREE_MARKERS_FALLBACK;
3328
3232
  }
3329
3233
  function markerPresent(root, rel) {
3330
- const path = (0, import_node_path14.join)(root, ...rel.split("/"));
3331
- if (!(0, import_node_fs21.existsSync)(path)) return false;
3234
+ const path = (0, import_node_path13.join)(root, ...rel.split("/"));
3235
+ if (!(0, import_node_fs19.existsSync)(path)) return false;
3332
3236
  try {
3333
- const stat = (0, import_node_fs21.statSync)(path);
3237
+ const stat = (0, import_node_fs19.statSync)(path);
3334
3238
  return stat.isFile() || stat.isDirectory();
3335
3239
  } catch {
3336
3240
  return false;
@@ -3349,13 +3253,13 @@ function treeIncompleteDetail(root, label) {
3349
3253
  }
3350
3254
  function packageIdentity(root) {
3351
3255
  try {
3352
- return JSON.parse((0, import_node_fs21.readFileSync)((0, import_node_path14.join)(root, "package.json"), "utf8")).name === PACKAGE2;
3256
+ return JSON.parse((0, import_node_fs19.readFileSync)((0, import_node_path13.join)(root, "package.json"), "utf8")).name === PACKAGE2;
3353
3257
  } catch {
3354
3258
  return false;
3355
3259
  }
3356
3260
  }
3357
3261
  function probeHermesInstallation(env = process.env) {
3358
- const location = (0, import_node_path14.join)(hermesHome(env), "plugins", "mmi");
3262
+ const location = (0, import_node_path13.join)(hermesHome(env), "plugins", "mmi");
3359
3263
  const version = yamlVersion(location);
3360
3264
  return { version, location, detail: version ? "installed Hermes plugin manifest" : "installed Hermes plugin manifest was unreadable" };
3361
3265
  }
@@ -3364,7 +3268,7 @@ function mmiOwned2(root) {
3364
3268
  }
3365
3269
  function discard2(path) {
3366
3270
  try {
3367
- (0, import_node_fs21.rmSync)(path, { recursive: true, force: true });
3271
+ (0, import_node_fs19.rmSync)(path, { recursive: true, force: true });
3368
3272
  } catch {
3369
3273
  }
3370
3274
  }
@@ -3372,19 +3276,19 @@ function message2(error) {
3372
3276
  return String(error?.message ?? error).replace(/\s+/g, " ").slice(0, 200);
3373
3277
  }
3374
3278
  function materializeHermesSkills(home) {
3375
- const pluginSkills = (0, import_node_path14.join)(home, "plugins", "mmi", "skills");
3376
- const skillsRoot = (0, import_node_path14.join)(home, "skills");
3377
- const targetRoot = (0, import_node_path14.join)(skillsRoot, "mmi");
3279
+ const pluginSkills = (0, import_node_path13.join)(home, "plugins", "mmi", "skills");
3280
+ const skillsRoot = (0, import_node_path13.join)(home, "skills");
3281
+ const targetRoot = (0, import_node_path13.join)(skillsRoot, "mmi");
3378
3282
  try {
3379
- if (!(0, import_node_fs21.existsSync)(pluginSkills)) return { ok: false, detail: `plugin skills tree missing at ${pluginSkills}` };
3380
- const names = (0, import_node_fs21.readdirSync)(pluginSkills, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith("_")).map((entry) => entry.name);
3283
+ if (!(0, import_node_fs19.existsSync)(pluginSkills)) return { ok: false, detail: `plugin skills tree missing at ${pluginSkills}` };
3284
+ const names = (0, import_node_fs19.readdirSync)(pluginSkills, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith("_")).map((entry) => entry.name);
3381
3285
  if (!names.length) return { ok: false, detail: `plugin skills tree is empty at ${pluginSkills}` };
3382
- (0, import_node_fs21.mkdirSync)(skillsRoot, { recursive: true });
3383
- const incoming = (0, import_node_path14.join)(skillsRoot, ".mmi-incoming");
3286
+ (0, import_node_fs19.mkdirSync)(skillsRoot, { recursive: true });
3287
+ const incoming = (0, import_node_path13.join)(skillsRoot, ".mmi-incoming");
3384
3288
  discard2(incoming);
3385
- (0, import_node_fs21.cpSync)(pluginSkills, incoming, { recursive: true });
3289
+ (0, import_node_fs19.cpSync)(pluginSkills, incoming, { recursive: true });
3386
3290
  discard2(targetRoot);
3387
- (0, import_node_fs21.renameSync)(incoming, targetRoot);
3291
+ (0, import_node_fs19.renameSync)(incoming, targetRoot);
3388
3292
  return { ok: true, detail: `provisioned ${names.length} skills to ${targetRoot}` };
3389
3293
  } catch (error) {
3390
3294
  return { ok: false, detail: message2(error) };
@@ -3406,8 +3310,8 @@ function hermesHomes(env = process.env) {
3406
3310
  const root = hermesHome(env);
3407
3311
  const homes = [root];
3408
3312
  try {
3409
- for (const entry of (0, import_node_fs21.readdirSync)((0, import_node_path14.join)(root, "profiles"), { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
3410
- if (entry.isDirectory() && !entry.name.startsWith(".")) homes.push((0, import_node_path14.join)(root, "profiles", entry.name));
3313
+ for (const entry of (0, import_node_fs19.readdirSync)((0, import_node_path13.join)(root, "profiles"), { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
3314
+ if (entry.isDirectory() && !entry.name.startsWith(".")) homes.push((0, import_node_path13.join)(root, "profiles", entry.name));
3411
3315
  }
3412
3316
  } catch {
3413
3317
  }
@@ -3433,32 +3337,29 @@ function hermesArm(options) {
3433
3337
  const primary = results[0].result;
3434
3338
  if (results.length === 1) return primary;
3435
3339
  const worst = results.reduce((a, b) => VERDICT_RANK[b.result.verdict] > VERDICT_RANK[a.result.verdict] ? b : a);
3436
- const detail = results.map(({ home, result }, index) => `${index === 0 ? "home" : `profile ${(0, import_node_path14.basename)(home)}`}: ${result.detail}`).join(" | ");
3340
+ const detail = results.map(({ home, result }, index) => `${index === 0 ? "home" : `profile ${(0, import_node_path13.basename)(home)}`}: ${result.detail}`).join(" | ");
3437
3341
  return {
3438
3342
  surface: "hermes",
3439
3343
  from: primary.from,
3440
3344
  to: primary.to,
3441
3345
  verdict: worst.result.verdict,
3442
3346
  detail: `${homes.length} Hermes homes \u2014 ${detail}`,
3443
- launchStaged: results.some(({ result }) => result.launchStaged) || void 0,
3444
- source: primary.source
3347
+ launchStaged: results.some(({ result }) => result.launchStaged) || void 0
3445
3348
  };
3446
3349
  }
3447
3350
  function armHermesHome(home, env, options, primary) {
3448
- const parent = (0, import_node_path14.join)(home, "plugins");
3449
- const live = (0, import_node_path14.join)(parent, "mmi");
3351
+ const parent = (0, import_node_path13.join)(home, "plugins");
3352
+ const live = (0, import_node_path13.join)(parent, "mmi");
3450
3353
  const installed = yamlVersion(live);
3451
- let source;
3452
3354
  const result = (from, to, verdict, detail, launchStaged = false) => ({
3453
3355
  surface: "hermes",
3454
3356
  from,
3455
3357
  to,
3456
3358
  verdict,
3457
3359
  detail,
3458
- launchStaged: launchStaged || void 0,
3459
- ...source ? { source } : {}
3360
+ launchStaged: launchStaged || void 0
3460
3361
  });
3461
- if ((0, import_node_fs21.existsSync)(live) && !mmiOwned2(live)) {
3362
+ if ((0, import_node_fs19.existsSync)(live) && !mmiOwned2(live)) {
3462
3363
  return result(installed, options.target, "defer", `${live} carries no ${PACKAGE2} package identity \u2014 refusing to displace an unmanaged Hermes mmi plugin`);
3463
3364
  }
3464
3365
  if (installed && compareSemver(installed, options.target) > 0) return result(installed, installed, "skip", `installed ${installed} is above candidate ${options.target} (monotonic)`);
@@ -3472,29 +3373,28 @@ function armHermesHome(home, env, options, primary) {
3472
3373
  if (!enabled2.ok) return result(installed, options.target, "fail", `plugin at target ${options.target}, but ${enabled2.detail}`);
3473
3374
  return result(installed, options.target, "ok", `already at target ${options.target}; ${skills2.detail}; ${enabled2.detail}`);
3474
3375
  }
3475
- if (options.dryRun) return result(installed, options.target, "ok", `dry-run: would stage ${PACKAGE2}@${options.target}, atomically switch ${installed ?? "absent"} -> ${options.target}, provision skills into ${(0, import_node_path14.join)(home, "skills", "mmi")}, then enable mmi in plugins.enabled`);
3476
- const staged = stagePackage({ surface: "hermes", packageName: PACKAGE2, target: options.target, witness: MANIFEST2, paths: options.paths, env, payload: options.payload });
3376
+ if (options.dryRun) return result(installed, options.target, "ok", `dry-run: would stage ${PACKAGE2}@${options.target}, atomically switch ${installed ?? "absent"} -> ${options.target}, provision skills into ${(0, import_node_path13.join)(home, "skills", "mmi")}, then enable mmi in plugins.enabled`);
3377
+ const staged = stagePackage({ surface: "hermes", packageName: PACKAGE2, target: options.target, witness: MANIFEST2, paths: options.paths, env });
3477
3378
  if ("defer" in staged) return result(installed, options.target, "defer", staged.defer);
3478
- source = staged.source;
3479
3379
  const stagedVersion = yamlVersion(staged.packageRoot);
3480
3380
  if (stagedVersion !== options.target) {
3481
3381
  return result(installed, options.target, "defer", `staged Hermes manifest is ${stagedVersion ?? "unreadable"}, expected ${options.target}`);
3482
3382
  }
3483
3383
  const stagedTree = treeIncompleteDetail(staged.packageRoot, "staged Hermes");
3484
3384
  if (stagedTree) return result(installed, options.target, "defer", stagedTree);
3485
- const scratch = (0, import_node_path14.join)(home, ".mmi-updater");
3486
- const launchTargetPath = (0, import_node_path14.join)(scratch, "launch-target.json");
3487
- const incomingRoot = (0, import_node_path14.join)(scratch, "incoming");
3488
- const incoming = (0, import_node_path14.join)(incomingRoot, options.target);
3489
- const quarantine = (0, import_node_path14.join)(scratch, "quarantine", `${installed ?? "unknown"}-${Date.now()}`);
3385
+ const scratch = (0, import_node_path13.join)(home, ".mmi-updater");
3386
+ const launchTargetPath = (0, import_node_path13.join)(scratch, "launch-target.json");
3387
+ const incomingRoot = (0, import_node_path13.join)(scratch, "incoming");
3388
+ const incoming = (0, import_node_path13.join)(incomingRoot, options.target);
3389
+ const quarantine = (0, import_node_path13.join)(scratch, "quarantine", `${installed ?? "unknown"}-${Date.now()}`);
3490
3390
  const priorLaunch = readLaunchTarget(launchTargetPath);
3491
3391
  const reuseIncoming = priorLaunch?.target === options.target && priorLaunch.incoming === incoming && yamlVersion(incoming) === options.target && treeHealthy2(incoming);
3492
3392
  if (!reuseIncoming) {
3493
3393
  try {
3494
- (0, import_node_fs21.mkdirSync)(parent, { recursive: true });
3495
- (0, import_node_fs21.mkdirSync)((0, import_node_path14.join)(scratch, "quarantine"), { recursive: true });
3394
+ (0, import_node_fs19.mkdirSync)(parent, { recursive: true });
3395
+ (0, import_node_fs19.mkdirSync)((0, import_node_path13.join)(scratch, "quarantine"), { recursive: true });
3496
3396
  discard2(incomingRoot);
3497
- (0, import_node_fs21.cpSync)(staged.packageRoot, incoming, { recursive: true });
3397
+ (0, import_node_fs19.cpSync)(staged.packageRoot, incoming, { recursive: true });
3498
3398
  } catch (error) {
3499
3399
  return result(installed, options.target, "defer", `cannot place incoming Hermes generation: ${message2(error)}`);
3500
3400
  }
@@ -3509,14 +3409,14 @@ function armHermesHome(home, env, options, primary) {
3509
3409
  return result(installed, options.target, "defer", incomingTree);
3510
3410
  }
3511
3411
  }
3512
- const displaced = (0, import_node_fs21.existsSync)(live);
3412
+ const displaced = (0, import_node_fs19.existsSync)(live);
3513
3413
  try {
3514
- (0, import_node_fs21.mkdirSync)((0, import_node_path14.join)(scratch, "quarantine"), { recursive: true });
3515
- if (displaced) (0, import_node_fs21.renameSync)(live, quarantine);
3516
- (0, import_node_fs21.renameSync)(incoming, live);
3414
+ (0, import_node_fs19.mkdirSync)((0, import_node_path13.join)(scratch, "quarantine"), { recursive: true });
3415
+ if (displaced) (0, import_node_fs19.renameSync)(live, quarantine);
3416
+ (0, import_node_fs19.renameSync)(incoming, live);
3517
3417
  } catch (error) {
3518
- if (displaced && !(0, import_node_fs21.existsSync)(live)) try {
3519
- (0, import_node_fs21.renameSync)(quarantine, live);
3418
+ if (displaced && !(0, import_node_fs19.existsSync)(live)) try {
3419
+ (0, import_node_fs19.renameSync)(quarantine, live);
3520
3420
  } catch {
3521
3421
  }
3522
3422
  discard2(incomingRoot);
@@ -3527,12 +3427,12 @@ function armHermesHome(home, env, options, primary) {
3527
3427
  const liveVersion = yamlVersion(live);
3528
3428
  const liveTree = treeIncompleteDetail(live, "live Hermes");
3529
3429
  if (liveVersion !== options.target || liveTree) {
3530
- const broken = (0, import_node_path14.join)(scratch, "rejected", `${options.target}-${Date.now()}`);
3430
+ const broken = (0, import_node_path13.join)(scratch, "rejected", `${options.target}-${Date.now()}`);
3531
3431
  const verifyDetail = liveVersion !== options.target ? `manifest is ${liveVersion ?? "unreadable"}, expected ${options.target}` : liveTree;
3532
3432
  try {
3533
- (0, import_node_fs21.mkdirSync)((0, import_node_path14.join)(scratch, "rejected"), { recursive: true });
3534
- (0, import_node_fs21.renameSync)(live, broken);
3535
- if (displaced) (0, import_node_fs21.renameSync)(quarantine, live);
3433
+ (0, import_node_fs19.mkdirSync)((0, import_node_path13.join)(scratch, "rejected"), { recursive: true });
3434
+ (0, import_node_fs19.renameSync)(live, broken);
3435
+ if (displaced) (0, import_node_fs19.renameSync)(quarantine, live);
3536
3436
  } catch (error) {
3537
3437
  return result(installed, liveVersion ?? "unknown", "fail", `post-switch Hermes verification failed and recovery failed: ${message2(error)}`);
3538
3438
  }
@@ -3547,199 +3447,12 @@ function armHermesHome(home, env, options, primary) {
3547
3447
  return result(installed, options.target, "ok", `converged ${installed ?? "absent"} -> ${options.target} (staged, verified, switched${displaced ? `; previous generation quarantined at ${quarantine}` : ""}); ${skills.detail}; ${enabled.detail}`);
3548
3448
  }
3549
3449
  function probeHermesLaunchStaging(env = process.env) {
3550
- return probeLaunchTargetVersion((0, import_node_path14.join)(hermesHome(env), ".mmi-updater", "launch-target.json"), yamlVersion);
3551
- }
3552
-
3553
- // src/payload-source.ts
3554
- var import_node_fs22 = require("node:fs");
3555
- var import_node_path15 = require("node:path");
3556
-
3557
- // ../installer/launcher/src/login-github.ts
3558
- async function postJson(url, body, fetchImpl) {
3559
- return fetchImpl(url, {
3560
- method: "POST",
3561
- headers: { "content-type": "application/json" },
3562
- body: JSON.stringify(body)
3563
- });
3564
- }
3565
- async function readBody(response) {
3566
- try {
3567
- return await response.text();
3568
- } catch {
3569
- return "";
3570
- }
3571
- }
3572
- function gateRefusal(method, url, status, body) {
3573
- const head = body.replace(/\s+/g, " ").trim().slice(0, 200);
3574
- return `the sign-in server refused the request \u2014 ${method} ${url} \u2192 ${status}${head ? `: ${head}` : ""}`;
3575
- }
3576
- async function refreshAccessToken(config, refreshToken, fetchImpl = fetch) {
3577
- const url = `${config.host}/gate/refresh`;
3578
- const response = await postJson(url, { refresh_token: refreshToken }, fetchImpl);
3579
- if (response.status === 403) return null;
3580
- if (!response.ok) {
3581
- throw new Error(gateRefusal("POST", url, response.status, await readBody(response)));
3582
- }
3583
- const data = await response.json();
3584
- if (typeof data.access_token !== "string" || typeof data.expires_in !== "number") {
3585
- throw new Error("the sign-in server returned a malformed refresh");
3586
- }
3587
- return {
3588
- accessToken: data.access_token,
3589
- expiresIn: data.expires_in,
3590
- ...typeof data.refresh_token === "string" ? { refreshToken: data.refresh_token } : {}
3591
- };
3592
- }
3593
-
3594
- // ../installer/launcher/src/login-google.ts
3595
- async function refreshGoogleToken(host, clientId, refreshToken, fetchImpl = fetch) {
3596
- const server = host.replace(/\/+$/, "");
3597
- const response = await fetchImpl(`${server}/oauth/token`, {
3598
- method: "POST",
3599
- headers: { "content-type": "application/x-www-form-urlencoded" },
3600
- body: new URLSearchParams({
3601
- grant_type: "refresh_token",
3602
- refresh_token: refreshToken,
3603
- client_id: clientId
3604
- }).toString()
3605
- });
3606
- if (!response.ok) return null;
3607
- const tokens = await response.json();
3608
- if (typeof tokens.access_token !== "string" || typeof tokens.expires_in !== "number") return null;
3609
- return {
3610
- accessToken: tokens.access_token,
3611
- refreshToken: typeof tokens.refresh_token === "string" ? tokens.refresh_token : refreshToken,
3612
- expiresIn: tokens.expires_in
3613
- };
3614
- }
3615
-
3616
- // ../installer/launcher/src/tokens.ts
3617
- async function ensureFreshToken(config, dir, fetchImpl = fetch) {
3618
- const stored = readTokens(dir);
3619
- if (!stored) return null;
3620
- if (stored.expiresAt - Date.now() > 6e4) return stored.accessToken;
3621
- if (!stored.refreshToken) return null;
3622
- if (config.loginKind === "github") {
3623
- const refreshed2 = await refreshAccessToken(config, stored.refreshToken, fetchImpl);
3624
- if (!refreshed2) {
3625
- clearTokens(dir);
3626
- return null;
3627
- }
3628
- writeTokens(dir, {
3629
- accessToken: refreshed2.accessToken,
3630
- refreshToken: refreshed2.refreshToken ?? stored.refreshToken,
3631
- expiresAt: Date.now() + refreshed2.expiresIn * 1e3
3632
- });
3633
- return refreshed2.accessToken;
3634
- }
3635
- if (!stored.clientId) {
3636
- clearTokens(dir);
3637
- return null;
3638
- }
3639
- const refreshed = await refreshGoogleToken(config.host, stored.clientId, stored.refreshToken, fetchImpl);
3640
- if (!refreshed) {
3641
- clearTokens(dir);
3642
- return null;
3643
- }
3644
- writeTokens(dir, {
3645
- accessToken: refreshed.accessToken,
3646
- refreshToken: refreshed.refreshToken,
3647
- expiresAt: Date.now() + refreshed.expiresIn * 1e3,
3648
- clientId: stored.clientId
3649
- });
3650
- return refreshed.accessToken;
3651
- }
3652
-
3653
- // src/payload-source.ts
3654
- var PayloadIntegrityError = class extends Error {
3655
- };
3656
- function tarballName(name, version) {
3657
- return `${name.replace("@", "").replace("/", "-")}-${version}.tgz`;
3658
- }
3659
- var mmiConfig = {
3660
- product: installer_product_default.launcher.product,
3661
- host: installer_product_default.launcher.host,
3662
- publicKey: installer_product_default.launcher.key,
3663
- binName: installer_product_default.launcher.bin,
3664
- loginKind: "github"
3665
- };
3666
- async function resolvePayloadTarball(options) {
3667
- const { packageName, version, paths } = options;
3668
- if (!/^\d+\.\d+\.\d+[A-Za-z0-9._-]*$/.test(version)) return null;
3669
- const file = tarballName(packageName, version);
3670
- const dir = options.productDir ?? (process.env.LAUNCHER_DIR || defaultProductDir("mmi"));
3671
- const launcherCache = cachedPayloadForVersion(dir, version);
3672
- if (launcherCache) {
3673
- try {
3674
- const metadata = JSON.parse((0, import_node_fs22.readFileSync)((0, import_node_path15.join)(launcherCache, "payload.json"), "utf8"));
3675
- if (metadata.version === version && (0, import_node_fs22.existsSync)((0, import_node_path15.join)(launcherCache, file))) return (0, import_node_path15.join)(launcherCache, file);
3676
- } catch {
3677
- }
3678
- }
3679
- const config = options.config ?? mmiConfig;
3680
- const cache = (0, import_node_path15.join)(paths.root, "payload-cache", version);
3681
- const manifestFile = (0, import_node_path15.join)(cache, "manifest.json");
3682
- let manifest2 = null;
3683
- try {
3684
- manifest2 = parseManifest(JSON.parse((0, import_node_fs22.readFileSync)(manifestFile, "utf8")));
3685
- if (!verifyManifest(manifest2, manifest2.signature, config)) throw new PayloadIntegrityError("cached release manifest signature is invalid");
3686
- if (manifest2.version !== version) throw new PayloadIntegrityError("cached release manifest version is wrong");
3687
- } catch (error) {
3688
- if (error instanceof PayloadIntegrityError) throw error;
3689
- if ((0, import_node_fs22.existsSync)(manifestFile)) throw new PayloadIntegrityError("cached release manifest is malformed");
3690
- manifest2 = null;
3691
- }
3692
- const cachedEntry = manifest2?.files.find((entry2) => entry2.path === file);
3693
- if (cachedEntry && (0, import_node_fs22.existsSync)((0, import_node_path15.join)(cache, file))) {
3694
- if (!verifyFileBytes(cachedEntry, (0, import_node_fs22.readFileSync)((0, import_node_path15.join)(cache, file)))) throw new PayloadIntegrityError(`cached ${file} failed its checksum`);
3695
- return (0, import_node_path15.join)(cache, file);
3696
- }
3697
- if (!(0, import_node_fs22.existsSync)(dir)) return null;
3698
- let token;
3699
- try {
3700
- token = await ensureFreshToken(config, dir, options.fetchImpl);
3701
- } catch {
3702
- return null;
3703
- }
3704
- if (!token) return null;
3705
- const fetchImpl = options.fetchImpl ?? fetch;
3706
- try {
3707
- manifest2 = await fetchVerifiedManifest(config, token, (url, init) => fetchImpl(url, { ...init, signal: AbortSignal.timeout(1e4) }));
3708
- } catch (error) {
3709
- if (error instanceof NeedsLoginError || error instanceof ForbiddenError || error instanceof TypeError || error.name === "AbortError") return null;
3710
- if (String(error.message).startsWith("the release server refused")) return null;
3711
- throw new PayloadIntegrityError(`release manifest verification failed: ${error.message}`);
3712
- }
3713
- if (manifest2.version !== version) return null;
3714
- const entry = manifest2.files.find((candidate) => candidate.path === file);
3715
- if (!entry) return null;
3716
- let bytes;
3717
- try {
3718
- const encoded = entry.path.split("/").map(encodeURIComponent).join("/");
3719
- const response = await fetchImpl(`${config.host}/release/${encoded}`, { headers: { authorization: `Bearer ${token}` }, signal: AbortSignal.timeout(3e5) });
3720
- if (!response.ok) return null;
3721
- bytes = Buffer.from(await response.arrayBuffer());
3722
- } catch {
3723
- return null;
3724
- }
3725
- if (!verifyFileBytes(entry, bytes)) throw new PayloadIntegrityError(`${file} failed its checksum`);
3726
- (0, import_node_fs22.mkdirSync)(cache, { recursive: true });
3727
- const temporary = (0, import_node_path15.join)(cache, `${file}.${process.pid}.tmp`);
3728
- try {
3729
- (0, import_node_fs22.writeFileSync)(temporary, bytes);
3730
- (0, import_node_fs22.renameSync)(temporary, (0, import_node_path15.join)(cache, file));
3731
- const signed = `${manifestFile}.${process.pid}.tmp`;
3732
- (0, import_node_fs22.writeFileSync)(signed, JSON.stringify(manifest2));
3733
- (0, import_node_fs22.renameSync)(signed, manifestFile);
3734
- } finally {
3735
- (0, import_node_fs22.rmSync)(temporary, { force: true });
3736
- }
3737
- return (0, import_node_path15.join)(cache, file);
3450
+ return probeLaunchTargetVersion((0, import_node_path13.join)(hermesHome(env), ".mmi-updater", "launch-target.json"), yamlVersion);
3738
3451
  }
3739
3452
 
3740
3453
  // src/reap.ts
3741
- var import_node_fs23 = require("node:fs");
3742
- var import_node_path16 = require("node:path");
3454
+ var import_node_fs20 = require("node:fs");
3455
+ var import_node_path14 = require("node:path");
3743
3456
  var import_node_perf_hooks = require("node:perf_hooks");
3744
3457
  function elapsedMs(startedAt) {
3745
3458
  return Math.round((import_node_perf_hooks.performance.now() - startedAt) * 10) / 10;
@@ -3748,7 +3461,7 @@ var KEEP_GENERATIONS2 = 2;
3748
3461
  var SCRATCH_AGE_MS = 24 * 60 * 6e4;
3749
3462
  function listDirs(path) {
3750
3463
  try {
3751
- return (0, import_node_fs23.readdirSync)(path, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
3464
+ return (0, import_node_fs20.readdirSync)(path, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
3752
3465
  } catch {
3753
3466
  return [];
3754
3467
  }
@@ -3756,7 +3469,7 @@ function listDirs(path) {
3756
3469
  function generationSets(root) {
3757
3470
  const children = listDirs(root);
3758
3471
  if (children.some((name) => parseSemver(name))) return [root];
3759
- return children.map((name) => (0, import_node_path16.join)(root, name)).filter((path) => listDirs(path).some((name) => parseSemver(name)));
3472
+ return children.map((name) => (0, import_node_path14.join)(root, name)).filter((path) => listDirs(path).some((name) => parseSemver(name)));
3760
3473
  }
3761
3474
  function pruneGenerations(root, category, dryRun) {
3762
3475
  let reaped = 0;
@@ -3769,7 +3482,7 @@ function pruneGenerations(root, category, dryRun) {
3769
3482
  continue;
3770
3483
  }
3771
3484
  try {
3772
- (0, import_node_fs23.rmSync)((0, import_node_path16.join)(set, version), { recursive: true, force: true });
3485
+ (0, import_node_fs20.rmSync)((0, import_node_path14.join)(set, version), { recursive: true, force: true });
3773
3486
  reaped += 1;
3774
3487
  } catch (error) {
3775
3488
  failures.push(`${version}: ${error?.code ?? error?.message ?? error}`);
@@ -3783,8 +3496,8 @@ function pruneGenerations(root, category, dryRun) {
3783
3496
  }
3784
3497
  var LEASE_STEAL_SCRATCH = /^lease\.lock\.stale-\d+$/;
3785
3498
  function atomicWriteScratch(path) {
3786
- const literal = (0, import_node_path16.basename)(path).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3787
- return { dir: (0, import_node_path16.dirname)(path), pattern: new RegExp(`^${literal}\\.tmp-\\d+$`) };
3499
+ const literal = (0, import_node_path14.basename)(path).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3500
+ return { dir: (0, import_node_path14.dirname)(path), pattern: new RegExp(`^${literal}\\.tmp-\\d+$`) };
3788
3501
  }
3789
3502
  function reapScratch(context, dryRun) {
3790
3503
  const category = "scratch";
@@ -3802,7 +3515,7 @@ function reapScratch(context, dryRun) {
3802
3515
  for (const [dir, patterns] of scanned) {
3803
3516
  let entries;
3804
3517
  try {
3805
- entries = (0, import_node_fs23.readdirSync)(dir, { withFileTypes: true });
3518
+ entries = (0, import_node_fs20.readdirSync)(dir, { withFileTypes: true });
3806
3519
  } catch {
3807
3520
  unreadable.push(dir);
3808
3521
  continue;
@@ -3810,10 +3523,10 @@ function reapScratch(context, dryRun) {
3810
3523
  for (const entry of entries) {
3811
3524
  if (!patterns.some((pattern) => pattern.test(entry.name))) continue;
3812
3525
  if (!entry.isFile()) continue;
3813
- const path = (0, import_node_path16.join)(dir, entry.name);
3526
+ const path = (0, import_node_path14.join)(dir, entry.name);
3814
3527
  let ageMs;
3815
3528
  try {
3816
- ageMs = now - (0, import_node_fs23.statSync)(path).mtimeMs;
3529
+ ageMs = now - (0, import_node_fs20.statSync)(path).mtimeMs;
3817
3530
  } catch {
3818
3531
  continue;
3819
3532
  }
@@ -3823,7 +3536,7 @@ function reapScratch(context, dryRun) {
3823
3536
  continue;
3824
3537
  }
3825
3538
  try {
3826
- (0, import_node_fs23.rmSync)(path, { force: true });
3539
+ (0, import_node_fs20.rmSync)(path, { force: true });
3827
3540
  reaped += 1;
3828
3541
  } catch (error) {
3829
3542
  failures.push(`${entry.name}: ${error?.code ?? error?.message ?? error}`);
@@ -3882,8 +3595,7 @@ async function reconcile(options) {
3882
3595
  const summary = { run, target: null, gate: null, managedSurfaces: null, atomicity: null, cli: null, updater: null, plugins: [], reap: [], surfaces: [], journalOk: true, reexec: null, exit: 0 };
3883
3596
  const recordArm = (arm, durationMs) => {
3884
3597
  if (arm.verdict === "fail") arm.repeatFailure = journalSurfaceRepeatedFail(paths.journalPath, arm.surface, run);
3885
- if (arm.source && !arm.detail.includes(`source: ${arm.source}`)) arm.detail += ` (source: ${arm.source})`;
3886
- journal({ kind: "arm", surface: arm.surface, from: arm.from, to: arm.to, verdict: arm.verdict, detail: arm.detail, source: arm.source, compat: arm.compat, durationMs });
3598
+ journal({ kind: "arm", surface: arm.surface, from: arm.from, to: arm.to, verdict: arm.verdict, detail: arm.detail, compat: arm.compat, durationMs });
3887
3599
  options.onArm?.({ ...arm, ...durationMs === void 0 ? {} : { durationMs } });
3888
3600
  if (arm.verdict === "ok" && !options.dryRun && !arm.launchStaged) clearPending(paths, arm.surface);
3889
3601
  if (arm.verdict === "defer") summary.exit = Math.max(summary.exit, 2);
@@ -3968,20 +3680,10 @@ async function reconcile(options) {
3968
3680
  phase("resolve", "ok");
3969
3681
  options.onTargetResolved?.(summary.target, summary.gate);
3970
3682
  phase("check", "running");
3971
- const payloadFor = async (packageName) => {
3972
- if (options.dryRun) return null;
3973
- try {
3974
- return await resolvePayloadTarball({ packageName, version: summary.target, paths });
3975
- } catch (error) {
3976
- if (error instanceof PayloadIntegrityError) return { defer: `payload integrity refusal: ${error.message}` };
3977
- return null;
3978
- }
3979
- };
3980
3683
  say("updater: self-bootstrap");
3981
3684
  const selfStartedAt = import_node_perf_hooks2.performance.now();
3982
3685
  const self = npmGlobalArm({
3983
3686
  surface: "updater",
3984
- payload: await payloadFor("@mutmutco/hub"),
3985
3687
  packageName: "@mutmutco/hub",
3986
3688
  distRel: "dist/index.cjs",
3987
3689
  target: summary.target,
@@ -4004,7 +3706,6 @@ async function reconcile(options) {
4004
3706
  const cliStartedAt = import_node_perf_hooks2.performance.now();
4005
3707
  const cli = npmGlobalArm({
4006
3708
  surface: "cli",
4007
- payload: await payloadFor("@mutmutco/cli"),
4008
3709
  packageName: "@mutmutco/cli",
4009
3710
  distRel: "dist/index.cjs",
4010
3711
  target: summary.target,
@@ -4030,9 +3731,7 @@ async function reconcile(options) {
4030
3731
  }
4031
3732
  say(`${probe.id}: converging to v${summary.target}`);
4032
3733
  const armStartedAt = import_node_perf_hooks2.performance.now();
4033
- const packageName = probe.id === "claude" ? "@mutmutco/claude-plugin" : probe.id === "cursor" ? "@mutmutco/cursor-plugin" : probe.id === "hermes" ? "@mutmutco/hermes-plugin" : null;
4034
- const payload = packageName ? await payloadFor(packageName) : null;
4035
- const arm = probe.id === "claude" ? claudeArm({ target: summary.target, dryRun: options.dryRun, paths, env, repoUrl, journalEvents, payload }) : probe.id === "codex" ? codexArm({ target: summary.target, dryRun: options.dryRun, env, repoUrl }) : probe.id === "cursor" ? cursorArm({ target: summary.target, dryRun: options.dryRun, paths, env, journalEvents, payload }) : probe.id === "jervcode" ? jervcodeArm({ target: summary.target, dryRun: options.dryRun, paths, env, journalEvents }) : probe.id === "hermes" ? hermesArm({ target: summary.target, dryRun: options.dryRun, paths, env, hostPresent: probe.present, journalEvents, payload }) : null;
3734
+ const arm = probe.id === "claude" ? claudeArm({ target: summary.target, dryRun: options.dryRun, paths, env, repoUrl, journalEvents }) : probe.id === "codex" ? codexArm({ target: summary.target, dryRun: options.dryRun, env, repoUrl }) : probe.id === "cursor" ? cursorArm({ target: summary.target, dryRun: options.dryRun, paths, env, journalEvents }) : probe.id === "jervcode" ? jervcodeArm({ target: summary.target, dryRun: options.dryRun, paths, env, journalEvents }) : probe.id === "hermes" ? hermesArm({ target: summary.target, dryRun: options.dryRun, paths, env, hostPresent: probe.present, journalEvents }) : null;
4036
3735
  if (arm) {
4037
3736
  summary.plugins.push(arm);
4038
3737
  summary.surfaces.push({ id: probe.id, present: true, action: `arm-${arm.verdict}` });
@@ -4068,9 +3767,9 @@ async function reconcile(options) {
4068
3767
 
4069
3768
  // src/scheduler.ts
4070
3769
  var import_node_child_process8 = require("node:child_process");
4071
- var import_node_fs24 = require("node:fs");
3770
+ var import_node_fs21 = require("node:fs");
4072
3771
  var import_node_os8 = require("node:os");
4073
- var import_node_path17 = require("node:path");
3772
+ var import_node_path15 = require("node:path");
4074
3773
  var TASK_NAME = "MMI Fleet Updater";
4075
3774
  var LAUNCHER_FILE = "reconcile-hidden.vbs";
4076
3775
  var RUN_BOUND = "PT15M";
@@ -4228,7 +3927,7 @@ WantedBy=timers.target
4228
3927
  }
4229
3928
  function readFileOrNull(path) {
4230
3929
  try {
4231
- return (0, import_node_fs24.readFileSync)(path, "utf8");
3930
+ return (0, import_node_fs21.readFileSync)(path, "utf8");
4232
3931
  } catch {
4233
3932
  return null;
4234
3933
  }
@@ -4277,7 +3976,7 @@ function windowsSchedulerStatus(env) {
4277
3976
  return { ok: false, supported: true, enabled: false, ...EMPTY_RUN_INFO, detail: `"${TASK_NAME}" is not registered \u2014 run \`mmi-hub autoupdate on\`` };
4278
3977
  }
4279
3978
  const hubDist = globalDist(env, "@mutmutco/hub", "dist/index.cjs");
4280
- const launcherPath = (0, import_node_path17.join)(statePaths(env).root, LAUNCHER_FILE);
3979
+ const launcherPath = (0, import_node_path15.join)(statePaths(env).root, LAUNCHER_FILE);
4281
3980
  const info = taskRunInfo();
4282
3981
  const runInfo = info ?? EMPTY_RUN_INFO;
4283
3982
  const fail2 = (detail) => ({ ok: false, supported: true, enabled: true, ...runInfo, detail });
@@ -4302,13 +4001,13 @@ function windowsSchedulerStatus(env) {
4302
4001
  return { ok: true, supported: true, enabled: true, ...runInfo, detail: `"${TASK_NAME}" registered ${CADENCE}; ${points}; ${ran}; next ${runInfo.nextRunTime ?? "unscheduled"}` };
4303
4002
  }
4304
4003
  function darwinSchedulerStatus(env) {
4305
- const plistPath = (0, import_node_path17.join)((0, import_node_os8.homedir)(), "Library", "LaunchAgents", LAUNCHD_PLIST_NAME);
4004
+ const plistPath = (0, import_node_path15.join)((0, import_node_os8.homedir)(), "Library", "LaunchAgents", LAUNCHD_PLIST_NAME);
4306
4005
  const plist = readFileOrNull(plistPath);
4307
4006
  if (!plist) {
4308
4007
  return { ok: false, supported: true, enabled: false, ...EMPTY_RUN_INFO, detail: `"${LAUNCHD_LABEL}" is not registered \u2014 run \`mmi-hub autoupdate on\`` };
4309
4008
  }
4310
4009
  const hubDist = globalDist(env, "@mutmutco/hub", "dist/index.cjs");
4311
- const launcherPath = (0, import_node_path17.join)(statePaths(env).root, POSIX_LAUNCHER_FILE);
4010
+ const launcherPath = (0, import_node_path15.join)(statePaths(env).root, POSIX_LAUNCHER_FILE);
4312
4011
  const fail2 = (detail) => ({ ok: false, supported: true, enabled: true, ...EMPTY_RUN_INFO, detail });
4313
4012
  if (!plist.includes(launcherPath)) {
4314
4013
  return fail2(`"${LAUNCHD_LABEL}" does not run the reconcile launcher ${launcherPath} \u2014 run \`mmi-hub autoupdate on\``);
@@ -4328,15 +4027,15 @@ function darwinSchedulerStatus(env) {
4328
4027
  return { ok: true, supported: true, enabled: true, ...EMPTY_RUN_INFO, detail: `"${LAUNCHD_LABEL}" registered ${POSIX_CADENCE}; ${points}` };
4329
4028
  }
4330
4029
  function linuxSchedulerStatus(env) {
4331
- const unitDir = (0, import_node_path17.join)((0, import_node_os8.homedir)(), ".config", "systemd", "user");
4332
- const timerPath = (0, import_node_path17.join)(unitDir, SYSTEMD_TIMER_NAME);
4030
+ const unitDir = (0, import_node_path15.join)((0, import_node_os8.homedir)(), ".config", "systemd", "user");
4031
+ const timerPath = (0, import_node_path15.join)(unitDir, SYSTEMD_TIMER_NAME);
4333
4032
  const timer = readFileOrNull(timerPath);
4334
- const service = readFileOrNull((0, import_node_path17.join)(unitDir, SYSTEMD_SERVICE_NAME));
4033
+ const service = readFileOrNull((0, import_node_path15.join)(unitDir, SYSTEMD_SERVICE_NAME));
4335
4034
  if (!timer || !service) {
4336
4035
  return { ok: false, supported: true, enabled: false, ...EMPTY_RUN_INFO, detail: `"${SYSTEMD_TIMER_NAME}" is not registered \u2014 run \`mmi-hub autoupdate on\`` };
4337
4036
  }
4338
4037
  const hubDist = globalDist(env, "@mutmutco/hub", "dist/index.cjs");
4339
- const launcherPath = (0, import_node_path17.join)(statePaths(env).root, POSIX_LAUNCHER_FILE);
4038
+ const launcherPath = (0, import_node_path15.join)(statePaths(env).root, POSIX_LAUNCHER_FILE);
4340
4039
  const fail2 = (detail) => ({ ok: false, supported: true, enabled: true, ...EMPTY_RUN_INFO, detail });
4341
4040
  if (!service.includes(launcherPath)) {
4342
4041
  return fail2(`"${SYSTEMD_SERVICE_NAME}" does not run the reconcile launcher ${launcherPath} \u2014 run \`mmi-hub autoupdate on\``);
@@ -4375,10 +4074,10 @@ function installWindowsTask(env) {
4375
4074
  const paths = ensureState(env);
4376
4075
  const userId = `${env.USERDOMAIN || env.COMPUTERNAME || ""}\\${env.USERNAME || ""}`.replace(/^\\/, "");
4377
4076
  if (!env.USERNAME) return { ok: false, detail: "cannot resolve the registering user (USERNAME unset) \u2014 the task principal must be explicit" };
4378
- const launcherPath = (0, import_node_path17.join)(paths.root, LAUNCHER_FILE);
4379
- (0, import_node_fs24.writeFileSync)(launcherPath, launcherVbs(process.execPath, hubDist), "utf8");
4380
- const xmlPath = (0, import_node_path17.join)(paths.root, "task.xml");
4381
- (0, import_node_fs24.writeFileSync)(xmlPath, "\uFEFF" + taskXml(launcherPath, paths.root, userId, localStartBoundary(/* @__PURE__ */ new Date())), "utf16le");
4077
+ const launcherPath = (0, import_node_path15.join)(paths.root, LAUNCHER_FILE);
4078
+ (0, import_node_fs21.writeFileSync)(launcherPath, launcherVbs(process.execPath, hubDist), "utf8");
4079
+ const xmlPath = (0, import_node_path15.join)(paths.root, "task.xml");
4080
+ (0, import_node_fs21.writeFileSync)(xmlPath, "\uFEFF" + taskXml(launcherPath, paths.root, userId, localStartBoundary(/* @__PURE__ */ new Date())), "utf16le");
4382
4081
  const create = schtasks(["/create", "/tn", TASK_NAME, "/xml", xmlPath, "/f"]);
4383
4082
  if (create.status !== 0) {
4384
4083
  const denied = /access is denied/i.test(create.stderr + create.stdout);
@@ -4394,11 +4093,11 @@ function refreshPosixLauncher(env) {
4394
4093
  const hubDist = globalDist(env, "@mutmutco/hub", "dist/index.cjs");
4395
4094
  if (!hubDist) return null;
4396
4095
  const paths = ensureState(env);
4397
- const launcherPath = (0, import_node_path17.join)(paths.root, POSIX_LAUNCHER_FILE);
4096
+ const launcherPath = (0, import_node_path15.join)(paths.root, POSIX_LAUNCHER_FILE);
4398
4097
  const desired = launcherSh(process.execPath, hubDist);
4399
4098
  if (readFileOrNull(launcherPath) === desired) return null;
4400
- (0, import_node_fs24.writeFileSync)(launcherPath, desired, "utf8");
4401
- (0, import_node_fs24.chmodSync)(launcherPath, 493);
4099
+ (0, import_node_fs21.writeFileSync)(launcherPath, desired, "utf8");
4100
+ (0, import_node_fs21.chmodSync)(launcherPath, 493);
4402
4101
  return launcherPath;
4403
4102
  }
4404
4103
  function installLaunchd(env) {
@@ -4410,13 +4109,13 @@ function installLaunchd(env) {
4410
4109
  const hubDist = globalDist(env, "@mutmutco/hub", "dist/index.cjs");
4411
4110
  if (!hubDist) return { ok: false, detail: "cannot resolve the global @mutmutco/hub dist \u2014 run `npm install -g @mutmutco/hub` first" };
4412
4111
  const paths = ensureState(env);
4413
- const launcherPath = (0, import_node_path17.join)(paths.root, POSIX_LAUNCHER_FILE);
4414
- (0, import_node_fs24.writeFileSync)(launcherPath, launcherSh(process.execPath, hubDist), "utf8");
4415
- (0, import_node_fs24.chmodSync)(launcherPath, 493);
4416
- const agentsDir = (0, import_node_path17.join)((0, import_node_os8.homedir)(), "Library", "LaunchAgents");
4417
- (0, import_node_fs24.mkdirSync)(agentsDir, { recursive: true });
4418
- const plistPath = (0, import_node_path17.join)(agentsDir, LAUNCHD_PLIST_NAME);
4419
- (0, import_node_fs24.writeFileSync)(plistPath, launchdPlist(launcherPath, paths.root), "utf8");
4112
+ const launcherPath = (0, import_node_path15.join)(paths.root, POSIX_LAUNCHER_FILE);
4113
+ (0, import_node_fs21.writeFileSync)(launcherPath, launcherSh(process.execPath, hubDist), "utf8");
4114
+ (0, import_node_fs21.chmodSync)(launcherPath, 493);
4115
+ const agentsDir = (0, import_node_path15.join)((0, import_node_os8.homedir)(), "Library", "LaunchAgents");
4116
+ (0, import_node_fs21.mkdirSync)(agentsDir, { recursive: true });
4117
+ const plistPath = (0, import_node_path15.join)(agentsDir, LAUNCHD_PLIST_NAME);
4118
+ (0, import_node_fs21.writeFileSync)(plistPath, launchdPlist(launcherPath, paths.root), "utf8");
4420
4119
  launchctl(["bootout", `gui/${uid()}/${LAUNCHD_LABEL}`]);
4421
4120
  const load = launchctl(["bootstrap", `gui/${uid()}`, plistPath]);
4422
4121
  if (load.status !== 0) {
@@ -4434,13 +4133,13 @@ function installSystemdTimer(env) {
4434
4133
  const hubDist = globalDist(env, "@mutmutco/hub", "dist/index.cjs");
4435
4134
  if (!hubDist) return { ok: false, detail: "cannot resolve the global @mutmutco/hub dist \u2014 run `npm install -g @mutmutco/hub` first" };
4436
4135
  const paths = ensureState(env);
4437
- const launcherPath = (0, import_node_path17.join)(paths.root, POSIX_LAUNCHER_FILE);
4438
- (0, import_node_fs24.writeFileSync)(launcherPath, launcherSh(process.execPath, hubDist), "utf8");
4439
- (0, import_node_fs24.chmodSync)(launcherPath, 493);
4440
- const unitDir = (0, import_node_path17.join)((0, import_node_os8.homedir)(), ".config", "systemd", "user");
4441
- (0, import_node_fs24.mkdirSync)(unitDir, { recursive: true });
4442
- (0, import_node_fs24.writeFileSync)((0, import_node_path17.join)(unitDir, SYSTEMD_SERVICE_NAME), systemdServiceUnit(launcherPath, paths.root), "utf8");
4443
- (0, import_node_fs24.writeFileSync)((0, import_node_path17.join)(unitDir, SYSTEMD_TIMER_NAME), systemdTimerUnit(), "utf8");
4136
+ const launcherPath = (0, import_node_path15.join)(paths.root, POSIX_LAUNCHER_FILE);
4137
+ (0, import_node_fs21.writeFileSync)(launcherPath, launcherSh(process.execPath, hubDist), "utf8");
4138
+ (0, import_node_fs21.chmodSync)(launcherPath, 493);
4139
+ const unitDir = (0, import_node_path15.join)((0, import_node_os8.homedir)(), ".config", "systemd", "user");
4140
+ (0, import_node_fs21.mkdirSync)(unitDir, { recursive: true });
4141
+ (0, import_node_fs21.writeFileSync)((0, import_node_path15.join)(unitDir, SYSTEMD_SERVICE_NAME), systemdServiceUnit(launcherPath, paths.root), "utf8");
4142
+ (0, import_node_fs21.writeFileSync)((0, import_node_path15.join)(unitDir, SYSTEMD_TIMER_NAME), systemdTimerUnit(), "utf8");
4444
4143
  const reload = systemctlUser(["daemon-reload"]);
4445
4144
  if (reload.status !== 0) {
4446
4145
  return { ok: false, detail: `systemctl --user daemon-reload failed: ${(reload.stderr || reload.stdout).trim() || "unknown error \u2014 is a user systemd instance running?"}` };
@@ -4478,28 +4177,28 @@ function uninstallWindowsTask(env) {
4478
4177
  return { ok: true, detail: `automatic updates off \u2014 removed "${TASK_NAME}"; installed tooling was kept` };
4479
4178
  }
4480
4179
  function uninstallLaunchd(env) {
4481
- const plistPath = (0, import_node_path17.join)((0, import_node_os8.homedir)(), "Library", "LaunchAgents", LAUNCHD_PLIST_NAME);
4180
+ const plistPath = (0, import_node_path15.join)((0, import_node_os8.homedir)(), "Library", "LaunchAgents", LAUNCHD_PLIST_NAME);
4482
4181
  const boot = launchctl(["bootout", `gui/${uid()}/${LAUNCHD_LABEL}`]);
4483
- if (boot.status !== 0 && (0, import_node_fs24.existsSync)(plistPath)) {
4182
+ if (boot.status !== 0 && (0, import_node_fs21.existsSync)(plistPath)) {
4484
4183
  return { ok: false, detail: `launchctl bootout failed: ${(boot.stderr || boot.stdout).trim() || "unknown error"}` };
4485
4184
  }
4486
4185
  try {
4487
- (0, import_node_fs24.rmSync)(plistPath, { force: true });
4186
+ (0, import_node_fs21.rmSync)(plistPath, { force: true });
4488
4187
  } catch {
4489
4188
  }
4490
4189
  dropLauncher(env, POSIX_LAUNCHER_FILE);
4491
4190
  return { ok: true, detail: `automatic updates off \u2014 removed "${LAUNCHD_LABEL}"; installed tooling was kept` };
4492
4191
  }
4493
4192
  function uninstallSystemdTimer(env) {
4494
- const unitDir = (0, import_node_path17.join)((0, import_node_os8.homedir)(), ".config", "systemd", "user");
4495
- const timerPath = (0, import_node_path17.join)(unitDir, SYSTEMD_TIMER_NAME);
4193
+ const unitDir = (0, import_node_path15.join)((0, import_node_os8.homedir)(), ".config", "systemd", "user");
4194
+ const timerPath = (0, import_node_path15.join)(unitDir, SYSTEMD_TIMER_NAME);
4496
4195
  const disable = systemctlUser(["disable", "--now", SYSTEMD_TIMER_NAME]);
4497
- if (disable.status !== 0 && (0, import_node_fs24.existsSync)(timerPath)) {
4196
+ if (disable.status !== 0 && (0, import_node_fs21.existsSync)(timerPath)) {
4498
4197
  return { ok: false, detail: `systemctl --user disable --now ${SYSTEMD_TIMER_NAME} failed: ${(disable.stderr || disable.stdout).trim() || "unknown error"}` };
4499
4198
  }
4500
4199
  try {
4501
- (0, import_node_fs24.rmSync)(timerPath, { force: true });
4502
- (0, import_node_fs24.rmSync)((0, import_node_path17.join)(unitDir, SYSTEMD_SERVICE_NAME), { force: true });
4200
+ (0, import_node_fs21.rmSync)(timerPath, { force: true });
4201
+ (0, import_node_fs21.rmSync)((0, import_node_path15.join)(unitDir, SYSTEMD_SERVICE_NAME), { force: true });
4503
4202
  } catch {
4504
4203
  }
4505
4204
  systemctlUser(["daemon-reload"]);
@@ -4514,16 +4213,16 @@ function uninstallTask(env = process.env) {
4514
4213
  }
4515
4214
  function dropLauncher(env, file) {
4516
4215
  try {
4517
- (0, import_node_fs24.rmSync)((0, import_node_path17.join)(statePaths(env).root, file), { force: true });
4216
+ (0, import_node_fs21.rmSync)((0, import_node_path15.join)(statePaths(env).root, file), { force: true });
4518
4217
  } catch {
4519
4218
  }
4520
4219
  }
4521
4220
 
4522
4221
  // src/status.ts
4523
- var import_node_fs25 = require("node:fs");
4222
+ var import_node_fs22 = require("node:fs");
4524
4223
  function readJournal(path) {
4525
4224
  try {
4526
- const events = (0, import_node_fs25.readFileSync)(path, "utf8").split("\n").filter((line) => line.trim()).map((line) => {
4225
+ const events = (0, import_node_fs22.readFileSync)(path, "utf8").split("\n").filter((line) => line.trim()).map((line) => {
4527
4226
  try {
4528
4227
  return JSON.parse(line);
4529
4228
  } catch {
@@ -4732,14 +4431,14 @@ function reportCounts(summary) {
4732
4431
  }
4733
4432
 
4734
4433
  // src/stamp.ts
4735
- var import_node_fs26 = require("node:fs");
4434
+ var import_node_fs23 = require("node:fs");
4736
4435
  var ALWAYS_ARMED = ["cli", "updater"];
4737
4436
  var PLUGIN_ARMS = /* @__PURE__ */ new Set(["claude", "codex", "jervcode", "cursor", "hermes"]);
4738
4437
  function fleetStamp(env = process.env) {
4739
4438
  const paths = statePaths(env);
4740
4439
  let events = [];
4741
4440
  try {
4742
- events = (0, import_node_fs26.readFileSync)(paths.journalPath, "utf8").split("\n").filter((line) => line.trim()).map((line) => {
4441
+ events = (0, import_node_fs23.readFileSync)(paths.journalPath, "utf8").split("\n").filter((line) => line.trim()).map((line) => {
4743
4442
  try {
4744
4443
  return JSON.parse(line);
4745
4444
  } catch {
@@ -4789,7 +4488,7 @@ function fleetStamp(env = process.env) {
4789
4488
  // src/index.ts
4790
4489
  function ownVersion() {
4791
4490
  try {
4792
- return JSON.parse((0, import_node_fs27.readFileSync)((0, import_node_path18.join)(__dirname, "..", "package.json"), "utf8")).version;
4491
+ return JSON.parse((0, import_node_fs24.readFileSync)((0, import_node_path16.join)(__dirname, "..", "package.json"), "utf8")).version;
4793
4492
  } catch {
4794
4493
  return "0.0.0";
4795
4494
  }
@@ -4952,7 +4651,6 @@ if (typeof require !== "undefined" && require.main === module) {
4952
4651
  renderNotice,
4953
4652
  renderReport,
4954
4653
  reportCounts,
4955
- resolvePayloadTarball,
4956
4654
  retiredSurfaces,
4957
4655
  retryHint,
4958
4656
  runMaintenance,
@@ -4962,7 +4660,6 @@ if (typeof require !== "undefined" && require.main === module) {
4962
4660
  sharedDocLockTimeoutReceipt,
4963
4661
  shippedTargetFrom,
4964
4662
  shouldHandOff,
4965
- stagePackage,
4966
4663
  statusScreen,
4967
4664
  surfaceArmPlan,
4968
4665
  systemdServiceUnit,