From 15c638d2dee8809fdbfc688e6f3ad22f7d38c8b4 Mon Sep 17 00:00:00 2001 From: tsushanth <78000697+tsushanth@users.noreply.github.com> Date: Sat, 13 Jun 2026 14:47:40 -0700 Subject: [PATCH 1/4] fix(ext/node): util.styleText() returns text unchanged when stream is not a TTY --- ext/node/polyfills/internal/util/inspect.mjs | 8 +++++++ tests/unit_node/util_test.ts | 25 ++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/ext/node/polyfills/internal/util/inspect.mjs b/ext/node/polyfills/internal/util/inspect.mjs index e9b65ee5119e29..b156a9b711fe08 100644 --- a/ext/node/polyfills/internal/util/inspect.mjs +++ b/ext/node/polyfills/internal/util/inspect.mjs @@ -676,6 +676,14 @@ function styleText(format, text, options) { stream, ); } + // Node's util.styleText returns the text unchanged when the target stream + // is not a TTY, so callers can pass any writable and only get color when + // the destination would render it. + if ( + stream !== undefined && stream !== null && !stream.isTTY + ) { + return text; + } } const formatArray = ArrayIsArray(format) ? format : [format]; diff --git a/tests/unit_node/util_test.ts b/tests/unit_node/util_test.ts index d0821966c7e742..faee2183218f9e 100644 --- a/tests/unit_node/util_test.ts +++ b/tests/unit_node/util_test.ts @@ -271,6 +271,31 @@ Deno.test("[util] styleText() with array of formats", () => { assertEquals(colored, "\x1b[31m\x1b[32merror\x1b[39m\x1b[39m"); }); +Deno.test("[util] styleText() respects stream.isTTY", () => { + const streamTTY = { write() {}, isTTY: true }; + const streamNoTTY = { write() {}, isTTY: false }; + + assertEquals( + util.styleText("bgYellow", "TTY", { stream: streamTTY }), + "\x1b[43mTTY\x1b[49m", + ); + assertEquals( + util.styleText("bgYellow", "No TTY", { stream: streamNoTTY }), + "No TTY", + ); +}); + +Deno.test("[util] styleText() with validateStream: false bypasses isTTY check", () => { + const streamNoTTY = { write() {}, isTTY: false }; + assertEquals( + util.styleText("bgYellow", "forced", { + stream: streamNoTTY, + validateStream: false, + }), + "\x1b[43mforced\x1b[49m", + ); +}); + Deno.test("[util] stripVTControlCharacters() removes OSC 8 hyperlinks", () => { // OSC 8 hyperlink with ESC \ (ST) terminator const input = From e1870bb7281f163c93252a840e7ce3c072199d74 Mon Sep 17 00:00:00 2001 From: tsushanth <78000697+tsushanth@users.noreply.github.com> Date: Sat, 13 Jun 2026 15:13:56 -0700 Subject: [PATCH 2/4] chore(npm): point peer-dependency warning at the overrides remedy (#35196) --- libs/npm_installer/resolution.rs | 3 ++- tests/specs/install/peer_dep_specific_constraint/install.out | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/libs/npm_installer/resolution.rs b/libs/npm_installer/resolution.rs index c24cd83f0dc3a4..65e9610ae04b9e 100644 --- a/libs/npm_installer/resolution.rs +++ b/libs/npm_installer/resolution.rs @@ -410,7 +410,8 @@ fn peer_dep_diagnostics_to_display_tree( // now output it let mut root_node = DisplayTreeNode { text: format!( - "{} The following peer dependency issues were found:", + "{} The following peer dependency issues were found.\n\ + To resolve, pin the affected package(s) under \"overrides\" in your package.json (https://docs.npmjs.com/cli/v10/configuring-npm/package-json#overrides):", colors::yellow("Warning") ), children: Vec::new(), diff --git a/tests/specs/install/peer_dep_specific_constraint/install.out b/tests/specs/install/peer_dep_specific_constraint/install.out index d0547b9cf13284..50711dc956400b 100644 --- a/tests/specs/install/peer_dep_specific_constraint/install.out +++ b/tests/specs/install/peer_dep_specific_constraint/install.out @@ -1,6 +1,7 @@ Download http://localhost:4260/@denotest%2fadd Download http://localhost:4260/@denotest%2fpeer-dep-specific-constraint -Warning The following peer dependency issues were found: +Warning The following peer dependency issues were found. + To resolve, pin the affected package(s) under "overrides" in your package.json (https://docs.npmjs.com/cli/v10/configuring-npm/package-json#overrides): └─┬ @denotest/peer-dep-specific-constraint@1.0.0 └── peer @denotest/add@0.5: resolved to 1.0.0 From 8ad7191e3df5a8a547d51b6cdf36deeec48d63fb Mon Sep 17 00:00:00 2001 From: tsushanth <78000697+tsushanth@users.noreply.github.com> Date: Sat, 13 Jun 2026 15:15:29 -0700 Subject: [PATCH 3/4] feat(jupyter): support transport="ipc" in kernel connection file (#35201) --- cli/js/jupyter_kernel.js | 53 ++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/cli/js/jupyter_kernel.js b/cli/js/jupyter_kernel.js index 1610d20f95301d..0422ea0e5c7ace 100644 --- a/cli/js/jupyter_kernel.js +++ b/cli/js/jupyter_kernel.js @@ -333,12 +333,25 @@ async function recvMultipart(conn) { // --- Per-channel servers ------------------------------------------------------- +/** + * Build the Deno.listen options for one Jupyter channel. A `transport: "ipc"` + * connection file points `ip` at a socket path prefix (e.g. `/tmp/.../deno-ipc`) + * and the kernel listens on `${ip}-${port}` per the Jupyter wire-protocol + * convention. Otherwise we listen on the supplied TCP host/port. + */ +function listenOptsForChannel(transport, ip, port) { + if (transport === "ipc") { + return { transport: "unix", path: `${ip}-${port}` }; + } + return { hostname: ip, port }; +} + /** * REP socket server (heartbeat). * For each connected peer, echo back every received message. */ -async function runHeartbeat(port, ip) { - const listener = Deno.listen({ hostname: ip, port }); +async function runHeartbeat(port, ip, transport) { + const listener = Deno.listen(listenOptsForChannel(transport, ip, port)); while (true) { const conn = await listener.accept(); (async () => { @@ -389,9 +402,10 @@ function makeQueue() { * every connected peer via `sendAll`). */ class RouterSocket { - constructor(port, ip) { + constructor(port, ip, transport) { this.port = port; this.ip = ip; + this.transport = transport; this.incoming = makeQueue(); this.peers = new Map(); // peerId (string) -> conn this._listen(); @@ -399,7 +413,9 @@ class RouterSocket { _listen() { (async () => { - const listener = Deno.listen({ hostname: this.ip, port: this.port }); + const listener = Deno.listen( + listenOptsForChannel(this.transport, this.ip, this.port), + ); while (true) { const conn = await listener.accept(); this._handlePeer(conn); @@ -468,16 +484,19 @@ class RouterSocket { * Sends the same frames to all connected subscribers. */ class PubSocket { - constructor(port, ip) { + constructor(port, ip, transport) { this.port = port; this.ip = ip; + this.transport = transport; this.conns = new Set(); this._listen(); } _listen() { (async () => { - const listener = Deno.listen({ hostname: this.ip, port: this.port }); + const listener = Deno.listen( + listenOptsForChannel(this.transport, this.ip, this.port), + ); while (true) { const conn = await listener.accept(); (async () => { @@ -525,17 +544,25 @@ class PubSocket { async function startJupyterKernel() { const info = JSON.parse(op_jupyter_get_connection_info()); - const { ip, key, hb_port, shell_port, control_port, stdin_port, iopub_port } = - info; + const { + ip, + key, + transport = "tcp", + hb_port, + shell_port, + control_port, + stdin_port, + iopub_port, + } = info; const session = crypto.randomUUID(); // Start heartbeat (purely async, fire-and-forget) - runHeartbeat(hb_port, ip); + runHeartbeat(hb_port, ip, transport); - const shell = new RouterSocket(shell_port, ip); - const control = new RouterSocket(control_port, ip); - const iopub = new PubSocket(iopub_port, ip); - const stdin = new RouterSocket(stdin_port, ip); + const shell = new RouterSocket(shell_port, ip, transport); + const control = new RouterSocket(control_port, ip, transport); + const iopub = new PubSocket(iopub_port, ip, transport); + const stdin = new RouterSocket(stdin_port, ip, transport); let executionCount = 0; let currentParentHeader = {}; From cba1151ad8642ffe3cf1c99c3a6c63d70ce41632 Mon Sep 17 00:00:00 2001 From: tsushanth <78000697+tsushanth@users.noreply.github.com> Date: Sat, 13 Jun 2026 15:25:49 -0700 Subject: [PATCH 4/4] fix(ext/node): make zlib writeSync _writeState argument optional (#35185) --- ext/node/ops/zlib/mod.rs | 14 ++++++++++---- tests/unit_node/zlib_test.ts | 26 ++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/ext/node/ops/zlib/mod.rs b/ext/node/ops/zlib/mod.rs index 51e321560e6b14..9f0e6754e363c6 100644 --- a/ext/node/ops/zlib/mod.rs +++ b/ext/node/ops/zlib/mod.rs @@ -434,7 +434,11 @@ impl Zlib { #[buffer] out: &mut [u8], #[smi] out_off: u32, #[smi] out_len: u32, - #[buffer] write_result: &mut [u32], + // Per-call result buffer added by #35043. Older callers (notably + // pngjs/sync-inflate) bound directly to `_handle.writeSync` and never + // pass it, so accept None and skip the avail_out/avail_in write-back + // when one isn't provided (#35185). + #[buffer] write_result: Option<&mut [u32]>, ) -> Result<(), ZlibError> { let err_info = { let mut zlib = self.inner.borrow_mut(); @@ -444,9 +448,11 @@ impl Zlib { zlib.start_write(input, in_off, in_len, out, out_off, out_len, flush)?; zlib.do_write(flush)?; - if write_result.len() >= 2 { - write_result[0] = zlib.strm.avail_out; - write_result[1] = zlib.strm.avail_in; + if let Some(write_result) = write_result { + if write_result.len() >= 2 { + write_result[0] = zlib.strm.avail_out; + write_result[1] = zlib.strm.avail_in; + } } zlib.get_error_info() }; diff --git a/tests/unit_node/zlib_test.ts b/tests/unit_node/zlib_test.ts index 7fe8053daec2a3..495875f78ec917 100644 --- a/tests/unit_node/zlib_test.ts +++ b/tests/unit_node/zlib_test.ts @@ -17,6 +17,7 @@ import { createDeflate, createGunzip, createGzip, + createInflate, createZstdCompress, createZstdDecompress, deflateSync, @@ -460,3 +461,28 @@ Deno.test("zlib write does not write through a detached _writeState", () => { assertEquals(state.buffer.byteLength, 0); } }); + +// pngjs's `sync-inflate.js` binds directly to `inflate._handle.writeSync` and +// invokes it with seven arguments (no per-call `_writeState`), relying on the +// pre-#35043 contract where the result buffer was registered at init time. The +// per-call argument is now optional so that signature keeps working (#35185). +Deno.test("zlib writeSync accepts the pre-#35043 seven-argument signature", () => { + const chunk = Buffer.from([ + 0x78, 0x9c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, + ]); + const out = Buffer.allocUnsafe(1024); + + // deno-lint-ignore no-explicit-any + const inflate = createInflate() as any; + + // Must not throw `expected typed ArrayBufferView` for the missing 8th arg. + inflate._handle.writeSync( + constants.Z_FINISH, + chunk, + 0, + chunk.length, + out, + 0, + out.length, + ); +});