Skip to content

fix: eliminate visible console windows on Windows debug sessions (#215) - #219

Merged
debugmcpdev merged 4 commits into
mainfrom
fix/215-windows-console-flash
Aug 1, 2026
Merged

fix: eliminate visible console windows on Windows debug sessions (#215)#219
debugmcpdev merged 4 commits into
mainfrom
fix/215-windows-console-flash

Conversation

@debugmcpdev

Copy link
Copy Markdown
Collaborator

Fixes #215 — console windows appearing on screen for every Python debug session on Windows.

The three findings (building on the reporter's excellent follow-up analysis)

  1. The persistent window was debugpy's launcher, not our spawns. The adapter process is spawned detached (no console at all), so its console-subsystem launcher grandchild gets a fresh visible console allocated by Windows — beyond the reach of any Node-side windowsHide, exactly as the reporter's process tree showed.
  2. console was being silently overridden. transformLaunchConfig hard-coded console: 'internalConsole', which is why every console value the reporter tried behaved identically.
  3. ~30 probe spawn sites lacked windowsHide across the adapter packages (the original report undercounted at 4; the follow-up's "closer to a dozen" was also low).

The fix

  • Run the adapter under pythonw.exe when a sibling of the resolved interpreter exists (win32 only). Same directory ⇒ same interpreter, version, site-packages, venv. Since the launch config pins no python, the launcher and debuggee inherit it — no process in the chain ever gets a console. This is the reporter's verified workaround, promoted to the default.
  • Honor user-supplied console (config.console ?? 'internalConsole').
  • windowsHide sweep: all probe/detection sites in adapter-python/-ruby/-rust/-go/-java/-dotnet and the shared policies, plus central defaults in ProcessManagerImpl.spawn and the proxy processSpawner binding (callers can still opt out). jdi-resolver's shell-based execSync('where javac') became execFileSync so the flag can apply.

Measurement (Windows 11, reporter's methodology)

EnumWindows + IsWindowVisible watcher filtered to ConsoleWindowClass/CASCADIA_HOSTING_WINDOW_CLASS, 15 ms sampling, new-HWND-only; validated with a deliberately visible console (counts 1) and a windowsHide spawn (counts 0). One full debug session per run (create_debug_sessionset_breakpointstart_debuggingget_stack_tracecontinue_executionclose_debug_session):

Build Visible console windows
Published 0.22.0 1 (reproduces the report)
This branch 0

Breakpoints, stack traces, and continue verified working under the pythonw chain; full unit suite (2496) and python adapter tests pass.

The reporter's remaining side-finding — debuggee stdout never reaching the MCP client — is now tracked in #218.

🤖 Generated with Claude Code

cynarlab and others added 2 commits August 1, 2026 07:23
Three-part fix for console windows flashing/persisting on Windows:

1. windowsHide sweep: add windowsHide:true to ~30 probe/detection spawn
   sites across all adapter packages and shared policies, defaulted
   centrally in ProcessManagerImpl.spawn and the proxy processSpawner
   binding. jdi-resolver's shell-based execSync('where javac') converted
   to execFileSync so the flag can apply.

2. Honor user-supplied console mode: transformLaunchConfig previously
   hard-coded console:'internalConsole', silently overriding
   dapLaunchArgs.console (why the reporter saw identical behavior for
   every value they tried).

3. Run the debugpy adapter under pythonw.exe when a sibling exists
   (win32): the adapter is spawned detached (no console), so debugpy's
   console-subsystem launcher grandchild got a fresh *visible* console
   allocated by Windows — unreachable by any Node-side windowsHide. The
   GUI-subsystem interpreter cascades to launcher and debuggee (launch
   config pins no python), so no process in the chain gets a console.

Measured on Windows 11 with an EnumWindows/IsWindowVisible watcher
(positive+negative controls validated), full debug session each run:
published 0.22.0 = 1 visible console window per session; with this fix
= 0. Breakpoints, stack traces, and stepping verified working.

Fixes #215

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@codecov

codecov Bot commented Aug 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.11765% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/proxy/dap-proxy-dependencies.ts 0.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@debugmcpdev
debugmcpdev merged commit ba76a67 into main Aug 1, 2026
10 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.

Python interpreter/debugpy probe spawns lack windowsHide: a console window flashes on screen for every session (Windows)

2 participants