Repository navigation
v0.1.0
Added
- The Windows backend, end to end. ConPTY through the in-box
kernel32
pseudoconsole API: spawn withargv/cwd/env, read, write, resize, kill
via a job object, and exit reporting. Noconpty.dll, noOpenConsole.exe,
no redistributable of any kind. - The per-pty helper executable, built by
rustcalone — noCargo.toml,
no crates, Rust std with hand-writtenextern "system"declarations. Linked
with-C target-feature=+crt-staticso it runs on a bare Windows with no
Visual C++ redistributable installed; a missing redistributable makes every
.nodeaddon fail asCannot find native binding, which reads like a missing
file rather than a missing runtime. - The framed stdin/stdout protocol (
native/proto.md) and its JS codec,
withstderrleft free for diagnostics so a crashing helper can still say why
without corrupting the stream. npm run verify:pty— the live suite: real shells, the execution oracle,
resize, kill, a failed spawn, an orphan sweep, and the leak bar. It opens with
a positive control (hold 20 ptys, confirm the gauges rise), because a leak
check that has never seen its gauges move cannot go red.prepublishOnlyreads every shipped binary's own PE / ELF / Mach-O header and
compares the machine field with the directory it sits in. A present-files
check is what let a host-archconpty.dllship green on a cross-arch build.
Notes
-
The helper resolves IN PLACE under the install directory and is never
extracted to a temp path. A hard constraint, not an implementation detail:
Genie's upgrade teardown kills and names everything running from the install
dir, so a helper inos.tmpdir()would be invisible to that sweep and one
stuck helper could jam an upgrade with nothing able to name it. -
ESM with an
exports.importcondition. Measured rather than chosen: a
built ESM Electron main bundle leaves packages external, and Node refuses a
named import from a CJS package with getter-defined exports. CJS is carried
too, for everyone else. -
The POSIX backend —
posix_openpt/grantpt/unlockpt/ptsname,
thenfork+setsid+ioctl(TIOCSCTTY)+dup2+execvp, with a
CLOEXEC errno pipe so a failed exec is reported rather than appearing as a
shell that exited 127. Verified by the live suite on real CI runners:platform per pty threads handles / fds memory win32-x6432 ms 0.000 0.000 OS handles 0.009 MB linux-x643 ms 0.000 0.000 fds 0.036 MB linux-arm642 ms 0.000 0.000 fds 0.021 MB darwin-arm6412 ms 0.000 0.000 fds 0.044 MB darwin-x64andwin32-arm64cross-compile clean but have not run — nothing
in CI hosts them natively, and "builds" is not "works". -
The leak check measures the bar's own units — threads, OS handles/fds and
RSS (test/live/process-stats.mjs). An earlier version gaugedlibuvhandle
counts, which are Node's event-loop handles rather than OS handles, and did
not measure threads at all; it reported a pass against a threshold it was not
measuring. An unavailable metric is now skipped out loud rather than scored
as zero. -
npm run linttypechecks the helper for all six targets, not just the
host.c_charis unsigned onaarch64-linuxand signed elsewhere, so
hardcodedi8C-string pointers compiled on four targets and failed on one;
acfg-heavy file is only as checked as the targets you compiled it for, and
the arms you did not compile are unparsed rather than merely untested.