Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ This changelog records changes to stable releases since 1.50.2. "TBA" changes he

## 1.105 (September 2025)

- feat: add `jsdbg` command for debugging Node.js from any terminal
- fix: slow sourcemap parsing for minified code ([#2265](https://github.com/microsoft/vscode-js-debug/issues/2265))
- fix: assorted race conditions on dwarf and breakpoint initialization

Expand Down
1 change: 1 addition & 0 deletions OPTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -437,3 +437,4 @@
"!**/node_modules/**"
]</pre></code><h4>webRoot</h4><p>This specifies the workspace absolute path to the webserver root. Used to resolve paths like <code>/app.js</code> to files on disk. Shorthand for a pathMapping for &quot;/&quot;</p>
<h5>Default value:</h4><pre><code>"${workspaceFolder}"</pre></code></details>

10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,16 @@ You can debug any Node.js process you run in the terminal with Auto Attach. If a

Once enabled, you can toggle Auto Attach by clicking the `Auto Attach: On/Off` button in the status bar on the bottom of your screen. You can also create a one-off terminal for debugging via the `Debug: Create JavaScript Debug Terminal` command.

Alternatively, you can use the `jsdbg` command in any terminal (with shell integration enabled) to quickly debug a Node.js command without switching to a JavaScript Debug Terminal:

```bash
jsdbg node myScript.js
jsdbg npm start
jsdbg yarn test
```

When you run `jsdbg <command>`, a new JavaScript Debug Terminal will be created with your command, allowing you to debug immediately.

### Profiling Support

You can capture and view performance profiles natively in VS Code, by clicking on the ⚪ button in the Call Stack view, or through the `Debug: Take Performance Profile` command. The profile information collected through VS Code is sourcemap-aware.
Expand Down
2 changes: 2 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { debugNpmScript } from './ui/debugNpmScript';
import { DebugSessionTracker } from './ui/debugSessionTracker';
import { registerDebugTerminalUI } from './ui/debugTerminalUI';
import { ExtensionApiFactory } from './ui/extensionApi';
import { registerJsdbgCommand } from './ui/jsdbgCommand';
import { attachProcess, pickProcess } from './ui/processPicker';
import { registerProfilingCommand } from './ui/profiling';
import { registerRequestCDPProxy } from './ui/requestCDPProxy';
Expand Down Expand Up @@ -104,6 +105,7 @@ export function activate(context: vscode.ExtensionContext): IExports {
registerCompanionBrowserLaunch(context);
registerCustomBreakpointsUI(context, debugSessionTracker);
registerDebugTerminalUI(context, services.get(DelegateLauncherFactory), services);
registerJsdbgCommand(context);
registerProfilingCommand(context, services);
registerAutoAttach(context, services.get(DelegateLauncherFactory), services);
registerRevealPage(context, debugSessionTracker);
Expand Down
82 changes: 82 additions & 0 deletions src/ui/jsdbgCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*---------------------------------------------------------
* Copyright (C) Microsoft Corporation. All rights reserved.
*--------------------------------------------------------*/

import * as vscode from 'vscode';
import { Commands } from '../common/contributionUtils';

/**
* Registers the jsdbg command terminal integration.
* This allows users to run `jsdbg node myScript.js` in any terminal
* to start a debug session, similar to the JavaScript Debug Terminal.
*/
export function registerJsdbgCommand(context: vscode.ExtensionContext) {
// Listen for command executions in all terminals
context.subscriptions.push(
vscode.window.onDidStartTerminalShellExecution(async event => {
const commandLine = event.execution.commandLine;
if (!commandLine || typeof commandLine.value !== 'string') {
return;
}

const command = commandLine.value.trim();

// Check if the command starts with jsdbg (case-sensitive)
// Match "jsdbg " or "jsdbg" followed by whitespace
const jsdbgMatch = command.match(/^jsdbg\s+(.+)$/);
if (jsdbgMatch) {
// Extract the actual command to debug
const actualCommand = jsdbgMatch[1].trim();

if (!actualCommand) {
vscode.window.showErrorMessage('Usage: jsdbg <command>\n\nExample: jsdbg node myScript.js');
return;
}

try {
// Get the current working directory from the terminal
const cwd = await getTerminalCwd(event.terminal);

// Create a JavaScript Debug Terminal with the command
await vscode.commands.executeCommand(
Commands.CreateDebuggerTerminal,
actualCommand,
cwd ? vscode.workspace.getWorkspaceFolder(vscode.Uri.file(cwd)) : undefined,
cwd ? { cwd } : undefined
);
} catch (error) {
vscode.window.showErrorMessage(
`Failed to create debug terminal: ${error instanceof Error ? error.message : String(error)}`
);
}
} else if (command === 'jsdbg') {
// Handle the case where jsdbg is run without arguments
vscode.window.showInformationMessage(
'Usage: jsdbg <command>\n\nExample: jsdbg node myScript.js',
'Learn More'
).then(selection => {
if (selection === 'Learn More') {
vscode.env.openExternal(vscode.Uri.parse(
'https://code.visualstudio.com/docs/nodejs/nodejs-debugging'
));
}
});
}
})
);
}

/**
* Attempts to get the current working directory of a terminal.
*/
async function getTerminalCwd(terminal: vscode.Terminal): Promise<string | undefined> {
// Try to get the CWD from shell integration
const shellIntegration = terminal.shellIntegration;
if (shellIntegration && shellIntegration.cwd) {
return shellIntegration.cwd.fsPath;
}

// Fallback to workspace folder
const folders = vscode.workspace.workspaceFolders;
return folders?.[0]?.uri.fsPath;
}