@gamecrate/cli 2.2.0 → 2.3.0

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/gamecrate.js +20 -12
  2. package/package.json +3 -2
package/dist/gamecrate.js CHANGED
@@ -1056,6 +1056,7 @@ import { basename, join } from "node:path";
1056
1056
  var CONTAINER_RUNTIME_DIR = "/tmp/xdg";
1057
1057
  var CONTAINER_LOG_DIR = "/logs";
1058
1058
  var X11_SOCKET_DIR = "/tmp/.X11-unix";
1059
+ var HOST_X11_DIR = "/run/host-x11";
1059
1060
  var CONTAINER_XAUTHORITY = "/tmp/xauth";
1060
1061
  var CONTAINER_XDG_DIR = "/xdg";
1061
1062
  var RUNTIME_DIR_SIZE = "64m";
@@ -1080,12 +1081,14 @@ function buildRunSpec(plan, modMounts, identity, image) {
1080
1081
  const proton = image?.launcher === "proton";
1081
1082
  const executable = image?.executable ?? game.executable;
1082
1083
  refuseProtonHeaded(plan.game, plan.mode, image);
1083
- const command = proton ? ["run-headless-windows", winPath(join(game.gameFiles.container, basename(executable)))] : headed ? [executable] : [
1084
+ const command = proton ? ["run-headless-windows", winPath(join(game.gameFiles.container, basename(executable)))] : headed ? ["run-headed", executable] : [
1084
1085
  "xvfb-run",
1085
1086
  "-a",
1086
1087
  `--server-args=-screen 0 ${settings.width}x${settings.height}x24`,
1087
1088
  executable
1088
1089
  ];
1090
+ if (headed)
1091
+ env.SCREEN = `${settings.width}x${settings.height}x24`;
1089
1092
  if (proton) {
1090
1093
  Object.assign(env, {
1091
1094
  SCREEN: `${settings.width}x${settings.height}x24`,
@@ -1106,7 +1109,7 @@ function buildRunSpec(plan, modMounts, identity, image) {
1106
1109
  }
1107
1110
  addScratch(mounts, env, plan, identity);
1108
1111
  if (headed)
1109
- addSession(mounts, env, plan);
1112
+ addSession(mounts, env, plan, identity);
1110
1113
  const deviceCgroupRules = [];
1111
1114
  if (settings.input) {
1112
1115
  mounts.push({ type: "bind", source: "/dev/input", target: "/dev/input", readonly: true });
@@ -1174,10 +1177,10 @@ function addScratch(mounts, env, plan, identity) {
1174
1177
  env.XDG_CACHE_HOME = `${CONTAINER_XDG_DIR}/cache`;
1175
1178
  env.XDG_DATA_HOME ??= `${CONTAINER_XDG_DIR}/data`;
1176
1179
  }
1177
- function addSession(mounts, env, plan) {
1180
+ function addSession(mounts, env, plan, identity) {
1178
1181
  const { settings } = plan;
1179
1182
  if (settings.display === "x11")
1180
- addX11(mounts, env);
1183
+ addX11(mounts, env, identity);
1181
1184
  else
1182
1185
  addWayland(mounts, env);
1183
1186
  if (!settings.audio)
@@ -1187,11 +1190,13 @@ function addSession(mounts, env, plan) {
1187
1190
  }
1188
1191
  env.PULSE_SERVER = `unix:${CONTAINER_RUNTIME_DIR}/pulse/native`;
1189
1192
  }
1190
- function addX11(mounts, env) {
1193
+ function addX11(mounts, env, identity) {
1191
1194
  const x11 = x11Session();
1192
1195
  if (!x11)
1193
1196
  return;
1194
- mounts.push({ type: "bind", source: X11_SOCKET_DIR, target: X11_SOCKET_DIR });
1197
+ mounts.push({ type: "tmpfs", target: X11_SOCKET_DIR, uid: identity.uid, gid: identity.gid, mode: "1777" });
1198
+ mounts.push({ type: "bind", source: X11_SOCKET_DIR, target: HOST_X11_DIR, readonly: true });
1199
+ env.HOST_X11_DIR = HOST_X11_DIR;
1195
1200
  env.DISPLAY = x11.display;
1196
1201
  env.XDG_SESSION_TYPE = "x11";
1197
1202
  env.SDL_VIDEODRIVER = "x11";
@@ -5318,6 +5323,11 @@ async function runOnce(argv, what) {
5318
5323
  ${stderr}`.trim());
5319
5324
  }
5320
5325
  var HEARTBEAT_MS = 1000;
5326
+ function spawnFailure(error) {
5327
+ const message = error instanceof Error ? error.message : String(error);
5328
+ const code = error?.code;
5329
+ return code === undefined || message.includes(code) ? message : `${message} (${code})`;
5330
+ }
5321
5331
  async function live(argv, what) {
5322
5332
  const since = Date.now();
5323
5333
  let lastNotice = 0;
@@ -5330,10 +5340,7 @@ async function live(argv, what) {
5330
5340
  status(`${what} (${notice})`);
5331
5341
  }, HEARTBEAT_MS);
5332
5342
  try {
5333
- return await captureLive(argv).catch((error) => ({
5334
- code: 127,
5335
- text: error instanceof Error ? error.message : String(error)
5336
- }));
5343
+ return await captureLive(argv).catch((error) => ({ code: 127, text: spawnFailure(error) }));
5337
5344
  } finally {
5338
5345
  clearInterval(timer);
5339
5346
  }
@@ -7583,7 +7590,7 @@ function published2(value) {
7583
7590
  }
7584
7591
 
7585
7592
  // src/index.ts
7586
- var VERSION = "2.2.0";
7593
+ var VERSION = "2.3.0";
7587
7594
  async function main(argv) {
7588
7595
  const supervised = supervisedDir(argv);
7589
7596
  try {
@@ -8048,7 +8055,8 @@ function steamcmdSource(runner, config) {
8048
8055
  }
8049
8056
  function gameForImage(args, config, defaults, game) {
8050
8057
  const base = config.games[game];
8051
- return withImageOverride(base, imageFor(base, launchProfile(args, defaults, base), args.image));
8058
+ const ref = args.image ?? imageFor(base, launchProfile(args, defaults, base));
8059
+ return withImageOverride(base, ref);
8052
8060
  }
8053
8061
  async function refs(args, config, defaults) {
8054
8062
  const game = requireGame(args, config);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gamecrate/cli",
3
- "version": "2.2.0",
3
+ "version": "2.3.0",
4
4
  "description": "Run a modded game in a container, with mods resolved from your local checkouts.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -34,7 +34,7 @@
34
34
  ],
35
35
  "scripts": {
36
36
  "typecheck": "tsc --noEmit",
37
- "test": "vitest run",
37
+ "test": "bun test --parallel",
38
38
  "build": "npm run build:node && npm run build:types && npm run build:binary",
39
39
  "build:node": "bun build ./src/index.ts --target=node --packages=external --define __VERSION__='\"'${npm_package_version:-0.0.0-dev}'\"' --outfile dist/gamecrate.js && bun build ./src/lib.ts --target=node --packages=external --outfile dist/lib.js",
40
40
  "build:types": "tsc -p tsconfig.build.json",
@@ -43,6 +43,7 @@
43
43
  "prepack": "npm run build:node && npm run build:types"
44
44
  },
45
45
  "devDependencies": {
46
+ "@types/bun": "^1.3.0",
46
47
  "@types/node": "^22.10.0",
47
48
  "@types/picomatch": "^4.0.0",
48
49
  "typescript": "^5.7.0"