ReviewOS

home-lang/home

Native Bun.Terminal: replace skeleton methods with real PTY I/O and ownership

#503
Open chris opened this 9 days ago ·
9 days ago

Follow-up to #66, #501 and #502. A wider unchanged subprocess audit selected three cases from test/js/bun/terminal/terminal-spawn.test.ts: data callbacks, stdout TTY detection, and inline terminal creation. Native Home reports 0 pass / 3 fail / 13 filtered out. Existing Terminal instances fail with terminal slave fd is no longer valid; inline creation returns PTY not supported on this platform on Darwin. Published a21f735fc produces the same failures, so these predate the input/kevent fixes.

packages/runtime/src/runtime/api/bun/terminal.zig still provides skeleton state and methods: createFromSpawn always returns NotSupported, ref/unref return undefined, and close/dispose primarily flip flags. Port the real current native terminal implementation: PTY creation and ownership, terminal reader/writer, callback delivery, process attachment, terminal modes/resize, ref/unref and idempotent asynchronous cleanup. An object with plausible fields or success-shaped no-ops is not the required capability.

Preserve original tests and deadlines. Validate standalone and inline terminal instances, actual TTY behavior and bytes, and the already-removed FilePoll semantics from #501. Include input payloads overridden by terminal stdio (#502) and resource/lifetime checks. Platform guards must remain honest; Darwin execution is available locally, while other platforms require distinct verification.

Installed Bun 1.3.14 passes only the inline case in this three-case control (1 pass / 2 timeout failures / 5 assertions); it is not a passing control for the whole newer selection. The pinned source and unchanged tests remain the target: 4982b91e3702094330f3be3883354c52b8c01323. Package-script dispatch remains separate in #497; ordinary spawn and stream behavior must not be conflated with terminal support.

9 days ago

Published 8157bde43 on codex/runtime-port (not merged into main), authored and committed as Chris without coauthors.

The terminal skeleton is replaced with actual PTY allocation, native reader/writer I/O, FilePoll dispatch, resize/termios/raw mode, callbacks, references, and disposal. POSIX backpressure completion now delivers drain. Reader ownership is acquired before synchronous registration callbacks and released once after re-entrant JavaScript. Each terminal owns its raw-mode snapshot; Darwin's 64-bit flag conversion saturates safely, including NaN/Infinity.

Two missing integration paths were also fixed: native VM startup now records inherited TTY descriptors and original attributes and restores stdio at exit; inline PTY spawn uses the existing native fork/exec/error-pipe implementation for setsid + TIOCSCTTY. This fixes actual child TTY streams, dimensions, raw mode, SIGWINCH, Ctrl+C, and SIGHUP behavior. Ordinary spawn retains its existing path.

Final macOS results against unchanged pin 4982b91e3702094330f3be3883354c52b8c01323:

FilePassedAssertionsExcluded
terminal.test.ts892201 TODO
terminal-spawn.test.ts15721 Windows-only skip
terminal-platform-gaps.test.ts1931None
stdin-pause-pty.test.ts12 + 1 snapshotNone

All four files and the inspected readline child fixture were verified byte-identical to the pin. No corpus assertions, deadlines, or workloads changed.

The new native regression checks natural ref/unref process lifetime, independent raw modes, 1,048,593 original input bytes under backpressure after the caller overwrites its buffer, drain receiver identity, /dev/tty, constructor cleanup with 0–3 available descriptor slots, 48 disposal/failed-inline-spawn cycles (including overridden Blob/typed-array stdin from #502), GC collection with a retained positive control, and 24 close/GC callbacks during reading. The previous published binary fails its reference-liveness control.

The final binary passes all 39 regression commands, including all 22 native regression files and full unchanged spawn (126 passed / 5,484 assertions / 5 skips). Three extra native terminal repeats pass, including VM destruction at exit. Seven adjacent stdin suites pass 34 / 197, excluding 3 TODOs. Native build and cached rebuild pass 17/17; focused formatting/lint/whitespace checks pass. Owned orphan sleep descendants were cleaned only after their tested parent exited normally.

Leaving this issue open for integration and platform verification: Linux/Windows execution and cross-compilation were not verified; restored ConPTY source is not a Windows test result. The separate package-script failure remains #497 (full child-process file: 31 passed / 1 failed / 1 skipped / 1 TODO / 70 assertions). Full port/suite completion remains open in #66.

9 days ago

Main integration/admission checkpoint 2427cb8f2 is now pushed (test(runtime): activate native terminal corpus).

The three terminal corpus files no longer become Home-generated TODOs. The aggregate corpus runner now routes this exact PTY matrix through Home's production VM and retains upstream platform skips in the same non-failure accounting used by the reduced runner.

macOS unchanged-corpus result through the normal home test packages/runtime/test/bun-corpus/js/bun/terminal entrypoint:

  • 3 files executed
  • 123 passed
  • 0 failed
  • 0 unsupported
  • 2 upstream non-running registrations (Bun's 1 Windows-only skip + 1 TODO)

Pinned Bun 4982b91e3702094330f3be3883354c52b8c01323 reports the identical semantic result: 123 pass, 1 skip, 1 TODO, 0 fail, 323 assertions. SHA-256 checks confirm all three copied files are byte-identical to that checkout. Full home_rt: 1,816 passed, 19 skipped, 0 failed.

This removes the macOS corpus suppression/integration portion. Keeping #503 open for its explicitly outstanding Linux/Windows execution and ConPTY verification.

9 days ago

Current main no longer has the Darwin skeleton behavior described in the opening report. At 58a2f2b427e6038bd8b103133cbec042551c9865, all three unchanged pinned terminal files are byte-identical to ~/Code/bun and Home matches pinned Bun exactly: 123 pass / 1 Windows-only skip / 1 upstream TODO / 0 fail / 323 assertions across terminal-platform-gaps.test.ts, terminal-spawn.test.ts, and terminal.test.ts.

The passing cases cover standalone and inline PTY creation, data callbacks, stdin/stdout/stderr TTY identity, dimensions and resize observation, writes/backpressure, raw/cooked termios restoration, ref/unref, close/dispose, sequential reuse, child exit ownership, UTF-8, CRLF and control-character behavior. The old three-case failures (terminal slave fd is no longer valid and Darwin PTY not supported) are gone.

Leaving this issue open for the explicit non-Darwin verification boundary and the unchanged upstream drain-callback TODO. No test, platform guard, TODO, workload, or deadline was modified.

Sign in to comment on this issue.