Files
windmill/debugger
Ruben Fiszel 372023e995 feat: add ws_base_url instance setting for WebSocket URL override (#8405)
* feat: add ws_base_url instance setting to override WebSocket base URL

Allow deployments behind reverse proxies to route WebSocket traffic
(LSP, debugger, multiplayer) to a different host/port than the main
frontend via a new instance setting.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: move ws_base_url to Advanced section with toggle and connectivity test

- Move setting from Core to Advanced > WebSocket section
- Render as toggle "Custom websocket base url from frontend to
  multiplayer/lsp/debugger" with conditional URL text field
- Add Test connectivity button (always visible) that checks HTTP health
  and WebSocket ping for all three services (LSP, Multiplayer, Debugger)
- Add /ws/ping and /ws/health endpoints to LSP service
- Add /ws_mp/health HTTP and __ping__ WS handlers to multiplayer service
- Add /ping WS handler to debugger service
- Add CORS headers to health endpoints for cross-origin testing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: toggle enabled check and testWs promise resolution

- Fix enabled derived to check only for null (not empty string),
  otherwise the toggle never turns on since toggleEnabled sets ''
- Fix testWs onclose handler to resolve(false) so the promise
  doesn't hang if the server closes without sending a message

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: make connectivity test work with existing services

- HTTP test: accept plain text "ok"/"okay" (old services) in addition
  to JSON {"status": "ok"} (new services), reject HTML (SPA fallback)
- WS test: resolve on onopen (connection established) instead of
  waiting for a specific pong message, so the test works even with
  services that don't have the new /ping handler yet

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 12:48:59 +00:00
..

Windmill Debug Module

A DAP (Debug Adapter Protocol) implementation for debugging Python and TypeScript/Bun scripts in Windmill's Monaco editor.

Overview

This module provides step-through debugging capabilities with breakpoints, variable inspection, and stack traces. It uses WebSocket communication between the Monaco editor frontend and language-specific debug backends.

Supported Languages

  • Python - Uses a bdb-based debugger via dap_websocket_server.py
  • TypeScript/Bun - Uses V8 Inspector Protocol via dap_websocket_server_bun.ts

Architecture

┌─────────────────────┐     WebSocket      ┌──────────────────────────┐
│  Monaco Editor      │◄──────────────────►│  DAP Debug Service       │
│  (dapClient.ts)     │    DAP Protocol    │  (dap_debug_service.ts)  │
└─────────────────────┘                    └──────────┬───────────────┘
                                                      │
                                           ┌──────────┴───────────┐
                                           │                      │
                                    ┌──────▼──────┐       ┌───────▼───────┐
                                    │   Python    │       │   Bun/TS      │
                                    │   Debugger  │       │   Debugger    │
                                    └─────────────┘       └───────────────┘

Files

File Description
dap_debug_service.ts Unified WebSocket server that routes to Python or Bun debuggers
dap_websocket_server.py Python debugger backend (bdb-based)
dap_websocket_server_bun.ts Bun/TypeScript debugger backend (V8 Inspector)
dapClient.ts Client-side DAP WebSocket client with Svelte store
MonacoDebugger.svelte Monaco editor integration component
DebugToolbar.svelte Debug control buttons (step, continue, etc.)
DebugPanel.svelte Variables and stack trace display panel
index.ts Module exports

Usage

Starting the Debug Service

bun run debug/dap_debug_service.ts

Options:

  • --port PORT - Server port (default: 3003)
  • --host HOST - Server host (default: 0.0.0.0)
  • --python-path PATH - Python binary path (default: python3)
  • --bun-path PATH - Bun binary path (default: bun)
  • --nsjail - Enable nsjail sandboxing for debugger processes
  • --nsjail-config PATH - Path to nsjail config file
  • --nsjail-path PATH - Path to nsjail binary (default: nsjail)

Endpoints

  • /python - Python debugging
  • /typescript - TypeScript/Bun debugging
  • /bun - Alias for /typescript

Environment Variables

Variable Description Default
DAP_PORT Server port 3003
DAP_HOST Server host 0.0.0.0
DAP_PYTHON_PATH Python binary path python3
DAP_BUN_PATH Bun binary path bun
DAP_NSJAIL_ENABLED Enable nsjail sandboxing false
DAP_NSJAIL_PATH nsjail binary path nsjail
DAP_NSJAIL_CONFIG nsjail config file path -

Frontend Integration

<script>
  import { MonacoDebugger } from './debug'
  let editor // Monaco editor instance
  let code = 'print("Hello")'
</script>

<MonacoDebugger {editor} {code} language="python3" />

Testing

# Test Python debugger
bun run debug/test_dap_server.py

# Test Bun debugger
bun run debug/test_dap_server_bun.ts

# Test unified service
bun run debug/test_debug_service.ts