Thank you for your interest in contributing! The codebase is in a mature state with well-established patterns, but it is very much still in active development. Our goal is to make this a hub for the open source computational biology community to collaborate: whether that's wrapping new models as they come out, improving existing tools, or building infrastructure that makes everything easier to use. Contributions of all kinds are welcome! Please try to adhere to the existing patterns and conventions as much as possible. (Coding agents are very helpful for this!)
This guide covers the conventions and workflows used in this project.
All you need is Python 3.10+ and pip:
pip install -e ".[dev]"System tools that standalone tool environments need (git, curl, gcc) are automatically provisioned on first use via a shared foundation environment — no manual setup required.
Task-specific guides live in .claude/skills/. Claude Code surfaces them as slash commands (e.g. /implement-tool); other agents read the same SKILL.md files directly.
implement-tool: step-by-step guide for implementing a new tool wrapper (architecture, templates, export chain, examples, tests)fix-env: troubleshooting recipes for tool environment setup failures
All persistent data (tool environments, model weights, micromamba) lives under PROTO_HOME (defaults to ~/.proto/). See the README setup instructions.
# Add to ~/.bashrc
export PROTO_HOME=/path/to/your/proto_homeSee the README for HuggingFace authentication setup.
Use descriptive branch names with a category prefix:
feat/description: new features or toolsfix/description: bug fixesrefactor/description: code restructuring without behavior changedocs/description: documentation-only changestest/description: test additions or fixes
Keep the title under 70 characters. Use imperative mood ("Add blast retry logic", not "Added" or "Adds").
Every PR must include Summary and Test plan sections. Include Problem for bug fixes.
## Summary
- Bullet points describing what changed and why
## Problem
<!-- For bug fixes only. Delete this section for features. -->
What's broken and why.
## Test plan
- [x] Completed verification step
- [ ] Remaining verification stepReference related issues in the PR body:
Closes #123: automatically closes the issue when mergedFixes #123: same behavior, preferred for bug fixesRelated to #123: links without auto-closing
We use three issue templates:
- Bug report: something is broken (include reproduction steps, error output, environment)
- Feature request: propose new functionality (include use case, proposed solution)
- Tool request: request a new bioinformatics tool wrapper (include tool name, operations to wrap, motivation)
When filing a bug, include the full traceback and your environment details (OS, Python version, GPU if relevant).
- ruff: enforced. Linting covers 22 rule groups including Pyflakes, pycodestyle, isort, pyupgrade, bugbear, bandit, pydocstyle (Google convention), and more (line length 120). Formatting is enforced in CI via
ruff format --check. Runruff check proto_tools testsbefore committing
- Mypy strict mode with Pydantic plugin. Every
# type: ignoremust include the error code. Preferassertguards for type narrowing. Do NOT usecast(),Protocol, orTYPE_CHECKINGblocks - Use
logging.getLogger(__name__), neverprint() - All biological coordinates are 1-indexed, inclusive
- Pydantic v2 models: Config uses
extra="forbid", Input usesextra="forbid", Output usesextra="forbid"
Tests use flat functions only, no test classes.
pytest # run everything the host can handle (GPU tests run iff a GPU is visible; slow + integration + extensive skipped)
pytest --gpu-only # filter: only GPU-marked tests
pytest --cpu-only # filter: only CPU-only tests
pytest --integration # add: include integration tests (external APIs/services)
pytest --ext # add: include extensive (combinatorial) tests
pytest --benchmark # add: include @pytest.mark.benchmark tests (slow gate bypassed)
pytest --all # add: include slow + integration (does NOT include extensive or benchmark)
pytest --all --cpu-only # add slow + integration, but skip GPU@pytest.mark.uses_gpu: requires GPU (auto-skipped without one)@pytest.mark.integration: tests external APIs or dispatches to real environments (skipped by default)@pytest.mark.slow: long-running tests@pytest.mark.skip_ci: skip in CI (e.g., tests that exceed CI runner memory limits)
Integration tests do not run on every push. To run them on a PR, add the run-integration label. Once the label is present, integration tests will re-run automatically on each subsequent push. Remove the label to stop running them.
See notes/testing.md for full conventions including naming, assertions, and file structure.
Every tool follows the universal Input / Config / run_{tool}() / Output pattern. The /implement-tool Claude Code skill provides the complete step-by-step guide with templates and examples.
Key requirements for new tools:
- Tool directory at
tools/{category}/{toolkit}/ @tool()decorator registration with all required metadataexample_input()factory functioncite.bibcitation fileexamples/example.ipynbnotebook- Follow the
__init__.pyexport chain: tool -> category ->tools/__init__.py
See CLAUDE.md for the full architecture reference.
- Use imperative mood: "Fix blast timeout" not "Fixed" or "Fixes"
- Keep the first line under 72 characters
- Reference issues where relevant: "Fix blast timeout on large queries (#42)"
- For multi-line messages, leave a blank line after the summary
Open an issue or start a discussion if you're unsure about anything. We're happy to help!