@gtc6244/immediacy-daemon 0.1.8 → 0.1.9
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/src/terminal.js +90 -17
- package/dist/src/terminal.js.map +1 -1
- package/package.json +2 -2
package/dist/src/terminal.js
CHANGED
|
@@ -5,9 +5,62 @@
|
|
|
5
5
|
* Output is coalesced on a short interval so we emit a few `terminal.data`
|
|
6
6
|
* frames per burst instead of one per write (§3 bandwidth guidance).
|
|
7
7
|
*/
|
|
8
|
+
import { chmodSync, readdirSync, statSync } from "node:fs";
|
|
9
|
+
import { createRequire } from "node:module";
|
|
10
|
+
import { dirname, join } from "node:path";
|
|
8
11
|
import * as pty from "node-pty";
|
|
9
12
|
const SHELL = process.env.SHELL || "/bin/zsh";
|
|
10
13
|
const FLUSH_MS = 16;
|
|
14
|
+
/**
|
|
15
|
+
* Re-assert the execute bit on node-pty's spawn helpers. On macOS node-pty
|
|
16
|
+
* doesn't exec the shell directly — it `posix_spawn`s a small `spawn-helper`
|
|
17
|
+
* binary that chdirs into `cwd` and execs the shell. If that helper lands
|
|
18
|
+
* without its `+x` bit (npm hoists node-pty above the daemon package, so the
|
|
19
|
+
* package's chmod postinstall — a fixed relative path — misses the hoisted
|
|
20
|
+
* copy), the spawn fails with a hint-free "posix_spawnp failed."
|
|
21
|
+
*
|
|
22
|
+
* node-pty uses the helper beside its loaded native module, which may be a
|
|
23
|
+
* prebuild (`prebuilds/<platform-arch>/`) or a source build (`build/Release`,
|
|
24
|
+
* `build/Debug`), so all three are checked. Only flips a helper that's actually
|
|
25
|
+
* missing the bit, and returns true *only* when it changed one — so the caller
|
|
26
|
+
* doesn't retry a spawn that failed for some other reason. No-ops off macOS:
|
|
27
|
+
* Linux uses forkpty and Windows uses conpty — neither ships a spawn-helper.
|
|
28
|
+
*/
|
|
29
|
+
function repairSpawnHelper() {
|
|
30
|
+
if (process.platform !== "darwin")
|
|
31
|
+
return false;
|
|
32
|
+
try {
|
|
33
|
+
const require = createRequire(import.meta.url);
|
|
34
|
+
const root = dirname(require.resolve("node-pty/package.json"));
|
|
35
|
+
const dirs = [join(root, "build", "Release"), join(root, "build", "Debug")];
|
|
36
|
+
try {
|
|
37
|
+
const prebuilds = join(root, "prebuilds");
|
|
38
|
+
for (const arch of readdirSync(prebuilds))
|
|
39
|
+
dirs.push(join(prebuilds, arch));
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
/* no prebuilds dir (pure source build) */
|
|
43
|
+
}
|
|
44
|
+
let fixed = false;
|
|
45
|
+
for (const dir of dirs) {
|
|
46
|
+
const helper = join(dir, "spawn-helper");
|
|
47
|
+
try {
|
|
48
|
+
const { mode } = statSync(helper);
|
|
49
|
+
if ((mode & 0o111) === 0) {
|
|
50
|
+
chmodSync(helper, mode | 0o111);
|
|
51
|
+
fixed = true;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
/* no helper in this dir */
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return fixed;
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
11
64
|
/** How much scrollback to retain for late-joining clients (terminal.snapshot). */
|
|
12
65
|
const SCROLLBACK_CAP = 256 * 1024;
|
|
13
66
|
export class Terminal {
|
|
@@ -21,26 +74,46 @@ export class Terminal {
|
|
|
21
74
|
this.onData = onData;
|
|
22
75
|
const cols = opts.cols && opts.cols > 0 ? opts.cols : 80;
|
|
23
76
|
const rows = opts.rows && opts.rows > 0 ? opts.rows : 24;
|
|
77
|
+
const spawn = () => pty.spawn(SHELL, [], {
|
|
78
|
+
name: "xterm-color",
|
|
79
|
+
// Honor a geometry the client sent before the shell existed; the PTY was
|
|
80
|
+
// otherwise hardwired to 80x24, wrapping the first-drawn output.
|
|
81
|
+
cols,
|
|
82
|
+
rows,
|
|
83
|
+
cwd,
|
|
84
|
+
// node-pty wants a pure string map; process.env may hold undefined
|
|
85
|
+
// entries (deleted vars), which can break spawn on some platforms.
|
|
86
|
+
env: Object.fromEntries(Object.entries(process.env).filter((e) => typeof e[1] === "string")),
|
|
87
|
+
});
|
|
88
|
+
// node-pty's native layer throws a bare "posix_spawnp failed." with no hint
|
|
89
|
+
// at what it tried to run. Re-throw with the attempted call so the surfaced
|
|
90
|
+
// error is actionable — the usual causes are a SHELL that doesn't resolve, a
|
|
91
|
+
// cwd that no longer exists (e.g. a deleted worktree), or node-pty's macOS
|
|
92
|
+
// spawn-helper having lost its execute bit.
|
|
93
|
+
const fail = (err) => {
|
|
94
|
+
const cause = err instanceof Error ? err.message : String(err);
|
|
95
|
+
return new Error(`failed to spawn terminal shell "${SHELL}" (cwd: ${cwd}, ${cols}x${rows}): ${cause}`, { cause: err });
|
|
96
|
+
};
|
|
24
97
|
try {
|
|
25
|
-
this.proc =
|
|
26
|
-
name: "xterm-color",
|
|
27
|
-
// Honor a geometry the client sent before the shell existed; the PTY was
|
|
28
|
-
// otherwise hardwired to 80x24, wrapping the first-drawn output.
|
|
29
|
-
cols,
|
|
30
|
-
rows,
|
|
31
|
-
cwd,
|
|
32
|
-
// node-pty wants a pure string map; process.env may hold undefined
|
|
33
|
-
// entries (deleted vars), which can break spawn on some platforms.
|
|
34
|
-
env: Object.fromEntries(Object.entries(process.env).filter((e) => typeof e[1] === "string")),
|
|
35
|
-
});
|
|
98
|
+
this.proc = spawn();
|
|
36
99
|
}
|
|
37
100
|
catch (err) {
|
|
38
|
-
//
|
|
39
|
-
//
|
|
40
|
-
//
|
|
41
|
-
//
|
|
42
|
-
|
|
43
|
-
|
|
101
|
+
// Self-heal the spawn-helper case once: chmod +x the helper and retry, so
|
|
102
|
+
// a stripped execute bit doesn't wedge the terminal until the next daemon
|
|
103
|
+
// reinstall. Only "posix_spawnp failed." can be a bad helper — it fires
|
|
104
|
+
// before any child exists. Later errors (e.g. "Could not set master fd to
|
|
105
|
+
// nonblocking.") mean node-pty already forked a child, so retrying would
|
|
106
|
+
// leak it; never retry those. repairSpawnHelper only reports success when
|
|
107
|
+
// it actually flipped a bit, so a SHELL/cwd failure won't loop either.
|
|
108
|
+
const isSpawnpFailure = err instanceof Error && err.message.includes("posix_spawnp failed");
|
|
109
|
+
if (!isSpawnpFailure || !repairSpawnHelper())
|
|
110
|
+
throw fail(err);
|
|
111
|
+
try {
|
|
112
|
+
this.proc = spawn();
|
|
113
|
+
}
|
|
114
|
+
catch (retryErr) {
|
|
115
|
+
throw fail(retryErr);
|
|
116
|
+
}
|
|
44
117
|
}
|
|
45
118
|
this.proc.onData((d) => this.enqueue(d));
|
|
46
119
|
this.proc.onExit(() => {
|
package/dist/src/terminal.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminal.js","sourceRoot":"","sources":["../../src/terminal.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAEhC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,UAAU,CAAC;AAC9C,MAAM,QAAQ,GAAG,EAAE,CAAC;AAEpB,kFAAkF;AAClF,MAAM,cAAc,GAAG,GAAG,GAAG,IAAI,CAAC;AAUlC,MAAM,OAAO,QAAQ;IAST;IARF,IAAI,CAAW;IACf,GAAG,GAAG,EAAE,CAAC;IACT,UAAU,GAAG,EAAE,CAAC;IAChB,UAAU,GAA0B,IAAI,CAAC;IACzC,MAAM,GAAG,KAAK,CAAC;IAEvB,YACE,GAAW,EACH,MAA8B,EACtC,OAAwB,EAAE;QADlB,WAAM,GAAN,MAAM,CAAwB;QAGtC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,
|
|
1
|
+
{"version":3,"file":"terminal.js","sourceRoot":"","sources":["../../src/terminal.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gtc6244/immediacy-daemon",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Mac daemon — Conductor core: worktrees + headless Claude Code sessions behind a multiplexed WSS protocol.",
|
|
6
6
|
"type": "module",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"access": "public"
|
|
23
23
|
},
|
|
24
24
|
"scripts": {
|
|
25
|
-
"postinstall": "
|
|
25
|
+
"postinstall": "node -e \"const{chmodSync,statSync,readdirSync}=require('fs'),{dirname,join}=require('path');try{const r=dirname(require.resolve('node-pty/package.json')),d=[join(r,'build','Release'),join(r,'build','Debug')];try{const p=join(r,'prebuilds');for(const a of readdirSync(p))d.push(join(p,a))}catch{}for(const x of d){try{const h=join(x,'spawn-helper');chmodSync(h,statSync(h).mode|0o111)}catch{}}}catch{}\"",
|
|
26
26
|
"dev": "tsx watch src/index.ts",
|
|
27
27
|
"start": "tsx src/index.ts",
|
|
28
28
|
"cli": "tsx src/cli.ts",
|