@brutalsystems/muster 0.7.4 → 0.7.5

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/hosts/pty.js +44 -2
  2. package/package.json +1 -1
package/dist/hosts/pty.js CHANGED
@@ -1,9 +1,50 @@
1
- import { mkdtemp, writeFile, rm } from "node:fs/promises";
1
+ import { mkdtemp, writeFile, rm, stat, chmod } from "node:fs/promises";
2
2
  import { tmpdir } from "node:os";
3
- import { join } from "node:path";
3
+ import { dirname, join } from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
+ import { createRequire } from "node:module";
5
6
  import { randomUUID } from "node:crypto";
6
7
  import { processRef, stopTree } from "../identity/processes.js";
8
+ /**
9
+ * node-pty 1.1.0's macOS prebuilt `spawn-helper` ships without its executable
10
+ * bit. `scripts/prepare-pty.mjs` sets it at install time, but that runs only
11
+ * if install scripts are permitted — and a global install that skips them
12
+ * leaves a pty launch failing with `posix_spawnp failed`, which names neither
13
+ * the file nor the permission. tmux launches are unaffected, so the breakage
14
+ * is invisible until someone happens to use this host.
15
+ *
16
+ * Re-checked here so a launch repairs itself rather than failing on something
17
+ * an install already knew how to fix. `root` is injectable for tests.
18
+ */
19
+ export async function ensureSpawnHelperExecutable(root) {
20
+ if (process.platform !== "darwin")
21
+ return;
22
+ const base = root ??
23
+ dirname(createRequire(import.meta.url).resolve("node-pty/package.json"));
24
+ for (const file of [
25
+ join(base, "prebuilds", `darwin-${process.arch}`, "spawn-helper"),
26
+ join(base, "build", "Release", "spawn-helper"),
27
+ ]) {
28
+ let info;
29
+ try {
30
+ info = await stat(file);
31
+ }
32
+ catch (e) {
33
+ if (e.code === "ENOENT")
34
+ continue;
35
+ throw e;
36
+ }
37
+ if ((info.mode & 0o111) !== 0)
38
+ continue;
39
+ try {
40
+ await chmod(file, info.mode | 0o111);
41
+ }
42
+ catch {
43
+ throw new Error(`node-pty's spawn-helper is not executable and could not be fixed: ${file}. ` +
44
+ `Run \`node scripts/prepare-pty.mjs\` from the Muster install, or use --host tmux.`);
45
+ }
46
+ }
47
+ }
7
48
  export class PtyHost {
8
49
  id = "pty";
9
50
  sessions = new Map();
@@ -21,6 +62,7 @@ export class PtyHost {
21
62
  }
22
63
  async launch(opts) {
23
64
  const module = await import("node-pty");
65
+ await ensureSpawnHelperExecutable();
24
66
  const dir = await mkdtemp(join(tmpdir(), "muster-pty-"));
25
67
  const file = join(dir, "launch.json");
26
68
  await writeFile(file, JSON.stringify(opts), { mode: 0o600 });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brutalsystems/muster",
3
- "version": "0.7.4",
3
+ "version": "0.7.5",
4
4
  "description": "Launch instructed, reachable local agent sessions",
5
5
  "type": "module",
6
6
  "engines": {