@mutmutco/installer-launcher 0.1.15 → 0.1.17

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
@@ -799,15 +799,24 @@ function createFace({ product, color = false, columns, env = process.env, operat
799
799
  const record = { v: PROGRESS_PROTOCOL, step: stripColor(title), state: kind };
800
800
  if (typeof measure === "number") record.ms = Math.max(0, Math.round(measure * 1e3));
801
801
  if (kind === "running" && typeof measure === "string") record.measure = measure;
802
- try {
803
- if (progressFile) appendFileSync(progressFile, `${JSON.stringify(record)}
804
- `);
805
- else writeSync(progressFd, `${JSON.stringify(record)}
806
- `);
807
- return true;
808
- } catch {
809
- return false;
802
+ const line = `${JSON.stringify(record)}
803
+ `;
804
+ if (progressFd !== null) {
805
+ try {
806
+ writeSync(progressFd, line);
807
+ return true;
808
+ } catch {
809
+ }
810
810
  }
811
+ if (progressFile) {
812
+ try {
813
+ appendFileSync(progressFile, line);
814
+ return true;
815
+ } catch {
816
+ return false;
817
+ }
818
+ }
819
+ return false;
811
820
  };
812
821
  const welcome = () => continuesFace || nested ? [] : [
813
822
  `${paint(identity.accent, GLYPH.diamond)} ${paint(identity.accent, identity.name)} \u2014 Mutatis Mutandis`,
@@ -821,7 +830,7 @@ function createFace({ product, color = false, columns, env = process.env, operat
821
830
  };
822
831
  const step = (title, measure = null, kind = "ok") => {
823
832
  if (emitMilestone(title, measure, kind)) return "";
824
- const glyph = title === "Armed hourly updates" && kind === "ok" ? GLYPH.clock : kind === "fail" ? paint(identity.accent, GLYPH.cross) : kind === "note" ? paint(PALETTE.muted, GLYPH.dot) : paint(PALETTE.green, GLYPH.check);
833
+ const glyph = title === "Armed hourly updates" && kind === "ok" ? GLYPH.clock : kind === "fail" ? paint(identity.accent, GLYPH.cross) : kind === "note" ? paint(PALETTE.muted, GLYPH.dot) : paint(identity.accent, GLYPH.check);
825
834
  const measured = measure === null || measure === void 0 ? "" : paint(PALETTE.muted, typeof measure === "number" ? `${Math.max(0, Math.round(measure))}s` : String(measure).trim());
826
835
  const time = measured;
827
836
  const column = Math.min(44, Math.max(0, width - 8));
@@ -842,7 +851,7 @@ function createFace({ product, color = false, columns, env = process.env, operat
842
851
  const content = Math.min(width - 6, Math.max(...body.map(visibleWidth)));
843
852
  const rule = paint(identity.accent, GLYPH.rule.repeat(content + 4));
844
853
  const frame = (left, right) => `${paint(identity.accent, left)}${rule}${paint(identity.accent, right)}`;
845
- const bodyRow = (line) => line.startsWith(GLYPH.check) ? `${paint(PALETTE.green, GLYPH.check)}${line.slice(1)}` : line;
854
+ const bodyRow = (line) => line.startsWith(GLYPH.check) ? `${paint(identity.accent, GLYPH.check)}${line.slice(1)}` : line;
846
855
  return [
847
856
  frame(GLYPH.boxTop, GLYPH.boxTopEnd),
848
857
  ...body.map((line) => `${paint(identity.accent, GLYPH.bar)} ${bodyRow(line)}${" ".repeat(Math.max(0, content - visibleWidth(line)))} ${paint(identity.accent, GLYPH.bar)}`),
@@ -873,16 +882,31 @@ import { appendFileSync as appendFileSync2, writeSync as writeSync2 } from "node
873
882
  import { Worker } from "node:worker_threads";
874
883
 
875
884
  // ../face/src/encoding.ts
885
+ import { execFileSync } from "node:child_process";
876
886
  var UNICODE_SPINNER_FRAMES = Object.freeze(["\u25D2", "\u25D0", "\u25D3", "\u25D1"]);
877
887
  var ASCII_SPINNER_FRAMES = Object.freeze(["-", "\\", "|", "/"]);
878
- function consoleRendersUnicode(env = process.env, platform = process.platform) {
888
+ var cachedCodePage;
889
+ function consoleOutputCodePage() {
890
+ if (cachedCodePage !== void 0) return cachedCodePage;
891
+ cachedCodePage = null;
892
+ try {
893
+ const out = execFileSync("chcp.com", { windowsHide: true, encoding: "utf8", timeout: 5e3 });
894
+ const pages = [...String(out).matchAll(/(\d{3,5})/gu)].map((m) => Number(m[1]));
895
+ cachedCodePage = pages.length ? pages[pages.length - 1] : null;
896
+ } catch {
897
+ cachedCodePage = null;
898
+ }
899
+ return cachedCodePage;
900
+ }
901
+ function consoleRendersUnicode(env = process.env, platform = process.platform, codePage = platform === "win32" ? consoleOutputCodePage() : null) {
879
902
  if (env.MM_FACE_ASCII === "1" || env.NO_UNICODE === "1") return false;
880
903
  const locale = env.LC_ALL || env.LC_CTYPE || env.LANG || "";
881
904
  if (locale === "C" || locale === "POSIX" || /^C\./u.test(locale) || /^POSIX\./u.test(locale)) return false;
882
905
  if (/cp437|ibm437|\b437\b/iu.test(locale)) return false;
883
906
  if (/utf-?8/iu.test(locale)) return true;
884
907
  if (platform === "win32") {
885
- return Boolean(env.WT_SESSION) || env.TERM_PROGRAM === "vscode" || env.CHCP === "65001" || env.ConEmuANSI === "ON";
908
+ if (env.WT_SESSION || env.ConEmuANSI === "ON") return true;
909
+ return codePage === 65001;
886
910
  }
887
911
  return true;
888
912
  }
@@ -1172,6 +1196,7 @@ function createInstallerRun(value, options = {}) {
1172
1196
  let chunkColumn = 0;
1173
1197
  const trailingCR = /* @__PURE__ */ new Set();
1174
1198
  let deferredActivity;
1199
+ const drawnPhaseCompletions = /* @__PURE__ */ new Set();
1175
1200
  const closeChunk = () => {
1176
1201
  if (chunkOpen) emit("\n", chunkChannel);
1177
1202
  chunkOpen = false;
@@ -1230,7 +1255,10 @@ function createInstallerRun(value, options = {}) {
1230
1255
  if (facts.detail) run2.relay(facts.detail);
1231
1256
  return;
1232
1257
  }
1233
- if (!face.continues(id, state)) durable(title, facts.seconds ?? facts.measure ?? null, state);
1258
+ if (!face.continues(id, state)) {
1259
+ durable(title, facts.seconds ?? facts.measure ?? null, state);
1260
+ if (state === "ok") drawnPhaseCompletions.add(title);
1261
+ }
1234
1262
  if (facts.detail) run2.relay(facts.detail);
1235
1263
  },
1236
1264
  surface(facts) {
@@ -1261,7 +1289,9 @@ function createInstallerRun(value, options = {}) {
1261
1289
  }
1262
1290
  return;
1263
1291
  }
1292
+ if (state !== "fail" && drawnPhaseCompletions.has(step)) return;
1264
1293
  durable(step, ms === void 0 ? null : ms / 1e3, state);
1294
+ if (state === "ok") drawnPhaseCompletions.add(step);
1265
1295
  },
1266
1296
  signIn({ url, code }) {
1267
1297
  start();
@@ -1776,7 +1806,7 @@ function page(title, body) {
1776
1806
  }
1777
1807
 
1778
1808
  // src/index.ts
1779
- var LAUNCHER_VERSION = true ? "0.1.15" : readVersionFromPackage();
1809
+ var LAUNCHER_VERSION = true ? "0.1.17" : readVersionFromPackage();
1780
1810
  function defaultPrint(message) {
1781
1811
  process.stdout.write(`${message}
1782
1812
  `);
@@ -703,7 +703,7 @@ async function installAcquisition(dir, candidate, version, acquisition, options)
703
703
  }
704
704
 
705
705
  // src/index.ts
706
- var import_node_child_process4 = require("node:child_process");
706
+ var import_node_child_process5 = require("node:child_process");
707
707
  var import_node_fs11 = require("node:fs");
708
708
  var import_node_os4 = require("node:os");
709
709
  var import_node_path6 = require("node:path");
@@ -831,15 +831,24 @@ function createFace({ product, color = false, columns, env = process.env, operat
831
831
  const record = { v: PROGRESS_PROTOCOL, step: stripColor(title), state: kind };
832
832
  if (typeof measure === "number") record.ms = Math.max(0, Math.round(measure * 1e3));
833
833
  if (kind === "running" && typeof measure === "string") record.measure = measure;
834
- try {
835
- if (progressFile) (0, import_node_fs6.appendFileSync)(progressFile, `${JSON.stringify(record)}
836
- `);
837
- else (0, import_node_fs6.writeSync)(progressFd, `${JSON.stringify(record)}
838
- `);
839
- return true;
840
- } catch {
841
- return false;
834
+ const line = `${JSON.stringify(record)}
835
+ `;
836
+ if (progressFd !== null) {
837
+ try {
838
+ (0, import_node_fs6.writeSync)(progressFd, line);
839
+ return true;
840
+ } catch {
841
+ }
842
+ }
843
+ if (progressFile) {
844
+ try {
845
+ (0, import_node_fs6.appendFileSync)(progressFile, line);
846
+ return true;
847
+ } catch {
848
+ return false;
849
+ }
842
850
  }
851
+ return false;
843
852
  };
844
853
  const welcome = () => continuesFace || nested ? [] : [
845
854
  `${paint(identity.accent, GLYPH.diamond)} ${paint(identity.accent, identity.name)} \u2014 Mutatis Mutandis`,
@@ -853,7 +862,7 @@ function createFace({ product, color = false, columns, env = process.env, operat
853
862
  };
854
863
  const step = (title, measure = null, kind = "ok") => {
855
864
  if (emitMilestone(title, measure, kind)) return "";
856
- const glyph = title === "Armed hourly updates" && kind === "ok" ? GLYPH.clock : kind === "fail" ? paint(identity.accent, GLYPH.cross) : kind === "note" ? paint(PALETTE.muted, GLYPH.dot) : paint(PALETTE.green, GLYPH.check);
865
+ const glyph = title === "Armed hourly updates" && kind === "ok" ? GLYPH.clock : kind === "fail" ? paint(identity.accent, GLYPH.cross) : kind === "note" ? paint(PALETTE.muted, GLYPH.dot) : paint(identity.accent, GLYPH.check);
857
866
  const measured = measure === null || measure === void 0 ? "" : paint(PALETTE.muted, typeof measure === "number" ? `${Math.max(0, Math.round(measure))}s` : String(measure).trim());
858
867
  const time = measured;
859
868
  const column = Math.min(44, Math.max(0, width - 8));
@@ -874,7 +883,7 @@ function createFace({ product, color = false, columns, env = process.env, operat
874
883
  const content = Math.min(width - 6, Math.max(...body.map(visibleWidth)));
875
884
  const rule = paint(identity.accent, GLYPH.rule.repeat(content + 4));
876
885
  const frame = (left, right) => `${paint(identity.accent, left)}${rule}${paint(identity.accent, right)}`;
877
- const bodyRow = (line) => line.startsWith(GLYPH.check) ? `${paint(PALETTE.green, GLYPH.check)}${line.slice(1)}` : line;
886
+ const bodyRow = (line) => line.startsWith(GLYPH.check) ? `${paint(identity.accent, GLYPH.check)}${line.slice(1)}` : line;
878
887
  return [
879
888
  frame(GLYPH.boxTop, GLYPH.boxTopEnd),
880
889
  ...body.map((line) => `${paint(identity.accent, GLYPH.bar)} ${bodyRow(line)}${" ".repeat(Math.max(0, content - visibleWidth(line)))} ${paint(identity.accent, GLYPH.bar)}`),
@@ -905,16 +914,31 @@ var import_node_fs7 = require("node:fs");
905
914
  var import_node_worker_threads = require("node:worker_threads");
906
915
 
907
916
  // ../face/src/encoding.ts
917
+ var import_node_child_process2 = require("node:child_process");
908
918
  var UNICODE_SPINNER_FRAMES = Object.freeze(["\u25D2", "\u25D0", "\u25D3", "\u25D1"]);
909
919
  var ASCII_SPINNER_FRAMES = Object.freeze(["-", "\\", "|", "/"]);
910
- function consoleRendersUnicode(env = process.env, platform = process.platform) {
920
+ var cachedCodePage;
921
+ function consoleOutputCodePage() {
922
+ if (cachedCodePage !== void 0) return cachedCodePage;
923
+ cachedCodePage = null;
924
+ try {
925
+ const out = (0, import_node_child_process2.execFileSync)("chcp.com", { windowsHide: true, encoding: "utf8", timeout: 5e3 });
926
+ const pages = [...String(out).matchAll(/(\d{3,5})/gu)].map((m) => Number(m[1]));
927
+ cachedCodePage = pages.length ? pages[pages.length - 1] : null;
928
+ } catch {
929
+ cachedCodePage = null;
930
+ }
931
+ return cachedCodePage;
932
+ }
933
+ function consoleRendersUnicode(env = process.env, platform = process.platform, codePage = platform === "win32" ? consoleOutputCodePage() : null) {
911
934
  if (env.MM_FACE_ASCII === "1" || env.NO_UNICODE === "1") return false;
912
935
  const locale = env.LC_ALL || env.LC_CTYPE || env.LANG || "";
913
936
  if (locale === "C" || locale === "POSIX" || /^C\./u.test(locale) || /^POSIX\./u.test(locale)) return false;
914
937
  if (/cp437|ibm437|\b437\b/iu.test(locale)) return false;
915
938
  if (/utf-?8/iu.test(locale)) return true;
916
939
  if (platform === "win32") {
917
- return Boolean(env.WT_SESSION) || env.TERM_PROGRAM === "vscode" || env.CHCP === "65001" || env.ConEmuANSI === "ON";
940
+ if (env.WT_SESSION || env.ConEmuANSI === "ON") return true;
941
+ return codePage === 65001;
918
942
  }
919
943
  return true;
920
944
  }
@@ -1204,6 +1228,7 @@ function createInstallerRun(value, options = {}) {
1204
1228
  let chunkColumn = 0;
1205
1229
  const trailingCR = /* @__PURE__ */ new Set();
1206
1230
  let deferredActivity;
1231
+ const drawnPhaseCompletions = /* @__PURE__ */ new Set();
1207
1232
  const closeChunk = () => {
1208
1233
  if (chunkOpen) emit("\n", chunkChannel);
1209
1234
  chunkOpen = false;
@@ -1262,7 +1287,10 @@ function createInstallerRun(value, options = {}) {
1262
1287
  if (facts.detail) run2.relay(facts.detail);
1263
1288
  return;
1264
1289
  }
1265
- if (!face.continues(id, state)) durable(title, facts.seconds ?? facts.measure ?? null, state);
1290
+ if (!face.continues(id, state)) {
1291
+ durable(title, facts.seconds ?? facts.measure ?? null, state);
1292
+ if (state === "ok") drawnPhaseCompletions.add(title);
1293
+ }
1266
1294
  if (facts.detail) run2.relay(facts.detail);
1267
1295
  },
1268
1296
  surface(facts) {
@@ -1293,7 +1321,9 @@ function createInstallerRun(value, options = {}) {
1293
1321
  }
1294
1322
  return;
1295
1323
  }
1324
+ if (state !== "fail" && drawnPhaseCompletions.has(step)) return;
1296
1325
  durable(step, ms === void 0 ? null : ms / 1e3, state);
1326
+ if (state === "ok") drawnPhaseCompletions.add(step);
1297
1327
  },
1298
1328
  signIn({ url, code }) {
1299
1329
  start();
@@ -1399,7 +1429,7 @@ function createInstallerRun(value, options = {}) {
1399
1429
  }
1400
1430
 
1401
1431
  // src/autoupdate.ts
1402
- var import_node_child_process2 = require("node:child_process");
1432
+ var import_node_child_process3 = require("node:child_process");
1403
1433
  var import_node_fs10 = require("node:fs");
1404
1434
  var import_node_os3 = require("node:os");
1405
1435
  var import_node_path5 = require("node:path");
@@ -1409,7 +1439,7 @@ function schedulePlatform(override) {
1409
1439
  return null;
1410
1440
  }
1411
1441
  function defaultExec(command2, args) {
1412
- const result = (0, import_node_child_process2.spawnSync)(command2, args, { encoding: "utf8", windowsHide: true });
1442
+ const result = (0, import_node_child_process3.spawnSync)(command2, args, { encoding: "utf8", windowsHide: true });
1413
1443
  if (result.error) return { code: 1, stdout: "", stderr: result.error.message };
1414
1444
  return {
1415
1445
  code: typeof result.status === "number" ? result.status : 1,
@@ -1574,14 +1604,14 @@ function firstLine(text) {
1574
1604
  }
1575
1605
 
1576
1606
  // src/login-github.ts
1577
- var import_node_child_process3 = require("node:child_process");
1607
+ var import_node_child_process4 = require("node:child_process");
1578
1608
  var realSleep = (ms) => new Promise((resolve3) => setTimeout(resolve3, ms));
1579
1609
  function openBrowser(url) {
1580
1610
  if (process.env.LAUNCHER_NO_OPEN === "1") return;
1581
1611
  const opener = process.platform === "darwin" ? "open" : process.platform === "win32" ? "rundll32" : "xdg-open";
1582
1612
  const args = process.platform === "win32" ? ["url.dll,FileProtocolHandler", url] : [url];
1583
1613
  try {
1584
- const child = (0, import_node_child_process3.spawn)(opener, args, { detached: true, stdio: "ignore", windowsHide: true });
1614
+ const child = (0, import_node_child_process4.spawn)(opener, args, { detached: true, stdio: "ignore", windowsHide: true });
1585
1615
  child.on("error", () => {
1586
1616
  });
1587
1617
  child.unref();
@@ -1808,7 +1838,7 @@ function page(title, body) {
1808
1838
  }
1809
1839
 
1810
1840
  // src/index.ts
1811
- var LAUNCHER_VERSION = true ? "0.1.15" : readVersionFromPackage();
1841
+ var LAUNCHER_VERSION = true ? "0.1.17" : readVersionFromPackage();
1812
1842
  function defaultPrint(message) {
1813
1843
  process.stdout.write(`${message}
1814
1844
  `);
@@ -2061,7 +2091,7 @@ function defaultRunEntry(entry2, cwd, env) {
2061
2091
  const [command2, ...args] = entry2;
2062
2092
  const shell = needsShell(command2);
2063
2093
  const commandLine = shell ? [command2, ...args].map(quoteForShell).join(" ") : command2;
2064
- const spawnEntry = (progress2) => (0, import_node_child_process4.spawnSync)(commandLine, shell ? [] : args, {
2094
+ const spawnEntry = (progress2) => (0, import_node_child_process5.spawnSync)(commandLine, shell ? [] : args, {
2065
2095
  cwd,
2066
2096
  stdio: progress2 ? ["inherit", "inherit", "inherit", "pipe"] : "inherit",
2067
2097
  shell,
@@ -2302,7 +2332,7 @@ async function runInstallEntry(entry2, cwd, env, installer, tokens = null) {
2302
2332
  const redact = (text) => secrets.reduce((safe, value) => safe.replaceAll(value, "[redacted]"), text);
2303
2333
  try {
2304
2334
  const result = await new Promise((resolve3) => {
2305
- const child = (0, import_node_child_process4.spawn)(shell ? [command2, ...args].map(quoteForShell).join(" ") : command2, shell ? [] : args, {
2335
+ const child = (0, import_node_child_process5.spawn)(shell ? [command2, ...args].map(quoteForShell).join(" ") : command2, shell ? [] : args, {
2306
2336
  cwd,
2307
2337
  shell,
2308
2338
  windowsHide: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mutmutco/installer-launcher",
3
- "version": "0.1.15",
3
+ "version": "0.1.17",
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",