@flydut/opencode-dap
v0.0.4
Published
[中文文档](README_zh.md)
Readme
opencode-dap
DAP (Debug Adapter Protocol) client for OpenCode — ported from oh-my-pi.
Lets AI coding agents debug programs via the Debug Adapter Protocol — supports 15 debug adapters covering ~19 languages. Drop it into OpenCode with a single plugin entry or use it as a standalone Bun/Node library.
Quick Start
opencode plugin @flydut/opencode-dapRestart OpenCode. The debug tool is available with 30+ actions. Debug sessions are automatically cleaned up on session idle/deleted.
Upgrade
opencode plugin @flydut/opencode-dap --forceVerify
grep "opencode-dap" ~/.local/share/opencode/log/opencode.logThen in OpenCode, run debug action=sessions to confirm the tool is registered.
Manual install (not recommended)
npm install @flydut/opencode-dap --save-devThen add to opencode.json:
{ "plugin": ["@flydut/opencode-dap"] }Supported Adapters
| Adapter | Languages | Command | Install |
|---|---|---|---|
| gdb | C, C++, Rust | gdb -i dap | system package |
| lldb-dap | C, C++, ObjC, Swift, Rust, Zig | lldb-dap | brew install llvm (macOS), apt install lldb |
| codelldb | C, C++, Rust, Zig | codelldb | VS Code extension |
| debugpy | Python | python -m debugpy.adapter | pip install debugpy |
| dlv | Go | dlv dap | go install github.com/go-delve/delve/cmd/dlv@latest |
| js-debug-adapter | JavaScript, TypeScript | js-debug-adapter | GitHub |
| netcoredbg | C#, F# | netcoredbg --interpreter=vscode | GitHub |
| kotlin-debug-adapter | Kotlin | kotlin-debug-adapter | GitHub |
| java-debug | Java | python3 -u $JDTLS_HOME/java_dap_bridge.py | see Java Setup |
| rdbg | Ruby | rdbg --open --command -- | gem install debug |
| php-debug-adapter | PHP | php-debug-adapter | VS Code extension |
| bash-debug-adapter | Bash/Shell | bash-debug-adapter | npm install -g @vscode/bash-debug |
| dart-debug-adapter | Dart | dart debug_adapter | Dart SDK |
| flutter-debug-adapter | Dart (Flutter) | dart debug_adapter | Flutter SDK |
| elixir-ls-debugger | Elixir | elixir-ls-debugger | GitHub |
Configuration (dap.json)
Adapter configuration is read from multiple locations, merged in priority order (lowest first):
| Priority | Location | Scope |
|----------|----------|-------|
| lowest | plugin defaults (defaults.json) | built-in |
| — | ~/.config/opencode/opencode-dap.json | global — all projects |
| highest | <project>/dap.json (or .opencode/dap.json) | project — overrides globals |
Set shared settings (JAVA_BIN, JDTLS_HOME) in the global config, and project-specific settings (mainClass, projectName, classPaths) in each project's dap.json.
Java
Java DAP debugging is special — there's no standalone debug adapter. Instead, the java-debug plugin runs inside Eclipse JDTLS as an OSGi bundle. This plugin ships a Python bridge script (java_dap_bridge.py) that:
- Starts a dedicated JDTLS LSP instance (isolated from the main OpenCode LSP)
- Completes the LSP handshake
- Sends
vscode.java.startDebugSessionto obtain a DAP TCP port - Bridges stdin/stdout ↔ TCP so OpenCode speaks plain DAP
Why a separate JDTLS instance? Opencode JDTLS communicates over stdio — a single bidirectional pipe carrying LSP messages. OpenCode's LSP integration occupies that pipe exclusively. The bridge therefore launches a second JDTLS instance dedicated to DAP, with its own workspace at ~/.cache/jdtls-workspace-dap/. To avoid re-importing Maven projects, the bridge automatically copies the LSP workspace (~/.cache/jdtls-workspace/) on first launch.
Recommendation — Use opencode-jdtls-launcher to manage your JDTLS installation. Its JVM parameters are tuned for large projects. While LSP and DAP still cannot reuse the same JDTLS instance, both can share a common workspace directory. If both have
NEED_REGEN_CDSenabled, they can also share the same CDS archive (requires matching JDTLS and JDK versions).
Prerequisites
| Component | Purpose | Download | |-----------|---------|----------| | Python ≥3.9 | Runs the bridge script | | | Eclipse JDTLS | Language server + debug host | download | | java-debug plugin | The DAP implementation inside JDTLS | GitHub Releases |
After downloading JDTLS, unpack it to a directory (e.g. ~/.local/share/jdtls/). The debug plugin jar goes into the same directory or a plugins/ subdirectory.
JDTLS_HOME and DEBUG_PLUGIN_JAR are required — put them in your global config. mainClass, projectName, and classPaths are optional: the AI can pass them dynamically via tool parameters, but for non-throwaway projects, adding them to the project dap.json reduces the chance of mistakes.
Global config (~/.config/opencode/opencode-dap.json)
{
"adapters": {
"java-debug": {
"env": {
"JDTLS_HOME": "/path/to/jdtls",
"DEBUG_PLUGIN_JAR": "$JDTLS_HOME/com.microsoft.java.debug.plugin-x.x.x.jar"
}
}
}
}Project config (<project root>/dap.json)
The command and args are inherited from the global config. Only set what differs per project — mainClass, projectName, classPaths, and optional overrides:
The projectName must match a module name in your JDTLS workspace. For multi-module Maven projects, use the module's artifactId.
{
"adapters": {
"java-debug": {
"launchDefaults": {
"mainClass": "com.example.Main",
"projectName": "artifactId",
"classPaths": ["target/classes"]
}
}
}
}When both configs exist, fields are deep-merged: launchDefaults, attachDefaults, and env are merged recursively; other fields are overwritten.
Bridge Script
The bridge script (java_dap_bridge.py) ships inside this plugin and is located automatically via the $OPC_DAP_ROOT variable. The default adapter config already references it as $OPC_DAP_ROOT/src/dap/java_dap_bridge.py.
If you need to override the path (e.g. to use a custom bridge), set args in your dap.json.
Environment Variables
All variables go under env in your adapter config. Variables marked with $VAR or ${VAR} syntax are expanded automatically — both in args (by the plugin) and in env values (by the bridge).
| Variable | Default | Description |
|----------|---------|-------------|
| JDTLS_HOME | — | JDTLS installation root |
| JAVA_HOME | java | $JAVA_HOME/bin/java |
| DEBUG_PLUGIN_JAR | — | Path to com.microsoft.java.debug.plugin-*.jar (required) |
| JDTLS_IMPORT_WAIT | 15 | Seconds to wait after JDTLS init for Maven/Gradle import |
| JDTLS_XMS | 128m | Initial JVM heap (DAP needs much less than LSP) |
| JDTLS_XMX | 512m | Max JVM heap |
| JDTLS_METASPACE_SIZE | 128m | Metaspace size |
| JDTLS_MAX_METASPACE_SIZE | 256m | Max Metaspace |
| DAP_HOST | 127.0.0.1 | DAP server bind address |
| DAP_CONNECT_TIMEOUT | 30 | TCP connect timeout (seconds) |
| LSP_INIT_TIMEOUT | 60 | JDTLS initialize timeout (seconds) |
