fix(core): deactivate idle TTY write handles (#35886)
## Summary
Allow Node-compatible TTY stdio writes to drain and then stop keeping
Deno alive, without changing the observable ref state of the underlying
stdio handle where that handle is exposed.
Adds a PTY integration regression for a large `process.stderr.write()`
that verifies the write callback runs and the process exits. On
platforms that expose `process.stderr._handle.hasRef()`, it also
verifies the handle remains ref'ed before and inside the callback.
## Root Cause
`uv_tty_init()` creates TTY handles with `UV_HANDLE_REF`, matching
Node's observable `process.stderr._handle.hasRef() === true` behavior
for stdio TTYs where `_handle` is exposed.
Deno's `uv_compat` write path also marks TTY handles `UV_HANDLE_ACTIVE`
via `ensure_tty_registered()`. Plain TTY writes drained their callbacks,
but the normal write-drain path did not clear `UV_HANDLE_ACTIVE`; only
the shutdown path deactivated the handle. Since loop liveness checks
count handles that are both active and ref'ed, an idle stdio TTY write
handle could keep Deno alive forever after all JS and children had
finished.
The fix deactivates TTY handles once there is no pending read, write, or
shutdown work. It leaves `UV_HANDLE_REF` untouched, so
`_handle.hasRef()` remains Node-compatible while idle inactive handles
no longer keep the loop alive.
Redirected output avoids the TTY stream path, which is why the same
script exited with stdout/stderr redirected.
## Validation
- `./tools/format.js ext/node/polyfills/process.ts
libs/core/uv_compat/tty.rs tests/integration/run_tests.rs
tests/testdata/run/process_stderr_tty_write_exit.js`
- `cargo test --test integration process_stderr_tty_write_exit`
- `cargo test -p deno_core uv_compat`
- `./tools/lint.js`
- Manual PTY reduction: large `process.stderr.write()` exits and reports
`_handle.hasRef()` as `true` before and inside the callback on macOS
- Manual PTY validation in `../v8x`: `target/debug/deno run -A
tests/harness/run.mjs rusty_v8 quickjs --rescue` exits cleanly with
`pass=267 fail=0 skip=0`
- CI: `test integration (1/2) debug windows-x86_64` passed on head
`3a9f366bf34b16ad3b0c12117233460c5320e2a0`