Skip to content

feat(dlx): prompt to approve ignored builds#11452

Merged
zkochan merged 9 commits into
mainfrom
fix/dlx-prompt-approve-builds
May 4, 2026
Merged

feat(dlx): prompt to approve ignored builds#11452
zkochan merged 9 commits into
mainfrom
fix/dlx-prompt-approve-builds

Conversation

@zkochan

@zkochan zkochan commented May 4, 2026

Copy link
Copy Markdown
Member

Summary

pnpm dlx (and pnpx/pnx/pnpm create) now mirrors the pnpm add -g flow when the launched package's transitive deps have install scripts:

  • dlx overrides strictDepBuilds: false for its install so the v11 default no longer turns ignored builds into an ERR_PNPM_IGNORED_BUILDS error. Without this, pnpx @google/gemini-cli (and similar — node-pty, @github/keytar) failed outright and forced users to retry with --allow-build=<pkg> for every offending dependency.
  • After install, dlx detects skipped builds via getAutomaticallyIgnoredBuilds and runs the same interactive approve-builds prompt as pnpm add -g. In non-interactive mode the install is committed with builds skipped, matching pnpm add -g in CI; users who need those scripts can re-invoke with --allow-build=<pkg> to force a fresh cache key.
  • If the install errors for unrelated reasons (network, etc.) the partially-populated prepare directory is removed so the next dlx run starts clean.

Closes #11444.

Plumbing

  • Exports getAutomaticallyIgnoredBuilds from @pnpm/building.commands so dlx can detect skipped builds without re-implementing modules-yaml reading.
  • Adds strictDepBuilds (optional) to InstallCommandOptions — already accepted at runtime via the spread, this just makes it explicit at the type level so callers can override it.

Test plan

  • Two new regression tests in exec/commands/test/dlx.e2e.ts:
    • non-interactive dlx no longer errors on ignored builds and the cache is populated
    • dlx runs approve-builds and the build artifacts end up in the dlx cache when invoked with a commands map and PNPM_AUTO_APPROVE_BUILDS_FOR_TESTS=1
  • Existing @pnpm/exec.commands dlx e2e tests continue to pass
  • @pnpm/exec.commands create tests updated to assert the new third (commands) argument forwarded from create.handler to dlx.handler

Summary by CodeRabbit

  • New Features

    • pnpm dlx (including pnpx, pnx, and pnpm create) now uses an interactive prompt to approve package builds when transitive dependencies contain install scripts, consistent with pnpm add -g behavior.
  • Bug Fixes

    • pnpm dlx now cleans up partially populated cache directories when installation fails, preventing reuse of broken installations.

zkochan added 4 commits May 4, 2026 17:46
`pnpm dlx`/`pnpx`/`pnx`/`pnpm create` now run the same interactive
`approve-builds` flow as `pnpm add -g` when the launched package depends
on transitive packages with install scripts. Previously, the
`strictDepBuilds` default in v11 made dlx fail with
`ERR_PNPM_IGNORED_BUILDS` and required users to re-invoke with
`--allow-build=<pkg>` for every offending dependency.

dlx also now removes the partially-populated cache directory on install
failure, so a subsequent run starts clean instead of reusing a broken
install whose builds had been silently skipped.
Copilot AI review requested due to automatic review settings May 4, 2026 15:53
@coderabbitai

coderabbitai Bot commented May 4, 2026

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5b23c94e-8b92-4ce4-98ec-34fe42cf84ed

📥 Commits

Reviewing files that changed from the base of the PR and between 41ecf8a and e0cc463.

📒 Files selected for processing (1)
  • .changeset/fix-dlx-prompt-approve-builds.md

📝 Walkthrough

Walkthrough

dlx and create now accept an optional commands map; dlx computes and passes an allowBuilds map to installs, runs an approve-builds prompt (TTY-guarded, with a test env override) when transitive install-script dependencies are ignored, and removes partially-populated dlx cache directories on failed installs. Types, exports, tests, and packaging refs were updated.

Changes

dlx approve-builds flow and cache cleanup

Layer / File(s) Summary
Type / Export Additions
installing/commands/src/install.ts, building/commands/src/index.ts, building/commands/src/policy/index.ts
Added strictDepBuilds?: boolean to InstallCommandOptions. Re-exported getAutomaticallyIgnoredBuilds from building.commands policy index.
Core Implementation
exec/commands/src/dlx.ts
handler now accepts commands?: CommandHandlerMap. On cache miss computes allowBuilds, calls add.handler with strictDepBuilds: false, invokes promptApproveDlxBuilds which uses getAutomaticallyIgnoredBuilds and conditionally calls approve-builds (TTY-gated; test env override). Deletes partially-populated cachedDir on parallel-recovery failure.
API/Caller Wiring
exec/commands/src/create.ts, exec/commands/package.json, exec/commands/tsconfig.json
create.handler forwards commands into dlx.handler. exec.commands adds @pnpm/building.commands workspace dependency and references it in tsconfig.
Tests / Regression / Docs
exec/commands/test/dlx.e2e.ts, exec/commands/test/create.ts, .changeset/fix-dlx-prompt-approve-builds.md
E2E tests added for non-interactive strictDepBuilds and test-forced approve-builds flows; create tests updated to expect third commands arg; changeset documents dlx prompting parity with pnpm add -g and cache cleanup on failed installs.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant DLX as dlx
    participant Add as add.handler
    participant Policy as building.commands
    participant FS as Filesystem

    User->>DLX: pnpm dlx <package> ...
    DLX->>FS: check cachedDir exists?
    alt cache miss
        DLX->>Add: add.handler(..., allowBuilds, strictDepBuilds:false)
        Add->>FS: populate cachedDir (install artifacts)
        DLX->>Policy: getAutomaticallyIgnoredBuilds(cachedDir)
        alt ignored builds present and approval allowed (TTY or TEST env)
            DLX->>Policy: approve-builds(allowBuilds[, all:true in test])
            Policy-->>Add: allow selected builds
            Add->>FS: run allowed build scripts / re-run install
        end
        DLX->>FS: mark completedDir
    else parallel-recovery failure (no completedDir)
        DLX->>FS: rm cachedDir (recursive, force)
        DLX-->>User: rethrow error
    end
    DLX-->>User: execute target package
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • feat(dlx): prompt to approve ignored builds #11452 — Implements the same dlx changes: optional commands param, approve-builds wiring via getAutomaticallyIgnoredBuilds/approveBuilds, cache removal on failed dlx install, and matching tests/tsconfig/package.json updates.

Poem

"I hopped through installs with ears alert and swift,
Prompting builds when scripts might drift.
If cache is broken, I tidy the track,
Then ask for approval and run builds back.
🐇✨"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(dlx): prompt to approve ignored builds' clearly and concisely summarizes the main change: adding an interactive approval prompt for ignored builds in the dlx command, which is directly reflected in the changeset.
Linked Issues check ✅ Passed The PR fully addresses all coding objectives from issue #11444 [#11444]: implements interactive approve-builds flow for dlx, removes partially-populated cache on install failures, adds regression tests, and prevents ERR_PNPM_IGNORED_BUILDS from blocking dlx runs.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing the approve-builds flow for dlx and handling cache cleanup on failures. Modifications to create.ts, dlx.ts, install.ts, building/commands, and test files align with the stated objectives and issue #11444.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/dlx-prompt-approve-builds

Review rate limit: 9/10 reviews remaining, refill in 6 minutes.

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

@coderabbitai

coderabbitai Bot commented May 4, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The PR enables pnpm dlx (and aliases pnpx, pnx, pnpm create) to interactively prompt for build approval when encountering transitive dependencies with install scripts under strict build policies. On approval failure, the partially-populated cache is deleted to ensure clean subsequent runs.

Changes

Interactive Build Approval Flow in dlx

Layer / File(s) Summary
Type & Import Setup
exec/commands/src/create.ts, exec/commands/src/dlx.ts
CommandHandlerMap type imported and threaded through handler signatures from create.ts to dlx.ts.
Core Install Logic
exec/commands/src/dlx.ts
Install wrapped in nested try/catch; on ERR_PNPM_IGNORED_BUILDS, conditionally invokes approve-builds handler if test env var or TTY is present; otherwise deletes cache directory and rethrows.
Test Fixture Setup
exec/commands/test/dlx.e2e.ts
Jest mock of @pnpm/installing.commands updated to spy on add.handler; approveBuilds handler imported from @pnpm/building.commands.
Regression Tests
exec/commands/test/dlx.e2e.ts
Two tests added: one verifies cache cleanup on ignored-build failure; one verifies successful install after approve-builds approval via test env var.
Dependency & Build Configuration
exec/commands/package.json, exec/commands/tsconfig.json
@pnpm/building.commands added to devDependencies and TypeScript project references.
Release Documentation
.changeset/fix-dlx-prompt-approve-builds.md
Changeset documents that dlx now prompts for build approval and cleans up cache on install failure.

Sequence Diagram

sequenceDiagram
    actor User
    participant dlx as dlx.handler
    participant add as add.handler
    participant approveBuilds as approve-builds handler
    participant fs as Filesystem (cache)

    User->>dlx: invoke dlx with package name
    dlx->>add: install package & dependencies
    add-->>dlx: ERR_PNPM_IGNORED_BUILDS error
    alt Test env var OR TTY AND approve-builds handler exists
        dlx->>approveBuilds: prompt user to approve builds
        approveBuilds-->>dlx: approval response
        dlx->>add: retry install with approved builds
        add-->>dlx: install success
        dlx->>User: execute package
    else No approval available
        dlx->>fs: delete partially-populated cache
        fs-->>dlx: cache cleaned
        dlx->>User: rethrow ERR_PNPM_IGNORED_BUILDS
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

A rabbit hops past build scripts denied,
Now asks approval with open pride,
Cache swept clean when hopes collide,
Interactive dlx, your helper guide! 🐰✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(dlx): prompt to approve ignored builds' directly and clearly describes the main feature being implemented: adding an interactive approval prompt to dlx when encountering ignored builds.
Linked Issues check ✅ Passed The code changes fully implement the core requirements from issue #11444: interactive approve-builds flow for dlx/pnpx/pnx/pnpm create when transitive packages have install scripts, cache cleanup on install failure, and restoration of pre-v11 functionality.
Out of Scope Changes check ✅ Passed All changes are directly related to the stated objectives: dlx handler enhancements for interactive builds approval, cache cleanup logic, necessary dependency additions, type updates, and regression tests—no unrelated modifications present.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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-prompt-approve-builds

Review rate limit: 9/10 reviews remaining, refill in 6 minutes.

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@exec/commands/src/dlx.ts`:
- Around line 194-215: The call to commands['approve-builds'] can throw (e.g.,
user cancel) and currently bypasses the cachedDir cleanup; wrap the await
commands['approve-builds'](...) call in a try/catch so that on any exception you
call fs.promises.rm(cachedDir, { recursive: true, force: true }) before
rethrowing the error (preserve the original error), ensuring the same cleanup
path used in the else branch when install fails.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c37e184e-e561-46b3-b56d-83954bb5ac4e

📥 Commits

Reviewing files that changed from the base of the PR and between bc9c3af and 354b8d1.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (6)
  • .changeset/fix-dlx-prompt-approve-builds.md
  • exec/commands/package.json
  • exec/commands/src/create.ts
  • exec/commands/src/dlx.ts
  • exec/commands/test/dlx.e2e.ts
  • exec/commands/tsconfig.json

Comment thread exec/commands/src/dlx.ts Outdated
zkochan added 3 commits May 4, 2026 18:08
…uilds

Mirror the global install flow: instead of letting `add.handler` throw
on transitive deps with unrun build scripts and recovering from the
error, dlx now sets `strictDepBuilds: false` for its install and uses
`getAutomaticallyIgnoredBuilds` to detect skipped builds afterwards.
The same `approve-builds` prompt is then run for those builds (or
skipped silently in non-interactive mode, matching `pnpm add -g`).

This addresses the review feedback that the previous catch-the-error
approach was hard to reason about — the install no longer relies on
strictDepBuilds being true to detect ignored builds, so there is no
error path to recover from inside the IGNORED_BUILDS branch.

Also exports `getAutomaticallyIgnoredBuilds` from
`@pnpm/building.commands` so dlx (and other consumers) can detect
skipped builds without duplicating modules-manifest reading logic, and
adds `strictDepBuilds` to `InstallCommandOptions` (already accepted at
runtime) so `add.handler` callers can override it explicitly.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@exec/commands/src/dlx.ts`:
- Around line 292-299: Detect skipped builds (call getAutomaticallyIgnoredBuilds
and inspect automaticallyIgnoredBuilds) before the early returns that check
commands?.['approve-builds'] and the interactive check
(autoApproveForTests/process.stdin.isTTY); if skipped builds exist and there is
no available recovery path (no approve-builds command and non-interactive
without AUTO_APPROVE_FOR_TESTS), do not let the caller treat opts.cachedDir as a
completed reusable dlx cache entry—return or mark the cache as non-final so the
directory is not linked into the shared cache. Ensure you reference the same
symbols: commands?.['approve-builds'], autoApproveForTests, process.stdin.isTTY,
getAutomaticallyIgnoredBuilds, automaticallyIgnoredBuilds, and opts.cachedDir
when implementing this reorder and early-exit behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5c2f50d5-6a17-4087-87bc-80b04bcf3155

📥 Commits

Reviewing files that changed from the base of the PR and between 2e087bf and 1f1d2a3.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (7)
  • .changeset/fix-dlx-prompt-approve-builds.md
  • building/commands/src/index.ts
  • building/commands/src/policy/index.ts
  • exec/commands/package.json
  • exec/commands/src/dlx.ts
  • exec/commands/test/dlx.e2e.ts
  • installing/commands/src/install.ts
✅ Files skipped from review due to trivial changes (2)
  • building/commands/src/policy/index.ts
  • .changeset/fix-dlx-prompt-approve-builds.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • exec/commands/package.json
  • exec/commands/test/dlx.e2e.ts

Comment thread exec/commands/src/dlx.ts
zkochan added 2 commits May 4, 2026 19:00
…ctively

Mirror the same trade-off pnpm add -g makes: a non-interactive install
with skipped build scripts is committed and reusable. Users who need
those scripts to run can re-invoke dlx with --allow-build=<pkg>, which
produces a different cache key and forces a fresh install.
Update pnpm version to patch and improve dlx prompt behavior for transitive packages. Ensure clean cache on install failure.
@zkochan zkochan merged commit 81b435a into main May 4, 2026
7 of 8 checks passed
@zkochan zkochan deleted the fix/dlx-prompt-approve-builds branch May 4, 2026 17:47
zkochan added a commit that referenced this pull request May 4, 2026
`pnpm dlx` (and `pnpx`/`pnx`/`pnpm create`) now mirrors the `pnpm add -g` flow when the launched package's transitive deps have install scripts:

- dlx overrides `strictDepBuilds: false` for its install so the v11 default no longer turns ignored builds into an `ERR_PNPM_IGNORED_BUILDS` error. Without this, `pnpx @google/gemini-cli` (and similar — `node-pty`, `@github/keytar`) failed outright and forced users to retry with `--allow-build=<pkg>` for every offending dependency.
- After install, dlx detects skipped builds via `getAutomaticallyIgnoredBuilds` and runs the same interactive `approve-builds` prompt as `pnpm add -g`. In non-interactive mode the install is committed with builds skipped, matching `pnpm add -g` in CI; users who need those scripts can re-invoke with `--allow-build=<pkg>` to force a fresh cache key.
- If the install errors for unrelated reasons (network, etc.) the partially-populated prepare directory is removed so the next dlx run starts clean.

Closes #11444.

### Plumbing

- Exports `getAutomaticallyIgnoredBuilds` from `@pnpm/building.commands` so dlx can detect skipped builds without re-implementing modules-yaml reading.
- Adds `strictDepBuilds` (optional) to `InstallCommandOptions` — already accepted at runtime via the spread, this just makes it explicit at the type level so callers can override it.
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.

pnpx @google/gemini-cli could not launch anymore

1 participant