Contributing to ADR Sensor
August 8, 2026 · View on GitHub
Thank you for your interest in contributing to ADR Sensor! This guide will help you get started.
Getting Started
- Fork the repository
- Clone your fork:
git clone https://github.com/YOUR_USERNAME/ADR.git cd ADR/Sensor - Install in development mode:
pip install -e ".[dev]" - Run tests to verify:
pytest tests/ -v
Development Workflow
- Create a branch for your change:
git checkout -b feature/my-new-parser - Make your changes
- Run tests and linting:
pytest tests/ -v ruff check adr_sensor/ ruff format adr_sensor/ - Commit and push
- Open a Pull Request
Adding a New Parser
This is the most common contribution. To add support for a new AI agent:
Step 1: Create the Parser
Create adr_sensor/parsers/my_agent_parser.py:
from pathlib import Path
from typing import List
from ..parsers.base_parser import BaseParser
from ..schemas.agent_event_schema import AgentEvent, ChatMessage, ToolUsage
class MyAgentParser(BaseParser):
"""Parser for MyAgent logs."""
def __init__(self):
# Set the path where your agent stores its logs
self.base_path = Path.home() / ".my-agent/logs"
def parse_all(self) -> List[AgentEvent]:
"""Parse all available MyAgent logs."""
entries = []
if not self.base_path.exists():
print(f"[MY_AGENT] No logs found at {self.base_path}")
return entries
# Your parsing logic here
# Convert logs into AgentEvent objects
return entries
Step 2: Register in Observer
Export the parser from adr_sensor/parsers/__init__.py, then register it in
adr_sensor/observer.py:
from .parsers.my_agent_parser import MyAgentParser
class AgentObserver:
SOURCES = (
...,
("my_agent", "MyAgent"), # (source key, display label)
)
def __init__(self, ...):
...
# The parser must be named <source key>_parser
self.my_agent_parser = MyAgentParser()
ingest_all() iterates SOURCES and resolves each parser as
self.<source>_parser, so no per-source branch is needed — it handles the
has_meaningful_content() filter, error isolation and error.log reporting for you.
If the agent only exists on some operating systems, add it to
PLATFORM_RESTRICTED_SOURCES so it is skipped elsewhere instead of failing:
PLATFORM_RESTRICTED_SOURCES = {
"claude_desktop": ("Darwin", "Windows"),
"my_agent": ("Darwin",),
}
Step 3: Add CLI Source
Nothing to do — adr_sensor/cli.py builds its --source choices from
AgentObserver.SOURCES. Add an example line to the CLI epilog if the new source
needs explanation.
Source keys are part of the Sensor's public contract — downstream detection pipelines filter on them. Treat renaming one as a breaking change and avoid it; prefer adding a new key alongside the existing one.
Step 4: Write Tests
Add test cases to tests/test_parsers.py (or tests/test_my_agent_parser.py for a
larger parser) covering:
- Parsing valid log files
- Handling missing directories
- Handling malformed data
- Age filtering, if the parser supports
max_age_days - Edge cases
Code Style
- Follow PEP 8
- Use type hints
- Use
rufffor formatting and linting - Keep parsers self-contained (each parser should handle its own errors)
Testing Guidelines
- All new code must have tests
- Tests should not depend on real log files existing on the machine
- Use
tmp_pathfixture for file-based tests - Use mocks for external dependencies
Reporting Issues
When reporting bugs, please include:
- Python version
- Operating system
- Steps to reproduce
- Error messages or unexpected output
License
By contributing, you agree that your contributions will be licensed under the Apache License 2.0.