feat(debugger): integrate NX Tcl Remote Debugger into NX Postprocessor
build_and_puplish.yml / build_and_publish (release) Successful in 35s

Embed the NX Tcl Remote Debugger into the NX Postprocessor extension.
Add a new debugging client, protocol, and adapter logic to
drive attach/launch, breakpoints, stepping, and evaluation
via the runtime adapter.

- Introduced a client debugger with a new adapter and protocol
- Wired attach/launch, breakpoints, stepping, and evaluation
- Updated docs and licensing to reflect the embedded debugger
This commit is contained in:
Christoph Brandau
2026-08-28 22:36:18 +02:00
parent 07ccd2d26a
commit c3d5116885
12 changed files with 1135 additions and 10 deletions
+63
View File
@@ -0,0 +1,63 @@
"use strict"
const test = require("node:test")
const assert = require("node:assert/strict")
const { PassThrough } = require("node:stream")
const { NxDebugAdapter } = require("../client/src/debugger/debugAdapter")
const manifest = require("../package.json")
function dapMessage(message) {
const json = JSON.stringify(message)
return `Content-Length: ${Buffer.byteLength(json, "utf8")}\r\n\r\n${json}`
}
function readDapMessage(stream) {
return new Promise((resolve, reject) => {
let buffer = Buffer.alloc(0)
const timer = setTimeout(() => reject(new Error("DAP response timed out")), 2000)
const onData = (chunk) => {
buffer = Buffer.concat([buffer, chunk])
const headerEnd = buffer.indexOf("\r\n\r\n")
if (headerEnd < 0) return
const header = buffer.subarray(0, headerEnd).toString("ascii")
const match = /Content-Length:\s*(\d+)/i.exec(header)
if (!match) return
const length = Number(match[1])
if (buffer.length < headerEnd + 4 + length) return
clearTimeout(timer)
stream.removeListener("data", onData)
resolve(JSON.parse(buffer.subarray(headerEnd + 4, headerEnd + 4 + length)))
}
stream.on("data", onData)
})
}
test("integrated manifest contributes the NX Tcl debugger", () => {
const debuggerContribution = manifest.contributes.debuggers.find(
(entry) => entry.type === "nx-tcl"
)
assert.ok(debuggerContribution)
assert.deepEqual(debuggerContribution.languages, ["tcl", "def"])
assert.deepEqual(
manifest.contributes.breakpoints.map((entry) => entry.language),
["tcl", "def"]
)
})
test("integrated adapter answers a DAP initialize request", async () => {
const input = new PassThrough()
const output = new PassThrough()
const adapter = new NxDebugAdapter(input, output)
const responsePromise = readDapMessage(output)
input.write(
dapMessage({ seq: 1, type: "request", command: "initialize", arguments: {} })
)
const response = await responsePromise
adapter.dispose()
assert.equal(response.success, true)
assert.equal(response.command, "initialize")
assert.equal(response.body.supportsConfigurationDoneRequest, true)
assert.equal(response.body.supportsSetVariable, true)
})