keel dap
Run a Keel program under the Debug Adapter Protocol (DAP), so an editor can set breakpoints, step, and inspect variables in a live interpreter session.
keel dap <file>
keel dap does not print program output to a terminal for a human to read. It speaks DAP over stdio — newline-free, Content-Length-framed JSON messages — to whichever client launched it. Point your editor’s debug configuration at the keel binary with this subcommand; you will not typically run it by hand.
Editor integration for vscode-keel — a launch.json config that lets VS Code’s “Run and Debug” panel invoke keel dap automatically — is Coming soon.
Status: not yet shipped. Until then, configure your DAP client to run
keel dap <file>(orkeel test --debug --filter <name> <file>) directly.
Behavior
- Parses and type-checks
<file>first — the same gatekeel runuses. A type error is reported and the session ends before any DAP handshake happens. - Source breakpoints are honored across every module the program imports, not just the entry file.
next(step over),stepIn, andstepOutbehave like a conventional debugger:nextdoes not descend into a called task;stepIndoes;stepOutruns until the current call returns.- The
scopesresponse includes aLocalsscope always, and anAgent Statescope whenever the paused frame is running inside a live agent (an@on_start/@on_stopblock or anon <event>handler) — its variables are that agent instance’s declaredstatefields. evaluate(hover/watch expressions) reuses the program’s own expression evaluator against the paused frame’s live locals, so it produces the same values and errors the paused statement would.- Only the innermost paused frame’s
Locals/Agent Stateare populated; outer frames appear instackTracebut theirvariablesrequests return no bindings. Seedocs/src/guide/debugging.mdfor the full list of D0 gaps.
keel test --debug
To debug a single test instead of a whole program, use keel test’s --debug flag together with --filter:
keel test --debug --filter "square works" suite.keel
--filter must match exactly one test — --debug fails fast with an error if it matches zero or more than one, since a DAP session can only debug a single running program. Parameterized tests (test "name" for case in cases { ... }) are not yet debuggable under --debug.
Example
task add(a: int, b: int) -> int {
sum = a + b # breakpoint here
return sum
}
x = 1
y = 2
z = add(x, y)
keel dap add.keel
A DAP client that sets a breakpoint on the sum = a + b line, runs configurationDone, and waits will receive a stopped event once the program reaches that statement; stackTrace/scopes/variables then show the add frame with a = 1 and b = 2 in scope.