Skip to content

Conversation

@mho22
Copy link
Collaborator

@mho22 mho22 commented Oct 14, 2025

Motivation for the change, related issues

Based on issue #2763

The current pain we have when we run a Playground CLI command with Xdebug enabled is the absence of the files located in the VFS in our IDE.

This pull request gives visibility to the VFS files with the help of a .playground-xdebug-root symlink and the generation of path mappings inside the developer's IDE.

Only the mounts from inside the current working directory are mapped.

Implementation details

  1. Symlinking > .playground-xdebug-root
  • It first removes a possibly existing symlink with name .playground-xdebug-root in the current working directory.
  • If --xdebug and --experimental-unsafe-ide-integration options are present, we symlink the temporary playground cli directory inside the current working directory.
  1. Path mapping in IDEs
  • It first clears all the configs named WP Playground CLI - Listen for Xdebug in VSCode and PHPStorm config files.
  • If --xdebug and --experimental-unsafe-ide-integration options are present, we add IDE configs and path mappings in the related configs.
  • PHPStorm : it adds a new server with name WP Playground CLI - Listen for Xdebug in .idea/workspace.xml.
  • VSCode : it adds a new configuration with name WP Playground CLI - Listen for Xdebug in .vscode/launch.json.

Next steps are reported in the Xdebug Follow-up issue.

Testing Instructions (or ideally a Blueprint)

Run as follows:

node --no-warnings=ExperimentalWarning  --experimental-strip-types --experimental-transform-types --import ./pac
kages/meta/src/node-es-module-loader/register.mts ./packages/playground/cli/src/cli.ts server --xdebug --experimental-unsafe-ide-integration

@mho22 mho22 changed the title [ xdebug ] Add --experimental-ide option to set xdebug path mappings [ xdebug ] Add --experimental-ide option in Playground CLI Oct 14, 2025
@mho22 mho22 mentioned this pull request Oct 14, 2025
11 tasks
@adamziel
Copy link
Collaborator

Let's support an optional explicit value, e.g. --experimental-ide=vscode just in case I work in multiple IDEs and only want to debug in one of them.

Also, this is the top of my vscode.json file:

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",

It means we cannot trivially use JSON.parse() :( These files are JSONC (JSON with comments) and we need a JSONC parser and serializer to work with them. Perhaps this one from Microsoft would work, maybe it's even the one used by VS Code.

@adamziel
Copy link
Collaborator

Some problems identifying the debug configuration:

CleanShot 2025-10-15 at 17 31 45@2x

Also, it's weird how the host is 127.0.0.1:9400 and port is 80.

@adamziel
Copy link
Collaborator

XDebug is running even during the Blueprint execution – how cool! Also, that's likely only useful for code developers. Let's set some php.ini option to disable xdebug until WordPress fully boots.

@adamziel
Copy link
Collaborator

We're definitely getting there! 🎉

CleanShot 2025-10-15 at 17 40 11@2x

@brandonpayton
Copy link
Member

I've been testing and reviewing the code and made some adjustments. The server host an port are now explicitly configured based on CLI's host and port.

I've seen PhpStorm report an Xdebug connection but haven't been able to hit any breakpoints yet.

@brandonpayton
Copy link
Member

brandonpayton commented Oct 18, 2025

I've been testing with an auto-mounted WordPress dir nested under the Playground repo like:
~/src/playground/wp-plugin-test-wordpress% node --experimental-strip-types --experimental-transform-types --disable-warning=ExperimentalWarning --import ../packages/meta/src/node-es-module-loader/register.mts ../packages/playground/cli/src/cli.ts server --auto-mount=. --verbosity=debug --skip-wordpress-setup --xdebug --experimental-ide

@brandonpayton
Copy link
Member

brandonpayton commented Oct 18, 2025

@adamziel is there any additional step in PhpStorm that I should have to do to tell PhpStorm to be able to hit breakpoints? Or should it just work if you have PhpStorm open and Playground CLI started with Xdebug support?

@adamziel
Copy link
Collaborator

adamziel commented Oct 18, 2025

I typically check "stop on first line" and set breakpoints from there @brandonpayton. And you need to turn on the "accept debug connections" toggle

@adamziel
Copy link
Collaborator

I've noticed this in my VS Code – might be related to something else, I'll need to dive into this. Also, I've added process.exit(1) on XDebug error to avoid silently passing failures and confusing users with "wait, why is my xdebug not connecting?". Also, JSONC.parse() needed the same options on re-validations so I added them. Will continue reviewing in 2 hours.

CleanShot 2025-10-27 at 13 30 16@2x

@adamziel
Copy link
Collaborator

Or in a few more hours, I forgot my power adapter :-)

@adamziel
Copy link
Collaborator

That error comes from xdebug, likely something wrong with our path mapping or the default initial breakpoint

https://bugs.xdebug.org/view.php?id=2302

@mho22
Copy link
Collaborator Author

mho22 commented Oct 27, 2025

I found that github issue in VScode-php-debug :

xdebug/vscode-php-debug#1020

Maybe this could be related to your VSCode or an extension you added? Because I don't have any Unknown sourceReference 0 error displayed when running the command in the description inside the wordpress-playground directory.

@brandonpayton
Copy link
Member

I plan to review in the next couple of hours. I also plan to make a few simple automated tests after factoring out IDE-specific bits into functions liks (pathMappings, inputConfigStr) => outputConfigStr, but those can come in a follow-up PR if needed.

@adamziel
Copy link
Collaborator

adamziel commented Oct 27, 2025

Yay! Also, when the ide integration is used, let's print something visible to tell the user what's next, e.g. per-IDE instructions, or a link to a new doc page explaining the next steps. Right now we know what to do, but it's not that obvious to a new person. Basically, let's handhold the user until they're in an active breakpoint cc @fellyph

Comment on lines 183 to 185
// NOTE: PhpStorm quirk: Xdebug only works when the full URL (including port)
// is provided in `host`. The separate `port` field is ignored or misinterpreted,
// so we rely solely on host: "host:port".
Copy link
Member

@brandonpayton brandonpayton Oct 25, 2025

Choose a reason for hiding this comment

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

Thanks for following upon on this!

"PHP": "${input:phpVersion}"
},
"enableDWARF": true
},
Copy link
Member

Choose a reason for hiding this comment

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

The "Debug PHP-WASM" target may not be working well now, and the "Debug Playground CLI with DWARF symbols" is a bit clunky. But personally, I would like to leave at least the Playground CLI target in our launch.json because it gives me a starting point to customize and debug with DWARF symbols.

vfsPath: '/',
};

clearXdebugIDEConfig(IDEConfigName, process.cwd())
Copy link
Member

Choose a reason for hiding this comment

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

If we are going to exit if these operations fail, let's await here.

And if we await here we could switch back to try/catch blocks here if desired. It seems a bit strange to me to mix the await and the explicit promise-chaining styles, but I don't really think it matters either way.

xml ===
'<?xml version="1.0" encoding="UTF-8"?>\n<project version="4">\n <component name="PhpServers">\n <servers></servers>\n </component>\n</project>'
) {
fs.unlinkSync(phpStormConfigFilePath);
Copy link
Member

Choose a reason for hiding this comment

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

Is there any harm in leaving the file in place? It doesn't seem safe to assume Playground CLI is the creator of the file.

Copy link
Collaborator Author

@mho22 mho22 Oct 27, 2025

Choose a reason for hiding this comment

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

I guess not, but I had in mind that if the remaining file looks like that, it certainly is because we created it in the first place. So we could destroy it. But I have the same feeling as you.

Copy link
Member

@brandonpayton brandonpayton Oct 27, 2025

Choose a reason for hiding this comment

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

Cool. 👍 yeah, I bet it will be true in most cases that an empty config is one created by us, but we can't really prove it without some other evidence. It's possible a user had some other config and then removed it during debugging. (just talking this out, not trying to further explain 😄 )


const json = jsoncApplyEdits(content, edits);
if (json === '{\n "configurations": []\n}') {
fs.unlinkSync(vsCodeConfigFilePath);
Copy link
Member

Choose a reason for hiding this comment

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

Same question as above. Should we just leave this file in place to be safe?

Sometimes vscode even auto adds sections to the file when opening various kinds of files?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

If vscode or phpstorm auto adds sections to the file, this means the file won't have that structure anymore so we won't have to destroy it. But, I still have the same feeling as you.

'/internal/shared/extensions/xdebug.ini'
)
) {
const ideKey = xdebugOptions?.ideKey || 'PLAYGROUNDCLI';
Copy link
Collaborator

Choose a reason for hiding this comment

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

PHPStorm seems to require the IDE key for debug configuration

Copy link
Member

Choose a reason for hiding this comment

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

Good catch

@adamziel
Copy link
Collaborator

I've added some developer instructions:

CleanShot 2025-10-28 at 01 11 23@2x

Also:

  • Creating a new debug configuration in PHPStorm config
  • Factored the config-altering logic and added test coverage

@brandonpayton
Copy link
Member

Thanks for adding tests, @adamziel! I ended up getting pulled away, was going to write them now, and found there was a conflict with the existing test file. Cool! Will read and see if there is anything to add.

@brandonpayton
Copy link
Member

@adamziel and @mho22, thank you for getting this ready today. It looks like this is about ready for merge.

I made a couple of minor fixes:

  • Fix xdebug ini test that didn't acknowledge new ideKey config
  • Move clearXdebugIDEConfig() into the run-cli try/catch because that operation can also throw.

If the tests pass, I think this is ready to merge.

"runtimeArgs": [
"--inspect-brk",
"--loader=${workspaceFolder}/packages/nx-extensions/src/executors/built-script/loader.mjs"
]
Copy link
Member

Choose a reason for hiding this comment

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

NOTE: While restoring the removed launch targets, I ended up formatting the file, so there are some whitespace changes like this.

Copy link
Member

@brandonpayton brandonpayton left a comment

Choose a reason for hiding this comment

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

I think this is good to go. Thanks, everyone!

@brandonpayton
Copy link
Member

brandonpayton commented Oct 28, 2025

I'll go ahead and merge this since I'm not aware of any remaining reservations. As a follow-up, I plan to submit a PR to have an initial worker for boot that does not hit Xdebug breakpoints during boot (unless maybe an additional flag is passed). I started this locally but don't remember how far along it is. Will see tomorrow.

@brandonpayton brandonpayton merged commit 46d50ec into trunk Oct 28, 2025
29 checks passed
@brandonpayton brandonpayton deleted the add-xdebug-path-mappings-with-experimental-ide branch October 28, 2025 03:55
@mho22
Copy link
Collaborator Author

mho22 commented Oct 28, 2025

🎉 🎉 🎉 ! Thank you @brandonpayton and @adamziel ! What a teamwork !

@brandonpayton
Copy link
Member

🎉 🎉 🎉 ! Thank you @brandonpayton and @adamziel ! What a teamwork !

Thank you, @mho22! This was fun!

adamziel pushed a commit that referenced this pull request Dec 9, 2025
…wasm CLI (#2947)

## Motivation for the change, related issues

Based on issue
#2763 and
following pull request
#2777

This pull request generates the IDE configuration files inside the
developer's IDE.

## Implementation details

- It first clears all the configs named `PHP.wasm CLI - Listen for
Xdebug` in VSCode and PHPStorm config files.
- If `--xdebug` and `--experimental-unsafe-ide-integration` options are
present, we add IDE configs in the related configs.
- PHPStorm : it adds a new `server` with name `PHP.wasm CLI - Listen for
Xdebug` in `.idea/workspace.xml`.
- VSCode : it adds a new `configuration` with name `PHP.wasm CLI -
Listen for Xdebug` in `.vscode/launch.json`.

- Correction of an error in Playground CLI console.logs.

- Creation of a new distinct package named `@php-wasm/cli-util` which is
integrated into PHP.wasm CLI and Playground CLI with the
`xdebug-path-mappings`.

Next steps are reported in the [Xdebug Follow-up
issue](#2315).

## Testing Instructions (or ideally a Blueprint)

CI

🧪 test-php-wasm-cli-util

cc @fellyph
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.

5 participants