Skip to content

Commit 7e9d773

Browse files
committed
chore: US-028 bridge fixes for Pi interactive TUI
- Fix process.kill(self, SIGWINCH) to dispatch signal handlers instead of exiting — Pi TUI sends SIGWINCH to refresh dimensions on startup - Add _stdinRead to ASYNC_BRIDGE_FNS in V8 sidecar to prevent event loop deadlock when process.stdin.resume() starts the readLoop - Rewrite pi-interactive.test.ts: remove all sandboxSkip/probe logic, use networkAdapter instead of inline fetch patching, ESM mode with PI_MAIN (avoids undici import issues with cli.js), proper env vars - Tests still fail due to additional V8 sidecar crash during Pi TUI init (further sandbox gaps to investigate)
1 parent f31ef1e commit 7e9d773

3 files changed

Lines changed: 105 additions & 165 deletions

File tree

native/v8-runtime/src/session.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,7 @@ pub(crate) const SYNC_BRIDGE_FNS: [&str; 31] = [
678678
"_childProcessSpawnSync",
679679
];
680680

681-
pub(crate) const ASYNC_BRIDGE_FNS: [&str; 7] = [
681+
pub(crate) const ASYNC_BRIDGE_FNS: [&str; 8] = [
682682
// Module loading (async)
683683
"_dynamicImport",
684684
// Timer
@@ -689,6 +689,8 @@ pub(crate) const ASYNC_BRIDGE_FNS: [&str; 7] = [
689689
"_networkHttpRequestRaw",
690690
"_networkHttpServerListenRaw",
691691
"_networkHttpServerCloseRaw",
692+
// Streaming stdin (async — must not block V8 thread)
693+
"_stdinRead",
692694
];
693695

694696
/// Run the session event loop: dispatch incoming messages to V8.

packages/nodejs/src/bridge/process.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -870,9 +870,22 @@ const process: Record<string, unknown> & {
870870
err.syscall = "kill";
871871
throw err;
872872
}
873-
// Resolve signal name to number (default SIGTERM)
873+
// Resolve signal name to number and string
874874
const sigNum = _resolveSignal(signal);
875-
// Self-kill - exit with 128 + signal number (POSIX convention)
875+
const sigName = typeof signal === "string" ? signal
876+
: Object.entries(_signalNumbers).find(([, n]) => n === sigNum)?.[0] ?? `SIG${sigNum}`;
877+
878+
// Signals with no default termination action (harmless if no handler)
879+
const _harmlessSignals = new Set([28 /* SIGWINCH */, 17 /* SIGCHLD */, 23 /* SIGURG */, 18 /* SIGCONT */]);
880+
881+
// Try dispatching to registered signal handlers first
882+
const handled = _emit(sigName, sigName);
883+
if (handled) return true;
884+
885+
// No handler — harmless signals are silently ignored (POSIX behavior)
886+
if (_harmlessSignals.has(sigNum)) return true;
887+
888+
// No handler for fatal signal — exit with 128 + signal number (POSIX convention)
876889
return (process as unknown as { exit: (code: number) => never }).exit(128 + sigNum);
877890
},
878891

0 commit comments

Comments
 (0)