Skip to content

fix: correct pass-through argument escaping on Windows - #633

Open
feiyuan1 wants to merge 2 commits into
open-cli-tools:mainfrom
feiyuan1:main
Open

feiyuan1 wants to merge 2 commits into
open-cli-tools:mainfrom
feiyuan1:main

Conversation

@feiyuan1

@feiyuan1 feiyuan1 commented Oct 18, 2026 •

Copy link
Copy Markdown

Background & Problem

When using --passthrough-arguments (-P) on Windows, concurrently relies on shell-quote to escape arguments. However, the current escaping logic is too eager, causing several issues:

  1. Over-escaping safe characters: Characters like = and @ are incorrectly escaped (e.g., --tags=@foo becomes --tags\=\@foo), which corrupts the arguments passed to the child process.
  2. Incorrect quote wrapping: shell-quote uses POSIX single quotes '' to wrap arguments containing spaces. However, Windows cmd.exe does not recognize single quotes, causing arguments to be split and broken.
  3. arguments containing both a space and a trailing backslash: E.g., C:\Program Files\, the C-Runtime parses the trailing \" as an escaped literal quote, breaking the argument.

(Related issues: #398, #487)

Fix

This PR introduces a platform-specific quoting strategy, referencing the implementation of shell-args:

  • On Windows: Introduce a custom winShellQuote logic. It replaces the POSIX-based quote(), using double quotes "" for arguments with spaces and avoiding unnecessary escaping for = and @.
  • On POSIX (Linux/macOS): Keep the existing shell-quote behavior to ensure no regressions.

Comment thread tsconfig.json
{
"compilerOptions": {
"lib": ["es2023"],
"types": ["node"],

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I'm not sure why this wasn't added previously, but in my local environment, TypeScript was throwing errors for Node.js global APIs (e.g., process). So I added "node" to compilerOptions.types here to resolve it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Your IDE might've used a newer TS version than the one installed in the project.

This will be necessary when that upgrade is finally done, but I'd like to revert this one

@coveralls

coveralls commented Oct 18, 2026 •

Copy link
Copy Markdown

Coverage Status

coverage: 98.652% (-0.1%) from 98.766% — feiyuan1:main into open-cli-tools:main

@gustavohenke gustavohenke left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

In case you missed it, concurrently now works with non-default shells: #589

This means that switching behaviour on the platform is not right when each shell has its own rules. You could have bash.exe on Windows, for instance.

return args
.map((arg) => {
// Only process arguments containing double quotes or spaces.
if (!contains(arg, '" ')) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You can write this as /["\s]/.test(arg)

});

// Wrap arguments containing spaces in double quotes
if (contains(arg, ' ')) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ditto here, a /\s/.test(arg) should work?

Comment thread tsconfig.json
{
"compilerOptions": {
"lib": ["es2023"],
"types": ["node"],

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Your IDE might've used a newer TS version than the one installed in the project.

This will be necessary when that upgrade is finally done, but I'd like to revert this one

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.

4 participants