debug-run 0.1.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.prettierignore +4 -0
- package/dist/index.cjs +219 -182
- package/package.json +13 -3
package/.prettierignore
ADDED
package/dist/index.cjs
CHANGED
|
@@ -961,7 +961,7 @@ var require_command = __commonJS({
|
|
|
961
961
|
var EventEmitter5 = require("node:events").EventEmitter;
|
|
962
962
|
var childProcess = require("node:child_process");
|
|
963
963
|
var path12 = require("node:path");
|
|
964
|
-
var
|
|
964
|
+
var fs3 = require("node:fs");
|
|
965
965
|
var process2 = require("node:process");
|
|
966
966
|
var { Argument: Argument2, humanReadableArgName } = require_argument();
|
|
967
967
|
var { CommanderError: CommanderError2 } = require_error();
|
|
@@ -1894,10 +1894,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1894
1894
|
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
1895
1895
|
function findFile(baseDir, baseName) {
|
|
1896
1896
|
const localBin = path12.resolve(baseDir, baseName);
|
|
1897
|
-
if (
|
|
1897
|
+
if (fs3.existsSync(localBin)) return localBin;
|
|
1898
1898
|
if (sourceExt.includes(path12.extname(baseName))) return void 0;
|
|
1899
1899
|
const foundExt = sourceExt.find(
|
|
1900
|
-
(ext) =>
|
|
1900
|
+
(ext) => fs3.existsSync(`${localBin}${ext}`)
|
|
1901
1901
|
);
|
|
1902
1902
|
if (foundExt) return `${localBin}${foundExt}`;
|
|
1903
1903
|
return void 0;
|
|
@@ -1909,7 +1909,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1909
1909
|
if (this._scriptPath) {
|
|
1910
1910
|
let resolvedScriptPath;
|
|
1911
1911
|
try {
|
|
1912
|
-
resolvedScriptPath =
|
|
1912
|
+
resolvedScriptPath = fs3.realpathSync(this._scriptPath);
|
|
1913
1913
|
} catch (err) {
|
|
1914
1914
|
resolvedScriptPath = this._scriptPath;
|
|
1915
1915
|
}
|
|
@@ -3021,7 +3021,7 @@ var require_commander = __commonJS({
|
|
|
3021
3021
|
});
|
|
3022
3022
|
|
|
3023
3023
|
// src/cli.ts
|
|
3024
|
-
var
|
|
3024
|
+
var fs2 = __toESM(require("node:fs"), 1);
|
|
3025
3025
|
|
|
3026
3026
|
// node_modules/commander/esm.mjs
|
|
3027
3027
|
var import_index = __toESM(require_commander(), 1);
|
|
@@ -3315,9 +3315,7 @@ function findVsdbg() {
|
|
|
3315
3315
|
path3.join(csharpExt, ".debugger", vsdbgDir, "vsdbg.exe")
|
|
3316
3316
|
);
|
|
3317
3317
|
}
|
|
3318
|
-
possiblePaths.push(
|
|
3319
|
-
path3.join(csharpExt, "debugAdapters", "vsdbg", "vsdbg")
|
|
3320
|
-
);
|
|
3318
|
+
possiblePaths.push(path3.join(csharpExt, "debugAdapters", "vsdbg", "vsdbg"));
|
|
3321
3319
|
for (const p of possiblePaths) {
|
|
3322
3320
|
if ((0, import_node_fs2.existsSync)(p)) {
|
|
3323
3321
|
return p;
|
|
@@ -3471,10 +3469,7 @@ Or install the C# Dev Kit extension for additional features.
|
|
|
3471
3469
|
// (testhost runs in optimized mode, breakpoints won't hit otherwise)
|
|
3472
3470
|
justMyCode: false
|
|
3473
3471
|
}),
|
|
3474
|
-
exceptionFilters: [
|
|
3475
|
-
"all",
|
|
3476
|
-
"user-unhandled"
|
|
3477
|
-
]
|
|
3472
|
+
exceptionFilters: ["all", "user-unhandled"]
|
|
3478
3473
|
};
|
|
3479
3474
|
|
|
3480
3475
|
// src/adapters/debugpy.ts
|
|
@@ -3690,6 +3685,24 @@ Alternative options:
|
|
|
3690
3685
|
|
|
3691
3686
|
// src/adapters/lldb.ts
|
|
3692
3687
|
var path7 = __toESM(require("node:path"), 1);
|
|
3688
|
+
var fs = __toESM(require("node:fs"), 1);
|
|
3689
|
+
function findHomebrewLLDB() {
|
|
3690
|
+
if (process.platform !== "darwin") {
|
|
3691
|
+
return null;
|
|
3692
|
+
}
|
|
3693
|
+
const homebrewPaths = [
|
|
3694
|
+
"/opt/homebrew/opt/llvm/bin/lldb-dap",
|
|
3695
|
+
// Apple Silicon
|
|
3696
|
+
"/usr/local/opt/llvm/bin/lldb-dap"
|
|
3697
|
+
// Intel Mac
|
|
3698
|
+
];
|
|
3699
|
+
for (const p of homebrewPaths) {
|
|
3700
|
+
if (fs.existsSync(p)) {
|
|
3701
|
+
return p;
|
|
3702
|
+
}
|
|
3703
|
+
}
|
|
3704
|
+
return null;
|
|
3705
|
+
}
|
|
3693
3706
|
var cachedPath4 = null;
|
|
3694
3707
|
var cachedType2 = null;
|
|
3695
3708
|
var lldbAdapter = {
|
|
@@ -3717,6 +3730,12 @@ var lldbAdapter = {
|
|
|
3717
3730
|
cachedType2 = "lldb-dap";
|
|
3718
3731
|
return lldbVscode;
|
|
3719
3732
|
}
|
|
3733
|
+
const homebrewLldb = findHomebrewLLDB();
|
|
3734
|
+
if (homebrewLldb) {
|
|
3735
|
+
cachedPath4 = homebrewLldb;
|
|
3736
|
+
cachedType2 = "lldb-dap";
|
|
3737
|
+
return homebrewLldb;
|
|
3738
|
+
}
|
|
3720
3739
|
const codeLldbPath = findCodeLLDB();
|
|
3721
3740
|
if (codeLldbPath) {
|
|
3722
3741
|
cachedPath4 = codeLldbPath;
|
|
@@ -3730,18 +3749,21 @@ LLDB debugger not found.
|
|
|
3730
3749
|
|
|
3731
3750
|
Options:
|
|
3732
3751
|
|
|
3733
|
-
1. Install LLVM
|
|
3734
|
-
|
|
3735
|
-
-
|
|
3736
|
-
- Fedora: dnf install lldb
|
|
3737
|
-
- The lldb-dap binary should be in your PATH
|
|
3752
|
+
1. Install LLVM via Homebrew (macOS, recommended):
|
|
3753
|
+
brew install llvm
|
|
3754
|
+
(debug-run auto-detects Homebrew LLVM, no PATH changes needed)
|
|
3738
3755
|
|
|
3739
3756
|
2. Install CodeLLDB VS Code extension:
|
|
3740
3757
|
- Open VS Code
|
|
3741
3758
|
- Install "CodeLLDB" extension (vadimcn.vscode-lldb)
|
|
3742
3759
|
- debug-run will use the bundled adapter
|
|
3743
3760
|
|
|
3744
|
-
3.
|
|
3761
|
+
3. Install LLVM system-wide:
|
|
3762
|
+
- Ubuntu/Debian: apt install lldb llvm
|
|
3763
|
+
- Fedora: dnf install lldb llvm
|
|
3764
|
+
- Ensure lldb-dap is in your PATH
|
|
3765
|
+
|
|
3766
|
+
4. Build from source:
|
|
3745
3767
|
- Download LLVM from https://releases.llvm.org
|
|
3746
3768
|
- Build with -DLLDB_ENABLE_DAP=ON
|
|
3747
3769
|
`.trim(),
|
|
@@ -3849,10 +3871,7 @@ var dotnetAdapter = {
|
|
|
3849
3871
|
request: "attach",
|
|
3850
3872
|
processId: options.pid
|
|
3851
3873
|
}),
|
|
3852
|
-
exceptionFilters: [
|
|
3853
|
-
"all",
|
|
3854
|
-
"user-unhandled"
|
|
3855
|
-
]
|
|
3874
|
+
exceptionFilters: ["all", "user-unhandled"]
|
|
3856
3875
|
};
|
|
3857
3876
|
var adapters = /* @__PURE__ */ new Map([
|
|
3858
3877
|
// Smart .NET adapter (tries vsdbg, then netcoredbg)
|
|
@@ -3915,9 +3934,7 @@ var DapTransport = class extends import_node_events.EventEmitter {
|
|
|
3915
3934
|
});
|
|
3916
3935
|
process2.on("exit", (code, signal) => {
|
|
3917
3936
|
this.closed = true;
|
|
3918
|
-
this.rejectAllPending(
|
|
3919
|
-
new Error(`Debug adapter exited with code ${code}, signal ${signal}`)
|
|
3920
|
-
);
|
|
3937
|
+
this.rejectAllPending(new Error(`Debug adapter exited with code ${code}, signal ${signal}`));
|
|
3921
3938
|
this.emit("exit", code, signal);
|
|
3922
3939
|
});
|
|
3923
3940
|
process2.on("error", (error) => {
|
|
@@ -4081,8 +4098,29 @@ var VSDA_PATHS = [
|
|
|
4081
4098
|
"/usr/share/code/resources/app/node_modules.asar.unpacked/vsda/build/Release/vsda.node",
|
|
4082
4099
|
"/usr/share/code-insiders/resources/app/node_modules.asar.unpacked/vsda/build/Release/vsda.node",
|
|
4083
4100
|
// Windows (common install locations)
|
|
4084
|
-
path9.join(
|
|
4085
|
-
|
|
4101
|
+
path9.join(
|
|
4102
|
+
process.env.LOCALAPPDATA || "",
|
|
4103
|
+
"Programs",
|
|
4104
|
+
"Microsoft VS Code",
|
|
4105
|
+
"resources",
|
|
4106
|
+
"app",
|
|
4107
|
+
"node_modules.asar.unpacked",
|
|
4108
|
+
"vsda",
|
|
4109
|
+
"build",
|
|
4110
|
+
"Release",
|
|
4111
|
+
"vsda.node"
|
|
4112
|
+
),
|
|
4113
|
+
path9.join(
|
|
4114
|
+
process.env.PROGRAMFILES || "",
|
|
4115
|
+
"Microsoft VS Code",
|
|
4116
|
+
"resources",
|
|
4117
|
+
"app",
|
|
4118
|
+
"node_modules.asar.unpacked",
|
|
4119
|
+
"vsda",
|
|
4120
|
+
"build",
|
|
4121
|
+
"Release",
|
|
4122
|
+
"vsda.node"
|
|
4123
|
+
)
|
|
4086
4124
|
];
|
|
4087
4125
|
var vsdaModule = null;
|
|
4088
4126
|
var vsdaLoadAttempted = false;
|
|
@@ -4096,7 +4134,17 @@ function loadVsda() {
|
|
|
4096
4134
|
// Cursor (VS Code fork) on macOS
|
|
4097
4135
|
"/Applications/Cursor.app/Contents/Resources/app/node_modules.asar.unpacked/vsda/build/Release/vsda.node",
|
|
4098
4136
|
// User-installed VS Code on Linux
|
|
4099
|
-
path9.join(
|
|
4137
|
+
path9.join(
|
|
4138
|
+
home,
|
|
4139
|
+
".vscode-server",
|
|
4140
|
+
"bin",
|
|
4141
|
+
"*",
|
|
4142
|
+
"node_modules.asar.unpacked",
|
|
4143
|
+
"vsda",
|
|
4144
|
+
"build",
|
|
4145
|
+
"Release",
|
|
4146
|
+
"vsda.node"
|
|
4147
|
+
)
|
|
4100
4148
|
];
|
|
4101
4149
|
const allPaths = [...VSDA_PATHS, ...additionalPaths];
|
|
4102
4150
|
for (const vsdaPath of allPaths) {
|
|
@@ -4485,9 +4533,7 @@ var SocketDapTransport = class extends import_node_events3.EventEmitter {
|
|
|
4485
4533
|
return new Promise((resolve10, reject) => {
|
|
4486
4534
|
const timeout = setTimeout(() => {
|
|
4487
4535
|
this.pendingRequests.delete(seq);
|
|
4488
|
-
reject(
|
|
4489
|
-
new Error(`Request '${command}' timed out after ${this.requestTimeout}ms`)
|
|
4490
|
-
);
|
|
4536
|
+
reject(new Error(`Request '${command}' timed out after ${this.requestTimeout}ms`));
|
|
4491
4537
|
}, this.requestTimeout);
|
|
4492
4538
|
this.pendingRequests.set(seq, {
|
|
4493
4539
|
resolve: (response) => {
|
|
@@ -4604,7 +4650,10 @@ var SocketDapTransport = class extends import_node_events3.EventEmitter {
|
|
|
4604
4650
|
break;
|
|
4605
4651
|
case "request":
|
|
4606
4652
|
if (process.env.DEBUG_DAP) {
|
|
4607
|
-
console.error(
|
|
4653
|
+
console.error(
|
|
4654
|
+
`[DAP reverse request] ${message.command}:`,
|
|
4655
|
+
JSON.stringify(message.arguments, null, 2)
|
|
4656
|
+
);
|
|
4608
4657
|
}
|
|
4609
4658
|
this.emit("reverseRequest", message);
|
|
4610
4659
|
this.emit(`reverseRequest:${message.command}`, message);
|
|
@@ -4700,25 +4749,34 @@ var SocketDapClient = class extends import_node_events4.EventEmitter {
|
|
|
4700
4749
|
this.transport.on("event", (event) => {
|
|
4701
4750
|
this.emit("event", event);
|
|
4702
4751
|
});
|
|
4703
|
-
this.transport.on(
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4707
|
-
console.error("[DAP] Child config:", JSON.stringify(childConfig));
|
|
4708
|
-
}
|
|
4709
|
-
try {
|
|
4710
|
-
await this.createChildSession(childConfig);
|
|
4711
|
-
this.transport.sendResponse(request.seq, "startDebugging", true);
|
|
4752
|
+
this.transport.on(
|
|
4753
|
+
"reverseRequest:startDebugging",
|
|
4754
|
+
async (request) => {
|
|
4755
|
+
const childConfig = request.arguments?.configuration || {};
|
|
4712
4756
|
if (process.env.DEBUG_DAP) {
|
|
4713
|
-
console.error("[DAP]
|
|
4757
|
+
console.error("[DAP] Creating child session for js-debug");
|
|
4758
|
+
console.error("[DAP] Child config:", JSON.stringify(childConfig));
|
|
4714
4759
|
}
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
|
|
4760
|
+
try {
|
|
4761
|
+
await this.createChildSession(childConfig);
|
|
4762
|
+
this.transport.sendResponse(request.seq, "startDebugging", true);
|
|
4763
|
+
if (process.env.DEBUG_DAP) {
|
|
4764
|
+
console.error("[DAP] Child session created successfully");
|
|
4765
|
+
}
|
|
4766
|
+
} catch (error) {
|
|
4767
|
+
if (process.env.DEBUG_DAP) {
|
|
4768
|
+
console.error("[DAP] Child session creation failed:", error);
|
|
4769
|
+
}
|
|
4770
|
+
this.transport.sendResponse(
|
|
4771
|
+
request.seq,
|
|
4772
|
+
"startDebugging",
|
|
4773
|
+
false,
|
|
4774
|
+
void 0,
|
|
4775
|
+
String(error)
|
|
4776
|
+
);
|
|
4718
4777
|
}
|
|
4719
|
-
this.transport.sendResponse(request.seq, "startDebugging", false, void 0, String(error));
|
|
4720
4778
|
}
|
|
4721
|
-
|
|
4779
|
+
);
|
|
4722
4780
|
this.on("serverOutput", (data) => {
|
|
4723
4781
|
if (process.env.DEBUG) {
|
|
4724
4782
|
console.error("[js-debug server]", data);
|
|
@@ -4733,7 +4791,7 @@ var SocketDapClient = class extends import_node_events4.EventEmitter {
|
|
|
4733
4791
|
}
|
|
4734
4792
|
/**
|
|
4735
4793
|
* Initialize the debug session
|
|
4736
|
-
*
|
|
4794
|
+
*
|
|
4737
4795
|
* Note: Unlike stdio-based adapters, js-debug sends the 'initialized' event
|
|
4738
4796
|
* after the launch request, not after initialize response. So we don't wait
|
|
4739
4797
|
* for it here.
|
|
@@ -5025,7 +5083,10 @@ var SocketDapClient = class extends import_node_events4.EventEmitter {
|
|
|
5025
5083
|
if (process.env.DEBUG_DAP) {
|
|
5026
5084
|
console.error("[DAP child] Setting breakpoints for:", bp.source?.path);
|
|
5027
5085
|
}
|
|
5028
|
-
const response = await this.childTransport.sendRequest(
|
|
5086
|
+
const response = await this.childTransport.sendRequest(
|
|
5087
|
+
"setBreakpoints",
|
|
5088
|
+
bp
|
|
5089
|
+
);
|
|
5029
5090
|
if (process.env.DEBUG_DAP) {
|
|
5030
5091
|
console.error("[DAP child] Breakpoint response:", JSON.stringify(response, null, 2));
|
|
5031
5092
|
}
|
|
@@ -5178,9 +5239,7 @@ function parseBreakpointSpec(spec) {
|
|
|
5178
5239
|
function parseLogpointSpec(spec) {
|
|
5179
5240
|
const match = spec.match(/^(.+):(\d+)\|(.+)$/);
|
|
5180
5241
|
if (!match) {
|
|
5181
|
-
throw new Error(
|
|
5182
|
-
`Invalid logpoint format: "${spec}". Expected "file:line|log message"`
|
|
5183
|
-
);
|
|
5242
|
+
throw new Error(`Invalid logpoint format: "${spec}". Expected "file:line|log message"`);
|
|
5184
5243
|
}
|
|
5185
5244
|
const [, file, lineStr, logMessage] = match;
|
|
5186
5245
|
const line = parseInt(lineStr, 10);
|
|
@@ -5274,14 +5333,7 @@ var BreakpointManager = class {
|
|
|
5274
5333
|
spec.id = this.nextId++;
|
|
5275
5334
|
spec.verified = false;
|
|
5276
5335
|
spec.message = error instanceof Error ? error.message : "Failed to set breakpoint";
|
|
5277
|
-
this.formatter.breakpointSet(
|
|
5278
|
-
spec.id,
|
|
5279
|
-
file,
|
|
5280
|
-
spec.line,
|
|
5281
|
-
false,
|
|
5282
|
-
spec.condition,
|
|
5283
|
-
spec.message
|
|
5284
|
-
);
|
|
5336
|
+
this.formatter.breakpointSet(spec.id, file, spec.line, false, spec.condition, spec.message);
|
|
5285
5337
|
}
|
|
5286
5338
|
}
|
|
5287
5339
|
}
|
|
@@ -5404,7 +5456,13 @@ var VariableInspector = class {
|
|
|
5404
5456
|
count: this.options.maxCollectionItems
|
|
5405
5457
|
});
|
|
5406
5458
|
for (const v of vars.variables) {
|
|
5407
|
-
result[v.name] = await this.expandVariable(
|
|
5459
|
+
result[v.name] = await this.expandVariable(
|
|
5460
|
+
v,
|
|
5461
|
+
this.options.maxDepth,
|
|
5462
|
+
visited,
|
|
5463
|
+
contentHashes,
|
|
5464
|
+
v.name
|
|
5465
|
+
);
|
|
5408
5466
|
}
|
|
5409
5467
|
}
|
|
5410
5468
|
}
|
|
@@ -5455,21 +5513,31 @@ var VariableInspector = class {
|
|
|
5455
5513
|
(child) => !this.isBlockedProperty(child.name)
|
|
5456
5514
|
);
|
|
5457
5515
|
if (this.options.omitNullProperties) {
|
|
5458
|
-
filteredChildren = filteredChildren.filter(
|
|
5459
|
-
(child) => !this.isNullValue(child.value)
|
|
5460
|
-
);
|
|
5516
|
+
filteredChildren = filteredChildren.filter((child) => !this.isNullValue(child.value));
|
|
5461
5517
|
}
|
|
5462
5518
|
if (this.isCollection(v.type, filteredChildren)) {
|
|
5463
5519
|
variable.value = {
|
|
5464
5520
|
type: v.type || "collection",
|
|
5465
5521
|
count: this.getCollectionCount(v, filteredChildren.length),
|
|
5466
|
-
items: await this.expandCollection(
|
|
5522
|
+
items: await this.expandCollection(
|
|
5523
|
+
filteredChildren,
|
|
5524
|
+
depth - 1,
|
|
5525
|
+
visited,
|
|
5526
|
+
contentHashes,
|
|
5527
|
+
currentPath
|
|
5528
|
+
)
|
|
5467
5529
|
};
|
|
5468
5530
|
} else {
|
|
5469
5531
|
const obj = {};
|
|
5470
5532
|
for (const child of filteredChildren) {
|
|
5471
5533
|
const childPath = currentPath ? `${currentPath}.${child.name}` : child.name;
|
|
5472
|
-
obj[child.name] = await this.expandVariable(
|
|
5534
|
+
obj[child.name] = await this.expandVariable(
|
|
5535
|
+
child,
|
|
5536
|
+
depth - 1,
|
|
5537
|
+
visited,
|
|
5538
|
+
contentHashes,
|
|
5539
|
+
childPath
|
|
5540
|
+
);
|
|
5473
5541
|
}
|
|
5474
5542
|
if (this.options.deduplicateByContent && Object.keys(obj).length > 0) {
|
|
5475
5543
|
const contentHash = this.computeContentHash(v.type, obj);
|
|
@@ -5734,24 +5802,24 @@ var ACTIONABLE_HINTS = {
|
|
|
5734
5802
|
"PostgresException:3D000": "PostgreSQL database does not exist - verify database name",
|
|
5735
5803
|
"PostgresException:42P01": "PostgreSQL table does not exist - run migrations or check table name",
|
|
5736
5804
|
// File system
|
|
5737
|
-
|
|
5738
|
-
|
|
5739
|
-
|
|
5740
|
-
|
|
5805
|
+
FileNotFoundException: "File not found - verify the file path exists and is accessible",
|
|
5806
|
+
DirectoryNotFoundException: "Directory not found - verify the directory path exists",
|
|
5807
|
+
UnauthorizedAccessException: "Access denied - check file/directory permissions or run with elevated privileges",
|
|
5808
|
+
IOException: "I/O error - check disk space, file locks, or permissions",
|
|
5741
5809
|
// Null reference
|
|
5742
|
-
|
|
5810
|
+
NullReferenceException: "Null reference - an object was not initialized before use. Check for null values in the call chain",
|
|
5743
5811
|
// Validation
|
|
5744
|
-
|
|
5745
|
-
|
|
5746
|
-
|
|
5747
|
-
|
|
5812
|
+
ArgumentNullException: "A required argument was null - check that all required parameters are provided",
|
|
5813
|
+
ArgumentException: "Invalid argument - check the parameter values being passed",
|
|
5814
|
+
ArgumentOutOfRangeException: "Argument out of range - check that values are within expected bounds",
|
|
5815
|
+
ValidationException: "Validation failed - check the input data against validation rules",
|
|
5748
5816
|
// Timeout
|
|
5749
|
-
|
|
5750
|
-
|
|
5751
|
-
|
|
5817
|
+
TimeoutException: "Operation timed out - increase timeout or check for performance issues",
|
|
5818
|
+
TaskCanceledException: "Task was cancelled - may indicate timeout or explicit cancellation",
|
|
5819
|
+
OperationCanceledException: "Operation was cancelled - check CancellationToken usage",
|
|
5752
5820
|
// Configuration
|
|
5753
|
-
|
|
5754
|
-
|
|
5821
|
+
ConfigurationException: "Configuration error - check app settings and configuration files",
|
|
5822
|
+
OptionsValidationException: "Options validation failed - check configuration values match expected schema",
|
|
5755
5823
|
// HTTP
|
|
5756
5824
|
"HttpRequestException:404": "HTTP 404 Not Found - verify the URL is correct",
|
|
5757
5825
|
"HttpRequestException:401": "HTTP 401 Unauthorized - check authentication credentials",
|
|
@@ -5838,11 +5906,13 @@ function extractExceptionEntryFromVariable(variable, depth) {
|
|
|
5838
5906
|
if (val["SocketErrorCode"]) data.socketErrorCode = extractStringValue(val["SocketErrorCode"]);
|
|
5839
5907
|
if (val["NativeErrorCode"]) data.nativeErrorCode = extractNumberValue(val["NativeErrorCode"]);
|
|
5840
5908
|
if (val["ErrorCode"]) data.errorCode = extractNumberValue(val["ErrorCode"]);
|
|
5841
|
-
if (val["<ErrorCode>k__BackingField"])
|
|
5909
|
+
if (val["<ErrorCode>k__BackingField"])
|
|
5910
|
+
data.errorCode = extractNumberValue(val["<ErrorCode>k__BackingField"]);
|
|
5842
5911
|
}
|
|
5843
5912
|
if (type.includes("HttpException") || type.includes("HttpRequestException")) {
|
|
5844
5913
|
if (val["StatusCode"]) data.httpStatusCode = extractNumberValue(val["StatusCode"]);
|
|
5845
|
-
if (val["<StatusCode>k__BackingField"])
|
|
5914
|
+
if (val["<StatusCode>k__BackingField"])
|
|
5915
|
+
data.httpStatusCode = extractNumberValue(val["<StatusCode>k__BackingField"]);
|
|
5846
5916
|
}
|
|
5847
5917
|
if (type.includes("ArgumentException") || type.includes("ArgumentNullException")) {
|
|
5848
5918
|
if (val["ParamName"]) data.paramName = extractStringValue(val["ParamName"]);
|
|
@@ -5850,7 +5920,8 @@ function extractExceptionEntryFromVariable(variable, depth) {
|
|
|
5850
5920
|
if (type.includes("FileNotFoundException") || type.includes("FileAccessException")) {
|
|
5851
5921
|
if (val["FileName"]) data.fileName = extractStringValue(val["FileName"]);
|
|
5852
5922
|
if (val["FilePath"]) data.filePath = extractStringValue(val["FilePath"]);
|
|
5853
|
-
if (val["<FilePath>k__BackingField"])
|
|
5923
|
+
if (val["<FilePath>k__BackingField"])
|
|
5924
|
+
data.filePath = extractStringValue(val["<FilePath>k__BackingField"]);
|
|
5854
5925
|
}
|
|
5855
5926
|
}
|
|
5856
5927
|
return {
|
|
@@ -6022,10 +6093,7 @@ var DebugSession = class {
|
|
|
6022
6093
|
async run() {
|
|
6023
6094
|
this.startTime = Date.now();
|
|
6024
6095
|
if (this.config.attach && this.config.pid) {
|
|
6025
|
-
this.formatter.sessionStartAttach(
|
|
6026
|
-
this.config.adapter.name,
|
|
6027
|
-
this.config.pid
|
|
6028
|
-
);
|
|
6096
|
+
this.formatter.sessionStartAttach(this.config.adapter.name, this.config.pid);
|
|
6029
6097
|
} else {
|
|
6030
6098
|
this.formatter.sessionStart(
|
|
6031
6099
|
this.config.adapter.name,
|
|
@@ -6147,9 +6215,7 @@ var DebugSession = class {
|
|
|
6147
6215
|
await this.client.configurationDone();
|
|
6148
6216
|
}
|
|
6149
6217
|
this.state = "running";
|
|
6150
|
-
this.formatter.emit(
|
|
6151
|
-
this.formatter.createEvent("process_launched", {})
|
|
6152
|
-
);
|
|
6218
|
+
this.formatter.emit(this.formatter.createEvent("process_launched", {}));
|
|
6153
6219
|
}
|
|
6154
6220
|
}
|
|
6155
6221
|
/**
|
|
@@ -6516,10 +6582,7 @@ var DebugSession = class {
|
|
|
6516
6582
|
};
|
|
6517
6583
|
if (this.config.diffVars && frameId) {
|
|
6518
6584
|
const currentLocals = await this.variableInspector.getLocals(frameId);
|
|
6519
|
-
const changes = this.variableInspector.diffVariables(
|
|
6520
|
-
this.previousLocals,
|
|
6521
|
-
currentLocals
|
|
6522
|
-
);
|
|
6585
|
+
const changes = this.variableInspector.diffVariables(this.previousLocals, currentLocals);
|
|
6523
6586
|
if (changes.length > 0) {
|
|
6524
6587
|
stepEvent.changes = changes;
|
|
6525
6588
|
}
|
|
@@ -6543,10 +6606,7 @@ var DebugSession = class {
|
|
|
6543
6606
|
return;
|
|
6544
6607
|
}
|
|
6545
6608
|
}
|
|
6546
|
-
const stopReason = await this.checkTraceStopConditions(
|
|
6547
|
-
stackDepth,
|
|
6548
|
-
frameId
|
|
6549
|
-
);
|
|
6609
|
+
const stopReason = await this.checkTraceStopConditions(stackDepth, frameId);
|
|
6550
6610
|
if (stopReason) {
|
|
6551
6611
|
await this.endTrace(threadId, stopReason, stackFrames, frameId);
|
|
6552
6612
|
return;
|
|
@@ -6742,9 +6802,11 @@ async function launchTestRunner(config) {
|
|
|
6742
6802
|
testProcess.on("exit", (code, signal) => {
|
|
6743
6803
|
if (!foundPid) {
|
|
6744
6804
|
exitedEarly = true;
|
|
6745
|
-
reject(
|
|
6746
|
-
|
|
6747
|
-
|
|
6805
|
+
reject(
|
|
6806
|
+
new Error(
|
|
6807
|
+
`Test process exited before testhost started. Exit code: ${code}, signal: ${signal}. Make sure the test project builds successfully and has tests.`
|
|
6808
|
+
)
|
|
6809
|
+
);
|
|
6748
6810
|
}
|
|
6749
6811
|
});
|
|
6750
6812
|
testProcess.on("error", (err) => {
|
|
@@ -6755,9 +6817,11 @@ async function launchTestRunner(config) {
|
|
|
6755
6817
|
setTimeout(() => {
|
|
6756
6818
|
if (!foundPid && !exitedEarly) {
|
|
6757
6819
|
testProcess.kill();
|
|
6758
|
-
reject(
|
|
6759
|
-
|
|
6760
|
-
|
|
6820
|
+
reject(
|
|
6821
|
+
new Error(
|
|
6822
|
+
"Timeout waiting for testhost to start. The VSTEST_HOST_DEBUG output was not detected within 60 seconds."
|
|
6823
|
+
)
|
|
6824
|
+
);
|
|
6761
6825
|
}
|
|
6762
6826
|
}, 6e4);
|
|
6763
6827
|
});
|
|
@@ -6793,18 +6857,11 @@ function parseTimeout(value) {
|
|
|
6793
6857
|
function createCli() {
|
|
6794
6858
|
const program2 = new Command();
|
|
6795
6859
|
program2.name("debug-run").description("CLI tool enabling AI agents to programmatically debug code via DAP").version("0.1.0");
|
|
6796
|
-
program2.argument("[program]", "Program to debug").option(
|
|
6797
|
-
"-a, --adapter <name>",
|
|
6798
|
-
`Debug adapter to use (${getAdapterNames().join(", ")})`
|
|
6799
|
-
).option("--args <args...>", "Arguments to pass to the program").option("--cwd <path>", "Working directory for the program").option(
|
|
6860
|
+
program2.argument("[program]", "Program to debug").option("-a, --adapter <name>", `Debug adapter to use (${getAdapterNames().join(", ")})`).option("--args <args...>", "Arguments to pass to the program").option("--cwd <path>", "Working directory for the program").option(
|
|
6800
6861
|
"-b, --breakpoint <spec...>",
|
|
6801
6862
|
'Breakpoint specifications (e.g., "file.ts:45" or "file.ts:45?condition")',
|
|
6802
6863
|
[]
|
|
6803
|
-
).option(
|
|
6804
|
-
"-e, --eval <expr...>",
|
|
6805
|
-
"Expressions to evaluate when breakpoints are hit",
|
|
6806
|
-
[]
|
|
6807
|
-
).option(
|
|
6864
|
+
).option("-e, --eval <expr...>", "Expressions to evaluate when breakpoints are hit", []).option(
|
|
6808
6865
|
"--assert <expr...>",
|
|
6809
6866
|
"Invariant expressions that must remain truthy; stops on first violation",
|
|
6810
6867
|
[]
|
|
@@ -6815,23 +6872,11 @@ function createCli() {
|
|
|
6815
6872
|
).option(
|
|
6816
6873
|
"--break-on-exception <filter...>",
|
|
6817
6874
|
'Break on exceptions (e.g., "all", "user-unhandled", "uncaught")'
|
|
6818
|
-
).option(
|
|
6819
|
-
"-t, --timeout <duration>",
|
|
6820
|
-
"Session timeout (e.g., 30s, 5000ms, 2m)",
|
|
6821
|
-
"60s"
|
|
6822
|
-
).option("--capture-locals", "Capture local variables at breakpoints", true).option("--no-capture-locals", "Disable capturing local variables").option("--pretty", "Pretty print JSON output", false).option(
|
|
6875
|
+
).option("-t, --timeout <duration>", "Session timeout (e.g., 30s, 5000ms, 2m)", "60s").option("--capture-locals", "Capture local variables at breakpoints", true).option("--no-capture-locals", "Disable capturing local variables").option("--pretty", "Pretty print JSON output", false).option(
|
|
6823
6876
|
"-s, --steps <count>",
|
|
6824
6877
|
"Number of steps to execute after hitting a breakpoint (step over)",
|
|
6825
6878
|
(val) => parseInt(val, 10)
|
|
6826
|
-
).option(
|
|
6827
|
-
"--capture-each-step",
|
|
6828
|
-
"Capture variables and location at each step",
|
|
6829
|
-
false
|
|
6830
|
-
).option(
|
|
6831
|
-
"--trace",
|
|
6832
|
-
"Enable trace mode - step through code after breakpoint hit",
|
|
6833
|
-
false
|
|
6834
|
-
).option(
|
|
6879
|
+
).option("--capture-each-step", "Capture variables and location at each step", false).option("--trace", "Enable trace mode - step through code after breakpoint hit", false).option(
|
|
6835
6880
|
"--trace-into",
|
|
6836
6881
|
"Use stepIn instead of stepOver in trace mode (follow into function calls)",
|
|
6837
6882
|
false
|
|
@@ -6840,39 +6885,21 @@ function createCli() {
|
|
|
6840
6885
|
"Maximum steps in trace mode before stopping (default: 500)",
|
|
6841
6886
|
(val) => parseInt(val, 10),
|
|
6842
6887
|
500
|
|
6843
|
-
).option(
|
|
6844
|
-
"--trace-until <expr>",
|
|
6845
|
-
"Stop trace when expression evaluates to truthy"
|
|
6846
|
-
).option(
|
|
6888
|
+
).option("--trace-until <expr>", "Stop trace when expression evaluates to truthy").option(
|
|
6847
6889
|
"--diff-vars",
|
|
6848
6890
|
"Show only changed variables in trace steps instead of full dumps",
|
|
6849
6891
|
false
|
|
6850
|
-
).option(
|
|
6851
|
-
"-o, --output <file>",
|
|
6852
|
-
"Write events to file instead of stdout"
|
|
6853
|
-
).option(
|
|
6854
|
-
"--include <types...>",
|
|
6855
|
-
"Only emit these event types (e.g., breakpoint_hit error)"
|
|
6856
|
-
).option(
|
|
6892
|
+
).option("-o, --output <file>", "Write events to file instead of stdout").option("--include <types...>", "Only emit these event types (e.g., breakpoint_hit error)").option(
|
|
6857
6893
|
"--exclude <types...>",
|
|
6858
6894
|
"Suppress these event types (e.g., program_output exception_thrown)"
|
|
6859
|
-
).addOption(
|
|
6860
|
-
new Option("--env <key=value...>", "Environment variables for the program")
|
|
6861
|
-
).option(
|
|
6862
|
-
"--attach",
|
|
6863
|
-
"Attach to a running process instead of launching",
|
|
6864
|
-
false
|
|
6865
|
-
).option(
|
|
6895
|
+
).addOption(new Option("--env <key=value...>", "Environment variables for the program")).option("--attach", "Attach to a running process instead of launching", false).option(
|
|
6866
6896
|
"--pid <processId>",
|
|
6867
6897
|
"Process ID to attach to (requires --attach)",
|
|
6868
6898
|
(val) => parseInt(val, 10)
|
|
6869
6899
|
).option(
|
|
6870
6900
|
"--test-project <path>",
|
|
6871
6901
|
"Run dotnet test with VSTEST_HOST_DEBUG=1 and auto-attach (for NUnit/xUnit/MSTest)"
|
|
6872
|
-
).option(
|
|
6873
|
-
"--test-filter <filter>",
|
|
6874
|
-
"Filter which tests to run (passed to dotnet test --filter)"
|
|
6875
|
-
).option(
|
|
6902
|
+
).option("--test-filter <filter>", "Filter which tests to run (passed to dotnet test --filter)").option(
|
|
6876
6903
|
"--expand-services",
|
|
6877
6904
|
"Fully expand service-like types (Logger, Repository, etc.) instead of showing compact form",
|
|
6878
6905
|
false
|
|
@@ -6880,11 +6907,7 @@ function createCli() {
|
|
|
6880
6907
|
"--show-null-props",
|
|
6881
6908
|
"Include null/undefined properties in output (normally omitted for token efficiency)",
|
|
6882
6909
|
false
|
|
6883
|
-
).option(
|
|
6884
|
-
"--no-dedupe",
|
|
6885
|
-
"Disable content-based deduplication of repeated objects",
|
|
6886
|
-
false
|
|
6887
|
-
).option(
|
|
6910
|
+
).option("--no-dedupe", "Disable content-based deduplication of repeated objects", false).option(
|
|
6888
6911
|
"--flatten-exceptions",
|
|
6889
6912
|
"Enable exception chain flattening and root cause classification (default: true)",
|
|
6890
6913
|
true
|
|
@@ -6896,34 +6919,40 @@ function createCli() {
|
|
|
6896
6919
|
"Maximum depth to traverse exception chain (default: 10)",
|
|
6897
6920
|
(val) => parseInt(val, 10),
|
|
6898
6921
|
10
|
|
6899
|
-
).action(
|
|
6900
|
-
|
|
6901
|
-
if (
|
|
6902
|
-
options.adapter
|
|
6922
|
+
).action(
|
|
6923
|
+
async (programPath, options) => {
|
|
6924
|
+
if (options.testProject) {
|
|
6925
|
+
if (!options.adapter) {
|
|
6926
|
+
options.adapter = "vsdbg";
|
|
6927
|
+
}
|
|
6928
|
+
await runTestDebugSession({ ...options, program: programPath, adapter: options.adapter });
|
|
6929
|
+
return;
|
|
6903
6930
|
}
|
|
6904
|
-
|
|
6905
|
-
|
|
6906
|
-
|
|
6907
|
-
|
|
6908
|
-
|
|
6909
|
-
|
|
6910
|
-
|
|
6911
|
-
|
|
6931
|
+
if (options.attach) {
|
|
6932
|
+
if (!options.pid) {
|
|
6933
|
+
console.error("Error: --pid is required when using --attach");
|
|
6934
|
+
console.error(
|
|
6935
|
+
"Usage: debug-run --attach --pid <processId> -a <adapter> -b <breakpoint>"
|
|
6936
|
+
);
|
|
6937
|
+
process.exit(1);
|
|
6938
|
+
}
|
|
6939
|
+
} else {
|
|
6940
|
+
if (!programPath) {
|
|
6941
|
+
console.error(
|
|
6942
|
+
"Error: <program> argument is required (or use --attach --pid, or --test-project)"
|
|
6943
|
+
);
|
|
6944
|
+
console.error("Usage: debug-run <program> -a <adapter> -b <breakpoint>");
|
|
6945
|
+
process.exit(1);
|
|
6946
|
+
}
|
|
6912
6947
|
}
|
|
6913
|
-
|
|
6914
|
-
|
|
6915
|
-
console.error(
|
|
6916
|
-
console.error("Usage: debug-run <program> -a <adapter> -b <breakpoint>");
|
|
6948
|
+
if (!options.adapter) {
|
|
6949
|
+
console.error("Error: --adapter is required");
|
|
6950
|
+
console.error(`Available adapters: ${getAdapterNames().join(", ")}`);
|
|
6917
6951
|
process.exit(1);
|
|
6918
6952
|
}
|
|
6953
|
+
await runDebugSession({ ...options, program: programPath, adapter: options.adapter });
|
|
6919
6954
|
}
|
|
6920
|
-
|
|
6921
|
-
console.error("Error: --adapter is required");
|
|
6922
|
-
console.error(`Available adapters: ${getAdapterNames().join(", ")}`);
|
|
6923
|
-
process.exit(1);
|
|
6924
|
-
}
|
|
6925
|
-
await runDebugSession({ ...options, program: programPath, adapter: options.adapter });
|
|
6926
|
-
});
|
|
6955
|
+
);
|
|
6927
6956
|
program2.command("list-adapters").description("List available debug adapters and their installation status").action(async () => {
|
|
6928
6957
|
await listAdapters();
|
|
6929
6958
|
});
|
|
@@ -6992,13 +7021,17 @@ async function runDebugSession(options) {
|
|
|
6992
7021
|
const hasBreakpoints = options.breakpoint.length > 0 || options.logpoint && options.logpoint.length > 0;
|
|
6993
7022
|
const hasExceptionBreakpoints = options.breakOnException && options.breakOnException.length > 0;
|
|
6994
7023
|
if (!hasBreakpoints && !hasExceptionBreakpoints && !options.attach) {
|
|
6995
|
-
console.error(
|
|
7024
|
+
console.error(
|
|
7025
|
+
"Error: At least one --breakpoint, --logpoint, or --break-on-exception is required"
|
|
7026
|
+
);
|
|
6996
7027
|
process.exit(1);
|
|
6997
7028
|
}
|
|
6998
7029
|
if (hasExceptionBreakpoints && adapter.exceptionFilters) {
|
|
6999
7030
|
for (const filter of options.breakOnException) {
|
|
7000
7031
|
if (!adapter.exceptionFilters.includes(filter)) {
|
|
7001
|
-
console.error(
|
|
7032
|
+
console.error(
|
|
7033
|
+
`Error: Adapter "${adapter.name}" does not support exception filter "${filter}"`
|
|
7034
|
+
);
|
|
7002
7035
|
console.error(`Supported filters: ${adapter.exceptionFilters.join(", ")}`);
|
|
7003
7036
|
process.exit(1);
|
|
7004
7037
|
}
|
|
@@ -7017,7 +7050,7 @@ async function runDebugSession(options) {
|
|
|
7017
7050
|
let outputStream = process.stdout;
|
|
7018
7051
|
let fileStream;
|
|
7019
7052
|
if (options.output) {
|
|
7020
|
-
fileStream =
|
|
7053
|
+
fileStream = fs2.createWriteStream(options.output);
|
|
7021
7054
|
outputStream = fileStream;
|
|
7022
7055
|
}
|
|
7023
7056
|
const formatter = new OutputFormatter({
|
|
@@ -7095,7 +7128,9 @@ async function installAdapter(name) {
|
|
|
7095
7128
|
Successfully installed netcoredbg!`);
|
|
7096
7129
|
console.log(`Path: ${installedPath}`);
|
|
7097
7130
|
} catch (error) {
|
|
7098
|
-
console.error(
|
|
7131
|
+
console.error(
|
|
7132
|
+
`Failed to install netcoredbg: ${error instanceof Error ? error.message : error}`
|
|
7133
|
+
);
|
|
7099
7134
|
process.exit(1);
|
|
7100
7135
|
}
|
|
7101
7136
|
} else if (normalizedName === "node" || normalizedName === "nodejs" || normalizedName === "js" || normalizedName === "javascript" || normalizedName === "typescript") {
|
|
@@ -7109,7 +7144,9 @@ Successfully installed netcoredbg!`);
|
|
|
7109
7144
|
Successfully installed js-debug!`);
|
|
7110
7145
|
console.log(`Path: ${installedPath}`);
|
|
7111
7146
|
} catch (error) {
|
|
7112
|
-
console.error(
|
|
7147
|
+
console.error(
|
|
7148
|
+
`Failed to install js-debug: ${error instanceof Error ? error.message : error}`
|
|
7149
|
+
);
|
|
7113
7150
|
process.exit(1);
|
|
7114
7151
|
}
|
|
7115
7152
|
} else if (normalizedName === "debugpy" || normalizedName === "python") {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "debug-run",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "CLI tool enabling AI agents to programmatically debug code via DAP",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -8,12 +8,19 @@
|
|
|
8
8
|
"debug-run": "dist/index.cjs"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
|
-
"prepare": "
|
|
11
|
+
"prepare": "husky",
|
|
12
12
|
"build": "node scripts/build.mjs",
|
|
13
13
|
"dev": "tsx ./src/index.ts",
|
|
14
14
|
"test": "vitest",
|
|
15
15
|
"test:run": "vitest run",
|
|
16
|
-
"typecheck": "tsc --noEmit"
|
|
16
|
+
"typecheck": "tsc --noEmit",
|
|
17
|
+
"format": "prettier --write src/",
|
|
18
|
+
"format:check": "prettier --check src/"
|
|
19
|
+
},
|
|
20
|
+
"lint-staged": {
|
|
21
|
+
"src/**/*.{ts,js}": [
|
|
22
|
+
"prettier --write"
|
|
23
|
+
]
|
|
17
24
|
},
|
|
18
25
|
"dependencies": {
|
|
19
26
|
"@vscode/debugprotocol": "^1.65.0",
|
|
@@ -25,6 +32,9 @@
|
|
|
25
32
|
"@types/node": "^20.0.0",
|
|
26
33
|
"bun-types": "^1.0.0",
|
|
27
34
|
"esbuild": "^0.27.2",
|
|
35
|
+
"husky": "^9.1.7",
|
|
36
|
+
"lint-staged": "^16.2.7",
|
|
37
|
+
"prettier": "^3.8.0",
|
|
28
38
|
"tsx": "^4.21.0",
|
|
29
39
|
"typescript": "^5.3.0",
|
|
30
40
|
"vitest": "^1.0.0"
|