Claude-skill-registry adapter-development
Comprehensive guide for AIDB debug adapter development. Covers component-based
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/adapter-development" ~/.claude/skills/majiayu000-claude-skill-registry-adapter-development && rm -rf "$T"
skills/data/adapter-development/SKILL.mdAIDB Adapter Development Skill
Executive Summary
AIDB debug adapters provide language-agnostic debugging capabilities through the Debug Adapter Protocol (DAP). The architecture is component-based - adapters delegate to specialized components rather than implementing everything in monolithic classes.
For comprehensive architecture details, see
docs/developer-guide/overview.md for the complete system architecture and data flow diagrams.
Core Architecture
DebugAdapter (base class) ├── ProcessManager - Process lifecycle (launch, monitor, stop, cleanup) ├── PortManager - Port acquisition, verification, release ├── LaunchOrchestrator - Launch sequence coordination ├── TargetResolver - Target type detection and normalization ├── SourcePathResolver - Source path resolution for remote debugging └── AdapterHooksMixin - Lifecycle hooks for extension points
Key Principles
- Component Delegation: Adapters delegate to focused components (ProcessManager, PortManager, LaunchOrchestrator)
- Lifecycle Hooks: Customize behavior via hooks rather than overriding entire methods
- Resource Management: Centralized cleanup via ResourceManager
- Human-Cadence Debugging: Operations happen at human speed, not API speed
- Language-Agnostic API: Same Python API works across Python, JavaScript, Java
Resource Files
This skill is organized into focused resource files for language-specific patterns:
- python-adapter-patterns.md - debugpy configuration, module vs script patterns
- javascript-adapter-patterns.md - vscode-js-debug, child sessions, Node.js patterns
- java-adapter-patterns.md - java-debug + JDT LS integration, compilation
Related Skills
When working on adapter development, you may also need:
- dap-protocol-guide - Adapters heavily rely on DAP protocol types and request/response patterns
- testing-strategy - Adapters must be tested using E2E patterns with DebugInterface abstraction
- code-reuse-enforcement - Always check for existing utilities before implementing adapter components
Quick Start: Creating a New Adapter
from aidb.adapters.base import DebugAdapter from aidb.adapters.base.config import AdapterConfig class MyLanguageAdapter(DebugAdapter): """My language debug adapter using component architecture.""" def __init__(self, session, ctx=None, config=None, **kwargs): if config is None: config = MyLanguageConfig() super().__init__( session=session, ctx=ctx, config=config, **kwargs ) # Register language-specific hooks self._register_my_language_hooks() def _register_my_language_hooks(self): """Register language-specific lifecycle hooks.""" self.register_hook( LifecycleHook.PRE_LAUNCH, self._validate_environment, priority=90 # High priority = runs first ) async def _validate_environment(self, context: HookContext): """Pre-launch hook to validate environment.""" # Validation logic here pass async def _build_launch_command(self, target, adapter_host, adapter_port, args=None): """Build the command to launch the debug adapter.""" return [ "/path/to/debug/adapter", "--host", adapter_host, "--port", str(adapter_port), target ] def _add_adapter_specific_vars(self, env: dict) -> dict: """Add language-specific environment variables.""" env["MY_LANG_DEBUG"] = "1" return env def _create_target_resolver(self) -> "TargetResolver": """Create language-specific target resolver.""" return MyLanguageTargetResolver(adapter=self, ctx=self.ctx) def _create_source_path_resolver(self) -> "SourcePathResolver": """Create language-specific source path resolver for remote debugging.""" return MyLanguageSourcePathResolver(adapter=self, ctx=self.ctx) def _get_process_name_pattern(self) -> str: """Get process name pattern for cleanup.""" return "my-language-debug"
Component Access Patterns
ProcessManager Usage
See
ProcessManager in src/aidb/adapters/base/components/process_manager.py for full implementation.
from aidb.resources.process_tags import ProcessType # Launch subprocess with session tagging proc = await self._process_manager.launch_subprocess( cmd=cmd, env=env, session_id=self.session.id, language=self.config.language, process_type=ProcessType.ADAPTER, # String constant: "adapter", "debuggee", or "lsp_server" kwargs={} ) # Wait for adapter readiness await self._process_manager.wait_for_adapter_ready(port, start_time) # Get process status if self._process_manager.is_alive: pid = self._process_manager.pid
PortManager Usage
See
PortManager in src/aidb/adapters/base/components/port_manager.py for full implementation. Key methods:
- Acquire and verify port availabilityacquire(requested_port=None)
- Release the portrelease()
property - Get current portport
LaunchOrchestrator Usage
See
LaunchOrchestrator in src/aidb/adapters/base/components/launch_orchestrator.py for full implementation. Key methods:
- Simple launch with target filelaunch(target, port, args)
- Launch with VS Code launch.json configurationlaunch_with_config(launch_config, port, workspace_root)
SourcePathResolver Usage
See
SourcePathResolver in src/aidb/adapters/base/source_path_resolver.py for base implementation. Each language adapter implements its own resolver:
- Python:
- Handles site-packages, venv, egg pathssrc/aidb/adapters/lang/python/source_path_resolver.py - JavaScript:
- Handles node_modules, webpack pathssrc/aidb/adapters/lang/javascript/source_path_resolver.py - Java:
- Handles JAR notation, Maven layoutssrc/aidb/adapters/lang/java/source_path_resolver.py
Key methods:
- Extract language-specific relative path from adapter-returned pathextract_relative_path(file_path)
- Resolve remote path to local source fileresolve(file_path, source_paths)
Lifecycle Hooks Reference
Hooks execute in priority order (lower number = runs first):
Hook Priorities
- 90-100: Critical validation (environment, target file)
- 70-80: Setup/preparation (workspaces, configurations)
- 50: Default priority
- 20-30: Post-operation delays/waits
- 10: Cleanup operations
Common Hooks
# Pre-launch validation self.register_hook( LifecycleHook.PRE_LAUNCH, self._validate_environment, priority=90 ) # Post-launch setup self.register_hook( LifecycleHook.POST_LAUNCH, self._wait_for_ready, priority=20 ) # Post-stop cleanup self.register_hook( LifecycleHook.POST_STOP, self._cleanup_resources, priority=10 )
Code Reuse: Existing Utilities
Before implementing new functionality, check these shared resources:
Base Classes
- DebugAdapter (
) - Base adapter with component architectureaidb/adapters/base/adapter.py - AdapterConfig (
) - Configuration base classaidb/adapters/base/config.py - BaseLaunchConfig (
) - VS Code launch.json supportaidb/adapters/base/launch.py
Components
- ProcessManager (
)aidb/adapters/base/components/process_manager.py - PortManager (
)aidb/adapters/base/components/port_manager.py - LaunchOrchestrator (
)aidb/adapters/base/components/launch_orchestrator.py
Utilities
- AdapterBinaryLocator (
) - Find adapter binariesaidb/adapters/utils/binary_locator.py - AdapterOutputCapture (
) - Capture stdout/stderraidb/adapters/utils/output_capture.py - AdapterTraceLogManager (
) - Trace log managementaidb/adapters/utils/trace_log.py
Common Patterns (aidb_common/
)
aidb_common/See source code docstrings in
src/aidb_common/ for detailed API documentation.
- Obj (
) - Base class with context supportaidb_common/patterns/ - normalize_path() (
) - Path normalizationaidb_common/path.py - config (
) - Environment variable readingaidb_common/config/ - Language enum (
) - Supported language constantsaidb_common/constants.py
Launch Configuration Patterns
Adapters can support VS Code launch.json configurations:
def get_launch_configuration(self) -> dict[str, Any]: """Get launch configuration for DAP Launch request.""" config = { "type": "mylang", "request": "launch", "name": "Debug MyLang", "program": self._target_file, "args": self._target_args, "cwd": self._target_cwd, "env": self._target_env, } return config
Environment Variable Patterns
See
src/aidb_common/env/ for environment handling utilities (reader.py, resolver.py).
Use the template method pattern for environment preparation:
def _prepare_environment(self) -> dict[str, str]: """Prepare environment (base implementation).""" env = self._load_base_environment() env = self._add_trace_configuration(env) return self._add_adapter_specific_vars(env) def _add_adapter_specific_vars(self, env: dict) -> dict: """Add language-specific variables (override this).""" env["MY_LANG_HOME"] = "/path/to/lang" return env
Resource Cleanup Patterns
Always implement proper cleanup in hooks:
async def stop(self) -> None: """Stop the debug adapter and clean up.""" context = await self.execute_hook(LifecycleHook.PRE_STOP) if not context.cancelled: # Stop process manager await self._process_manager.stop() # Release port if self.port: self._port_manager.release() # Cleanup auxiliary components if self._trace_manager: self._trace_manager.cleanup() await self.execute_hook(LifecycleHook.POST_STOP)
Process Tagging for Orphan Detection
All AIDB-spawned processes are tagged with environment variables for safe cleanup:
from aidb.resources.process_tags import ProcessType # Automatically handled by ProcessManager proc = await self.process_manager.launch_subprocess( cmd=cmd, env=env, session_id=self.session.id, # Tags process with session ID language=self.config.language, # Tags with language process_type=ProcessType.ADAPTER, # String constant: "adapter", "debuggee", or "lsp_server" kwargs={} )
Tags enable:
- Safe orphan detection across sessions
- Cleanup of only AIDB-owned processes
- Session-to-process mapping
DAP Protocol Reference
The authoritative DAP protocol reference is in
src/aidb/dap/protocol/ - fully typed and always up-to-date.
from aidb.dap.protocol.types import ( Capabilities, InitializeRequest, LaunchRequest, SetBreakpointsRequest, )
Testing Your Adapter
Use the shared test infrastructure:
# Test with API directly session = await client.start_session( target="/path/to/file", language="mylang", breakpoints=[{"line": 10}] ) # Test with launch.json session = await client.start_session( target="/path/to/file", language="mylang", launch_config_name="Debug MyLang", workspace_root="/path/to/project" )
Navigation to Resource Files
For detailed language-specific patterns and examples:
- Python Adapter Patterns →
resources/python-adapter-patterns.md- debugpy configuration, module vs script patterns, trace logging
- JavaScript Adapter Patterns →
resources/javascript-adapter-patterns.md- vscode-js-debug, child sessions, Node.js debugging, breakpoint transfer
- Java Adapter Patterns →
resources/java-adapter-patterns.md- java-debug + JDT LS integration, compilation, pooling patterns
Important Reminders
- Don't override entire methods - Use lifecycle hooks for customization
- Don't manage processes directly - Use ProcessManager component
- Don't handle ports manually - Use PortManager component
- Don't forget cleanup - Register POST_STOP hooks
- Don't block async operations - Use await for I/O operations
- Check existing code first - Look for reusable utilities before implementing
File Paths Reference
All file paths mentioned in this skill are relative to the repo root:
- Base adapter:
src/aidb/adapters/base/adapter.py - Components:
src/aidb/adapters/base/components/ - SourcePathResolver base:
src/aidb/adapters/base/source_path_resolver.py - Python adapter:
src/aidb/adapters/lang/python/python.py - Python source resolver:
src/aidb/adapters/lang/python/source_path_resolver.py - JavaScript adapter:
src/aidb/adapters/lang/javascript/javascript.py - JavaScript source resolver:
src/aidb/adapters/lang/javascript/source_path_resolver.py - Java adapter:
src/aidb/adapters/lang/java/java.py - Java source resolver:
src/aidb/adapters/lang/java/source_path_resolver.py - DAP protocol:
(types.py, requests.py, responses.py, events.py, bodies.py, base.py)src/aidb/dap/protocol/