feat(debug): enable Python debug workflow and debug server integration

Adds an end-to-end Python debug workflow for the extension.
Includes a new prepare-debug.ps1 script and a VS Code task.
Extends the Python server and extension to coordinate a debug session and safe startup.

- Add prepare-debug.ps1 and a VS Code task to build the debug bundle
- Enable Python debug wiring in the server and tests
- Ensure a single stable Python debug session during startup
This commit is contained in:
Christoph Brandau
2026-08-17 11:02:22 +02:00
parent 35a4357551
commit 33cf282b0a
14 changed files with 349 additions and 73 deletions
+35 -12
View File
@@ -10,13 +10,21 @@
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": ["--extensionDevelopmentPath=${workspaceFolder}"],
"outFiles": ["${workspaceFolder}/client/**/*.js"],
"args": [
"--extensionDevelopmentPath=${env:TEMP}/nx-post-support-vscode-debug",
"${env:TEMP}/nx-post-support-vscode-debug",
"${env:TEMP}/nx-post-support-vscode-debug/test/test.tcl"
],
"cwd": "${env:TEMP}/nx-post-support-vscode-debug",
"outFiles": ["${env:TEMP}/nx-post-support-vscode-debug/dist/**/*.js"],
"sourceMaps": true,
"resolveSourceMapLocations": [
"${env:TEMP}/nx-post-support-vscode-debug/dist/**/*.js",
"!**/node_modules/**"
],
"skipFiles": ["<node_internals>/**"],
"autoAttachChildProcesses": true,
"preLaunchTask": {
"type": "npm",
"script": "watch"
}
"preLaunchTask": "NX Post Support: Compile Debug"
},
{
"name": "Python Attach",
@@ -34,10 +42,24 @@
"name": "Debug Extension (hidden)",
"type": "extensionHost",
"request": "launch",
"args": ["--extensionDevelopmentPath=${workspaceFolder}"],
"outFiles": ["${workspaceFolder}/client/**/*.js"],
"runtimeExecutable": "${execPath}",
"args": [
"--extensionDevelopmentPath=${env:TEMP}/nx-post-support-vscode-debug",
"${env:TEMP}/nx-post-support-vscode-debug",
"${env:TEMP}/nx-post-support-vscode-debug/test/test.tcl"
],
"cwd": "${env:TEMP}/nx-post-support-vscode-debug",
"outFiles": ["${env:TEMP}/nx-post-support-vscode-debug/dist/**/*.js"],
"sourceMaps": true,
"resolveSourceMapLocations": [
"${env:TEMP}/nx-post-support-vscode-debug/dist/**/*.js",
"!**/node_modules/**"
],
"skipFiles": ["<node_internals>/**"],
"env": {
"USE_DEBUGPY": "True"
"USE_DEBUGPY": "True",
"NXPS_DEBUG_HOST": "127.0.0.1",
"NXPS_DEBUG_PORT": "5678"
},
"presentation": {
"hidden": true,
@@ -49,8 +71,9 @@
"name": "Python debug server (hidden)",
"type": "debugpy",
"request": "attach",
"listen": { "host": "localhost", "port": 5678 },
"justMyCode": true,
"listen": { "host": "127.0.0.1", "port": 5678 },
"justMyCode": false,
"logToFile": true,
"presentation": {
"hidden": true,
"group": "",
@@ -63,7 +86,7 @@
"name": "Debug Extension and Python",
"configurations": ["Python debug server (hidden)", "Debug Extension (hidden)"],
"stopAll": true,
"preLaunchTask": "npm: watch",
"preLaunchTask": "NX Post Support: Compile Debug",
"presentation": {
"hidden": false,
"group": "",
+57
View File
@@ -0,0 +1,57 @@
param(
[Parameter(Mandatory = $true)]
[string]$WorkspaceRoot,
[Parameter(Mandatory = $true)]
[string]$DebugRoot
)
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
function ConvertFrom-ExtendedWindowsPath {
param([string]$Path)
if ($Path.StartsWith("\\?\UNC\", [System.StringComparison]::OrdinalIgnoreCase)) {
return "\\" + $Path.Substring(8)
}
if ($Path.StartsWith("\\?\", [System.StringComparison]::OrdinalIgnoreCase)) {
return $Path.Substring(4)
}
return $Path
}
$workspacePath = ConvertFrom-ExtendedWindowsPath $WorkspaceRoot
$workspaceItem = Get-Item -LiteralPath $workspacePath
if (-not $workspaceItem.PSIsContainer) {
throw "Workspace root is not a directory: $workspacePath"
}
$workspacePath = $workspaceItem.FullName
$debugPath = ConvertFrom-ExtendedWindowsPath $DebugRoot
$tempPath = [System.IO.Path]::GetFullPath([System.IO.Path]::GetTempPath()).TrimEnd("\")
$debugParent = [System.IO.Path]::GetFullPath((Split-Path -Parent $debugPath)).TrimEnd("\")
if (-not $debugParent.Equals($tempPath, [System.StringComparison]::OrdinalIgnoreCase)) {
throw "Debug alias must be located directly below the user temp directory: $debugPath"
}
if (Test-Path -LiteralPath $debugPath) {
$debugItem = Get-Item -LiteralPath $debugPath -Force
if ($debugItem.LinkType -ne "Junction") {
throw "Debug alias exists but is not a junction: $debugPath"
}
$currentTarget = (Get-Item -LiteralPath $debugItem.Target).FullName
if (-not $currentTarget.Equals($workspacePath, [System.StringComparison]::OrdinalIgnoreCase)) {
# Removing a junction removes only the link, never the target directory.
Remove-Item -LiteralPath $debugPath -Force
}
}
if (-not (Test-Path -LiteralPath $debugPath)) {
New-Item -ItemType Junction -Path $debugPath -Target $workspacePath | Out-Null
}
Write-Output "Debug extension path: $debugPath -> $workspacePath"
& npm.cmd --prefix $workspacePath run compile:debug
exit $LASTEXITCODE
+26
View File
@@ -0,0 +1,26 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "NX Post Support: Compile Debug",
"type": "process",
"command": "powershell.exe",
"args": [
"-NoLogo",
"-NoProfile",
"-ExecutionPolicy",
"Bypass",
"-Command",
"& { param([string]$WorkspaceRoot, [string]$DebugRoot); $scriptRoot = $WorkspaceRoot; if ($scriptRoot.StartsWith('\\\\?\\')) { $scriptRoot = $scriptRoot.Substring(4) }; & (Join-Path $scriptRoot '.vscode\\prepare-debug.ps1') -WorkspaceRoot $WorkspaceRoot -DebugRoot $DebugRoot; exit $LASTEXITCODE }",
"${workspaceFolder}",
"${env:TEMP}\\nx-post-support-vscode-debug"
],
"problemMatcher": [],
"presentation": {
"reveal": "always",
"panel": "dedicated",
"clear": true
}
}
]
}