Extension Debug @piex-dev/dap

dap — Real Debugging for Coding Agents

TL;DR

After installing @piex-dev/dap, the agent can "run and look" like a human. It won't replace tests, but it turns "guess the variable" into "read the variable".

Overview

Most coding agents "fix bugs" by reading code, guessing a cause, editing a few lines, re-running tests in bash, then guessing again. This works for simple issues but breaks on runtime-only problems: which stack frame threw? what was that local variable? does a breakpoint on a conditional branch hold?

DAP is the VS Code debugging protocol. @piex-dev/dap brings it to Pi: the model calls a debug tool to launch, set breakpoints, step and inspect variables.

How it works

Three layers: Agent (Pi + LLM decides) → DAP client (@piex-dev/dap translates to standard DAP requests) → Debug Adapter (debugpy/dlv/lldb-dap controls the process). The session state machine is running/stopped/terminated; each tool call returns a session summary + formatted text, not raw JSON-RPC.

lifecycle
launch/attach → spawn adapter(stdio) → initialize
→ running → stopped(breakpoint/step/exception)
→ stack_trace/variables/evaluate
→ continue/step_* → terminate

Adapter selection: defaults.json holds start command, language suffix, project-root marker and launch/attach defaults; launch auto-picks by suffix + workspace marker. The Node port is stdio-only (covers local debugging, no socket lifecycle), no remote TCP attach.

Usage

Install

bash
pi install npm:@piex-dev/dap

Source: extensions/dap

Prerequisites

The extension handles protocol and sessions, not installing debuggers. Install the adapter for your language:

bash
pip install debugpy        # Python
brew install llvm           # lldb-dap
go install github.com/go-delve/delve/cmd/dlv@latest  # Go

14 adapters supported: gdb, lldb-dap, codelldb, debugpy, dlv, js-debug-adapter, netcoredbg, kotlin-debug-adapter, rdbg, php-debug-adapter, bash-debug-adapter, dart-debug-adapter, flutter-debug-adapter, elixir-ls-debugger.

Configuration

Defaults live in extensions/dap/defaults.json. No manual config needed — the extension auto-selects an adapter by file suffix + project-root marker; the model may also name an adapter explicitly.

Typical usage

debug tool
debug(action=launch, program=./main.py)
debug(action=set_breakpoint, path=main.py, line=42)
debug(action=continue)
# after hit
debug(action=stack_trace)
debug(action=variables, variablesReference=…)
debug(action=evaluate, expression="user.id")

Verify

bash
pi -e ./extensions/dap/src/dap.ts -p "what is 1+1" --no-session

Implementation

dap.ts registers the debug tool and dispatches actions; client.ts handles Content-Length frames + JSON-RPC; session.ts manages sessions, breakpoint queue, output buffer and idle cleanup; config.ts reads defaults.json and picks an adapter.

Domainactions
Sessionlaunch / attach / terminate / sessions / output
Breakpointsset_breakpoint / remove_breakpoint
Executioncontinue / step_over / step_in / step_out / pause
Inspectionstack_trace / threads / scopes / variables / evaluate
Low-leveldisassemble / read_memory / write_memory / modules / loaded_sources / custom_request

Capabilities are checked against the adapter's reported capabilities: unsupported ops error out, no silent no-op. Engineering details: serialized breakpoint mutations, ring-buffered output (~128KB), idle reaping, clamped timeouts (5s–300s, default 30s), non-interactive env injection (PAGER=cat).

Design notes

ProjectMechanismpiex choice
oh-my-pi dapfull DAP client: stdio + TCP + WebSocket; 14+ adapters; structured output; TUI variable explorerAdopted: 14-adapter config, JSON-RPC framing, breakpoint queue, output cap, idle reaping. Not adopted: TCP/WebSocket, TUI overlay (pi API limits)
VS Code DAPthree-layer spec (editor / client / adapter)Borrowed: three-layer split, capabilities check, auto context summary on stop

Core trade-off: stdio only (simple and safe), no remote attach; text output first, TUI later; capabilities-driven action surface, not all at once.

Changelog

Roadmap

CurrentImpactPlan
stdio only, no TCP/WebSockethard to attach remote debug serversoptional TCP as advanced, stdio default
data/instruction/exception breakpoints not fully exposed"who wrote this memory" questions are hardgradually expose by capabilities
completions, exceptionInfo not all exposedexisting adapter capabilities unusedadd actions by usage frequency
plain-text outputstack/vars less readable than ompdefault stop summary first, then TUI
depends on locally installed adaptershigher setup barrierdocument gaps; preinstall in eval images

Product direction: context-on-stop (auto top frame + key vars); project-aware launch (read .vscode/launch.json); eval hook (debug_success reproducible tasks).

Version history

VersionDateChanges
0.1.12026-07-19Initial release: 14-adapter default config; DAP client (stdio + JSON-RPC); session management (breakpoint queue, ring-buffered output, idle reaping, clamped timeout); Node port (Bun.spawn → child_process.spawn)