Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix(dlx): shorten dlx cache path to avoid Windows MAX_PATH failures#12605

Merged
zkochan merged 2 commits into
mainfrom
fix-dlx-windows-max-path
Jun 23, 2026
Merged

fix(dlx): shorten dlx cache path to avoid Windows MAX_PATH failures#12605
zkochan merged 2 commits into
mainfrom
fix-dlx-windows-max-path

Conversation

@zkochan

@zkochan zkochan commented Jun 23, 2026

Copy link
Copy Markdown
Member

Summary

Follow-up to the dlx cleanup fix (#12575). With the error-masking gone, the Windows CI flake on dlx prompts to approve ignored builds when invoked with a commands map now shows its true cause:

@pnpm.e2e/[email protected] preinstall: `hello-world-js-bin && node create generated-by-preinstall`
spawn C:\Windows\system32\cmd.exe ENOENT

spawn <full-path-to-cmd.exe> ENOENT — where cmd.exe clearly exists — is the classic Windows signature of the child's cwd not resolving. The lifecycle script runs with cwd = <pkgRoot>, and for that transitive dep the directory is 259 chars, right at Windows' MAX_PATH (260):

…\cache\dlx\<64-hex key>\<time-pid prepare>\node_modules\.pnpm\@[email protected]\node_modules\@pnpm.e2e\pre-and-postinstall-scripts-example

CreateProcess can't resolve an over-length lpCurrentDirectory, and Node surfaces it as the misleading spawn cmd.exe ENOENT. It's flaky rather than constant because the <prepare> segment (<time>-<pid> in hex) and the temp-dir segment vary in length run to run, straddling 260. It only hits this test because most deps have their builds skipped (no script spawned in the deep dir); this is the one that triggers the approve-builds rebuild.

The two dlx-specific path segments are pure overhead on top of pnpm's already-deep virtual store, so this shortens both:

  • cache keycreateHexHash (64 hex chars) → createShortHash (32 chars / 128 bits, ample for a cache key). pacquet already truncated to 32 via create_short_hash, so this also restores parity between the two stacks.
  • prepare dir — encode time/pid in base36 instead of hex.

This takes the measured directory from 259 → ~225 chars, comfortably under MAX_PATH for realistic package names — not just the test.

Squash Commit Body

The dlx cache path is <cacheDir>/dlx/<key>/<prepare>/node_modules/.pnpm/
<pkgId>/node_modules/<pkg>. The <key> (64-char sha256 hex) and <prepare>
(<time>-<pid> in hex) segments are dlx overhead on top of pnpm's already-
deep virtual-store layout. For a transitive dep with a long name this tips
the package directory over Windows' MAX_PATH (260) — measured at 259 chars
for @pnpm.e2e/pre-and-postinstall-scripts-example in the dlx e2e test. A
lifecycle script then runs with that directory as its cwd, and CreateProcess
fails to resolve an over-length cwd, which Node surfaces as the confusing
"spawn C:\Windows\system32\cmd.exe ENOENT". Flaky rather than constant
because the <prepare> and temp-dir segments vary in length, straddling 260.

Shorten both dlx-specific segments:
- cache key: createShortHash (32 hex, 128 bits) instead of createHexHash
  (64). pacquet already truncated to 32, so this also restores parity.
- prepare dir: encode time and pid in base36 instead of hex.

Checklist

  • The change is implemented in both the TypeScript CLI and the Rust
    pacquet/ port, or the description notes what still needs porting.
  • Added a changeset (pnpm changeset) if this PR changes any published
    package. Keep it short and written for pnpm users — it becomes a release note.
  • Added or updated tests.
  • Updated the documentation if needed.

Written by an agent (Claude Code, claude-opus-4-8).

Summary by CodeRabbit

Bug Fixes

  • Fixed pnpm dlx on Windows failing due to overly long cache/lifecycle working paths hitting MAX_PATH, causing errors like failed cmd.exe spawns.
  • Updated dlx cache key and temporary prepare-directory naming to use a shorter base36 encoding, reducing path length while keeping uniqueness to avoid collisions.

The dlx cache path is `<cacheDir>/dlx/<key>/<prepare>/node_modules/.pnpm/
<pkgId>/node_modules/<pkg>`. The `<key>` (a 64-char sha256 hex) and
`<prepare>` (`<time>-<pid>` in hex) segments are dlx overhead on top of
pnpm's already-deep virtual-store layout. For a transitive dep with a
long name this tips the package directory over Windows' MAX_PATH (260) —
measured at 259 chars for `@pnpm.e2e/pre-and-postinstall-scripts-example`
in the dlx e2e test. A lifecycle script then runs with that directory as
its cwd, and CreateProcess fails to resolve an over-length cwd, which
Node surfaces as the confusing `spawn C:\Windows\system32\cmd.exe ENOENT`.

It was flaky rather than constant because the `<prepare>` and temp-dir
segments vary in length run to run, straddling the 260 boundary.

Shorten both dlx-specific segments:
- cache key: use createShortHash (32 hex chars, 128 bits) instead of the
  full createHexHash (64). pacquet already truncated to 32 via
  create_short_hash, so this also brings the two stacks back in parity.
- prepare dir: encode time and pid in base36 instead of hex.

This keeps the package directory comfortably under MAX_PATH for realistic
package names, not just the test.
@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 9772db1b-5a26-44e4-8a7a-843ccd0c7412

📥 Commits

Reviewing files that changed from the base of the PR and between 6d035b5 and f19adba.

📒 Files selected for processing (1)
  • pnpm11/exec/commands/test/dlx.e2e.ts

📝 Walkthrough

Walkthrough

The PR shortens pnpm dlx cache paths to prevent Windows MAX_PATH overflows. In the TypeScript implementation, createCacheKey switches from createHexHash to createShortHash, and getPrepareDir switches from base16 to base36 for timestamp/pid encoding. The Rust implementation adds a to_base36 helper and applies the same base36 change to get_prepare_dir. Tests and a changeset entry are updated accordingly.

Changes

dlx cache path shortening

Layer / File(s) Summary
TypeScript: createShortHash for cache key and base36 for prepare dir
pnpm11/exec/commands/src/dlx.ts, pnpm11/exec/commands/test/dlx.createCacheKey.test.ts, pnpm11/exec/commands/test/dlx.e2e.ts, .changeset/dlx-shorten-cache-path-windows.md
createCacheKey uses createShortHash instead of createHexHash; getPrepareDir uses base36 encoding of Date.now() and process.pid. Test imports and expected values updated to createShortHash. E2e test validation updated to accept base36 format for prepare-dir components. Changeset documents the patch release for @pnpm/exec.commands and pnpm.
Rust: to_base36 helper and prepare dir encoding
pacquet/crates/cli/src/cli_args/dlx.rs, pacquet/crates/cli/src/cli_args/dlx/tests.rs
Adds a to_base36 helper with a DIGITS constant implementing lowercase base36 encoding. get_prepare_dir switches from {millis:x}-{pid:x} hex format to to_base36(millis)-to_base36(pid). Test updated to assert base36 directory name.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-dlx-windows-max-path

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Shorten pnpm dlx cache paths to avoid Windows MAX_PATH spawn failures
🐞 Bug fix 🧪 Tests 📝 Documentation 🕐 20-40 Minutes

Grey Divider

Description

• Shorten pnpm dlx cache key and prepare directory segments to reduce path depth on Windows.
• Prevent flaky lifecycle-script failures caused by over-length cwd resolving as `spawn cmd.exe
 ENOENT`.
• Align TypeScript and Rust (pacquet) implementations and update tests + changeset.
Diagram

graph TD
  P["pnpm dlx (TS)"] --> K["createShortHash()"] --> C[("dlx cache dir")]
  C --> D["prepare dir (base36)"] --> W["lifecycle scripts"] --> X["Windows CreateProcess"]
  R["pacquet dlx (Rust)"] --> C
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Use Windows long-path (\\?\) prefixes for cwd/process spawns
  • ➕ Could address MAX_PATH issues more generally across deep paths
  • ➖ Hard to apply safely across Node/toolchain boundaries; not all consumers handle verbatim paths well
  • ➖ Does not reduce path length for other filesystem operations; increases risk of subtle Windows-only bugs
2. Relocate dlx cache to a shorter root on Windows (e.g., user temp root alias)
  • ➕ Big path-length reduction without changing key/dir formats
  • ➖ Behavioral change in where cache lives; may affect cache reuse/cleanup expectations
  • ➖ Still vulnerable if users configure a long cache root or packages are extremely deep
3. Compress dlx path with an opaque directory layout (single-level store)
  • ➕ Maximum path shortening; avoids nesting under pnpm virtual-store structure
  • ➖ Large architectural divergence from pnpm store semantics; higher risk and harder parity with pacquet
  • ➖ More migration/compat concerns for existing caches

Recommendation: The PR’s approach (shorter cache key + base36 prepare dir) is the best tradeoff: it meaningfully reduces path depth with minimal behavioral change, keeps cache semantics intact, and maintains TS/Rust parity. The alternatives either introduce Windows-specific path handling risks or require larger cache-layout redesigns.

Files changed (5) +46 / -10

Bug fix (2) +33 / -4
dlx.rsSwitch pacquet dlx prepare dir naming from hex to base36 +22/-1

Switch pacquet dlx prepare dir naming from hex to base36

• Updates 'get_prepare_dir' to encode 'time' and 'pid' in lowercase base36 to reduce dlx path length on Windows. Introduces a 'to_base36' helper matching JavaScript’s 'toString(36)' output.

pacquet/crates/cli/src/cli_args/dlx.rs

dlx.tsShorten dlx cache key and prepare dir to avoid Windows MAX_PATH +11/-3

Shorten dlx cache key and prepare dir to avoid Windows MAX_PATH

• Changes 'createCacheKey' to use 'createShortHash' (32 hex chars) instead of the full sha256 hex hash to reduce cache-path depth. Updates 'getPrepareDir' to use base36-encoded time and pid to further shorten per-run staging directories.

pnpm11/exec/commands/src/dlx.ts

Tests (2) +7 / -6
tests.rsUpdate pacquet test to expect base36 prepare dir encoding +5/-4

Update pacquet test to expect base36 prepare dir encoding

• Renames and adjusts the 'get_prepare_dir' unit test to validate base36 encoding of millis and pid, using an explicit numeric example. Ensures the Rust port matches the updated directory-name contract.

pacquet/crates/cli/src/cli_args/dlx/tests.rs

dlx.createCacheKey.test.tsAdjust createCacheKey test to assert short-hash behavior +2/-2

Adjust createCacheKey test to assert short-hash behavior

• Updates the expected cache key in tests from 'createHexHash' to 'createShortHash', reflecting the new 32-character cache-key contract. Keeps existing order-independence coverage intact.

pnpm11/exec/commands/test/dlx.createCacheKey.test.ts

Documentation (1) +6 / -0
dlx-shorten-cache-path-windows.mdAdd changeset documenting dlx Windows MAX_PATH fix +6/-0

Add changeset documenting dlx Windows MAX_PATH fix

• Adds a patch-level changeset for 'pnpm' and '@pnpm/exec.commands' describing shortened dlx cache paths to prevent Windows 'MAX_PATH' overflow that can surface as 'spawn cmd.exe ENOENT'.

.changeset/dlx-shorten-cache-path-windows.md

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Jun 23, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Outdated prepare-dir validator ✓ Resolved 🐞 Bug ☼ Reliability
Description
getPrepareDir() now encodes time/pid in base36, but sanitizeDlxCacheComponent() in dlx e2e tests
still validates the prepare dir as hex and can throw when both segments contain only g-z letters.
This can introduce CI flakiness/failures in tests that verify dlx cache directory contents.
Code

pnpm11/exec/commands/src/dlx.ts[R453-458]

function getPrepareDir (cachePath: string): string {
-  const name = `${new Date().getTime().toString(16)}-${process.pid.toString(16)}`
+  // base36 (vs hex) keeps this segment short — see createCacheKey for why dlx
+  // path length matters on Windows. time+pid stays unique across concurrent
+  // dlx processes and across a process's own retries of a failed install.
+  const name = `${Date.now().toString(36)}-${process.pid.toString(36)}`
return path.join(cachePath, name)
Evidence
The production code now generates base36 time-pid directory names, while the e2e test helper
explicitly throws unless the directory looks like two hex numbers; base36 can violate that
assumption, causing test failures when verifying cache contents.

pnpm11/exec/commands/src/dlx.ts[453-459]
pnpm11/exec/commands/test/dlx.e2e.ts[39-48]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`pnpm11/exec/commands/src/dlx.ts` changed the dlx prepare directory name from hex to base36. The e2e test helper `sanitizeDlxCacheComponent()` still enforces a hex-only format and may throw, making dlx cache tests flaky.
### Issue Context
The prepare dir now uses `Date.now().toString(36)` and `process.pid.toString(36)`, which can legally contain letters `g-z`. The test currently checks `/[0-9a-f]+/`.
### Fix Focus Areas
- pnpm11/exec/commands/test/dlx.e2e.ts[39-50]
### What to change
- Update `sanitizeDlxCacheComponent()` to validate base36 instead of hex (e.g. `^[0-9a-z]+$` for both segments), or remove the hex-format assertion entirely since the function’s purpose is just to mask variability.
- Keep returning the same redacted placeholder (`***********-*****`) so snapshot-like comparisons remain stable.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

@github-actions github-actions Bot added the reviewed: coderabbit CodeRabbit submitted an approving review label Jun 23, 2026
@github-actions

github-actions Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Micro-Benchmark Results

Linux

group                          main                                   pr
-----                          ----                                   --
tarball/download_dependency    1.01      7.6±0.29ms   573.5 KB/sec    1.00      7.5±0.35ms   576.5 KB/sec

Comment thread pnpm11/exec/commands/src/dlx.ts
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 6d035b5

@codecov-commenter

codecov-commenter commented Jun 23, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.30769% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 88.13%. Comparing base (f742b04) to head (f19adba).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
pacquet/crates/cli/src/cli_args/dlx.rs 92.30% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #12605      +/-   ##
==========================================
- Coverage   88.15%   88.13%   -0.03%     
==========================================
  Files         326      329       +3     
  Lines       46556    47045     +489     
==========================================
+ Hits        41043    41461     +418     
- Misses       5513     5584      +71     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

Copy link
Copy Markdown
Contributor

Integrated-Benchmark Report (Linux)

Each scenario reports direct installs and pnpr installs. Bencher consumes pacquet@HEAD and pnpr@HEAD.

Scenario: Isolated linker: fresh restore, cold cache + cold store

Command Mean [s] Min [s] Max [s] Relative
pacquet@HEAD 4.763 ± 0.164 4.588 4.994 1.66 ± 0.08
pacquet@main 4.748 ± 0.164 4.582 5.036 1.65 ± 0.08
pnpr@HEAD 2.876 ± 0.119 2.741 3.088 1.00 ± 0.05
pnpr@main 2.871 ± 0.099 2.756 3.034 1.00
BENCHMARK_REPORT.json
{
  "results": [
    {
      "command": "pacquet@HEAD",
      "mean": 4.762650982320001,
      "stddev": 0.16376580814532576,
      "median": 4.71740543412,
      "user": 3.8535771199999997,
      "system": 3.4855510599999997,
      "min": 4.587513249120001,
      "max": 4.9939351191200005,
      "times": [
        4.94540030012,
        4.8886310251200005,
        4.9939351191200005,
        4.93932697412,
        4.75449385712,
        4.587513249120001,
        4.598439642120001,
        4.6803170111200005,
        4.58945352012,
        4.6489991251200005
      ]
    },
    {
      "command": "pacquet@main",
      "mean": 4.74757047402,
      "stddev": 0.16412195864157894,
      "median": 4.697598257120001,
      "user": 3.8494857200000006,
      "system": 3.47487326,
      "min": 4.58186413812,
      "max": 5.03587706012,
      "times": [
        4.943364386120001,
        4.909829090120001,
        4.58826319012,
        4.58186413812,
        4.597011305120001,
        4.63661793612,
        4.78768112012,
        5.03587706012,
        4.687083616120001,
        4.7081128981200004
      ]
    },
    {
      "command": "pnpr@HEAD",
      "mean": 2.8763414830200005,
      "stddev": 0.11853029691424062,
      "median": 2.8420608651200006,
      "user": 2.70594372,
      "system": 3.0220651600000004,
      "min": 2.74116287612,
      "max": 3.08782421812,
      "times": [
        2.80545467712,
        2.8521790421200004,
        2.8098339401200003,
        3.0852277791200002,
        2.7926783321200004,
        2.74116287612,
        2.8319426881200003,
        2.8985631001200005,
        2.8585481771200003,
        3.08782421812
      ]
    },
    {
      "command": "pnpr@main",
      "mean": 2.8709170147200003,
      "stddev": 0.09854207661542384,
      "median": 2.8505564316200003,
      "user": 2.68687342,
      "system": 3.02689176,
      "min": 2.7556562651200003,
      "max": 3.03366605812,
      "times": [
        3.03366605812,
        2.7928578991200004,
        2.85934514812,
        2.8005082321200003,
        2.89761281712,
        2.96417276412,
        2.76790012012,
        2.8417677151200005,
        2.9956831281200005,
        2.7556562651200003
      ]
    }
  ]
}

Scenario: Isolated linker: fresh restore, hot cache + hot store

Command Mean [ms] Min [ms] Max [ms] Relative
pacquet@HEAD 627.4 ± 17.6 605.8 652.9 1.00 ± 0.03
pacquet@main 627.2 ± 6.6 616.8 636.5 1.00
pnpr@HEAD 716.4 ± 101.8 655.0 1000.3 1.14 ± 0.16
pnpr@main 737.1 ± 79.5 697.0 960.0 1.18 ± 0.13
BENCHMARK_REPORT.json
{
  "results": [
    {
      "command": "pacquet@HEAD",
      "mean": 0.62744251726,
      "stddev": 0.01758221967086557,
      "median": 0.6314405752600001,
      "user": 0.36718579999999995,
      "system": 1.3207751399999998,
      "min": 0.60580418126,
      "max": 0.6529372012600001,
      "times": [
        0.64184394026,
        0.6529372012600001,
        0.6058990602600001,
        0.6083381612600001,
        0.6374828652600001,
        0.6253982852600001,
        0.6383459732600001,
        0.6150889742600001,
        0.60580418126,
        0.64328653026
      ]
    },
    {
      "command": "pacquet@main",
      "mean": 0.62721179636,
      "stddev": 0.006604220255775496,
      "median": 0.6281929687600001,
      "user": 0.3762709,
      "system": 1.3201397400000001,
      "min": 0.6168434582600001,
      "max": 0.63651335626,
      "times": [
        0.6168434582600001,
        0.62535015126,
        0.6331384802600001,
        0.6286540812600001,
        0.6319005672600001,
        0.63651335626,
        0.62773185626,
        0.61769490226,
        0.62240142726,
        0.6318896832600001
      ]
    },
    {
      "command": "pnpr@HEAD",
      "mean": 0.7163789955600002,
      "stddev": 0.10184192602034102,
      "median": 0.6846512092600001,
      "user": 0.38983729999999994,
      "system": 1.3570096399999998,
      "min": 0.6549659412600001,
      "max": 1.0003352482599999,
      "times": [
        0.6680092332600001,
        0.66875502326,
        0.6549659412600001,
        0.6844077502600001,
        0.6848946682600001,
        0.6740625032600001,
        0.6996003582600001,
        0.7033800442600001,
        1.0003352482599999,
        0.7253791852600001
      ]
    },
    {
      "command": "pnpr@main",
      "mean": 0.7370623001600002,
      "stddev": 0.07946595799829897,
      "median": 0.71217460026,
      "user": 0.40081950000000005,
      "system": 1.36941144,
      "min": 0.69697829826,
      "max": 0.9599737782600001,
      "times": [
        0.73402409826,
        0.7020088252600001,
        0.69858876526,
        0.7208147882600001,
        0.7226705002600001,
        0.70353441226,
        0.9599737782600001,
        0.72901246626,
        0.69697829826,
        0.7030170692600001
      ]
    }
  ]
}

Scenario: Isolated linker: fresh install, cold cache + cold store

Command Mean [s] Min [s] Max [s] Relative
pacquet@HEAD 4.807 ± 0.076 4.681 4.896 1.51 ± 0.04
pacquet@main 4.842 ± 0.042 4.773 4.910 1.53 ± 0.03
pnpr@HEAD 3.174 ± 0.056 3.108 3.288 1.00
pnpr@main 3.183 ± 0.114 3.025 3.431 1.00 ± 0.04
BENCHMARK_REPORT.json
{
  "results": [
    {
      "command": "pacquet@HEAD",
      "mean": 4.80697255416,
      "stddev": 0.07639174372241217,
      "median": 4.82757268666,
      "user": 3.80469108,
      "system": 3.44058524,
      "min": 4.68052484716,
      "max": 4.89592437216,
      "times": [
        4.74370799916,
        4.68052484716,
        4.69250113516,
        4.8407924821599995,
        4.87706027216,
        4.89592437216,
        4.85022048616,
        4.80824476016,
        4.86639629616,
        4.8143528911599995
      ]
    },
    {
      "command": "pacquet@main",
      "mean": 4.84246465056,
      "stddev": 0.041729725050824944,
      "median": 4.852279194159999,
      "user": 3.8425885799999997,
      "system": 3.4453095400000002,
      "min": 4.77302882416,
      "max": 4.9103849431599995,
      "times": [
        4.8626727251599995,
        4.81063687916,
        4.77302882416,
        4.84322284116,
        4.864543181159999,
        4.9103849431599995,
        4.88246596816,
        4.8613355471599995,
        4.80493533616,
        4.811420260159999
      ]
    },
    {
      "command": "pnpr@HEAD",
      "mean": 3.1743707054600003,
      "stddev": 0.0564116052281647,
      "median": 3.1693977116600003,
      "user": 2.76313588,
      "system": 3.1477591400000002,
      "min": 3.10805634416,
      "max": 3.28792631016,
      "times": [
        3.17367397716,
        3.2048096211600003,
        3.17857682516,
        3.23599534416,
        3.14633761716,
        3.28792631016,
        3.16512144616,
        3.11250080816,
        3.13070876116,
        3.10805634416
      ]
    },
    {
      "command": "pnpr@main",
      "mean": 3.18344877986,
      "stddev": 0.1141784185012634,
      "median": 3.16612829566,
      "user": 2.77242868,
      "system": 3.1497136399999994,
      "min": 3.02475484216,
      "max": 3.4306517971600003,
      "times": [
        3.24775456416,
        3.11240247616,
        3.02475484216,
        3.19805838516,
        3.4306517971600003,
        3.1799540731600002,
        3.1523025181600004,
        3.27612255416,
        3.1148730921600003,
        3.09761349616
      ]
    }
  ]
}

Scenario: Isolated linker: fresh install, hot cache + hot store

Command Mean [s] Min [s] Max [s] Relative
pacquet@HEAD 1.363 ± 0.009 1.349 1.376 1.01 ± 0.02
pacquet@main 1.355 ± 0.024 1.335 1.419 1.00
pnpr@HEAD 1.433 ± 0.020 1.409 1.474 1.06 ± 0.02
pnpr@main 1.458 ± 0.060 1.425 1.623 1.08 ± 0.05
BENCHMARK_REPORT.json
{
  "results": [
    {
      "command": "pacquet@HEAD",
      "mean": 1.36324213766,
      "stddev": 0.008608602974314185,
      "median": 1.36313589296,
      "user": 1.3459069599999998,
      "system": 1.6999346799999997,
      "min": 1.34938473446,
      "max": 1.37562550546,
      "times": [
        1.35720330446,
        1.35500098246,
        1.3574383434600001,
        1.37091381346,
        1.37240780546,
        1.36817510146,
        1.36028036946,
        1.37562550546,
        1.36599141646,
        1.34938473446
      ]
    },
    {
      "command": "pacquet@main",
      "mean": 1.35520702806,
      "stddev": 0.024172138488727794,
      "median": 1.3493556774600002,
      "user": 1.3324311599999998,
      "system": 1.69439538,
      "min": 1.33529152546,
      "max": 1.41902187146,
      "times": [
        1.35845762346,
        1.41902187146,
        1.33774868046,
        1.34284938546,
        1.34360667646,
        1.33529152546,
        1.3652626514600001,
        1.3499629184600002,
        1.35112051146,
        1.34874843646
      ]
    },
    {
      "command": "pnpr@HEAD",
      "mean": 1.43298634186,
      "stddev": 0.020190174897126996,
      "median": 1.4298512739600002,
      "user": 0.5897201599999999,
      "system": 1.59261478,
      "min": 1.40875568046,
      "max": 1.47362658646,
      "times": [
        1.45913165046,
        1.4164084564600001,
        1.47362658646,
        1.43607234046,
        1.40875568046,
        1.4371300474600002,
        1.42130092846,
        1.4245535014600001,
        1.41773518046,
        1.43514904646
      ]
    },
    {
      "command": "pnpr@main",
      "mean": 1.45802681706,
      "stddev": 0.05986159149546809,
      "median": 1.43932987696,
      "user": 0.5862163600000001,
      "system": 1.56574088,
      "min": 1.42464610146,
      "max": 1.62290858746,
      "times": [
        1.42549998146,
        1.46873793246,
        1.62290858746,
        1.4270207674600002,
        1.45946895146,
        1.44135147246,
        1.44651436246,
        1.42681173246,
        1.43730828146,
        1.42464610146
      ]
    }
  ]
}

Scenario: Isolated linker: fresh install, cold cache + hot store

Command Mean [s] Min [s] Max [s] Relative
pacquet@HEAD 3.086 ± 0.014 3.068 3.103 2.15 ± 0.04
pacquet@main 3.101 ± 0.077 3.033 3.248 2.16 ± 0.07
pnpr@HEAD 1.451 ± 0.017 1.422 1.483 1.01 ± 0.02
pnpr@main 1.438 ± 0.028 1.404 1.497 1.00
BENCHMARK_REPORT.json
{
  "results": [
    {
      "command": "pacquet@HEAD",
      "mean": 3.085984677,
      "stddev": 0.01363895141559595,
      "median": 3.0873756971999997,
      "user": 1.8121735600000002,
      "system": 2.0125989199999994,
      "min": 3.0676485387,
      "max": 3.1030131727,
      "times": [
        3.0803160026999996,
        3.0919457017,
        3.0700379866999996,
        3.1030131727,
        3.1026412707,
        3.0931560926999997,
        3.0676485387,
        3.0828056926999996,
        3.0979300337,
        3.0703522776999996
      ]
    },
    {
      "command": "pacquet@main",
      "mean": 3.1006358134,
      "stddev": 0.07726993910203878,
      "median": 3.0629010932,
      "user": 1.83490776,
      "system": 1.98734942,
      "min": 3.0334618997,
      "max": 3.2476012546999997,
      "times": [
        3.0334618997,
        3.0465363176999998,
        3.1190338116999996,
        3.2476012546999997,
        3.1154914967,
        3.0499292707,
        3.0451698207,
        3.0492047277,
        3.2240566186999997,
        3.0758729156999998
      ]
    },
    {
      "command": "pnpr@HEAD",
      "mean": 1.4512084001,
      "stddev": 0.016665224102967433,
      "median": 1.4542618507,
      "user": 0.59121536,
      "system": 1.6222485199999999,
      "min": 1.4222778297,
      "max": 1.4831905517000001,
      "times": [
        1.4604653487,
        1.4557906737,
        1.4222778297,
        1.4462966107,
        1.4563215067,
        1.4340601257,
        1.4408484827,
        1.4600998437000001,
        1.4527330277000001,
        1.4831905517000001
      ]
    },
    {
      "command": "pnpr@main",
      "mean": 1.4381860873,
      "stddev": 0.028316341307965984,
      "median": 1.4419522607,
      "user": 0.5890966599999999,
      "system": 1.5595908200000002,
      "min": 1.4037854927,
      "max": 1.4969539047,
      "times": [
        1.4427924697,
        1.4425819507,
        1.4969539047,
        1.4437125017,
        1.4072432977,
        1.4037854927,
        1.4660479067,
        1.4413225707,
        1.4169761177,
        1.4204446607
      ]
    }
  ]
}

@github-actions

Copy link
Copy Markdown
Contributor

🐰 Bencher Report

Branchpr/12605
Testbedpacquet
Click to view all benchmark results
BenchmarkLatencyBenchmark Result
milliseconds (ms)
(Result Δ%)
Upper Boundary
milliseconds (ms)
(Limit %)
isolated-linker.fresh-install.cold-cache.cold-store📈 view plot
🚷 view threshold
4,806.97 ms
(+7.55%)Baseline: 4,469.54 ms
5,363.45 ms
(89.62%)
isolated-linker.fresh-install.cold-cache.hot-store📈 view plot
🚷 view threshold
3,085.98 ms
(+1.91%)Baseline: 3,028.16 ms
3,633.79 ms
(84.92%)
isolated-linker.fresh-install.hot-cache.hot-store📈 view plot
🚷 view threshold
1,363.24 ms
(+1.92%)Baseline: 1,337.53 ms
1,605.04 ms
(84.94%)
isolated-linker.fresh-restore.cold-cache.cold-store📈 view plot
🚷 view threshold
4,762.65 ms
(+14.64%)Baseline: 4,154.59 ms
4,985.50 ms
(95.53%)
isolated-linker.fresh-restore.hot-cache.hot-store📈 view plot
🚷 view threshold
627.44 ms
(+0.68%)Baseline: 623.22 ms
747.87 ms
(83.90%)
🐰 View full continuous benchmarking report in Bencher

@github-actions

Copy link
Copy Markdown
Contributor

🐰 Bencher Report

Branchpr/12605
Testbedpnpr

⚠️ WARNING: No Threshold found!

Without a Threshold, no Alerts will ever be generated.

Click here to create a new Threshold
For more information, see the Threshold documentation.
To only post results if a Threshold exists, set the --ci-only-thresholds flag.

Click to view all benchmark results
BenchmarkLatencymilliseconds (ms)
isolated-linker.fresh-install.cold-cache.cold-store📈 view plot
⚠️ NO THRESHOLD
3,174.37 ms
isolated-linker.fresh-install.cold-cache.hot-store📈 view plot
⚠️ NO THRESHOLD
1,451.21 ms
isolated-linker.fresh-install.hot-cache.hot-store📈 view plot
⚠️ NO THRESHOLD
1,432.99 ms
isolated-linker.fresh-restore.cold-cache.cold-store📈 view plot
⚠️ NO THRESHOLD
2,876.34 ms
isolated-linker.fresh-restore.hot-cache.hot-store📈 view plot
⚠️ NO THRESHOLD
716.38 ms
🐰 View full continuous benchmarking report in Bencher

getPrepareDir now encodes time and pid in base36, so the dlx cache
e2e helper must accept letters g-z. The previous hex check (with
buggy && logic) could throw on a valid base36 name.
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit f19adba

1 similar comment
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit f19adba

@zkochan zkochan merged commit ec7cf70 into main Jun 23, 2026
32 checks passed
@zkochan zkochan deleted the fix-dlx-windows-max-path branch June 23, 2026 11:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants