# Debug Server Each Deft runtime can expose an in-process **debug server** that external processes (the shell app, editors, VS Code extensions, custom tooling) connect to via TCP. The protocol is JSON-RPC 2.0 over newline-delimited TCP. Use cases: - Live introspection from an external REPL. - Editor integration: list defs, get source, inspect variables, complete symbols. - Step-debugger backends. - Hot-reload workflows. ## `debug/*` Stdlib functions | Function | Returns | Purpose | |---|---|---| | `[debug/serve :name $port]` | server resource | Start a debug server | | `[debug/stop $server]` | nil | Stop a server | | `[debug/list]` | list | List active debug servers | ## Starting a Server
 def srv [debug/serve :my-app 8765]
echo "debug server on :8765" 
External processes can now connect to `127.0.0.1:8765` and start sending JSON-RPC requests. ## The Protocol JSON-RPC 2.0 over newline-delimited TCP. Each request is a single-line JSON object; each response is a single-line JSON object. ```json { "jsonrpc": "2.0", "id": 1, "method": "eval", "params": { "code": "(+ 1 2)" } } ``` ```json { "jsonrpc": "2.0", "id": 1, "result": { "value": 3, "print": "" } } ``` Notifications (no `id`) are used for events the server emits spontaneously — trace output, breakpoints firing, etc. ## Common Methods | Method | Purpose | |---|---| | `eval` | Evaluate a code string in the runtime | | `list-defs` | List defs in the current namespace | | `list-vars` | List vars in the current namespace | | `inspect` | Inspect a named value | | `get-source` | Get the source code of a def | | `complete` | Complete a symbol at a cursor position | | `reload` | Reload a module | See `packages/stdext/src/debug-host.dft` for the host-side implementations and `packages/stdext/src/debug-client.dft` for a Deft-level client you can embed in your own tooling. ## Connecting a Client Any TCP-speaking process can connect. A minimal Deft client:
 import "deft/stdext/debug-client" as dbg

def session [dbg/connect 8765]

set result [dbg/eval $session "(+ 1 2)"]
echo $result~value                               # => 3

set defs [dbg/list-defs $session]
for name $defs { echo $name }

dbg/_close $session 
`packages/stdext/src/debug-client.dft` provides a full client with reconnect, retry, and request/response correlation. ## The Shell's Use The TUI's `shell` app uses the debug protocol to provide an in-process REPL. When you "attach" the shell to a runtime, it spawns a child runtime running a debug server, then drives it from the shell panel:
 # packages/stdext/src/repl.dft (simplified)
def create {|name|
    if [runtime/exists? $name] { return $name }
    if [err? [runtime/create $name]] { return nil }
    runtime/spawn $name [launcher-path] %{ :repl-name $name }
|
} 
The launched REPL host opens a debug server on a per-name port; the shell connects and routes user input through `eval`. ## Editor Integration The editor app connects to the active shell's debug server to provide: - Symbol completion (`complete` method) - Go-to-definition (`inspect` + `get-source`) - Inline documentation (`get-source` + `info/props`) - Eval-in-REPL (`eval`) See `packages/editor/src/editor.dft` and `packages/stdext/src/debug-client.dft` for the production code. ## Limits - Max 8 debug servers per process. - Max 16 sessions per server. - Sessions are line-buffered; very large eval payloads should be chunked. ## Lifecycle
 def srv [debug/serve :dev 8765]

# ... server runs in the background, dispatching requests on the
# event loop ...

debug/stop $srv                                # graceful shutdown 
`debug/stop` closes the listener and all active sessions. Sessions get a clean EOF; they should reconnect if they want to keep talking. ## Quick Reference | Form | Purpose | |---|---| | `[debug/serve :name $port]` | Start server | | `[debug/stop $server]` | Stop server | | `[debug/list]` | Active servers | | Client: `dbg/connect $port` (from stdext/debug-client) | Connect | | Client: `dbg/eval $session $code` | Eval | | Client: `dbg/list-defs $session` | List defs | | Client: `dbg/_close $session` | Disconnect |