@mutmutco/installer-launcher 1.4.0 → 1.4.2

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.
package/dist/launcher.js CHANGED
@@ -1295,6 +1295,7 @@ function createInstallerRun(value, options = {}) {
1295
1295
  };
1296
1296
  let started = false;
1297
1297
  let finished = false;
1298
+ let currentSurfaces = 0;
1298
1299
  let operation = options.operation;
1299
1300
  const start = () => {
1300
1301
  if (started || finished) return;
@@ -1363,6 +1364,7 @@ function createInstallerRun(value, options = {}) {
1363
1364
  if (!status) throw new Error("installer run: unknown surface state");
1364
1365
  const separator = tty ? "\xB7" : "-";
1365
1366
  const activation = facts.state === "updated" && surface.activation ? ` ${separator} ${surface.activation}` : "";
1367
+ if (facts.state === "current" && facts.id !== LAUNCHER_SURFACE) currentSurfaces++;
1366
1368
  const completed = ["updated", "current", "kept", "skipped"].includes(facts.state);
1367
1369
  durable(`${facts.id}${versions} ${separator} ${status}${activation}`, completed ? facts.seconds ?? null : null, facts.state === "failed" ? "fail" : facts.state === "updated" ? "ok" : "note");
1368
1370
  if (facts.detail) run2.relay(facts.detail);
@@ -1465,7 +1467,7 @@ function createInstallerRun(value, options = {}) {
1465
1467
  spinner.stop();
1466
1468
  finished = true;
1467
1469
  if (options.quiet && facts.updated === 0 && facts.failed === 0 && !facts.operationFailed) return;
1468
- const changed = !facts.version ? "No release target is available." : facts.dryRun ? `Would update ${facts.updated} of ${facts.total} surfaces to ${facts.version}.` : facts.installed ? `Installed ${facts.version} across ${facts.total} surfaces.` : `Updated ${facts.updated} of ${facts.total} surfaces to ${facts.version}.`;
1470
+ const changed = !facts.version ? "No release target is available." : facts.dryRun ? `Would update ${facts.updated} of ${facts.total} surfaces to ${facts.version}.` : facts.installed ? `Installed ${facts.version} across ${facts.total} surfaces.` : facts.updated === 0 && currentSurfaces > 0 ? `${currentSurfaces >= facts.total ? "All" : `${currentSurfaces} of`} ${facts.total} surfaces already at ${facts.version}.` : `Updated ${facts.updated} of ${facts.total} surfaces to ${facts.version}.`;
1469
1471
  const ready = facts.failed === 0 && !facts.dryRun && !facts.deferred && !facts.operationFailed && Boolean(facts.version);
1470
1472
  const deferred = Boolean(facts.deferred) && facts.failed === 0 && !facts.operationFailed;
1471
1473
  const body = [
@@ -2263,7 +2265,7 @@ async function refreshLauncher(target, options = {}) {
2263
2265
  }
2264
2266
 
2265
2267
  // src/index.ts
2266
- var LAUNCHER_VERSION = true ? "1.4.0" : readVersionFromPackage();
2268
+ var LAUNCHER_VERSION = true ? "1.4.2" : readVersionFromPackage();
2267
2269
  function defaultPrint(message) {
2268
2270
  process.stdout.write(`${message}
2269
2271
  `);
@@ -3068,6 +3070,22 @@ function within(fetchImpl, ms) {
3068
3070
  return ((input, init) => fetchImpl(input, { ...init, signal: AbortSignal.timeout(ms) }));
3069
3071
  }
3070
3072
  var STATUS_PROBE_MS = 3e3;
3073
+ function readBudget(cwd, env) {
3074
+ const command2 = process.platform === "win32" ? "mmi-cli.cmd" : "mmi-cli";
3075
+ const result = spawnSync4(command2, ["devops", "github", "budget", "--json"], {
3076
+ cwd,
3077
+ env,
3078
+ shell: needsShell(command2),
3079
+ encoding: "utf8",
3080
+ stdio: "pipe",
3081
+ timeout: 1e4,
3082
+ killSignal: "SIGKILL",
3083
+ windowsHide: true,
3084
+ maxBuffer: 64 * 1024
3085
+ });
3086
+ if (result.error || result.status !== 0) throw new Error("Budget unavailable");
3087
+ return result.stdout;
3088
+ }
3071
3089
  async function doStatus(config, dir, options, ui, print, json) {
3072
3090
  const fetchImpl = within(options.fetchImpl ?? fetch, STATUS_PROBE_MS);
3073
3091
  const local = localFacts(config, dir, options);
@@ -3075,12 +3093,22 @@ async function doStatus(config, dir, options, ui, print, json) {
3075
3093
  fetchReleaseVersion(config, fetchImpl),
3076
3094
  readLauncherRecord(launcherTarget(config), { fetch: fetchImpl, timeoutMs: STATUS_PROBE_MS })
3077
3095
  ]);
3096
+ let budget = null;
3097
+ const hub = config.product === "mmi" || config.product === "mmi-hub";
3098
+ if (hub && local.installed) {
3099
+ try {
3100
+ const parsed = JSON.parse((options.readBudget ?? readBudget)(payloadDir(dir), payloadEnv(dir) ?? process.env));
3101
+ if (typeof parsed?.line === "string" && parsed.line.startsWith("GitHub budget \xB7 ")) budget = parsed;
3102
+ } catch {
3103
+ }
3104
+ }
3078
3105
  const launcherNewer = record !== null && compareVersions(record.version, LAUNCHER_VERSION) > 0;
3079
3106
  const releaseOrder = local.installed && release ? compareVersions(release, local.installed) : null;
3080
3107
  const verdict = verdictFor(ui, local, launcherNewer || (releaseOrder ?? 0) > 0, `${ui.bin} doctor`);
3081
3108
  if (json) {
3082
3109
  print(JSON.stringify({
3083
3110
  product: config.product,
3111
+ ...hub ? { budget: budget ?? "unknown" } : {},
3084
3112
  launcher: { version: LAUNCHER_VERSION, available: launcherNewer ? record.version : null },
3085
3113
  installed: local.installed,
3086
3114
  release,
@@ -3094,7 +3122,13 @@ async function doStatus(config, dir, options, ui, print, json) {
3094
3122
  const launcherRow = record === null ? { surface: "launcher", state: `${LAUNCHER_VERSION} \xB7 ${SURFACE_WORDS.unknown}`, mark: "note" } : launcherNewer ? { surface: "launcher", state: `${LAUNCHER_VERSION} \u2192 ${record.version} \xB7 ${SURFACE_WORDS.behind}`, mark: "note" } : { surface: "launcher", state: `${LAUNCHER_VERSION} \xB7 ${SURFACE_WORDS.current}`, mark: "ok" };
3095
3123
  const productRow = !local.installed ? { surface: config.product, state: SURFACE_WORDS.missing, mark: "fail" } : releaseOrder === null ? { surface: config.product, state: `${local.installed} \xB7 ${SURFACE_WORDS.unknown}`, mark: "note" } : releaseOrder > 0 ? { surface: config.product, state: `${local.installed} \u2192 ${release} \xB7 ${SURFACE_WORDS.behind}`, mark: "note" } : releaseOrder < 0 ? { surface: config.product, state: `${local.installed} \xB7 ${SURFACE_WORDS.ahead}`, mark: "note" } : { surface: config.product, state: `${local.installed} \xB7 ${SURFACE_WORDS.current}`, mark: "ok" };
3096
3124
  ui.show(renderReport(ui.product, {
3097
- rows: [launcherRow, productRow, signInRow(local), autoUpdateRow(local.schedule)],
3125
+ rows: [
3126
+ launcherRow,
3127
+ productRow,
3128
+ signInRow(local),
3129
+ autoUpdateRow(local.schedule),
3130
+ ...hub ? [{ surface: "github", state: budget?.line ?? "unknown", mark: budget && !budget.line.includes("unknown") ? "ok" : "note" }] : []
3131
+ ],
3098
3132
  verdict: { ...verdict, facts: [release ? `The release is ${release}.` : "The release version could not be read."] }
3099
3133
  }, ui.render));
3100
3134
  return verdict.state === "fail" ? 1 : 0;
@@ -1328,6 +1328,7 @@ function createInstallerRun(value, options = {}) {
1328
1328
  };
1329
1329
  let started = false;
1330
1330
  let finished = false;
1331
+ let currentSurfaces = 0;
1331
1332
  let operation = options.operation;
1332
1333
  const start = () => {
1333
1334
  if (started || finished) return;
@@ -1396,6 +1397,7 @@ function createInstallerRun(value, options = {}) {
1396
1397
  if (!status) throw new Error("installer run: unknown surface state");
1397
1398
  const separator = tty ? "\xB7" : "-";
1398
1399
  const activation = facts.state === "updated" && surface.activation ? ` ${separator} ${surface.activation}` : "";
1400
+ if (facts.state === "current" && facts.id !== LAUNCHER_SURFACE) currentSurfaces++;
1399
1401
  const completed = ["updated", "current", "kept", "skipped"].includes(facts.state);
1400
1402
  durable(`${facts.id}${versions} ${separator} ${status}${activation}`, completed ? facts.seconds ?? null : null, facts.state === "failed" ? "fail" : facts.state === "updated" ? "ok" : "note");
1401
1403
  if (facts.detail) run2.relay(facts.detail);
@@ -1498,7 +1500,7 @@ function createInstallerRun(value, options = {}) {
1498
1500
  spinner.stop();
1499
1501
  finished = true;
1500
1502
  if (options.quiet && facts.updated === 0 && facts.failed === 0 && !facts.operationFailed) return;
1501
- const changed = !facts.version ? "No release target is available." : facts.dryRun ? `Would update ${facts.updated} of ${facts.total} surfaces to ${facts.version}.` : facts.installed ? `Installed ${facts.version} across ${facts.total} surfaces.` : `Updated ${facts.updated} of ${facts.total} surfaces to ${facts.version}.`;
1503
+ const changed = !facts.version ? "No release target is available." : facts.dryRun ? `Would update ${facts.updated} of ${facts.total} surfaces to ${facts.version}.` : facts.installed ? `Installed ${facts.version} across ${facts.total} surfaces.` : facts.updated === 0 && currentSurfaces > 0 ? `${currentSurfaces >= facts.total ? "All" : `${currentSurfaces} of`} ${facts.total} surfaces already at ${facts.version}.` : `Updated ${facts.updated} of ${facts.total} surfaces to ${facts.version}.`;
1502
1504
  const ready = facts.failed === 0 && !facts.dryRun && !facts.deferred && !facts.operationFailed && Boolean(facts.version);
1503
1505
  const deferred = Boolean(facts.deferred) && facts.failed === 0 && !facts.operationFailed;
1504
1506
  const body = [
@@ -2296,7 +2298,7 @@ async function refreshLauncher(target, options = {}) {
2296
2298
  }
2297
2299
 
2298
2300
  // src/index.ts
2299
- var LAUNCHER_VERSION = true ? "1.4.0" : readVersionFromPackage();
2301
+ var LAUNCHER_VERSION = true ? "1.4.2" : readVersionFromPackage();
2300
2302
  function defaultPrint(message) {
2301
2303
  process.stdout.write(`${message}
2302
2304
  `);
@@ -3101,6 +3103,22 @@ function within(fetchImpl, ms) {
3101
3103
  return ((input, init) => fetchImpl(input, { ...init, signal: AbortSignal.timeout(ms) }));
3102
3104
  }
3103
3105
  var STATUS_PROBE_MS = 3e3;
3106
+ function readBudget(cwd, env) {
3107
+ const command2 = process.platform === "win32" ? "mmi-cli.cmd" : "mmi-cli";
3108
+ const result = (0, import_node_child_process5.spawnSync)(command2, ["devops", "github", "budget", "--json"], {
3109
+ cwd,
3110
+ env,
3111
+ shell: needsShell(command2),
3112
+ encoding: "utf8",
3113
+ stdio: "pipe",
3114
+ timeout: 1e4,
3115
+ killSignal: "SIGKILL",
3116
+ windowsHide: true,
3117
+ maxBuffer: 64 * 1024
3118
+ });
3119
+ if (result.error || result.status !== 0) throw new Error("Budget unavailable");
3120
+ return result.stdout;
3121
+ }
3104
3122
  async function doStatus(config, dir, options, ui, print, json) {
3105
3123
  const fetchImpl = within(options.fetchImpl ?? fetch, STATUS_PROBE_MS);
3106
3124
  const local = localFacts(config, dir, options);
@@ -3108,12 +3126,22 @@ async function doStatus(config, dir, options, ui, print, json) {
3108
3126
  fetchReleaseVersion(config, fetchImpl),
3109
3127
  readLauncherRecord(launcherTarget(config), { fetch: fetchImpl, timeoutMs: STATUS_PROBE_MS })
3110
3128
  ]);
3129
+ let budget = null;
3130
+ const hub = config.product === "mmi" || config.product === "mmi-hub";
3131
+ if (hub && local.installed) {
3132
+ try {
3133
+ const parsed = JSON.parse((options.readBudget ?? readBudget)(payloadDir(dir), payloadEnv(dir) ?? process.env));
3134
+ if (typeof parsed?.line === "string" && parsed.line.startsWith("GitHub budget \xB7 ")) budget = parsed;
3135
+ } catch {
3136
+ }
3137
+ }
3111
3138
  const launcherNewer = record !== null && compareVersions(record.version, LAUNCHER_VERSION) > 0;
3112
3139
  const releaseOrder = local.installed && release ? compareVersions(release, local.installed) : null;
3113
3140
  const verdict = verdictFor(ui, local, launcherNewer || (releaseOrder ?? 0) > 0, `${ui.bin} doctor`);
3114
3141
  if (json) {
3115
3142
  print(JSON.stringify({
3116
3143
  product: config.product,
3144
+ ...hub ? { budget: budget ?? "unknown" } : {},
3117
3145
  launcher: { version: LAUNCHER_VERSION, available: launcherNewer ? record.version : null },
3118
3146
  installed: local.installed,
3119
3147
  release,
@@ -3127,7 +3155,13 @@ async function doStatus(config, dir, options, ui, print, json) {
3127
3155
  const launcherRow = record === null ? { surface: "launcher", state: `${LAUNCHER_VERSION} \xB7 ${SURFACE_WORDS.unknown}`, mark: "note" } : launcherNewer ? { surface: "launcher", state: `${LAUNCHER_VERSION} \u2192 ${record.version} \xB7 ${SURFACE_WORDS.behind}`, mark: "note" } : { surface: "launcher", state: `${LAUNCHER_VERSION} \xB7 ${SURFACE_WORDS.current}`, mark: "ok" };
3128
3156
  const productRow = !local.installed ? { surface: config.product, state: SURFACE_WORDS.missing, mark: "fail" } : releaseOrder === null ? { surface: config.product, state: `${local.installed} \xB7 ${SURFACE_WORDS.unknown}`, mark: "note" } : releaseOrder > 0 ? { surface: config.product, state: `${local.installed} \u2192 ${release} \xB7 ${SURFACE_WORDS.behind}`, mark: "note" } : releaseOrder < 0 ? { surface: config.product, state: `${local.installed} \xB7 ${SURFACE_WORDS.ahead}`, mark: "note" } : { surface: config.product, state: `${local.installed} \xB7 ${SURFACE_WORDS.current}`, mark: "ok" };
3129
3157
  ui.show(renderReport(ui.product, {
3130
- rows: [launcherRow, productRow, signInRow(local), autoUpdateRow(local.schedule)],
3158
+ rows: [
3159
+ launcherRow,
3160
+ productRow,
3161
+ signInRow(local),
3162
+ autoUpdateRow(local.schedule),
3163
+ ...hub ? [{ surface: "github", state: budget?.line ?? "unknown", mark: budget && !budget.line.includes("unknown") ? "ok" : "note" }] : []
3164
+ ],
3131
3165
  verdict: { ...verdict, facts: [release ? `The release is ${release}.` : "The release version could not be read."] }
3132
3166
  }, ui.render));
3133
3167
  return verdict.state === "fail" ? 1 : 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mutmutco/installer-launcher",
3
- "version": "1.4.0",
3
+ "version": "1.4.2",
4
4
  "description": "Single-executable (SEA) launcher: sign-in, gated payload fetch, self-update. One copy ships per product.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",