Skip to content

Conversation

@renovate
Copy link
Contributor

@renovate renovate bot commented Nov 22, 2025

This PR contains the following updates:

Package Change Age Adoption Passing Confidence
zx (source) 8.5.2 -> 8.8.5 age adoption passing confidence

GitHub Vulnerability Alerts

CVE-2025-13437

When zx is invoked with --prefer-local=, the CLI creates a symlink named ./node_modules pointing to /node_modules. Due to a logic error in src/cli.ts (linkNodeModules / cleanup), the function returns the target path instead of the alias (symlink path). The later cleanup routine removes what it received, which deletes the target directory itself. Result: zx can delete an external /node_modules outside the current working directory.


Release Notes

google/zx (zx)

v8.8.5: — Temporary Reservoir

Compare Source

This release fixes the issue, when zx flushes external node_modules on linking #​1348 #​1349 #​1355

Also globby@15.0.0 arrives here.

v8.8.4: — Flange Coupling

Compare Source

It's time. This release updates zx internals to make the ps API and related methods ProcessPromise.kill(), kill() work on Windows systems without wmic.
#​1344 webpod/ps#15

  1. WMIC will be missing in Windows 11 25H2 (kernel >= 26000)
  2. The windows-latest label in GitHub Actions will migrate from Windows Server 2022 to Windows Server 2025 beginning September 2, 2025 and finishing by September 30, 2025.

https://github.blog/changelog/2025-07-31-github-actions-new-apis-and-windows-latest-migration-notice/#windows-latest-image-label-migration

v8.8.3: — Sealing Gasket

Compare Source

Continues #​1339 to prevent injections via Proxy input or custom toString() manipulations.

v8.8.2: — Leaking Valve

Compare Source

Fixes potential cmd injection via kill() method for Windows platform. #​1337 #​1339. Affects the versions range 8.7.1...8.8.1.

v8.8.1: — Turbo Flush

Compare Source

We keep improving the projects internal infra to bring more stability, safety and performance for artifacts.

Featfixes
  • Applied flags filtration for CLI-driven deps install #​1308
  • Added kill() event logging #​1312
  • Set SIGTERM as kill() fallback signal #​1313
  • Allowed stdio() arg be an array #​1311
const p = $({halt: true})`cmd`
p.stdio([stream, 'ignore', 'pipe'])
Enhancements

v8.8.0: — Pressure Tested

Compare Source

This release enhances the coherence between the ProcessPromise and the Streams API, eliminating the need for certain script-level workarounds.

✨ New Features
unpipe() — Selectively stop piping

You can now call .unpipe() to stop data transfer from a source to a destination without closing any of the pair. #​1302

const p1 = $`echo foo && sleep 0.1 && echo bar && sleep 0.1 && echo baz && sleep 0.1 && echo qux`
const p2 = $`echo 1 && sleep 0.15 && echo 2 && sleep 0.1 && echo 3`
const p3 = $`cat`

p1.pipe(p3)
p2.pipe(p3)

setTimeout(() => p1.unpipe(p3), 150)

const { stdout } = await p3
// 'foo\n1\nbar\n2\n3\n'
Many-to-one piping

Multiple sources can now stream into a single destination. All sources complete before the destination closes. #​1300

const $h = $({ halt: true })
const p1 = $`echo foo`
const p2 = $h`echo a && sleep 0.1 && echo c && sleep 0.2 && echo e`
const p3 = $h`sleep 0.05 && echo b && sleep 0.1 && echo d`
const p4 = $`sleep 0.4 && echo bar`
const p5 = $h`cat`

await p1
p1.pipe(p5)
p2.pipe(p5)
p3.pipe(p5)
p4.pipe(p5)

const { stdout } = await p5.run()
// 'foo\na\nb\nc\nd\ne\nbar\n'
Piping from rejected processes

Processes that exit with errors can now still pipe their output. The internal recorder retains their stream, status, and exit code. #​1296

const p1 = $({ nothrow: true })`echo foo && exit 1`
await p1

const p2 = p1.pipe($({ nothrow: true })`cat`)
await p2

p1.output.toString() // 'foo\n'
p1.output.ok         // false
p1.output.exitCode   // 1

p2.output.toString() // 'foo\n'
p2.output.ok         // false
p2.output.exitCode   // 1
Components versions

Since zx bundles third-party libraries without their package.jsons, their versions weren’t previously visible. You can now access them via the versions static map — including zx itself. #​1298 #​1295

import { versions } from 'zx'

versions.zx     // 8.7.2
versions.chalk  // 5.4.1

v8.7.2: — Copper Crafter

Compare Source

Stability and customizability improvements

  • Handle nothrow option on ProcessPromise init stage #​1288
const o = await $({ nothrow: true })`\033`
o.ok      // false
o.cause   // Error
  • Handle _snapshot.killSignal value on kill() #​1287
const p = $({killSignal: 'SIGKILL'})`sleep 10`
await p.kill()
p.signal  // 'SIGKILL'
import { Fail } from 'zx'

Fail.EXIT_CODES['2'] = 'Custom error message'
Fail.formatErrorMessage = (err: Error, from: string): string =>
  `${err.message} (${from})`
import type { $, Options } from 'zx'

const custom$: $ = (pieces: TemplateStringsArray | Partial<Options>, ...args: any[]) => {
  // ... custom implementation
}

v8.7.1: — Pipe Whisperer

Compare Source

Continues v8.7.0: handles new ps() corner case and improves $.kill mechanics on Windows #​1266 #​1267 #​1269 webpod/ps#14

v8.7.0: — Solder Savior

Compare Source

Important fixes for annoying flaky bugs

kill() 🐞

We've found an interesting case #​1262

const p = $`sleep 1000`
const {pid} = p // 12345
await p.kill()

If we kill the process again, the result might be unexpected:

await ps({pid}) // {pid: 12345, ppid: 67890, command: 'another command', ...}
p.kill()

This happens because the pid may be reused by the system for another process, so we've added extra assertions to prevent indeterminacy:

p.kill()  // Error: Too late to kill the process.
p.abort() // Error: Too late to abort the process.
ps() 🐛
  • ps() uses wmic internally on Windows, it relies on fragile heuristics to parse the output. We have improved this logic to handle more format variants, but over time (in v9 maybe) we're planning to change the approach.

#​1256 #​1263 webpod/ps#12 webpod/ingrid#6

const [root] = await ps.lookup({ pid: process.pid })
assert.equal(root.pid, process.pid)

v8.6.2: — Flow Unstoppable

Compare Source

Fixes $.prefix & $.postfix values settings via env variables #​1261 #​1260

v8.6.1: — Drain Hero

Compare Source

  • Use process.env.SHELL as default shell if defined #​1252
SHELL=/bin/zsh zx script.js
  • Accept numeric strings as parseDuration() arg #​1249
await sleep(1000)   // 1 second
await sleep('1000') // 1 second

v8.6.0: — Valve Vanguard

Compare Source

  • Enabled thenable params processing for $ literals #​1237
const a1 = $`echo foo`
const a2 = new Promise((resolve) => setTimeout(resolve, 20, ['bar', 'baz']))

await $`echo ${a1} ${a2}` // foo bar baz

v8.5.5: — PVC Wizard

Compare Source

Minor feature polish.

  • ProcessPromise and ProcessOutput lines() getters now accept a custom delimiter #​1220 #​1218
const cwd = tempdir()
const delimiter = '\0'

const p1 = $({
  cwd
})`touch foo bar baz; find ./ -type f -print0 -maxdepth 1`
(await p1.lines(delimiter)).sort() // ['./bar', './baz', './foo']
  
// or via options
const lines = []
const p2 = $({
  delimiter,
  cwd,
})`find ./ -type f -print0 -maxdepth 1`

for await (const line of p2) {
  lines.push(line)
}

lines.sort() // ['./bar', './baz', './foo']

v8.5.4: — Pipe Dreamer

Compare Source

v8.5.3: — Trap Master

Compare Source

  • Another portion of JSR related improvements #​1193 #​1192
  • Goods refactoring #​1195
    • Fixes expBackoff implementation
    • Sets $.log.output as default spinner() output
    • Makes configurable question() I/O
  • Added Graaljs compatability test #​1194
  • Docs improvements, usage examples updates #​1198

Configuration

📅 Schedule: Branch creation - "" in timezone Asia/Shanghai, Automerge - At any time (no schedule defined).

🚦 Automerge: Enabled.

Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate renovate bot enabled auto-merge (squash) November 22, 2025 15:37
@codspeed-hq
Copy link

codspeed-hq bot commented Nov 22, 2025

CodSpeed Performance Report

Merging #135 will not alter performance

Comparing renovate/npm-zx-vulnerability (b7e9d3d) with main (8238fcf)

Summary

✅ 6 untouched

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