UNPKG

@debugmcp/mcp-debugger

Version:

Step-through debugging MCP server for LLMs

1,340 lines (1,329 loc) 785 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __esm = (fn, res) => function __init() { return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; }; var __commonJS = (cb, mod) => function __require() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // ../../node_modules/.pnpm/tsup@8.5.0_postcss@8.5.6_typescript@5.9.2/node_modules/tsup/assets/cjs_shims.js var getImportMetaUrl, importMetaUrl; var init_cjs_shims = __esm({ "../../node_modules/.pnpm/tsup@8.5.0_postcss@8.5.6_typescript@5.9.2/node_modules/tsup/assets/cjs_shims.js"() { "use strict"; getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.src || new URL("main.js", document.baseURI).href; importMetaUrl = /* @__PURE__ */ getImportMetaUrl(); } }); // ../shared/dist/interfaces/debug-adapter.js var AdapterState, DebugFeature, AdapterErrorCode; var init_debug_adapter = __esm({ "../shared/dist/interfaces/debug-adapter.js"() { "use strict"; init_cjs_shims(); (function(AdapterState2) { AdapterState2["UNINITIALIZED"] = "uninitialized"; AdapterState2["INITIALIZING"] = "initializing"; AdapterState2["READY"] = "ready"; AdapterState2["CONNECTED"] = "connected"; AdapterState2["DEBUGGING"] = "debugging"; AdapterState2["DISCONNECTED"] = "disconnected"; AdapterState2["ERROR"] = "error"; })(AdapterState || (AdapterState = {})); (function(DebugFeature2) { DebugFeature2["CONDITIONAL_BREAKPOINTS"] = "conditionalBreakpoints"; DebugFeature2["FUNCTION_BREAKPOINTS"] = "functionBreakpoints"; DebugFeature2["EXCEPTION_BREAKPOINTS"] = "exceptionBreakpoints"; DebugFeature2["VARIABLE_PAGING"] = "variablePaging"; DebugFeature2["EVALUATE_FOR_HOVERS"] = "evaluateForHovers"; DebugFeature2["SET_VARIABLE"] = "setVariable"; DebugFeature2["SET_EXPRESSION"] = "setExpression"; DebugFeature2["DATA_BREAKPOINTS"] = "dataBreakpoints"; DebugFeature2["DISASSEMBLE_REQUEST"] = "disassembleRequest"; DebugFeature2["TERMINATE_THREADS_REQUEST"] = "terminateThreadsRequest"; DebugFeature2["DELAYED_STACK_TRACE_LOADING"] = "delayedStackTraceLoading"; DebugFeature2["LOADED_SOURCES_REQUEST"] = "loadedSourcesRequest"; DebugFeature2["LOG_POINTS"] = "logPoints"; DebugFeature2["TERMINATE_REQUEST"] = "terminateRequest"; DebugFeature2["RESTART_REQUEST"] = "restartRequest"; DebugFeature2["EXCEPTION_OPTIONS"] = "exceptionOptions"; DebugFeature2["EXCEPTION_INFO_REQUEST"] = "exceptionInfoRequest"; DebugFeature2["STEP_BACK"] = "stepBack"; DebugFeature2["REVERSE_DEBUGGING"] = "reverseDebugging"; DebugFeature2["STEP_IN_TARGETS_REQUEST"] = "stepInTargetsRequest"; })(DebugFeature || (DebugFeature = {})); (function(AdapterErrorCode2) { AdapterErrorCode2["ENVIRONMENT_INVALID"] = "ENVIRONMENT_INVALID"; AdapterErrorCode2["EXECUTABLE_NOT_FOUND"] = "EXECUTABLE_NOT_FOUND"; AdapterErrorCode2["ADAPTER_NOT_INSTALLED"] = "ADAPTER_NOT_INSTALLED"; AdapterErrorCode2["INCOMPATIBLE_VERSION"] = "INCOMPATIBLE_VERSION"; AdapterErrorCode2["CONNECTION_FAILED"] = "CONNECTION_FAILED"; AdapterErrorCode2["CONNECTION_TIMEOUT"] = "CONNECTION_TIMEOUT"; AdapterErrorCode2["CONNECTION_LOST"] = "CONNECTION_LOST"; AdapterErrorCode2["INVALID_RESPONSE"] = "INVALID_RESPONSE"; AdapterErrorCode2["UNSUPPORTED_OPERATION"] = "UNSUPPORTED_OPERATION"; AdapterErrorCode2["DEBUGGER_ERROR"] = "DEBUGGER_ERROR"; AdapterErrorCode2["SCRIPT_NOT_FOUND"] = "SCRIPT_NOT_FOUND"; AdapterErrorCode2["PERMISSION_DENIED"] = "PERMISSION_DENIED"; AdapterErrorCode2["UNKNOWN_ERROR"] = "UNKNOWN_ERROR"; })(AdapterErrorCode || (AdapterErrorCode = {})); } }); // ../shared/dist/interfaces/adapter-registry.js var init_adapter_registry = __esm({ "../shared/dist/interfaces/adapter-registry.js"() { "use strict"; init_cjs_shims(); } }); // ../shared/dist/models/index.js var DebugLanguage, SessionLifecycleState, ExecutionState, SessionState; var init_models = __esm({ "../shared/dist/models/index.js"() { "use strict"; init_cjs_shims(); (function(DebugLanguage2) { DebugLanguage2["PYTHON"] = "python"; DebugLanguage2["JAVASCRIPT"] = "javascript"; DebugLanguage2["RUST"] = "rust"; DebugLanguage2["MOCK"] = "mock"; })(DebugLanguage || (DebugLanguage = {})); (function(SessionLifecycleState2) { SessionLifecycleState2["CREATED"] = "created"; SessionLifecycleState2["ACTIVE"] = "active"; SessionLifecycleState2["TERMINATED"] = "terminated"; })(SessionLifecycleState || (SessionLifecycleState = {})); (function(ExecutionState2) { ExecutionState2["INITIALIZING"] = "initializing"; ExecutionState2["RUNNING"] = "running"; ExecutionState2["PAUSED"] = "paused"; ExecutionState2["TERMINATED"] = "terminated"; ExecutionState2["ERROR"] = "error"; })(ExecutionState || (ExecutionState = {})); (function(SessionState2) { SessionState2["CREATED"] = "created"; SessionState2["INITIALIZING"] = "initializing"; SessionState2["READY"] = "ready"; SessionState2["RUNNING"] = "running"; SessionState2["PAUSED"] = "paused"; SessionState2["STOPPED"] = "stopped"; SessionState2["ERROR"] = "error"; })(SessionState || (SessionState = {})); } }); // ../shared/dist/factories/adapter-factory.js var init_adapter_factory = __esm({ "../shared/dist/factories/adapter-factory.js"() { "use strict"; init_cjs_shims(); } }); // ../shared/dist/interfaces/adapter-policy.js var DefaultAdapterPolicy; var init_adapter_policy = __esm({ "../shared/dist/interfaces/adapter-policy.js"() { "use strict"; init_cjs_shims(); DefaultAdapterPolicy = { name: "default", supportsReverseStartDebugging: false, childSessionStrategy: "none", shouldDeferParentConfigDone: () => false, buildChildStartArgs: (pendingId) => { throw new Error(`DefaultAdapterPolicy is a placeholder and cannot start child sessions (pendingId=${pendingId}).`); }, isChildReadyEvent: () => false, getDapAdapterConfiguration: () => ({ type: "default" }), resolveExecutablePath: (providedPath) => providedPath, getDebuggerConfiguration: () => ({}), requiresCommandQueueing: () => false, shouldQueueCommand: () => ({ shouldQueue: false, shouldDefer: false, reason: "DefaultAdapterPolicy is inactive until a real adapter is selected" }), createInitialState: () => ({ initialized: false, configurationDone: false }), isInitialized: () => false, isConnected: () => false, matchesAdapter: () => false, getInitializationBehavior: () => ({}), getDapClientBehavior: () => ({}) }; } }); // ../shared/dist/interfaces/adapter-policy-js.js var JsDebugAdapterPolicy; var init_adapter_policy_js = __esm({ "../shared/dist/interfaces/adapter-policy-js.js"() { "use strict"; init_cjs_shims(); init_dist(); JsDebugAdapterPolicy = { name: "js-debug", supportsReverseStartDebugging: true, childSessionStrategy: "launchWithPendingTarget", shouldDeferParentConfigDone: () => true, buildChildStartArgs: (pendingId, parentConfig) => { const type = typeof parentConfig?.type === "string" ? parentConfig.type : "pwa-node"; return { command: "attach", args: { type, request: "attach", __pendingTargetId: pendingId, continueOnAttach: true // js-debug requires true to work properly } }; }, isChildReadyEvent: (evt) => { return evt?.event === "thread" || evt?.event === "stopped"; }, /** * Check if a stack frame is a Node.js internal frame */ isInternalFrame: (frame) => { const filePath = frame.file || ""; return filePath.includes("<node_internals>"); }, /** * Filter stack frames to optionally remove Node.js internals */ filterStackFrames: (frames, includeInternals) => { if (includeInternals) { return frames; } const filtered = frames.filter((frame) => !JsDebugAdapterPolicy.isInternalFrame(frame)); if (filtered.length === 0 && frames.length > 0) { return [frames[0]]; } return filtered; }, /** * Extract local variables for JavaScript, filtering out internals by default */ extractLocalVariables: (stackFrames, scopes, variables, includeSpecial = false) => { if (!stackFrames || stackFrames.length === 0) { return []; } const topFrame = stackFrames[0]; const frameScopes = scopes[topFrame.id]; if (!frameScopes || frameScopes.length === 0) { return []; } let localScope = frameScopes.find((scope) => scope.name === "Local" || scope.name === "Locals" || scope.name.startsWith("Local:") || scope.name.startsWith("Block:")); if (!localScope) { localScope = frameScopes.find((scope) => scope.name === "Script" || scope.name === "Module" || scope.name === "module" || scope.name.toLowerCase().includes("global")); } if (!localScope) { return []; } let localVars = variables[localScope.variablesReference] || []; if (!includeSpecial) { localVars = localVars.filter((v) => { const name = v.name; if (name === "this") { return false; } if (name === "__proto__" || name === "prototype") { return false; } if (name.startsWith("[[") && name.endsWith("]]")) { return false; } if (name.startsWith("$") || name.startsWith("_$")) { return false; } return true; }); } return localVars; }, /** * JavaScript uses various local scope names */ getLocalScopeName: () => { return ["Local", "Local:", "Block:", "Script", "Global"]; }, getDapAdapterConfiguration: () => { return { type: "pwa-node" // VS Code JavaScript/TypeScript debugger type }; }, resolveExecutablePath: (providedPath) => { if (providedPath) { return providedPath; } return "node"; }, getDebuggerConfiguration: () => { return { // JavaScript debugger configuration for js-debug/pwa-node requiresStrictHandshake: true, // js-debug requires strict initialization sequence skipConfigurationDone: false, supportsVariableType: true // JavaScript debugger supports variable type information }; }, isSessionReady: (state, options) => state === SessionState.PAUSED || !options.stopOnEntry && state === SessionState.RUNNING, /** * Perform JavaScript-specific handshake sequence for js-debug/pwa-node. * This includes the strict initialization sequence required by js-debug. */ performHandshake: async (context) => { const { proxyManager, sessionId, dapLaunchArgs, scriptPath, scriptArgs, breakpoints, launchConfig } = context; const pm = proxyManager; if (!pm || !pm.isRunning()) { console.warn(`[JsDebugAdapterPolicy] performHandshake skipped: proxy manager not running for session ${sessionId}`); return; } try { console.info(`[JsDebugAdapterPolicy] [JS] Sending 'initialize' request`); await pm.sendDapRequest("initialize", { clientID: "mcp", adapterID: "javascript", linesStartAt1: true, columnsStartAt1: true, pathFormat: "path", // CRITICAL: Tell js-debug we support multi-session for proper breakpoint handling supportsStartDebuggingRequest: true }); } catch (e) { console.warn(`[JsDebugAdapterPolicy] [JS] 'initialize' failed or deferred: ${e instanceof Error ? e.message : String(e)}`); } await new Promise((resolve2) => { let done = false; const timer = setTimeout(() => { if (done) return; done = true; console.warn(`[JsDebugAdapterPolicy] [JS] Timeout waiting for DAP 'initialized' event`); resolve2(); }, 1e4); const onHandler = (event) => { if (done) return; const eventName = typeof event === "string" ? event : event?.event; if (eventName === "initialized") { done = true; clearTimeout(timer); pm.removeListener("dap-event", onHandler); resolve2(); } }; pm.on("dap-event", onHandler); }); try { console.info(`[JsDebugAdapterPolicy] [JS] Sending 'setExceptionBreakpoints' []`); await pm.sendDapRequest("setExceptionBreakpoints", { filters: [] }); } catch (e) { console.warn(`[JsDebugAdapterPolicy] [JS] 'setExceptionBreakpoints' failed or unsupported: ${e instanceof Error ? e.message : String(e)}`); } try { const grouped = /* @__PURE__ */ new Map(); for (const bp of breakpoints.values()) { const breakpoint = bp; const arr = grouped.get(breakpoint.file) || []; arr.push({ line: breakpoint.line, condition: breakpoint.condition }); grouped.set(breakpoint.file, arr); } for (const [file, bps] of grouped) { console.info(`[JsDebugAdapterPolicy] [JS] Sending 'setBreakpoints' for ${file} (${bps.length})`); await pm.sendDapRequest("setBreakpoints", { source: { path: file }, breakpoints: bps }); } } catch (e) { console.warn(`[JsDebugAdapterPolicy] [JS] 'setBreakpoints' failed: ${e instanceof Error ? e.message : String(e)}`); } try { console.info(`[JsDebugAdapterPolicy] [JS] Sending 'configurationDone'`); await pm.sendDapRequest("configurationDone", {}); } catch (e) { console.warn(`[JsDebugAdapterPolicy] [JS] 'configurationDone' failed or deferred: ${e instanceof Error ? e.message : String(e)}`); } const a = dapLaunchArgs || {}; const baseLaunchConfig = launchConfig ? { ...launchConfig } : {}; const baseRecord = baseLaunchConfig; const getPortValue = (value) => typeof value === "number" && Number.isFinite(value) ? value : void 0; const type = typeof baseLaunchConfig.type === "string" ? baseLaunchConfig.type : typeof a.type === "string" ? a.type : "pwa-node"; const req = typeof baseLaunchConfig.request === "string" ? baseLaunchConfig.request : typeof a.request === "string" ? a.request : "launch"; const attachPort = getPortValue(baseRecord.attachSimplePort) ?? getPortValue(baseRecord.port) ?? getPortValue(a.attachSimplePort) ?? getPortValue(a.port); if (req === "attach" && typeof attachPort === "number" && attachPort > 0) { try { console.info(`[JsDebugAdapterPolicy] [JS] Sending 'attach' to ${attachPort} (address=127.0.0.1)`); await pm.sendDapRequest("attach", { type, request: "attach", address: "127.0.0.1", port: attachPort, continueOnAttach: true, attachExistingChildren: true, attachSimplePort: attachPort }); } catch (e) { console.warn(`[JsDebugAdapterPolicy] [JS] 'attach' failed: ${e instanceof Error ? e.message : String(e)}`); } } else { try { const path7 = await import("path"); if (typeof baseLaunchConfig.program !== "string" || !baseLaunchConfig.program.length) { baseLaunchConfig.program = scriptPath; } if ((!Array.isArray(baseLaunchConfig.args) || baseLaunchConfig.args.length === 0) && Array.isArray(scriptArgs) && scriptArgs.length > 0) { baseLaunchConfig.args = scriptArgs; } if (typeof baseLaunchConfig.cwd !== "string" || !baseLaunchConfig.cwd.length) { baseLaunchConfig.cwd = scriptPath ? path7.dirname(scriptPath) : process.cwd(); } if (typeof baseLaunchConfig.stopOnEntry !== "boolean" && typeof a?.stopOnEntry === "boolean") { baseLaunchConfig.stopOnEntry = a.stopOnEntry; } if (typeof baseLaunchConfig.justMyCode !== "boolean" && typeof a?.justMyCode === "boolean") { baseLaunchConfig.justMyCode = a.justMyCode; } if (typeof baseLaunchConfig.console !== "string") { baseLaunchConfig.console = "internalConsole"; } if (typeof baseLaunchConfig.outputCapture !== "string") { baseLaunchConfig.outputCapture = "std"; } if (typeof baseLaunchConfig.smartStep !== "boolean") { baseLaunchConfig.smartStep = true; } if (typeof baseLaunchConfig.pauseForSourceMap !== "boolean") { baseLaunchConfig.pauseForSourceMap = true; } if (typeof baseLaunchConfig.runtimeExecutable !== "string") { baseLaunchConfig.runtimeExecutable = process.execPath; } const finalLaunchArgs = { ...baseLaunchConfig, type, request: req }; if (typeof baseLaunchConfig.sourceMaps === "boolean") { finalLaunchArgs.sourceMaps = baseLaunchConfig.sourceMaps; } else if (typeof a.sourceMaps === "boolean") { finalLaunchArgs.sourceMaps = a.sourceMaps; } const resolvedOutFiles = Array.isArray(baseLaunchConfig.outFiles) && baseLaunchConfig.outFiles.length > 0 ? baseLaunchConfig.outFiles : Array.isArray(a.outFiles) && a.outFiles.length > 0 ? a.outFiles : void 0; if (resolvedOutFiles) { finalLaunchArgs.outFiles = resolvedOutFiles; } const resolvedSourcemapLocations = Array.isArray(baseLaunchConfig.resolveSourceMapLocations) ? baseLaunchConfig.resolveSourceMapLocations : Array.isArray(a.resolveSourceMapLocations) ? a.resolveSourceMapLocations : void 0; if (resolvedSourcemapLocations) { finalLaunchArgs.resolveSourceMapLocations = resolvedSourcemapLocations; } console.info(`[JsDebugAdapterPolicy] [JS] Sending 'launch' for program='${finalLaunchArgs.program}' cwd='${finalLaunchArgs.cwd}'`); await pm.sendDapRequest("launch", finalLaunchArgs); } catch (e) { console.warn(`[JsDebugAdapterPolicy] [JS] 'launch' failed: ${e instanceof Error ? e.message : String(e)}`); } } console.info(`[JsDebugAdapterPolicy] [JS] Handshake complete. Multi-session architecture now handling debugging.`); }, /** * JavaScript adapter requires command queueing for proper initialization */ requiresCommandQueueing: () => true, /** * Determine if a command should be queued based on JavaScript-specific state */ shouldQueueCommand: (command, state) => { const jsState = state; if (command === "initialize") { return { shouldQueue: false, shouldDefer: false }; } if (!jsState.initializeResponded) { return { shouldQueue: true, shouldDefer: false, reason: `Queuing '${command}' until 'initialize' response (JS adapter)` }; } const configCommands = /* @__PURE__ */ new Set([ "setBreakpoints", "setFunctionBreakpoints", "setExceptionBreakpoints", "setDataBreakpoints", "setInstructionBreakpoints", "configurationDone" ]); if (!jsState.initialized && configCommands.has(command)) { return { shouldQueue: true, shouldDefer: false, reason: `Queuing '${command}' until 'initialized' event (JS adapter)` }; } if ((command === "launch" || command === "attach") && !jsState.configurationDone) { return { shouldQueue: true, shouldDefer: true, // Signal that we need to inject configurationDone first reason: `JS: deferring '${command}' until configurationDone (strict order)` }; } return { shouldQueue: false, shouldDefer: false }; }, /** * Process queued commands in JavaScript-specific order */ processQueuedCommands: (commands) => { const typedCommands = commands; const isConfig = (cmd) => [ "setBreakpoints", "setFunctionBreakpoints", "setExceptionBreakpoints", "setDataBreakpoints", "setInstructionBreakpoints" ].includes(cmd); const configs = typedCommands.filter((p) => isConfig(p.dapCommand)); const configDone = typedCommands.filter((p) => p.dapCommand === "configurationDone"); const launches = typedCommands.filter((p) => p.dapCommand === "launch" || p.dapCommand === "attach"); const others = typedCommands.filter((p) => !isConfig(p.dapCommand) && p.dapCommand !== "configurationDone" && p.dapCommand !== "launch" && p.dapCommand !== "attach"); return [...configs, ...configDone, ...launches, ...others]; }, /** * Create initial state for JavaScript adapter */ createInitialState: () => { return { initialized: false, configurationDone: false, initializeResponded: false, startSent: false, pendingCommands: [] }; }, /** * Update state when a command is sent */ updateStateOnCommand: (command, _args, state) => { const jsState = state; if (command === "initialize") { } else if (command === "configurationDone") { jsState.configurationDone = true; } else if (command === "launch" || command === "attach") { jsState.startSent = true; } }, /** * Update state when a command response is received */ updateStateOnResponse: (command, _response, state) => { const jsState = state; if (command === "initialize") { jsState.initializeResponded = true; } }, /** * Update state when an event is received */ updateStateOnEvent: (event, _body, state) => { const jsState = state; if (event === "initialized") { jsState.initialized = true; } }, /** * Check if JavaScript adapter is initialized */ isInitialized: (state) => { const jsState = state; return jsState.initialized && jsState.initializeResponded; }, /** * Check if JavaScript adapter is connected */ isConnected: (state) => { const jsState = state; return jsState.initializeResponded; }, /** * Check if this policy applies to the given adapter command */ matchesAdapter: (adapterCommand) => { const commandStr = adapterCommand.command.toLowerCase(); const argsStr = adapterCommand.args.join(" ").toLowerCase(); return commandStr.includes("js-debug") || commandStr.includes("pwa-node") || commandStr.includes("vsDebugServer") || argsStr.includes("js-debug") || argsStr.includes("pwa-node") || argsStr.includes("vsDebugServer"); }, /** * JavaScript adapter has special initialization requirements */ getInitializationBehavior: () => { return { deferConfigDone: true, // Must defer configurationDone until after launch/attach addRuntimeExecutable: true, // Needs to add runtimeExecutable to launch args trackInitializeResponse: true, // Must track initialize response separately requiresInitialStop: true // Must ensure initial stop after launch/attach }; }, /** * JavaScript-specific DAP client behaviors */ getDapClientBehavior: () => { return { // Handle reverse startDebugging requests handleReverseRequest: async (request, context) => { if (request.command === "startDebugging") { const args = request?.arguments ?? {}; const cfg = args?.configuration ?? {}; const pendingId = cfg?.__pendingTargetId; context.sendResponse(request, {}); if (pendingId && typeof pendingId === "string") { if (!context.adoptedTargets.has(pendingId)) { context.adoptedTargets.add(pendingId); return { handled: true, createChildSession: true, childConfig: { host: cfg.host || "localhost", port: cfg.port || 9229, pendingId, parentConfig: cfg } }; } } return { handled: true }; } else if (request.command === "runInTerminal") { context.sendResponse(request, {}); return { handled: true }; } return { handled: false }; }, // Commands that should be routed to child sessions childRoutedCommands: /* @__PURE__ */ new Set([ "threads", "pause", "continue", "next", "stepIn", "stepOut", "stackTrace", "scopes", "variables", "evaluate", "loadedSources", "source", "setVariable", "setExpression", "restart", "disconnect", "terminate", "goto", "restartFrame", "stepBack", "reverseContinue" ]), // JavaScript-specific child session behaviors mirrorBreakpointsToChild: true, deferParentConfigDone: true, pauseAfterChildAttach: true, stackTraceRequiresChild: true, // Normalize adapter ID for initialize normalizeAdapterId: (requestedId) => { if (requestedId.toLowerCase() === "javascript") { return "pwa-node"; } return requestedId; }, // Timeouts childInitTimeout: 12e3, suppressPostAttachConfigDone: false // Child session needs configurationDone }; }, /** * Get the configuration for spawning the JavaScript debug adapter (js-debug/pwa-node) */ getAdapterSpawnConfig: (payload) => { if (payload.adapterCommand) { return { command: payload.adapterCommand.command, args: payload.adapterCommand.args, host: payload.adapterHost, port: payload.adapterPort, logDir: payload.logDir, env: payload.adapterCommand.env }; } console.warn("[JsDebugAdapterPolicy] No adapter command provided - JavaScript debugging may not work correctly"); return void 0; } }; } }); // ../shared/dist/interfaces/adapter-policy-python.js var PythonAdapterPolicy; var init_adapter_policy_python = __esm({ "../shared/dist/interfaces/adapter-policy-python.js"() { "use strict"; init_cjs_shims(); init_dist(); PythonAdapterPolicy = { name: "python", supportsReverseStartDebugging: false, childSessionStrategy: "none", shouldDeferParentConfigDone: () => false, buildChildStartArgs: () => { throw new Error("PythonAdapterPolicy does not support child sessions"); }, isChildReadyEvent: (evt) => { return evt?.event === "initialized"; }, /** * Extract local variables for Python, filtering out special variables by default */ extractLocalVariables: (stackFrames, scopes, variables, includeSpecial = false) => { if (!stackFrames || stackFrames.length === 0) { return []; } const topFrame = stackFrames[0]; const frameScopes = scopes[topFrame.id]; if (!frameScopes || frameScopes.length === 0) { return []; } const localScope = frameScopes.find((scope) => scope.name === "Locals" || scope.name === "Local"); if (!localScope) { return []; } let localVars = variables[localScope.variablesReference] || []; if (!includeSpecial) { localVars = localVars.filter((v) => { const name = v.name; if (name === "special variables" || name === "function variables") { return false; } if (name.startsWith("__") && name.endsWith("__")) { const keepDunders = ["__name__", "__file__", "__doc__"]; return keepDunders.includes(name); } if (name.startsWith("_pydev") || name === "_") { return false; } return true; }); } return localVars; }, /** * Python uses "Locals" for local variables scope */ getLocalScopeName: () => { return ["Locals"]; }, getDapAdapterConfiguration: () => { return { type: "debugpy" // Python Debug Adapter Protocol type }; }, resolveExecutablePath: (providedPath) => { if (providedPath) { return providedPath; } if (process.env.PYTHON_PATH) { return process.env.PYTHON_PATH; } return process.platform === "win32" ? "python" : "python3"; }, getDebuggerConfiguration: () => { return { // Python debugger configuration requiresStrictHandshake: false, skipConfigurationDone: false, supportsVariableType: true // Python debugpy supports variable type information }; }, isSessionReady: (state) => state === SessionState.PAUSED, /** * Validate that a Python command is a real Python executable, not a Windows Store alias. * This validation is critical on Windows to avoid false positives. */ validateExecutable: async (pythonCmd) => { const { spawn: spawn2 } = await import("child_process"); return new Promise((resolve2) => { const child = spawn2(pythonCmd, ["-c", "import sys; sys.exit(0)"], { stdio: ["ignore", "ignore", "pipe"] }); let stderrData = ""; child.stderr?.on("data", (data) => { stderrData += data.toString(); }); child.on("error", () => resolve2(false)); child.on("exit", (code) => { const storeAlias = code === 9009 || stderrData.includes("Microsoft Store") || stderrData.includes("Windows Store") || stderrData.includes("AppData\\Local\\Microsoft\\WindowsApps"); if (storeAlias) { resolve2(false); } else { resolve2(code === 0); } }); }); }, /** * Python adapter doesn't require command queueing */ requiresCommandQueueing: () => false, /** * Python doesn't need to queue commands */ shouldQueueCommand: () => { return { shouldQueue: false, shouldDefer: false, reason: "Python adapter does not queue commands" }; }, /** * Create initial state for Python adapter */ createInitialState: () => { return { initialized: false, configurationDone: false }; }, /** * Update state when a command is sent */ updateStateOnCommand: (command, _args, state) => { if (command === "configurationDone") { state.configurationDone = true; } }, /** * Update state when an event is received */ updateStateOnEvent: (event, _body, state) => { if (event === "initialized") { state.initialized = true; } }, /** * Check if Python adapter is initialized */ isInitialized: (state) => { return state.initialized; }, /** * Check if Python adapter is connected */ isConnected: (state) => { return state.initialized; }, /** * Check if this policy applies to the given adapter command */ matchesAdapter: (adapterCommand) => { const commandStr = adapterCommand.command.toLowerCase(); const argsStr = adapterCommand.args.join(" ").toLowerCase(); return commandStr.includes("debugpy") || commandStr.includes("python") || argsStr.includes("debugpy") || argsStr.includes("-m debugpy"); }, /** * Python adapter has no special initialization requirements */ getInitializationBehavior: () => { return {}; }, /** * Python DAP client behaviors - minimal since Python doesn't use child sessions */ getDapClientBehavior: () => { return { // Python doesn't handle reverse requests handleReverseRequest: async (request, context) => { if (request.command === "runInTerminal") { context.sendResponse(request, {}); return { handled: true }; } return { handled: false }; }, // No child session routing needed childRoutedCommands: void 0, // Python-specific behaviors mirrorBreakpointsToChild: false, deferParentConfigDone: false, pauseAfterChildAttach: false, // No adapter ID normalization needed normalizeAdapterId: void 0, // Standard timeouts childInitTimeout: 5e3, suppressPostAttachConfigDone: false }; }, /** * Get the configuration for spawning the Python debug adapter (debugpy) */ getAdapterSpawnConfig: (payload) => { if (payload.adapterCommand) { return { command: payload.adapterCommand.command, args: payload.adapterCommand.args, host: payload.adapterHost, port: payload.adapterPort, logDir: payload.logDir, env: payload.adapterCommand.env }; } const pythonPath = payload.executablePath || "python"; return { command: pythonPath, args: [ "-m", "debugpy.adapter", "--host", payload.adapterHost, "--port", String(payload.adapterPort), "--log-dir", payload.logDir ], host: payload.adapterHost, port: payload.adapterPort, logDir: payload.logDir }; } }; } }); // ../shared/dist/interfaces/adapter-policy-rust.js var path, RustAdapterPolicy; var init_adapter_policy_rust = __esm({ "../shared/dist/interfaces/adapter-policy-rust.js"() { "use strict"; init_cjs_shims(); path = __toESM(require("path"), 1); init_dist(); RustAdapterPolicy = { name: "rust", supportsReverseStartDebugging: false, childSessionStrategy: "none", shouldDeferParentConfigDone: () => false, buildChildStartArgs: () => { throw new Error("RustAdapterPolicy does not support child sessions"); }, isChildReadyEvent: (evt) => { return evt?.event === "initialized"; }, /** * Extract local variables for Rust, filtering out special variables by default */ extractLocalVariables: (stackFrames, scopes, variables, includeSpecial = false) => { if (!stackFrames || stackFrames.length === 0) { return []; } const topFrame = stackFrames[0]; const frameScopes = scopes[topFrame.id]; if (!frameScopes || frameScopes.length === 0) { return []; } const localScope = frameScopes.find((scope) => scope.name === "Local" || scope.name === "Locals"); if (!localScope) { return []; } let localVars = variables[localScope.variablesReference] || []; if (!includeSpecial) { localVars = localVars.filter((v) => { const name = v.name; if (name.startsWith("$") || name.startsWith("__")) { return false; } if (name.startsWith("_lldb") || name.startsWith("_debug")) { return false; } return true; }); } return localVars; }, /** * Rust/CodeLLDB uses "Local" or "Locals" for local variables scope */ getLocalScopeName: () => { return ["Local", "Locals"]; }, getDapAdapterConfiguration: () => { return { type: "lldb" // CodeLLDB adapter type }; }, resolveExecutablePath: (providedPath) => { if (providedPath) { return providedPath; } if (process.env.CARGO_PATH) { return process.env.CARGO_PATH; } return void 0; }, getDebuggerConfiguration: () => { return { // CodeLLDB debugger configuration requiresStrictHandshake: false, skipConfigurationDone: false, supportsVariableType: true, // CodeLLDB supports variable type information supportsValueFormat: true, // CodeLLDB supports value formatting supportsMemoryReferences: true // CodeLLDB supports memory references }; }, isSessionReady: (state) => state === SessionState.PAUSED, /** * Validate that the CodeLLDB adapter is available and executable */ validateExecutable: async (codelldbPath) => { const fs4 = await import("fs/promises"); const { spawn: spawn2 } = await import("child_process"); try { await fs4.access(codelldbPath, fs4.constants.F_OK); return new Promise((resolve2) => { const child = spawn2(codelldbPath, ["--version"], { stdio: ["ignore", "pipe", "pipe"] }); let output = ""; child.stdout?.on("data", (data) => { output += data.toString(); }); child.on("error", () => resolve2(false)); child.on("exit", (code) => { resolve2(code === 0 && output.includes("codelldb")); }); }); } catch { return false; } }, /** * Rust adapter doesn't require command queueing */ requiresCommandQueueing: () => false, /** * Rust doesn't need to queue commands */ shouldQueueCommand: () => { return { shouldQueue: false, shouldDefer: false, reason: "Rust/CodeLLDB adapter does not queue commands" }; }, /** * Create initial state for Rust adapter */ createInitialState: () => { return { initialized: false, configurationDone: false }; }, /** * Update state when a command is sent */ updateStateOnCommand: (command, _args, state) => { if (command === "configurationDone") { state.configurationDone = true; } }, /** * Update state when an event is received */ updateStateOnEvent: (event, _body, state) => { if (event === "initialized") { state.initialized = true; } }, /** * Check if Rust adapter is initialized */ isInitialized: (state) => { return state.initialized; }, /** * Check if Rust adapter is connected */ isConnected: (state) => { return state.initialized; }, /** * Check if this policy applies to the given adapter command */ matchesAdapter: (adapterCommand) => { const commandStr = adapterCommand.command.toLowerCase(); const argsStr = adapterCommand.args.join(" ").toLowerCase(); return commandStr.includes("codelldb") || commandStr.includes("lldb-server") || argsStr.includes("codelldb") || argsStr.includes("lldb"); }, /** * Rust adapter has no special initialization requirements */ getInitializationBehavior: () => { return {}; }, /** * Rust DAP client behaviors - minimal since Rust doesn't use child sessions */ getDapClientBehavior: () => { return { // Rust doesn't handle reverse requests handleReverseRequest: async (request, context) => { if (request.command === "runInTerminal") { context.sendResponse(request, {}); return { handled: true }; } return { handled: false }; }, // No child session routing needed childRoutedCommands: void 0, // Rust-specific behaviors mirrorBreakpointsToChild: false, deferParentConfigDone: false, pauseAfterChildAttach: false, // No adapter ID normalization needed normalizeAdapterId: void 0, // Standard timeouts childInitTimeout: 5e3, suppressPostAttachConfigDone: false }; }, /** * Get the configuration for spawning the Rust debug adapter (CodeLLDB) */ getAdapterSpawnConfig: (payload) => { if (payload.adapterCommand) { return { command: payload.adapterCommand.command, args: payload.adapterCommand.args, host: payload.adapterHost, port: payload.adapterPort, logDir: payload.logDir, env: payload.adapterCommand.env }; } const platform = process.platform; const arch = process.arch; let platformDir = ""; if (platform === "win32") { platformDir = "win32-x64"; } else if (platform === "darwin") { platformDir = arch === "arm64" ? "darwin-arm64" : "darwin-x64"; } else if (platform === "linux") { platformDir = arch === "arm64" ? "linux-arm64" : "linux-x64"; } const codelldbPath = payload.executablePath || path.resolve(process.cwd(), "packages", "adapter-rust", "vendor", "codelldb", platformDir, "adapter", `codelldb${platform === "win32" ? ".exe" : ""}`); return { command: codelldbPath, args: [ "--port", String(payload.adapterPort) ], host: payload.adapterHost, port: payload.adapterPort, logDir: payload.logDir, env: { ...process.env, // Windows specific: enable native PDB reader ...platform === "win32" ? { LLDB_USE_NATIVE_PDB_READER: "1" } : {} } }; } }; } }); // ../shared/dist/interfaces/adapter-policy-mock.js var MockAdapterPolicy; var init_adapter_policy_mock = __esm({ "../shared/dist/interfaces/adapter-policy-mock.js"() { "use strict"; init_cjs_shims(); MockAdapterPolicy = { name: "mock", supportsReverseStartDebugging: false, childSessionStrategy: "none", shouldDeferParentConfigDone: () => false, buildChildStartArgs: () => { throw new Error("MockAdapterPolicy does not support child sessions"); }, isChildReadyEvent: (evt) => { return evt?.event === "initialized"; }, /** * Mock adapter doesn't need stack frame filtering */ filterStackFrames: (frames) => { return frames; }, /** * Extract local variables for mock adapter (simple implementation) */ extractLocalVariables: (stackFrames, scopes, variables) => { if (!stackFrames || stackFrames.length === 0) { return []; } const topFrame = stackFrames[0]; const frameScopes = scopes[topFrame.id]; if (!frameScopes || frameScopes.length === 0) { return []; } const localScope = frameScopes[0]; if (!localScope) { return []; } return variables[localScope.variablesReference] || []; }, /** * Mock adapter uses simple scope names */ getLocalScopeName: () => { return ["Local", "Locals"]; }, getDapAdapterConfiguration: () => { return { type: "mock" // Mock adapter type for testing }; }, resolveExecutablePath: (providedPath) => { return providedPath || "mock"; }, getDebuggerConfiguration: () => { return { // Mock adapter configuration for testing requiresStrictHandshake: false, skipConfigurationDone: false, supportsVariableType: false // Mock adapter has simple variable support }; }, /** * Mock adapter doesn't require command queueing */ requiresCommandQueueing: () => false, /** * Mock adapter doesn't queue commands */ shouldQueueCommand: () => { return { shouldQueue: false, shouldDefer: false, reason: "Mock adapter does not queue commands" }; }, /** * Create initial state for mock adapter */ createInitialState: () => { return { initialized: false, configurationDone: false }; }, /** * Update state when a command is sent */ updateStateOnCommand: (command, _args, state) => { if (command === "configurationDone") { state.configurationDone = true; } }, /** * Update state when an event is received */ updateStateOnEvent: (event, _body, state) => { if (event === "initialized") { state.initialized = true; } }, /** * Check if mock adapter is initialized */ isInitialized: (state) => { return state.initialized; }, /** * Check if mock adapter is connected */ isConnected: (state) => { return state.initialized; }, /** * Check if this policy applies to the given adapter command */ matchesAdapter: (adapterCommand) => { const commandStr = adapterCommand.command.toLowerCase(); const argsStr = adapterCommand.args.join(" ").toLowerCase(); return commandStr.includes("mock-adapter") || argsStr.includes("mock-adapter"); }, /** * Mock adapter has no special initialization requirements */ getInitializationBehavior: () => { return {}; }, /** * Mock DAP client behaviors - minimal for testing */ getDapClientBehavior: () => { return { // Mock doesn't handle reverse requests handleReverseRequest: void 0, // No child session routing needed for mock childRoutedCommands: void 0, // Mock-specific behaviors (all disabled) mirrorBreakpointsToChild: false, deferParentConfigDone: false, pauseAfterChildAttach: false, // No adapter ID normalization needed normalizeAdapterId: void 0, // Standard timeouts childInitTimeout: 1e3, // Shorter for testing suppressPostAttachConfigDone: false }; }, /** * Get the configuration for spawning the mock debug adapter (for testing)