Skip to content

fix(pty): cooked-mode echo/signal discipline + kernel-PTY stdin for TTY guests#179

Merged
NathanFlurry merged 2 commits into
mainfrom
nathan/pty-cooked-tty-guests
Jul 2, 2026
Merged

fix(pty): cooked-mode echo/signal discipline + kernel-PTY stdin for TTY guests#179
NathanFlurry merged 2 commits into
mainfrom
nathan/pty-cooked-tty-guests

Conversation

@NathanFlurry

@NathanFlurry NathanFlurry commented Jul 2, 2026

Copy link
Copy Markdown
Member
  • Register projected { packageDir } package bin commands in the kernel command table so projected wasm commands can spawn (previously ENOEXEC/ENOENT)
  • Surface cooked-mode PTY echo and ONLCR-processed guest output through the master as a single ordered stdout stream
  • Echo signal characters (^C / ^\ / ^Z) only when no foreground process group is attached; with one, the byte is consumed as a signal
  • Raw mode now disables OPOST/ONLCR (cfmakeraw parity); cooked mode restores it
  • TTY guest-node processes read stdin from the kernel PTY slave, so echo, line editing, ICRNL, VEOF and ISIG signals behave like a real TTY; the bridge derives process isTTY and window size from the kernel
  • Wasm runner reports kernel-PTY stdio as CHARACTER_DEVICE (guest is_terminal/isatty now true) and host_tty.read short-polls so blocking reads no longer starve host stdin writes
  • Enable brush's reedline backend for the wasm sh build: interactive shell gets history, arrow keys, and Ctrl-R reverse search

…ommand table

The { packageDir } projection lands each package's bin/<cmd> at
/opt/agentos/bin/<cmd> and puts that directory on PATH, but never
registered the commands in the kernel command table (only 'provides'
populates /__secure_exec/commands), so spawning any projected wasm
command failed with ENOEXEC/ENOENT. Register each projected command's
/opt/agentos/bin entrypoint after mount setup, mirroring what
discover_command_guest_paths does for provides, and refresh the guest
PATH env accordingly.
@railway-app railway-app Bot temporarily deployed to secure-exec / secure-exec-pr-179 July 2, 2026 00:20 Destroyed
@NathanFlurry NathanFlurry force-pushed the nathan/pty-cooked-tty-guests branch from c783db8 to 8c664c7 Compare July 2, 2026 00:21
@railway-app railway-app Bot temporarily deployed to secure-exec / secure-exec-pr-179 July 2, 2026 00:21 Destroyed
@NathanFlurry NathanFlurry force-pushed the nathan/pty-cooked-tty-guests branch from 8c664c7 to 21cc55d Compare July 2, 2026 00:22
@railway-app railway-app Bot temporarily deployed to secure-exec / secure-exec-pr-179 July 2, 2026 00:22 Destroyed
@railway-app

railway-app Bot commented Jul 2, 2026

Copy link
Copy Markdown

🚅 Environment secure-exec-pr-179 in rivet-frontend has no services deployed.


🚅 Deployed to the secure-exec-pr-179 environment in secure-exec

Service Status Web Updated (UTC)
secure-exec 😴 Sleeping (View Logs) Web Jul 2, 2026 at 4:03 am

@NathanFlurry NathanFlurry force-pushed the nathan/pty-cooked-tty-guests branch from 21cc55d to 6d7feea Compare July 2, 2026 03:07
@railway-app railway-app Bot temporarily deployed to secure-exec / secure-exec-pr-179 July 2, 2026 03:07 Destroyed
@NathanFlurry NathanFlurry force-pushed the nathan/pty-cooked-tty-guests branch from 6d7feea to 0ec005d Compare July 2, 2026 03:56
@railway-app railway-app Bot temporarily deployed to secure-exec / secure-exec-pr-179 July 2, 2026 03:56 Destroyed
@NathanFlurry NathanFlurry force-pushed the nathan/pty-cooked-tty-guests branch from 0ec005d to 28d52e0 Compare July 2, 2026 04:42
@railway-app railway-app Bot temporarily deployed to secure-exec / secure-exec-pr-179 July 2, 2026 04:42 Destroyed
…TY guests

Kernel (pty.rs):
- LineDisciplineConfig gains opost/onlcr toggles so raw mode disables
  output post-processing (cfmakeraw parity) and cooked mode restores it.
- Signal chars (^C / ^\ / ^Z) echo their caret form only when no
  foreground process group is attached; with a foreground pgroup the
  byte is consumed as a signal and never echoed.

Sidecar:
- Track the PTY master fd on ActiveProcess and drain the master output
  buffer after every host stdin write, surfacing cooked-mode echo (and
  ONLCR-processed guest output) as the single ordered Stdout stream.
- Route cooked-TTY guest stdout through the PTY slave (OPOST/ONLCR);
  raw-TTY output passes through unmodified for full-screen apps.
- __pty_set_raw_mode toggles opost/onlcr alongside icanon/echo/isig.
- TTY guest-node: dup2 the PTY slave onto fds 0-2 and, after each master
  write, forward the cooked slave input to the isolate's stream-stdin
  dispatch (VEOF propagates as end-of-stdin), so echo, VERASE/VKILL/
  VWERASE, ICRNL, VEOF and ISIG signals behave like a real TTY for
  process.stdin.

Wasm runner:
- Report kernel-PTY stdio fds as CHARACTER_DEVICE in fd_fdstat_get (and
  answer the host-env isatty shim from the kernel), so guest
  is_terminal()/isatty() finally see the TTY — the runner-process fds
  behind the delegate are pipes. Fixes interactive guests that gate
  behavior on stdin being a terminal (e.g. brush suppressing its
  prompt).
- host_tty.read short-polls __kernel_stdin_read in 10ms slices instead
  of one long blocking read: a long read occupies the sidecar service
  loop, so the host->guest stdin write it waits for (e.g. the CPR reply
  to crossterm's cursor-position query) queues behind it and the read
  self-deadlocks until timeout.

Registry (native):
- Enable brush's reedline feature for the wasm sh build (history,
  arrows, reverse search in the VM shell). The wasi support patches for
  crossterm/brush-interactive/fd-lock already existed; the remaining
  gap was upstream brush-interactive declaring tokio only for
  unix/windows while its reedline modules use tokio::sync
  unconditionally — added as
  patches/crates/brush-interactive/0002-wasi-tokio-dep.patch.

Bridge (bridge-src):
- New tty-config resolver derives process.stdin/stdout/stderr isTTY and
  cols/rows from _kernelIsatty/_kernelTtySize with safe fallbacks;
  process/console builtins consume it.
@NathanFlurry NathanFlurry force-pushed the nathan/pty-cooked-tty-guests branch from 28d52e0 to 8c4ba5f Compare July 2, 2026 04:43
@railway-app railway-app Bot temporarily deployed to secure-exec / secure-exec-pr-179 July 2, 2026 04:43 Destroyed
@NathanFlurry NathanFlurry merged commit b4f2b9f into main Jul 2, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant