diff --git a/src/Runner.Worker/Dap/DapMessages.cs b/src/Runner.Worker/Dap/DapMessages.cs
new file mode 100644
index 000000000..bf8685981
--- /dev/null
+++ b/src/Runner.Worker/Dap/DapMessages.cs
@@ -0,0 +1,1134 @@
+using System.Collections.Generic;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+namespace GitHub.Runner.Worker.Dap
+{
+ public enum DapCommand
+ {
+ Continue,
+ Next,
+ StepIn,
+ StepOut,
+ Disconnect
+ }
+
+ ///
+ /// Base class of requests, responses, and events per DAP specification.
+ ///
+ public class ProtocolMessage
+ {
+ ///
+ /// Sequence number of the message (also known as message ID).
+ /// The seq for the first message sent by a client or debug adapter is 1,
+ /// and for each subsequent message is 1 greater than the previous message.
+ ///
+ [JsonProperty("seq")]
+ public int Seq { get; set; }
+
+ ///
+ /// Message type: 'request', 'response', 'event'
+ ///
+ [JsonProperty("type")]
+ public string Type { get; set; }
+ }
+
+ ///
+ /// A client or debug adapter initiated request.
+ ///
+ public class Request : ProtocolMessage
+ {
+ ///
+ /// The command to execute.
+ ///
+ [JsonProperty("command")]
+ public string Command { get; set; }
+
+ ///
+ /// Object containing arguments for the command.
+ /// Using JObject for flexibility with different argument types.
+ ///
+ [JsonProperty("arguments")]
+ public JObject Arguments { get; set; }
+ }
+
+ ///
+ /// Response for a request.
+ ///
+ public class Response : ProtocolMessage
+ {
+ ///
+ /// Sequence number of the corresponding request.
+ ///
+ [JsonProperty("request_seq")]
+ public int RequestSeq { get; set; }
+
+ ///
+ /// Outcome of the request. If true, the request was successful.
+ ///
+ [JsonProperty("success")]
+ public bool Success { get; set; }
+
+ ///
+ /// The command requested.
+ ///
+ [JsonProperty("command")]
+ public string Command { get; set; }
+
+ ///
+ /// Contains the raw error in short form if success is false.
+ ///
+ [JsonProperty("message", NullValueHandling = NullValueHandling.Ignore)]
+ public string Message { get; set; }
+
+ ///
+ /// Contains request result if success is true and error details if success is false.
+ ///
+ [JsonProperty("body", NullValueHandling = NullValueHandling.Ignore)]
+ public object Body { get; set; }
+ }
+
+ ///
+ /// A debug adapter initiated event.
+ ///
+ public class Event : ProtocolMessage
+ {
+ public Event()
+ {
+ Type = "event";
+ }
+
+ ///
+ /// Type of event.
+ ///
+ [JsonProperty("event")]
+ public string EventType { get; set; }
+
+ ///
+ /// Event-specific information.
+ ///
+ [JsonProperty("body", NullValueHandling = NullValueHandling.Ignore)]
+ public object Body { get; set; }
+ }
+
+ #region Initialize Request/Response
+
+ ///
+ /// Arguments for 'initialize' request.
+ ///
+ public class InitializeRequestArguments
+ {
+ ///
+ /// The ID of the client using this adapter.
+ ///
+ [JsonProperty("clientID")]
+ public string ClientId { get; set; }
+
+ ///
+ /// The human-readable name of the client using this adapter.
+ ///
+ [JsonProperty("clientName")]
+ public string ClientName { get; set; }
+
+ ///
+ /// The ID of the debug adapter.
+ ///
+ [JsonProperty("adapterID")]
+ public string AdapterId { get; set; }
+
+ ///
+ /// The ISO-639 locale of the client using this adapter, e.g. en-US or de-CH.
+ ///
+ [JsonProperty("locale")]
+ public string Locale { get; set; }
+
+ ///
+ /// If true all line numbers are 1-based (default).
+ ///
+ [JsonProperty("linesStartAt1")]
+ public bool LinesStartAt1 { get; set; } = true;
+
+ ///
+ /// If true all column numbers are 1-based (default).
+ ///
+ [JsonProperty("columnsStartAt1")]
+ public bool ColumnsStartAt1 { get; set; } = true;
+
+ ///
+ /// Determines in what format paths are specified. The default is 'path'.
+ ///
+ [JsonProperty("pathFormat")]
+ public string PathFormat { get; set; } = "path";
+
+ ///
+ /// Client supports the type attribute for variables.
+ ///
+ [JsonProperty("supportsVariableType")]
+ public bool SupportsVariableType { get; set; }
+
+ ///
+ /// Client supports the paging of variables.
+ ///
+ [JsonProperty("supportsVariablePaging")]
+ public bool SupportsVariablePaging { get; set; }
+
+ ///
+ /// Client supports the runInTerminal request.
+ ///
+ [JsonProperty("supportsRunInTerminalRequest")]
+ public bool SupportsRunInTerminalRequest { get; set; }
+
+ ///
+ /// Client supports memory references.
+ ///
+ [JsonProperty("supportsMemoryReferences")]
+ public bool SupportsMemoryReferences { get; set; }
+
+ ///
+ /// Client supports progress reporting.
+ ///
+ [JsonProperty("supportsProgressReporting")]
+ public bool SupportsProgressReporting { get; set; }
+ }
+
+ ///
+ /// Debug adapter capabilities returned in InitializeResponse.
+ ///
+ public class Capabilities
+ {
+ ///
+ /// The debug adapter supports the configurationDone request.
+ ///
+ [JsonProperty("supportsConfigurationDoneRequest")]
+ public bool SupportsConfigurationDoneRequest { get; set; }
+
+ ///
+ /// The debug adapter supports function breakpoints.
+ ///
+ [JsonProperty("supportsFunctionBreakpoints")]
+ public bool SupportsFunctionBreakpoints { get; set; }
+
+ ///
+ /// The debug adapter supports conditional breakpoints.
+ ///
+ [JsonProperty("supportsConditionalBreakpoints")]
+ public bool SupportsConditionalBreakpoints { get; set; }
+
+ ///
+ /// The debug adapter supports a (side effect free) evaluate request for data hovers.
+ ///
+ [JsonProperty("supportsEvaluateForHovers")]
+ public bool SupportsEvaluateForHovers { get; set; }
+
+ ///
+ /// The debug adapter supports stepping back via the stepBack and reverseContinue requests.
+ ///
+ [JsonProperty("supportsStepBack")]
+ public bool SupportsStepBack { get; set; }
+
+ ///
+ /// The debug adapter supports setting a variable to a value.
+ ///
+ [JsonProperty("supportsSetVariable")]
+ public bool SupportsSetVariable { get; set; }
+
+ ///
+ /// The debug adapter supports restarting a frame.
+ ///
+ [JsonProperty("supportsRestartFrame")]
+ public bool SupportsRestartFrame { get; set; }
+
+ ///
+ /// The debug adapter supports the gotoTargets request.
+ ///
+ [JsonProperty("supportsGotoTargetsRequest")]
+ public bool SupportsGotoTargetsRequest { get; set; }
+
+ ///
+ /// The debug adapter supports the stepInTargets request.
+ ///
+ [JsonProperty("supportsStepInTargetsRequest")]
+ public bool SupportsStepInTargetsRequest { get; set; }
+
+ ///
+ /// The debug adapter supports the completions request.
+ ///
+ [JsonProperty("supportsCompletionsRequest")]
+ public bool SupportsCompletionsRequest { get; set; }
+
+ ///
+ /// The debug adapter supports the modules request.
+ ///
+ [JsonProperty("supportsModulesRequest")]
+ public bool SupportsModulesRequest { get; set; }
+
+ ///
+ /// The debug adapter supports the terminate request.
+ ///
+ [JsonProperty("supportsTerminateRequest")]
+ public bool SupportsTerminateRequest { get; set; }
+
+ ///
+ /// The debug adapter supports the terminateDebuggee attribute on the disconnect request.
+ ///
+ [JsonProperty("supportTerminateDebuggee")]
+ public bool SupportTerminateDebuggee { get; set; }
+
+ ///
+ /// The debug adapter supports the delayed loading of parts of the stack.
+ ///
+ [JsonProperty("supportsDelayedStackTraceLoading")]
+ public bool SupportsDelayedStackTraceLoading { get; set; }
+
+ ///
+ /// The debug adapter supports the loadedSources request.
+ ///
+ [JsonProperty("supportsLoadedSourcesRequest")]
+ public bool SupportsLoadedSourcesRequest { get; set; }
+
+ ///
+ /// The debug adapter supports sending progress reporting events.
+ ///
+ [JsonProperty("supportsProgressReporting")]
+ public bool SupportsProgressReporting { get; set; }
+
+ ///
+ /// The debug adapter supports the runInTerminal request.
+ ///
+ [JsonProperty("supportsRunInTerminalRequest")]
+ public bool SupportsRunInTerminalRequest { get; set; }
+
+ ///
+ /// The debug adapter supports the cancel request.
+ ///
+ [JsonProperty("supportsCancelRequest")]
+ public bool SupportsCancelRequest { get; set; }
+
+ ///
+ /// The debug adapter supports exception options.
+ ///
+ [JsonProperty("supportsExceptionOptions")]
+ public bool SupportsExceptionOptions { get; set; }
+
+ ///
+ /// The debug adapter supports value formatting options.
+ ///
+ [JsonProperty("supportsValueFormattingOptions")]
+ public bool SupportsValueFormattingOptions { get; set; }
+
+ ///
+ /// The debug adapter supports exception info request.
+ ///
+ [JsonProperty("supportsExceptionInfoRequest")]
+ public bool SupportsExceptionInfoRequest { get; set; }
+ }
+
+ #endregion
+
+ #region Attach Request
+
+ ///
+ /// Arguments for 'attach' request. Additional attributes are implementation specific.
+ ///
+ public class AttachRequestArguments
+ {
+ ///
+ /// Arbitrary data from the previous, restarted session.
+ ///
+ [JsonProperty("__restart", NullValueHandling = NullValueHandling.Ignore)]
+ public object Restart { get; set; }
+ }
+
+ #endregion
+
+ #region Disconnect Request
+
+ ///
+ /// Arguments for 'disconnect' request.
+ ///
+ public class DisconnectRequestArguments
+ {
+ ///
+ /// A value of true indicates that this disconnect request is part of a restart sequence.
+ ///
+ [JsonProperty("restart")]
+ public bool Restart { get; set; }
+
+ ///
+ /// Indicates whether the debuggee should be terminated when the debugger is disconnected.
+ ///
+ [JsonProperty("terminateDebuggee")]
+ public bool TerminateDebuggee { get; set; }
+
+ ///
+ /// Indicates whether the debuggee should stay suspended when the debugger is disconnected.
+ ///
+ [JsonProperty("suspendDebuggee")]
+ public bool SuspendDebuggee { get; set; }
+ }
+
+ #endregion
+
+ #region Threads Request/Response
+
+ ///
+ /// A Thread in DAP represents a unit of execution.
+ /// For Actions runner, we have a single thread representing the job.
+ ///
+ public class Thread
+ {
+ ///
+ /// Unique identifier for the thread.
+ ///
+ [JsonProperty("id")]
+ public int Id { get; set; }
+
+ ///
+ /// The name of the thread.
+ ///
+ [JsonProperty("name")]
+ public string Name { get; set; }
+ }
+
+ ///
+ /// Response body for 'threads' request.
+ ///
+ public class ThreadsResponseBody
+ {
+ ///
+ /// All threads.
+ ///
+ [JsonProperty("threads")]
+ public List Threads { get; set; } = new List();
+ }
+
+ #endregion
+
+ #region StackTrace Request/Response
+
+ ///
+ /// Arguments for 'stackTrace' request.
+ ///
+ public class StackTraceArguments
+ {
+ ///
+ /// Retrieve the stacktrace for this thread.
+ ///
+ [JsonProperty("threadId")]
+ public int ThreadId { get; set; }
+
+ ///
+ /// The index of the first frame to return.
+ ///
+ [JsonProperty("startFrame")]
+ public int? StartFrame { get; set; }
+
+ ///
+ /// The maximum number of frames to return.
+ ///
+ [JsonProperty("levels")]
+ public int? Levels { get; set; }
+ }
+
+ ///
+ /// A Stackframe contains the source location.
+ /// For Actions runner, each step is a stack frame.
+ ///
+ public class StackFrame
+ {
+ ///
+ /// An identifier for the stack frame.
+ ///
+ [JsonProperty("id")]
+ public int Id { get; set; }
+
+ ///
+ /// The name of the stack frame, typically a method name.
+ /// For Actions, this is the step display name.
+ ///
+ [JsonProperty("name")]
+ public string Name { get; set; }
+
+ ///
+ /// The source of the frame.
+ ///
+ [JsonProperty("source", NullValueHandling = NullValueHandling.Ignore)]
+ public Source Source { get; set; }
+
+ ///
+ /// The line within the source of the frame.
+ ///
+ [JsonProperty("line")]
+ public int Line { get; set; }
+
+ ///
+ /// Start position of the range covered by the stack frame.
+ ///
+ [JsonProperty("column")]
+ public int Column { get; set; }
+
+ ///
+ /// The end line of the range covered by the stack frame.
+ ///
+ [JsonProperty("endLine", NullValueHandling = NullValueHandling.Ignore)]
+ public int? EndLine { get; set; }
+
+ ///
+ /// End position of the range covered by the stack frame.
+ ///
+ [JsonProperty("endColumn", NullValueHandling = NullValueHandling.Ignore)]
+ public int? EndColumn { get; set; }
+
+ ///
+ /// A hint for how to present this frame in the UI.
+ ///
+ [JsonProperty("presentationHint", NullValueHandling = NullValueHandling.Ignore)]
+ public string PresentationHint { get; set; }
+ }
+
+ ///
+ /// A Source is a descriptor for source code.
+ ///
+ public class Source
+ {
+ ///
+ /// The short name of the source.
+ ///
+ [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
+ public string Name { get; set; }
+
+ ///
+ /// The path of the source to be shown in the UI.
+ ///
+ [JsonProperty("path", NullValueHandling = NullValueHandling.Ignore)]
+ public string Path { get; set; }
+
+ ///
+ /// If the value > 0 the contents of the source must be retrieved through
+ /// the 'source' request (even if a path is specified).
+ ///
+ [JsonProperty("sourceReference", NullValueHandling = NullValueHandling.Ignore)]
+ public int? SourceReference { get; set; }
+
+ ///
+ /// A hint for how to present the source in the UI.
+ ///
+ [JsonProperty("presentationHint", NullValueHandling = NullValueHandling.Ignore)]
+ public string PresentationHint { get; set; }
+ }
+
+ ///
+ /// Response body for 'stackTrace' request.
+ ///
+ public class StackTraceResponseBody
+ {
+ ///
+ /// The frames of the stack frame.
+ ///
+ [JsonProperty("stackFrames")]
+ public List StackFrames { get; set; } = new List();
+
+ ///
+ /// The total number of frames available in the stack.
+ ///
+ [JsonProperty("totalFrames", NullValueHandling = NullValueHandling.Ignore)]
+ public int? TotalFrames { get; set; }
+ }
+
+ #endregion
+
+ #region Scopes Request/Response
+
+ ///
+ /// Arguments for 'scopes' request.
+ ///
+ public class ScopesArguments
+ {
+ ///
+ /// Retrieve the scopes for the stack frame identified by frameId.
+ ///
+ [JsonProperty("frameId")]
+ public int FrameId { get; set; }
+ }
+
+ ///
+ /// A Scope is a named container for variables.
+ /// For Actions runner, scopes are: github, env, inputs, steps, secrets, runner, job
+ ///
+ public class Scope
+ {
+ ///
+ /// Name of the scope such as 'Arguments', 'Locals', or 'Registers'.
+ /// For Actions: 'github', 'env', 'inputs', 'steps', 'secrets', 'runner', 'job'
+ ///
+ [JsonProperty("name")]
+ public string Name { get; set; }
+
+ ///
+ /// A hint for how to present this scope in the UI.
+ ///
+ [JsonProperty("presentationHint", NullValueHandling = NullValueHandling.Ignore)]
+ public string PresentationHint { get; set; }
+
+ ///
+ /// The variables of this scope can be retrieved by passing the value of
+ /// variablesReference to the variables request.
+ ///
+ [JsonProperty("variablesReference")]
+ public int VariablesReference { get; set; }
+
+ ///
+ /// The number of named variables in this scope.
+ ///
+ [JsonProperty("namedVariables", NullValueHandling = NullValueHandling.Ignore)]
+ public int? NamedVariables { get; set; }
+
+ ///
+ /// The number of indexed variables in this scope.
+ ///
+ [JsonProperty("indexedVariables", NullValueHandling = NullValueHandling.Ignore)]
+ public int? IndexedVariables { get; set; }
+
+ ///
+ /// If true, the number of variables in this scope is large or expensive to retrieve.
+ ///
+ [JsonProperty("expensive")]
+ public bool Expensive { get; set; }
+
+ ///
+ /// The source for this scope.
+ ///
+ [JsonProperty("source", NullValueHandling = NullValueHandling.Ignore)]
+ public Source Source { get; set; }
+
+ ///
+ /// The start line of the range covered by this scope.
+ ///
+ [JsonProperty("line", NullValueHandling = NullValueHandling.Ignore)]
+ public int? Line { get; set; }
+
+ ///
+ /// Start position of the range covered by this scope.
+ ///
+ [JsonProperty("column", NullValueHandling = NullValueHandling.Ignore)]
+ public int? Column { get; set; }
+
+ ///
+ /// The end line of the range covered by this scope.
+ ///
+ [JsonProperty("endLine", NullValueHandling = NullValueHandling.Ignore)]
+ public int? EndLine { get; set; }
+
+ ///
+ /// End position of the range covered by this scope.
+ ///
+ [JsonProperty("endColumn", NullValueHandling = NullValueHandling.Ignore)]
+ public int? EndColumn { get; set; }
+ }
+
+ ///
+ /// Response body for 'scopes' request.
+ ///
+ public class ScopesResponseBody
+ {
+ ///
+ /// The scopes of the stack frame.
+ ///
+ [JsonProperty("scopes")]
+ public List Scopes { get; set; } = new List();
+ }
+
+ #endregion
+
+ #region Variables Request/Response
+
+ ///
+ /// Arguments for 'variables' request.
+ ///
+ public class VariablesArguments
+ {
+ ///
+ /// The variable for which to retrieve its children.
+ ///
+ [JsonProperty("variablesReference")]
+ public int VariablesReference { get; set; }
+
+ ///
+ /// Filter to limit the child variables to either named or indexed.
+ ///
+ [JsonProperty("filter", NullValueHandling = NullValueHandling.Ignore)]
+ public string Filter { get; set; }
+
+ ///
+ /// The index of the first variable to return.
+ ///
+ [JsonProperty("start", NullValueHandling = NullValueHandling.Ignore)]
+ public int? Start { get; set; }
+
+ ///
+ /// The number of variables to return.
+ ///
+ [JsonProperty("count", NullValueHandling = NullValueHandling.Ignore)]
+ public int? Count { get; set; }
+ }
+
+ ///
+ /// A Variable is a name/value pair.
+ ///
+ public class Variable
+ {
+ ///
+ /// The variable's name.
+ ///
+ [JsonProperty("name")]
+ public string Name { get; set; }
+
+ ///
+ /// The variable's value.
+ ///
+ [JsonProperty("value")]
+ public string Value { get; set; }
+
+ ///
+ /// The type of the variable's value.
+ ///
+ [JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)]
+ public string Type { get; set; }
+
+ ///
+ /// If variablesReference is > 0, the variable is structured and its children
+ /// can be retrieved by passing variablesReference to the variables request.
+ ///
+ [JsonProperty("variablesReference")]
+ public int VariablesReference { get; set; }
+
+ ///
+ /// The number of named child variables.
+ ///
+ [JsonProperty("namedVariables", NullValueHandling = NullValueHandling.Ignore)]
+ public int? NamedVariables { get; set; }
+
+ ///
+ /// The number of indexed child variables.
+ ///
+ [JsonProperty("indexedVariables", NullValueHandling = NullValueHandling.Ignore)]
+ public int? IndexedVariables { get; set; }
+
+ ///
+ /// A memory reference to a location appropriate for this result.
+ ///
+ [JsonProperty("memoryReference", NullValueHandling = NullValueHandling.Ignore)]
+ public string MemoryReference { get; set; }
+
+ ///
+ /// A reference that allows the client to request the location where the
+ /// variable's value is declared.
+ ///
+ [JsonProperty("declarationLocationReference", NullValueHandling = NullValueHandling.Ignore)]
+ public int? DeclarationLocationReference { get; set; }
+
+ ///
+ /// The evaluatable name of this variable which can be passed to the evaluate
+ /// request to fetch the variable's value.
+ ///
+ [JsonProperty("evaluateName", NullValueHandling = NullValueHandling.Ignore)]
+ public string EvaluateName { get; set; }
+ }
+
+ ///
+ /// Response body for 'variables' request.
+ ///
+ public class VariablesResponseBody
+ {
+ ///
+ /// All (or a range) of variables for the given variable reference.
+ ///
+ [JsonProperty("variables")]
+ public List Variables { get; set; } = new List();
+ }
+
+ #endregion
+
+ #region Continue Request/Response
+
+ ///
+ /// Arguments for 'continue' request.
+ ///
+ public class ContinueArguments
+ {
+ ///
+ /// Specifies the active thread. If the debug adapter supports single thread
+ /// execution, setting this will resume only the specified thread.
+ ///
+ [JsonProperty("threadId")]
+ public int ThreadId { get; set; }
+
+ ///
+ /// If this flag is true, execution is resumed only for the thread with given
+ /// threadId. If false, all threads are resumed.
+ ///
+ [JsonProperty("singleThread")]
+ public bool SingleThread { get; set; }
+ }
+
+ ///
+ /// Response body for 'continue' request.
+ ///
+ public class ContinueResponseBody
+ {
+ ///
+ /// If true, all threads are resumed. If false, only the thread with the given
+ /// threadId is resumed.
+ ///
+ [JsonProperty("allThreadsContinued")]
+ public bool AllThreadsContinued { get; set; } = true;
+ }
+
+ #endregion
+
+ #region Next Request
+
+ ///
+ /// Arguments for 'next' request.
+ ///
+ public class NextArguments
+ {
+ ///
+ /// Specifies the thread for which to resume execution for one step.
+ ///
+ [JsonProperty("threadId")]
+ public int ThreadId { get; set; }
+
+ ///
+ /// Stepping granularity.
+ ///
+ [JsonProperty("granularity", NullValueHandling = NullValueHandling.Ignore)]
+ public string Granularity { get; set; }
+
+ ///
+ /// If this flag is true, all other suspended threads are not resumed.
+ ///
+ [JsonProperty("singleThread")]
+ public bool SingleThread { get; set; }
+ }
+
+ #endregion
+
+ #region Evaluate Request/Response
+
+ ///
+ /// Arguments for 'evaluate' request.
+ ///
+ public class EvaluateArguments
+ {
+ ///
+ /// The expression to evaluate.
+ ///
+ [JsonProperty("expression")]
+ public string Expression { get; set; }
+
+ ///
+ /// Evaluate the expression in the scope of this stack frame.
+ ///
+ [JsonProperty("frameId", NullValueHandling = NullValueHandling.Ignore)]
+ public int? FrameId { get; set; }
+
+ ///
+ /// The context in which the evaluate request is used.
+ /// Values: 'watch', 'repl', 'hover', 'clipboard', 'variables'
+ ///
+ [JsonProperty("context", NullValueHandling = NullValueHandling.Ignore)]
+ public string Context { get; set; }
+ }
+
+ ///
+ /// Response body for 'evaluate' request.
+ ///
+ public class EvaluateResponseBody
+ {
+ ///
+ /// The result of the evaluate request.
+ ///
+ [JsonProperty("result")]
+ public string Result { get; set; }
+
+ ///
+ /// The type of the evaluate result.
+ ///
+ [JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)]
+ public string Type { get; set; }
+
+ ///
+ /// If variablesReference is > 0, the evaluate result is structured.
+ ///
+ [JsonProperty("variablesReference")]
+ public int VariablesReference { get; set; }
+
+ ///
+ /// The number of named child variables.
+ ///
+ [JsonProperty("namedVariables", NullValueHandling = NullValueHandling.Ignore)]
+ public int? NamedVariables { get; set; }
+
+ ///
+ /// The number of indexed child variables.
+ ///
+ [JsonProperty("indexedVariables", NullValueHandling = NullValueHandling.Ignore)]
+ public int? IndexedVariables { get; set; }
+
+ ///
+ /// A memory reference to a location appropriate for this result.
+ ///
+ [JsonProperty("memoryReference", NullValueHandling = NullValueHandling.Ignore)]
+ public string MemoryReference { get; set; }
+ }
+
+ #endregion
+
+ #region Events
+
+ ///
+ /// Body for 'stopped' event.
+ /// The event indicates that the execution of the debuggee has stopped.
+ ///
+ public class StoppedEventBody
+ {
+ ///
+ /// The reason for the event. For backward compatibility this string is shown
+ /// in the UI if the description attribute is missing.
+ /// Values: 'step', 'breakpoint', 'exception', 'pause', 'entry', 'goto',
+ /// 'function breakpoint', 'data breakpoint', 'instruction breakpoint'
+ ///
+ [JsonProperty("reason")]
+ public string Reason { get; set; }
+
+ ///
+ /// The full reason for the event, e.g. 'Paused on exception'.
+ /// This string is shown in the UI as is and can be translated.
+ ///
+ [JsonProperty("description", NullValueHandling = NullValueHandling.Ignore)]
+ public string Description { get; set; }
+
+ ///
+ /// The thread which was stopped.
+ ///
+ [JsonProperty("threadId", NullValueHandling = NullValueHandling.Ignore)]
+ public int? ThreadId { get; set; }
+
+ ///
+ /// A value of true hints to the client that this event should not change the focus.
+ ///
+ [JsonProperty("preserveFocusHint", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? PreserveFocusHint { get; set; }
+
+ ///
+ /// Additional information. E.g. if reason is 'exception', text contains the
+ /// exception name.
+ ///
+ [JsonProperty("text", NullValueHandling = NullValueHandling.Ignore)]
+ public string Text { get; set; }
+
+ ///
+ /// If allThreadsStopped is true, a debug adapter can announce that all threads
+ /// have stopped.
+ ///
+ [JsonProperty("allThreadsStopped", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? AllThreadsStopped { get; set; }
+
+ ///
+ /// Ids of the breakpoints that triggered the event.
+ ///
+ [JsonProperty("hitBreakpointIds", NullValueHandling = NullValueHandling.Ignore)]
+ public List HitBreakpointIds { get; set; }
+ }
+
+ ///
+ /// Body for 'continued' event.
+ /// The event indicates that the execution of the debuggee has continued.
+ ///
+ public class ContinuedEventBody
+ {
+ ///
+ /// The thread which was continued.
+ ///
+ [JsonProperty("threadId")]
+ public int ThreadId { get; set; }
+
+ ///
+ /// If true, all threads have been resumed.
+ ///
+ [JsonProperty("allThreadsContinued", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? AllThreadsContinued { get; set; }
+ }
+
+ ///
+ /// Body for 'terminated' event.
+ /// The event indicates that debugging of the debuggee has terminated.
+ ///
+ public class TerminatedEventBody
+ {
+ ///
+ /// A debug adapter may set restart to true to request that the client
+ /// restarts the session.
+ ///
+ [JsonProperty("restart", NullValueHandling = NullValueHandling.Ignore)]
+ public object Restart { get; set; }
+ }
+
+ ///
+ /// Body for 'output' event.
+ /// The event indicates that the target has produced some output.
+ ///
+ public class OutputEventBody
+ {
+ ///
+ /// The output category. If not specified, 'console' is assumed.
+ /// Values: 'console', 'important', 'stdout', 'stderr', 'telemetry'
+ ///
+ [JsonProperty("category", NullValueHandling = NullValueHandling.Ignore)]
+ public string Category { get; set; }
+
+ ///
+ /// The output to report.
+ ///
+ [JsonProperty("output")]
+ public string Output { get; set; }
+
+ ///
+ /// Support for keeping an output log organized by grouping related messages.
+ /// Values: 'start', 'startCollapsed', 'end'
+ ///
+ [JsonProperty("group", NullValueHandling = NullValueHandling.Ignore)]
+ public string Group { get; set; }
+
+ ///
+ /// If variablesReference is > 0, the output contains objects which can be
+ /// retrieved by passing variablesReference to the variables request.
+ ///
+ [JsonProperty("variablesReference", NullValueHandling = NullValueHandling.Ignore)]
+ public int? VariablesReference { get; set; }
+
+ ///
+ /// The source location where the output was produced.
+ ///
+ [JsonProperty("source", NullValueHandling = NullValueHandling.Ignore)]
+ public Source Source { get; set; }
+
+ ///
+ /// The source location's line where the output was produced.
+ ///
+ [JsonProperty("line", NullValueHandling = NullValueHandling.Ignore)]
+ public int? Line { get; set; }
+
+ ///
+ /// The position in line where the output was produced.
+ ///
+ [JsonProperty("column", NullValueHandling = NullValueHandling.Ignore)]
+ public int? Column { get; set; }
+
+ ///
+ /// Additional data to report.
+ ///
+ [JsonProperty("data", NullValueHandling = NullValueHandling.Ignore)]
+ public object Data { get; set; }
+ }
+
+ ///
+ /// Body for 'thread' event.
+ /// The event indicates that a thread has started or exited.
+ ///
+ public class ThreadEventBody
+ {
+ ///
+ /// The reason for the event.
+ /// Values: 'started', 'exited'
+ ///
+ [JsonProperty("reason")]
+ public string Reason { get; set; }
+
+ ///
+ /// The identifier of the thread.
+ ///
+ [JsonProperty("threadId")]
+ public int ThreadId { get; set; }
+ }
+
+ ///
+ /// Body for 'exited' event.
+ /// The event indicates that the debuggee has exited and returns its exit code.
+ ///
+ public class ExitedEventBody
+ {
+ ///
+ /// The exit code returned from the debuggee.
+ ///
+ [JsonProperty("exitCode")]
+ public int ExitCode { get; set; }
+ }
+
+ #endregion
+
+ #region Error Response
+
+ ///
+ /// A structured error message.
+ ///
+ public class Message
+ {
+ ///
+ /// Unique identifier for the message.
+ ///
+ [JsonProperty("id")]
+ public int Id { get; set; }
+
+ ///
+ /// A format string for the message.
+ ///
+ [JsonProperty("format")]
+ public string Format { get; set; }
+
+ ///
+ /// An object used as a dictionary for looking up the variables in the format string.
+ ///
+ [JsonProperty("variables", NullValueHandling = NullValueHandling.Ignore)]
+ public Dictionary Variables { get; set; }
+
+ ///
+ /// If true send to telemetry.
+ ///
+ [JsonProperty("sendTelemetry", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? SendTelemetry { get; set; }
+
+ ///
+ /// If true show user.
+ ///
+ [JsonProperty("showUser", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? ShowUser { get; set; }
+
+ ///
+ /// A url where additional information about this message can be found.
+ ///
+ [JsonProperty("url", NullValueHandling = NullValueHandling.Ignore)]
+ public string Url { get; set; }
+
+ ///
+ /// A label that is presented to the user as the UI for opening the url.
+ ///
+ [JsonProperty("urlLabel", NullValueHandling = NullValueHandling.Ignore)]
+ public string UrlLabel { get; set; }
+ }
+
+ ///
+ /// Body for error responses.
+ ///
+ public class ErrorResponseBody
+ {
+ ///
+ /// A structured error message.
+ ///
+ [JsonProperty("error", NullValueHandling = NullValueHandling.Ignore)]
+ public Message Error { get; set; }
+ }
+
+ #endregion
+}
diff --git a/src/Runner.Worker/Dap/IDapDebugSession.cs b/src/Runner.Worker/Dap/IDapDebugSession.cs
new file mode 100644
index 000000000..5a45d49da
--- /dev/null
+++ b/src/Runner.Worker/Dap/IDapDebugSession.cs
@@ -0,0 +1,32 @@
+using System.Threading;
+using System.Threading.Tasks;
+using GitHub.Runner.Common;
+
+namespace GitHub.Runner.Worker.Dap
+{
+ public enum DapSessionState
+ {
+ WaitingForConnection,
+ Initializing,
+ Ready,
+ Paused,
+ Running,
+ Terminated
+ }
+
+ [ServiceLocator(Default = typeof(DapDebugSession))]
+ public interface IDapDebugSession : IRunnerService
+ {
+ bool IsActive { get; }
+ DapSessionState State { get; }
+ void SetDapServer(IDapServer server);
+ Task WaitForHandshakeAsync(CancellationToken cancellationToken);
+ Task OnStepStartingAsync(IStep step, IExecutionContext jobContext, bool isFirstStep, CancellationToken cancellationToken);
+ void OnStepCompleted(IStep step);
+ void OnJobCompleted();
+ void CancelSession();
+ void HandleClientConnected();
+ void HandleClientDisconnected();
+ Task HandleMessageAsync(string messageJson, CancellationToken cancellationToken);
+ }
+}
diff --git a/src/Runner.Worker/Dap/IDapServer.cs b/src/Runner.Worker/Dap/IDapServer.cs
new file mode 100644
index 000000000..a5b879360
--- /dev/null
+++ b/src/Runner.Worker/Dap/IDapServer.cs
@@ -0,0 +1,18 @@
+using System.Threading;
+using System.Threading.Tasks;
+using GitHub.Runner.Common;
+
+namespace GitHub.Runner.Worker.Dap
+{
+ [ServiceLocator(Default = typeof(DapServer))]
+ public interface IDapServer : IRunnerService
+ {
+ void SetSession(IDapDebugSession session);
+ Task StartAsync(int port, CancellationToken cancellationToken);
+ Task WaitForConnectionAsync(CancellationToken cancellationToken);
+ Task StopAsync();
+ void SendMessage(ProtocolMessage message);
+ void SendEvent(Event evt);
+ void SendResponse(Response response);
+ }
+}