Skip to content

fix: exit cleanly on Ctrl+C when npm runs the framework on Windows - #413

Merged
petebacondarwin merged 2 commits into
cloudflare:mainfrom
Cherry:fix/windows-npm-ctrl-c-prompt
Nov 5, 2026
Merged

petebacondarwin merged 2 commits into
cloudflare:mainfrom
Cherry:fix/windows-npm-ctrl-c-prompt

Conversation

@Cherry

@Cherry Cherry commented Oct 25, 2026

Copy link
Copy Markdown
Contributor

Fixes #412

On Windows, cf dev, cf build and cf init run npm/npx through the npm.cmd/npx.cmd bundled with Node. Those keep a batch file running under npm, so after Ctrl+C cmd sits at Terminate batch job (Y/N)? and cf never exits.

runProjectCommand now resolves npm/npx to the CLI script the launcher would run and starts it with Node directly. It follows the launcher's own lookup: the node.exe next to it, and an npm upgraded into the global prefix via npm-prefix.js. Anything it doesn't recognise runs as before.

pnpm projects still prompt from pnpm's own node_modules\.bin shims, which is outside cf.

  • Added npx cases to the Windows console Ctrl+C test, using a verbatim copy of npm's npx.cmd. They hang without this change.
  • Added unit tests for the resolver
  • Added a patch changeset

Node's bundled npm.cmd and npx.cmd keep a batch file running under npm,
so Ctrl+C left cf waiting at cmd's "Terminate batch job (Y/N)?" prompt.
Run npm's CLI script with Node directly instead.

Fixes cloudflare#412
@github-actions

Copy link
Copy Markdown
Contributor

Hi @Cherry. Thanks for contributing to cf!

During the open beta, we’re being very intentional about the changes we accept so that we can prioritise stability for GA. We’re limiting pull requests to contributions coordinated with the team in advance, so this PR has been automatically closed.

We’d still love to hear about your use case, so please make sure it’s captured in a cf issue. If the proposed change fits our priorities, we’d be happy to take another look at this PR.

@github-actions github-actions Bot closed this Oct 25, 2026
@clanky-the-clanker

clanky-the-clanker Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

This pull request's reviews are posted as pull request reviews: see the review of 6af1ec92.

@pkg-pr-new

pkg-pr-new Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
npm i https://pkg.pr.new/cf@413

commit: 61f184c

@petebacondarwin

Copy link
Copy Markdown
Collaborator

clanker review

Comment thread packages/cli/src/lib/npm-launcher.ts Resolved
Comment thread packages/cli/src/lib/npm-launcher.ts Resolved

@clanky-the-clanker clanky-the-clanker 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.

⚠️ Out of date: this review is of 6af1ec92; the pull request is now at 61f184ce. Someone with write access can comment clanky review (or clanker review or @clanky-the-clanker review) to review the new commits.

💬 Approved with comments — The fix works. Two WARNINGs: on some PATH layouts the resolver can choose a different npm (it skips .exe shims) or a different Node (it falls back to process.execPath) than npm's launcher would. Two smaller notes on environment handling and the probe timeout.

Findings: 2 warnings · 1 info · 1 suggestion (4 are inline comments on the diff)

The decision is advisory: this review is a comment and never approves, blocks or requests changes on the pull request.

🔧 Fix with your agent

Paste the following into your coding agent to investigate and fix these issues.

Fix the following code review issues found in pull request #413.

Before making changes, review each issue and present a brief summary table:
- For each finding, state whether you agree, disagree, or need clarification
- If you disagree (e.g., the fix would require disproportionate changes
  for minimal ROI, or the finding is factually incorrect), explain why
- If you need to clarify something before deciding, ask those questions
- Then share your plan for which issues to tackle and in what order

## WARNING (2)

### [Code Quality] The PATH scan only looks for `npm.cmd`/`npx.cmd`, so it skips an earlier `npm.exe`/`npx.exe` shim and can run a different npm than before.
- **File:** packages/cli/src/lib/npm-launcher.ts:24

### [Code Quality] When there is no adjacent `node.exe`, the code falls back to `process.execPath` instead of `node` from PATH, so the project can run under a different Node version.
- **File:** packages/cli/src/lib/npm-launcher.ts:35

## INFO (1)

### [Performance] The synchronous `npm-prefix.js` probe has no timeout, so a hung probe would hang `cf dev`/`cf build`.
- **File:** packages/cli/src/lib/npm-launcher.ts:50

## SUGGESTION (1)

### [Code Quality] The resolver reads `process.env`, but the child is started with `options.env`.
- **File:** packages/cli/src/lib/autoconfig.ts:183

📋 Code Quality: ⚠️ 2 warnings · 1 suggestion

The resolver fixes the Ctrl+C hang, but it finds npm and Node differently from npm's launcher and PATH, so it can run a different npm or Node.

Recommendation: 📝 Minor Comments

  • [WARNING] The PATH scan only looks for npm.cmd/npx.cmd, so it skips an earlier npm.exe/npx.exe shim and can run a different npm than before. (packages/cli/src/lib/npm-launcher.ts:24)
  • [WARNING] When there is no adjacent node.exe, the code falls back to process.execPath instead of node from PATH, so the project can run under a different Node version. (packages/cli/src/lib/npm-launcher.ts:35)
  • [SUGGESTION] The resolver reads process.env, but the child is started with options.env. (packages/cli/src/lib/autoconfig.ts:183)
View full review
  • Lookup order (npm-launcher.ts:22-24): the resolver takes the first PATH entry that contains npm.cmd/npx.cmd. An earlier native npm.exe/npx.exe or shim is skipped, which bypasses version managers that put such shims first.
  • Node fallback (npm-launcher.ts:34-35): with no adjacent node.exe, npm's launcher uses node from PATH. This code uses cf's own process.execPath instead, both for the CLI and for npm-prefix.js.
  • Environment (autoconfig.ts:183): resolveNpmLauncher reads process.env, but the child is started with options.env.

⚡ Performance: 💬 1 info

The npm-prefix.js probe is synchronous and has no timeout.

Recommendation: 💬 Optional Nits

  • [INFO] The synchronous npm-prefix.js probe has no timeout, so a hung probe would hang cf dev/cf build. (packages/cli/src/lib/npm-launcher.ts:50)
View full review

globalPrefixScript spawns Node synchronously on every Windows npm/npx delegation. It blocks the event loop and has no timeout.


✅ All other checks passed

🔒 Security: ✅ LGTM

No security issues. execFileSync takes an argument array, so it runs no shell, and the command name is limited to npm/npx by a strict regex. The PATH lookup does not search the current directory.


📖 AGENTS.md: ✅ LGTM

No issues found.


📝 Documentation: ✅ LGTM

The changeset follows the repository's conventions.


Reviewed commit: 6af1ec92

Comment thread packages/cli/src/lib/npm-launcher.ts Resolved
Comment thread packages/cli/src/lib/npm-launcher.ts Resolved
Comment thread packages/cli/src/lib/npm-launcher.ts Resolved
Comment thread packages/cli/src/lib/autoconfig.ts Resolved
@dario-piotrowicz
dario-piotrowicz removed their request for review November 5, 2026 11:47
Resolve npm the way the child process would and only rewrite npm's batch launchers, fall back to node on PATH, and time out the global prefix probe.
@petebacondarwin
petebacondarwin added this pull request to the merge queue Nov 5, 2026
Merged via the queue into cloudflare:main with commit fed10c4 Nov 5, 2026
15 checks passed
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.

Ctrl+C leaves cf dev stuck at "Terminate batch job (Y/N)?" on Windows in npm projects

2 participants