- DAPProxyServer: DAP JSON dispatcher, routes by command, default handlers for all standard DAP commands, response envelope with seq/type/request_seq/success - DebugAdapterRouter: per-language adapter capability registry; routeCommand gates on active language AND adapter support - PolyglotStackTraceDecoder: infers language from source extension, marks boundary frames where adjacent frames differ in language, sets astNodeId per frame - LanguageSeamFrameDetector: detectSeams/primarySeam/seamCount/frameLanguages/ crossesBoundary over decoded polyglot stacks - Sprint279IntegrationSummary: poly-sort (Python+Rust) end-to-end DAP pipeline 26/26 tests passing (5+5+5+5+6). All new headers well under 600 lines. LoRA recorded: sprint279-2026-03-01 (7 calls, 5535 tokens). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
62 lines
1.9 KiB
C++
62 lines
1.9 KiB
C++
#pragma once
|
|
#include <functional>
|
|
#include <map>
|
|
#include <nlohmann/json.hpp>
|
|
#include <string>
|
|
|
|
namespace whetstone {
|
|
|
|
class DAPProxyServer {
|
|
public:
|
|
using Handler = std::function<nlohmann::json(const nlohmann::json& args)>;
|
|
|
|
DAPProxyServer() {
|
|
auto empty = [](const nlohmann::json&) -> nlohmann::json { return nlohmann::json::object(); };
|
|
for (const auto& cmd : {"initialize","launch","attach","setBreakpoints",
|
|
"stackTrace","scopes","variables","continue",
|
|
"next","stepIn","stepOut","disconnect"})
|
|
handlers_[cmd] = empty;
|
|
}
|
|
|
|
nlohmann::json handle(const nlohmann::json& msg) {
|
|
if (!msg.contains("type")) return {};
|
|
|
|
std::string type = msg["type"].get<std::string>();
|
|
|
|
// Events: no response
|
|
if (type == "event") return {};
|
|
|
|
// Requests
|
|
if (type == "request") {
|
|
std::string command = msg.value("command", "");
|
|
int reqSeq = msg.value("seq", 0);
|
|
nlohmann::json args = msg.contains("arguments") ? msg["arguments"]
|
|
: nlohmann::json::object();
|
|
nlohmann::json body = nlohmann::json::object();
|
|
auto it = handlers_.find(command);
|
|
if (it != handlers_.end()) body = it->second(args);
|
|
|
|
return {
|
|
{"seq", ++seq_},
|
|
{"type", "response"},
|
|
{"request_seq", reqSeq},
|
|
{"command", command},
|
|
{"success", true},
|
|
{"body", body}
|
|
};
|
|
}
|
|
|
|
return {};
|
|
}
|
|
|
|
void registerHandler(const std::string& command, Handler h) {
|
|
handlers_[command] = std::move(h);
|
|
}
|
|
|
|
private:
|
|
std::map<std::string, Handler> handlers_;
|
|
int seq_ = 0;
|
|
};
|
|
|
|
} // namespace whetstone
|