diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 00000000000..8bc6c565f3e
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,30 @@
+{
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Debug Gateway",
+ "type": "node",
+ "request": "launch",
+ "runtimeArgs": ["openclaw.mjs", "gateway", "run"],
+ "console": "integratedTerminal",
+ "skipFiles": ["/**", "node_modules/**"],
+ "outFiles": ["${workspaceFolder}/dist/**/*.js"],
+ "sourceMaps": true,
+ "smartStep": true,
+ "internalConsoleOptions": "openOnSessionStart"
+ },
+ {
+ "name": "Rebuild and Debug Gateway",
+ "type": "node",
+ "request": "launch",
+ "runtimeExecutable": "pnpm",
+ "runtimeArgs": ["run", "openclaw", "--", "gateway", "run"],
+ "console": "integratedTerminal",
+ "skipFiles": ["/**", "node_modules/**"],
+ "outFiles": ["${workspaceFolder}/dist/**/*.js"],
+ "sourceMaps": true,
+ "smartStep": true,
+ "internalConsoleOptions": "openOnSessionStart"
+ }
+ ]
+}
diff --git a/README.md b/README.md
index 767f4bc2141..392e23a7b61 100644
--- a/README.md
+++ b/README.md
@@ -555,5 +555,5 @@ Thanks to all clawtributors:
-
+
diff --git a/docs/help/debugging.md b/docs/help/debugging.md
index 61539ec39a3..0aade9ae4b0 100644
--- a/docs/help/debugging.md
+++ b/docs/help/debugging.md
@@ -160,3 +160,37 @@ Default file:
- Raw stream logs can include full prompts, tool output, and user data.
- Keep logs local and delete them after debugging.
- If you share logs, scrub secrets and PII first.
+
+## Debugging in VSCode
+
+### Overview
+
+The OpenClaw project uses tsdown to bundle TypeScript code into JavaScript for distribution. Source maps are required to enable debugging in VSCode-based IDEs because many of the generated files end up with hashed names as part of scoped builds. Generating source maps is a single change before build time and the included launch.json configurations target the Gateway service, but can be adapted quickly for other purposes.
+
+### Setup
+
+#### Included Configurations
+
+1. **Debug Gateway** - Debugs the Gateway service of a pre-existing build
+2. **Rebuild and Debug Gateway** - Debugs the Gateway service after creating a new build
+
+#### Using the Debugger
+
+1. First, build the project with source map generation enabled:
+ - Set OUTPUT_SOURCE_MAPS to true in tsdown.config.ts
+ - Run rm -rf dist/ && pnpm build to rebuild the project
+
+2. Start debugging:
+ - Open the Run and Debug panel from the Activity Bar or press Ctrl+Shift+D
+ - Select one of the debug configurations from the dropdown
+ - Press the "Start Debugging" button next to the dropdown or press F5
+
+3. Set breakpoints in your TypeScript source files (under `src/` directory)
+ - The debugger will correctly map breakpoints to the compiled JavaScript via source maps
+ - You'll be able to inspect variables, step through code, etc.
+
+#### Additional Notes
+
+- If using the "Rebuild and Debug Gateway" option, restarting the debugger will also rebuild the project with any updated code
+- Change the `launch.json` settings for `runtimeArgs` to debug other sections of the project
+- If you need to use the built OpenClaw CLI for other tasks (i.e. `dashboard --no-open` if your debug session spawns a new auth token) you can run it in another shell as `node ./openclaw.mjs` or a shell alias like `alias openclaw-build="node $(pwd)/openclaw.mjs"`
diff --git a/tsdown.config.ts b/tsdown.config.ts
index 1806debd474..38cd0b7e0c8 100644
--- a/tsdown.config.ts
+++ b/tsdown.config.ts
@@ -3,6 +3,7 @@ import { defineConfig } from "tsdown";
const env = {
NODE_ENV: "production",
};
+const OUTPUT_SOURCE_MAPS = false;
function buildInputOptions(options: { onLog?: unknown; [key: string]: unknown }) {
if (process.env.OPENCLAW_BUILD_VERBOSE === "1") {
@@ -36,6 +37,7 @@ function nodeBuildConfig(config: Record) {
env,
fixedExtension: false,
platform: "node",
+ sourcemap: OUTPUT_SOURCE_MAPS,
inputOptions: buildInputOptions,
};
}