@tablation/crew 0.129.0 → 0.129.1

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/cli.js +29 -9
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -5165,9 +5165,22 @@ function planDaemonControl(crewHome, hostShip, hasSystemd) {
5165
5165
  }
5166
5166
  return { mechanism: "none", startCommand: null, stopCommand: null, statusCommand: null };
5167
5167
  }
5168
+ function withUserBusEnv(env = process.env, opts = {}) {
5169
+ const platform2 = opts.platform ?? process.platform;
5170
+ const uid = opts.uid === void 0 ? process.getuid?.() ?? null : opts.uid;
5171
+ if (platform2 !== "linux" || uid === null) return env;
5172
+ const dir = `/run/user/${uid}`;
5173
+ if (env.XDG_RUNTIME_DIR && env.DBUS_SESSION_BUS_ADDRESS) return env;
5174
+ if (!(opts.exists ?? existsSync15)(dir)) return env;
5175
+ return {
5176
+ ...env,
5177
+ XDG_RUNTIME_DIR: env.XDG_RUNTIME_DIR || dir,
5178
+ DBUS_SESSION_BUS_ADDRESS: env.DBUS_SESSION_BUS_ADDRESS || `unix:path=${env.XDG_RUNTIME_DIR || dir}/bus`
5179
+ };
5180
+ }
5168
5181
  function runAll(commands, cwd, log) {
5169
5182
  for (const [bin, ...args] of commands) {
5170
- const res = spawnSync5(bin, args, { cwd, encoding: "utf8" });
5183
+ const res = spawnSync5(bin, args, { cwd, encoding: "utf8", env: withUserBusEnv() });
5171
5184
  if (res.error || res.status !== 0) {
5172
5185
  log.warn(`${bin} ${args.join(" ")} exited ${res.status ?? "error"}`, {
5173
5186
  output: `${res.stdout ?? ""}${res.stderr ?? ""}${res.error ? String(res.error) : ""}`
@@ -5393,7 +5406,7 @@ function removeCrontabLine(marker) {
5393
5406
  }
5394
5407
  function detectSystemd() {
5395
5408
  if (process.platform !== "linux") return false;
5396
- const res = spawnSync5("systemctl", ["--user", "status"], { encoding: "utf8" });
5409
+ const res = spawnSync5("systemctl", ["--user", "status"], { encoding: "utf8", env: withUserBusEnv() });
5397
5410
  return !res.error;
5398
5411
  }
5399
5412
 
@@ -13893,6 +13906,11 @@ function managedRuntimeWarnings(kind, ship) {
13893
13906
  }
13894
13907
  return out;
13895
13908
  }
13909
+ function runtimeDirWarning(platform2, uid, exists, user = "the crew user") {
13910
+ if (platform2 !== "linux" || uid === null || uid === 0) return null;
13911
+ if (exists(`/run/user/${uid}`)) return null;
13912
+ return `/run/user/${uid} is missing, so \`systemctl --user\` cannot reach the user manager: lingering is off for ${user}; run \`sudo loginctl enable-linger ${user}\``;
13913
+ }
13896
13914
  var MANAGED_GIT_EMAIL = "crew@tablation.dev";
13897
13915
  function readGlobalGitIdentity() {
13898
13916
  const get2 = (key) => {
@@ -14139,7 +14157,7 @@ function doctorSelftestLines(stored, toolchains) {
14139
14157
  // src/cli.ts
14140
14158
  import { resolve as resolve7, dirname as dirname35, join as join56, basename as basename16 } from "path";
14141
14159
  import { fileURLToPath as fileURLToPath2 } from "url";
14142
- import { hostname as hostname5, homedir as homedir11 } from "os";
14160
+ import { hostname as hostname5, homedir as homedir11, userInfo as userInfo2 } from "os";
14143
14161
  import { spawnSync as spawnSync12 } from "child_process";
14144
14162
  import { parse as parseYaml2 } from "yaml";
14145
14163
 
@@ -15656,7 +15674,7 @@ function realProvisionDeps(crewHome) {
15656
15674
  if (mechanism === "systemd") {
15657
15675
  const system = ctx.root || existsSync33(systemUnitPathFor(label));
15658
15676
  const ctl = system ? ["systemctl"] : ["systemctl", "--user"];
15659
- running = spawnSync9(ctl[0], [...ctl.slice(1), "is-active", "--quiet", `${label}.service`]).status === 0;
15677
+ running = spawnSync9(ctl[0], [...ctl.slice(1), "is-active", "--quiet", `${label}.service`], { env: withUserBusEnv() }).status === 0;
15660
15678
  if (!system) {
15661
15679
  const out = spawnSync9("loginctl", ["show-user", ctx.user, "-p", "Linger"], { encoding: "utf8" });
15662
15680
  lingering = /Linger=yes/.test(out.stdout ?? "");
@@ -26514,7 +26532,7 @@ if (command === "passenger-sync-daemon") {
26514
26532
  `
26515
26533
  );
26516
26534
  if (!dryRun) {
26517
- spawnSync12("systemctl", ["--user", "disable", "--now", `${label}.timer`], { cwd: CREW_HOME });
26535
+ spawnSync12("systemctl", ["--user", "disable", "--now", `${label}.timer`], { cwd: CREW_HOME, env: withUserBusEnv() });
26518
26536
  try {
26519
26537
  unlinkSync5(staleTimer);
26520
26538
  } catch {
@@ -27810,7 +27828,7 @@ ${cu.tail.trimEnd()}
27810
27828
  }
27811
27829
  let failed = false;
27812
27830
  for (const cmd2 of commands) {
27813
- const res2 = spawnSync12(cmd2[0], cmd2.slice(1), { cwd: CREW_HOME, encoding: "utf8" });
27831
+ const res2 = spawnSync12(cmd2[0], cmd2.slice(1), { cwd: CREW_HOME, encoding: "utf8", env: withUserBusEnv() });
27814
27832
  if (res2.stdout) process.stdout.write(res2.stdout);
27815
27833
  if (res2.stderr) process.stderr.write(res2.stderr);
27816
27834
  if (cmd2 === control.startCommand && (res2.error || res2.status !== 0)) {
@@ -27828,7 +27846,7 @@ ${cu.tail.trimEnd()}
27828
27846
  `);
27829
27847
  break;
27830
27848
  }
27831
- const res = spawnSync12(cmd[0], cmd.slice(1), { cwd: CREW_HOME, encoding: "utf8" });
27849
+ const res = spawnSync12(cmd[0], cmd.slice(1), { cwd: CREW_HOME, encoding: "utf8", env: withUserBusEnv() });
27832
27850
  if (res.stdout) process.stdout.write(res.stdout);
27833
27851
  if (res.stderr) process.stderr.write(res.stderr);
27834
27852
  if (daemonSub !== "status" && (res.error || res.status !== 0)) {
@@ -30541,7 +30559,7 @@ ${where.join("\n")}`);
30541
30559
  }
30542
30560
  const host = hostPlatform();
30543
30561
  const control = host === "windows" ? null : planDaemonControl(CREW_HOME, host, detectSystemd());
30544
- const unitStatus = control?.statusCommand ? spawnSync12(control.statusCommand[0], control.statusCommand.slice(1), { cwd: CREW_HOME, encoding: "utf8" }) : null;
30562
+ const unitStatus = control?.statusCommand ? spawnSync12(control.statusCommand[0], control.statusCommand.slice(1), { cwd: CREW_HOME, encoding: "utf8", env: withUserBusEnv() }) : null;
30545
30563
  const unitRunning = unitStatus !== null && !unitStatus.error && unitStatus.status === 0;
30546
30564
  if (!unitRunning && control?.mechanism === "systemd" && control.startCommand) {
30547
30565
  const res = spawnSync12(control.startCommand[0], control.startCommand.slice(1), { cwd: CREW_HOME, encoding: "utf8" });
@@ -30566,7 +30584,7 @@ ${where.join("\n")}`);
30566
30584
  );
30567
30585
  if (flag("now") && control?.stopCommand && control.startCommand) {
30568
30586
  for (const cmd of [control.stopCommand, control.startCommand]) {
30569
- const res = spawnSync12(cmd[0], cmd.slice(1), { cwd: CREW_HOME, encoding: "utf8" });
30587
+ const res = spawnSync12(cmd[0], cmd.slice(1), { cwd: CREW_HOME, encoding: "utf8", env: withUserBusEnv() });
30570
30588
  if (cmd === control.startCommand && (res.error || res.status !== 0)) {
30571
30589
  process.stderr.write(`crew reload: ${cmd.join(" ")} exited ${res.status ?? "error"}
30572
30590
  `);
@@ -31144,6 +31162,8 @@ watermark: ${state.watermark()}
31144
31162
  }
31145
31163
  }
31146
31164
  for (const message of roleCapWarnings(cfg.ship)) problems.push({ severity: "note", kind: "role_cap_above_ship_cap", message });
31165
+ const runtimeDir = runtimeDirWarning(process.platform, process.getuid?.() ?? null, existsSync51, userInfo2().username);
31166
+ if (runtimeDir) problems.push({ severity: "attention", kind: "runtime_dir_missing", message: runtimeDir });
31147
31167
  if (!flag("offline")) {
31148
31168
  const shipKind = await doctorShipKind(route2, cfg.ship);
31149
31169
  for (const message of managedRuntimeWarnings(shipKind, cfg.ship)) problems.push({ severity: "attention", kind: "managed_runtime_default", message });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tablation/crew",
3
- "version": "0.129.0",
3
+ "version": "0.129.1",
4
4
  "description": "A standing team of headless agents that picks work off a Tablation board, does it on a machine you control, and reports back.",
5
5
  "type": "module",
6
6
  "license": "MIT",