-
Notifications
You must be signed in to change notification settings - Fork 0
Add AI contributor skills, per-script structure, and CI pipeline #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
76c6c87
39ef3cd
a81dbaf
5a38336
1b94ea9
bd44bf7
a5ec12f
2436785
70019e4
b575f69
85d6fd3
7313299
9c280ad
ec6b25d
9f3e0e1
6ca1237
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| --- | ||
| name: contribute-script | ||
| description: Guide creation of a new pyopenms script contribution β scaffolding through validation | ||
| --- | ||
|
|
||
| # Contribute Script | ||
|
|
||
| Guide an AI agent through creating a new pyopenms CLI tool for the agentomics repo. Follow every step β this is a rigid skill. | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| Read `AGENTS.md` in the repo root for the full contributor guide and code patterns. | ||
|
|
||
| ## Steps | ||
|
|
||
| ### 1. Understand the tool | ||
|
|
||
| Ask the user: | ||
| - What does this tool do? What pyopenms functionality does it use? | ||
| - What gap in OpenMS/pyopenms does it fill? | ||
|
|
||
| ### 2. Determine the domain | ||
|
|
||
| Ask: Is this a **proteomics** or **metabolomics** tool? If neither fits, discuss whether a new domain directory is needed. | ||
|
|
||
| ### 3. Pick a name | ||
|
|
||
| Choose a descriptive snake_case name for the tool (e.g. `peptide_mass_calculator`, `isotope_pattern_matcher`). Confirm with the user. | ||
|
|
||
| ### 4. Create a feature branch | ||
|
|
||
| ```bash | ||
| git checkout -b add/<tool_name> | ||
| ``` | ||
|
|
||
| ### 5. Scaffold the directory | ||
|
|
||
| ```bash | ||
| mkdir -p scripts/<domain>/<tool_name>/tests | ||
| ``` | ||
|
|
||
| Create these files: | ||
|
|
||
| **`requirements.txt`:** | ||
| ``` | ||
| pyopenms | ||
| ``` | ||
| Add any additional dependencies the script needs (one per line, no version pins). | ||
|
|
||
| **`tests/conftest.py`:** | ||
| ```python | ||
| import sys | ||
| import os | ||
|
|
||
| import pytest | ||
|
|
||
| sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..")) | ||
|
|
||
| try: | ||
| import pyopenms # noqa: F401 | ||
|
|
||
| HAS_PYOPENMS = True | ||
| except ImportError: | ||
| HAS_PYOPENMS = False | ||
|
|
||
| requires_pyopenms = pytest.mark.skipif(not HAS_PYOPENMS, reason="pyopenms not installed") | ||
| ``` | ||
|
|
||
| ### 6. Write the script | ||
|
|
||
| Create `scripts/<domain>/<tool_name>/<tool_name>.py` following these patterns: | ||
|
|
||
| - Module-level docstring with description, supported features, and CLI usage examples | ||
| - pyopenms import guard: | ||
| ```python | ||
| try: | ||
| import pyopenms as oms | ||
| except ImportError: | ||
| sys.exit("pyopenms is required. Install it with: pip install pyopenms") | ||
| ``` | ||
| - `PROTON = 1.007276` constant where mass-to-charge calculations are needed | ||
| - Importable functions as the primary interface (with type hints and numpy-style docstrings) | ||
| - `main()` function with argparse CLI | ||
| - `if __name__ == "__main__": main()` guard | ||
|
|
||
| ### 7. Write tests | ||
|
|
||
| Create `scripts/<domain>/<tool_name>/tests/test_<tool_name>.py`: | ||
|
|
||
| - Import `requires_pyopenms` from conftest | ||
| - Decorate test classes with `@requires_pyopenms` | ||
| - Use `from <tool_name> import <function>` inside test methods | ||
| - For file-I/O scripts: generate synthetic data using pyopenms objects in test fixtures, write to `tempfile.TemporaryDirectory()` | ||
| - Cover: basic functionality, edge cases, key parameters | ||
|
|
||
| ### 8. Write README | ||
|
|
||
| Create `scripts/<domain>/<tool_name>/README.md` with a brief description and CLI usage examples. | ||
|
|
||
| ### 9. Validate | ||
|
|
||
| Invoke the `validate-script` skill on the new script directory. Both ruff and pytest must pass. | ||
|
|
||
| ### 10. Commit | ||
|
|
||
| ```bash | ||
| git add scripts/<domain>/<tool_name>/ | ||
| git commit -m "Add <tool_name>: <brief description>" | ||
| ``` | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| --- | ||
| name: validate-script | ||
| description: Validate a pyopenms script in an isolated venv β runs ruff lint and pytest | ||
| --- | ||
|
|
||
| # Validate Script | ||
|
|
||
| Validate any script in the agentomics repo by running ruff and pytest in a fresh isolated venv. | ||
|
|
||
| ## Steps (follow exactly β rigid skill) | ||
|
|
||
| 1. **Identify the script directory.** If the user provided a path, use it. Otherwise, ask which script to validate. The path should be `scripts/<domain>/<tool_name>/`. | ||
|
|
||
| 2. **Verify the directory structure.** Confirm it contains: | ||
| - `<tool_name>.py` | ||
| - `requirements.txt` | ||
| - `tests/` directory with at least one `test_*.py` file | ||
|
|
||
| 3. **Create a temporary venv and run validation.** Execute these commands: | ||
|
|
||
| ```bash | ||
| SCRIPT_DIR=<path-to-script-directory> | ||
| VENV_DIR=$(mktemp -d) | ||
| python -m venv "$VENV_DIR" | ||
| "$VENV_DIR/bin/python" -m pip install -r "$SCRIPT_DIR/requirements.txt" | ||
| "$VENV_DIR/bin/python" -m pip install pytest ruff | ||
| "$VENV_DIR/bin/python" -m ruff check "$SCRIPT_DIR/" | ||
| PYTHONPATH="$SCRIPT_DIR" "$VENV_DIR/bin/python" -m pytest "$SCRIPT_DIR/tests/" -v | ||
| rm -rf "$VENV_DIR" | ||
| ``` | ||
|
Comment on lines
+21
to
+30
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π§© Analysis chainπ Script executed: #!/bin/bash
# Demonstrate cleanup behavior with and without trap.
# Expected: without trap, temp dir remains after failure; with trap, it is removed.
set -euo pipefail
echo "Without trap:"
if bash -c 'set -e; V=$(mktemp -d); false; rm -rf "$V"' 2>/dev/null; then :; fi
# Can't read V from subshell directly; show equivalent reproducible pattern:
bash -c 'set -e; V=$(mktemp -d); echo "$V" > /tmp/venv_path_no_trap; false; rm -rf "$V"' || true
V1=$(cat /tmp/venv_path_no_trap)
if [ -d "$V1" ]; then echo "Leaked: $V1"; rm -rf "$V1"; fi
echo "With trap:"
bash -c 'set -e; V=$(mktemp -d); echo "$V" > /tmp/venv_path_trap; trap "rm -rf \"$V\"" EXIT; false' || true
V2=$(cat /tmp/venv_path_trap)
if [ -d "$V2" ]; then echo "Unexpected leak: $V2"; else echo "Cleaned as expected"; fiRepository: OpenMS/agentomics Length of output: 133 π Script executed: # Check if the file exists and read the relevant lines
if [ -f ".claude/skills/validate-script.md" ]; then
echo "=== File exists, reading lines 15-40 for context ==="
sed -n '15,40p' ".claude/skills/validate-script.md" | cat -n
else
echo "File not found at .claude/skills/validate-script.md"
# Search for similar files
find . -name "*validate*script*" -o -name "*.md" -path "*claude*" 2>/dev/null | head -20
fiRepository: OpenMS/agentomics Length of output: 1064 π Script executed: # Get actual line numbers and check for line 34 reference
wc -l ".claude/skills/validate-script.md"
echo "=== Lines 20-35 (to see full context and line 34) ==="
sed -n '20,35p' ".claude/skills/validate-script.md" | cat -nRepository: OpenMS/agentomics Length of output: 886 Add trap-based cleanup to ensure venv removal on failure. The current code does not guarantee cleanup if any command fails before the final Suggested command block update ```bash
SCRIPT_DIR=<path-to-script-directory>
VENV_DIR=$(mktemp -d)
+ trap 'rm -rf "$VENV_DIR"' EXIT
python -m venv "$VENV_DIR"
"$VENV_DIR/bin/python" -m pip install -r "$SCRIPT_DIR/requirements.txt"
"$VENV_DIR/bin/python" -m pip install pytest ruff
"$VENV_DIR/bin/python" -m ruff check "$SCRIPT_DIR/"
PYTHONPATH="$SCRIPT_DIR" "$VENV_DIR/bin/python" -m pytest "$SCRIPT_DIR/tests/" -v
- rm -rf "$VENV_DIR"Verify each finding against the current code and only fix it if needed. In @.claude/skills/validate-script.md around lines 21 - 30, Add a trap-based |
||
|
|
||
| 4. **Report results.** Summarize pass/fail for both ruff and pytest. If either fails, show the relevant error output so the user can fix it. | ||
|
|
||
| 5. **Clean up.** Ensure the temporary venv is removed even if validation fails. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| name: Validate Scripts | ||
|
|
||
| on: | ||
| pull_request: | ||
| paths: | ||
| - 'scripts/**' | ||
|
|
||
| jobs: | ||
| detect-changes: | ||
| runs-on: ubuntu-latest | ||
| outputs: | ||
| matrix: ${{ steps.detect.outputs.matrix }} | ||
| has_changes: ${{ steps.detect.outputs.has_changes }} | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
|
|
||
| - id: detect | ||
| name: Detect changed script directories | ||
| run: | | ||
| # Note: github.base_ref is only available on pull_request events | ||
| # Find all script directories that changed in this PR | ||
| CHANGED=$(git diff --name-only origin/${{ github.base_ref }}...HEAD -- 'scripts/' \ | ||
| | grep -oP 'scripts/[^/]+/[^/]+/' \ | ||
| | sort -u \ | ||
| | jq -R -s -c 'split("\n") | map(select(length > 0))') | ||
|
Comment on lines
+24
to
+27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π§© Analysis chainπ Script executed: #!/bin/bash
# Reproduce grep no-match behavior under bash -e in a command-substitution pipeline.
# Expected: first block fails; second block with `|| true` succeeds.
set -euo pipefail
echo "a/b/c.txt" > /tmp/changed_paths.txt
echo "Case 1 (without || true) - should fail:"
if bash -e -c 'X=$(cat /tmp/changed_paths.txt | grep -oP "scripts/[^/]+/[^/]+/" | sort -u); echo "$X"'; then
echo "Unexpected success"
else
echo "Failed as expected"
fi
echo "Case 2 (with || true) - should succeed:"
bash -e -c 'X=$(cat /tmp/changed_paths.txt | grep -oP "scripts/[^/]+/[^/]+/" || true); echo "X=${X:-<empty>}"'Repository: OpenMS/agentomics Length of output: 170 π Script executed: cat -n .github/workflows/validate.yml | head -50Repository: OpenMS/agentomics Length of output: 1897 π Script executed: git ls-files '.github/workflows/'Repository: OpenMS/agentomics Length of output: 91 π Web query:
π‘ Result: In GitHub Actions, for run steps on Linux/macOS runners (non-Windows), the default shell behavior when no shell is explicitly specified is to use bash -e {0} if bash is available, or sh -e {0} otherwise. The -e flag enables set -e semantics, causing the script to exit immediately if any command returns a non-zero exit code (fail-fast behavior). When shell: bash is explicitly specified, it uses bash --noprofile --norc -eo pipefail {0}, which includes set -e, set -o pipefail (fail on pipeline failure), and suppresses profile/rc loading. This is the default to enforce fail-fast behavior in CI scripts, ensuring steps fail early on errors. To disable, use shell: bash {0} or set +e in the script. On Windows, the default is PowerShell, not bash. Citations:
π Script executed: fd -t f '.github/workflows/' -name '*.yml' -o -name '*.yaml' | xargs grep -l 'git diff' | head -5Repository: OpenMS/agentomics Length of output: 291 π Script executed: #!/bin/bash
# Test grep behavior with pipefail (which GitHub Actions uses by default)
echo "a/b/c.txt" > /tmp/changed_paths.txt
echo "Case 1 (bash -eo pipefail, without || true) - should fail:"
if bash -eo pipefail -c 'X=$(cat /tmp/changed_paths.txt | grep -oP "scripts/[^/]+/[^/]+/" | sort -u); echo "$X"'; then
echo "Unexpected success"
else
echo "Failed as expected (exit code: $?)"
fi
echo ""
echo "Case 2 (bash -eo pipefail, with || true) - should succeed:"
if bash -eo pipefail -c 'X=$(cat /tmp/changed_paths.txt | grep -oP "scripts/[^/]+/[^/]+/" || true | sort -u); echo "X=${X:-<empty>}"'; then
echo "Succeeded as expected"
else
echo "Unexpected failure"
fiRepository: OpenMS/agentomics Length of output: 245 π Script executed: fd '.github/workflows' -type fRepository: OpenMS/agentomics Length of output: 231 π Script executed: find .github/workflows -type f -name '*.yml' -o -name '*.yaml'Repository: OpenMS/agentomics Length of output: 91 π Script executed: grep -r "grep -oP" .github/workflows/Repository: OpenMS/agentomics Length of output: 139 Add fallback to grep to prevent pipeline failure on zero matches. In GitHub Actions, the default shell ( Suggested fix CHANGED=$(git diff --name-only origin/${{ github.base_ref }}...HEAD -- 'scripts/' \
| grep -oP 'scripts/[^/]+/[^/]+/' \
+ || true \
| sort -u \
| jq -R -s -c 'split("\n") | map(select(length > 0))')π€ Prompt for AI Agents |
||
|
|
||
| if [ "$CHANGED" = "[]" ] || [ -z "$CHANGED" ]; then | ||
| echo "has_changes=false" >> "$GITHUB_OUTPUT" | ||
| echo "matrix=[]" >> "$GITHUB_OUTPUT" | ||
| else | ||
| echo "has_changes=true" >> "$GITHUB_OUTPUT" | ||
| echo "matrix=$CHANGED" >> "$GITHUB_OUTPUT" | ||
| fi | ||
|
|
||
| validate: | ||
| needs: detect-changes | ||
| if: needs.detect-changes.outputs.has_changes == 'true' | ||
| runs-on: ubuntu-latest | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| script_dir: ${{ fromJson(needs.detect-changes.outputs.matrix) }} | ||
| name: Validate ${{ matrix.script_dir }} | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: '3.11' | ||
|
|
||
| - name: Create venv and install dependencies | ||
| run: | | ||
| python -m venv /tmp/validate_venv | ||
| /tmp/validate_venv/bin/python -m pip install -r ${{ matrix.script_dir }}requirements.txt | ||
| /tmp/validate_venv/bin/python -m pip install pytest ruff | ||
|
|
||
| - name: Lint with ruff | ||
| run: | | ||
| /tmp/validate_venv/bin/python -m ruff check ${{ matrix.script_dir }} | ||
|
|
||
| - name: Run tests | ||
| run: | | ||
| PYTHONPATH=${{ matrix.script_dir }} /tmp/validate_venv/bin/python -m pytest ${{ matrix.script_dir }}tests/ -v | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| # AGENTS.md β AI Contributor Guide | ||
|
|
||
| This file instructs AI agents (Claude Code, GitHub Copilot, Cursor, Gemini, etc.) how to contribute scripts to the agentomics repository. | ||
|
|
||
| ## Project Purpose | ||
|
|
||
| Agentomics is a collection of standalone CLI tools built with [pyopenms](https://pyopenms.readthedocs.io/) for proteomics and metabolomics workflows. These tools fill gaps not yet covered by OpenMS/pyopenms. All code in this repo is written by AI agents. | ||
|
|
||
| ## Contribution Requirements | ||
|
|
||
| Every script must be a **self-contained directory** under `scripts/<domain>/<tool_name>/`: | ||
|
|
||
| ``` | ||
| scripts/<domain>/<tool_name>/ | ||
| βββ <tool_name>.py # The tool itself | ||
| βββ requirements.txt # pyopenms + any script-specific deps (no version pins) | ||
| βββ README.md # Brief description + CLI usage examples | ||
| βββ tests/ | ||
| βββ conftest.py # Shared test config (see below) | ||
| βββ test_<tool_name>.py | ||
| ``` | ||
|
|
||
| ### Rules | ||
|
|
||
| - `<domain>` is `proteomics` or `metabolomics` | ||
| - `requirements.txt` always includes `pyopenms` with no version pin β builds against latest | ||
| - No cross-script imports β each script is fully independent | ||
| - No `__init__.py` files β these are NOT Python packages | ||
| - No scripts that duplicate functionality already in OpenMS/pyopenms | ||
|
|
||
| ## Code Patterns | ||
|
|
||
| ### Script structure | ||
|
|
||
| Every script must have: | ||
|
|
||
| 1. **Module docstring** with description, features, and usage examples | ||
| 2. **pyopenms import guard:** | ||
| ```python | ||
| import sys | ||
| try: | ||
| import pyopenms as oms | ||
| except ImportError: | ||
| sys.exit("pyopenms is required. Install it with: pip install pyopenms") | ||
| ``` | ||
| 3. **Importable functions** as the primary interface (with type hints and numpy-style docstrings) | ||
| 4. **`main()` function** with argparse CLI | ||
| 5. **`if __name__ == "__main__": main()`** guard | ||
| 6. **`PROTON = 1.007276`** constant where mass-to-charge calculations are needed | ||
|
|
||
| ### Test structure | ||
|
|
||
| Every `tests/conftest.py` must contain: | ||
|
|
||
| ```python | ||
| import sys | ||
| import os | ||
|
|
||
| import pytest | ||
|
|
||
| sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..")) | ||
|
|
||
| try: | ||
| import pyopenms # noqa: F401 | ||
| HAS_PYOPENMS = True | ||
| except ImportError: | ||
| HAS_PYOPENMS = False | ||
|
|
||
| requires_pyopenms = pytest.mark.skipif(not HAS_PYOPENMS, reason="pyopenms not installed") | ||
| ``` | ||
|
|
||
| Test files: | ||
| - Decorate test classes with `@requires_pyopenms` from conftest | ||
| - Import script functions inside test methods: `from <tool_name> import <function>` | ||
| - For file-I/O scripts: generate synthetic data using pyopenms objects, write to `tempfile.TemporaryDirectory()` | ||
|
|
||
| ## Validation | ||
|
|
||
| Every script must pass validation in an **isolated venv** before it can be merged. Run these commands from the repo root: | ||
|
|
||
| ```bash | ||
| SCRIPT_DIR=scripts/<domain>/<tool_name> | ||
| VENV_DIR=$(mktemp -d) | ||
| python -m venv "$VENV_DIR" | ||
| "$VENV_DIR/bin/python" -m pip install -r "$SCRIPT_DIR/requirements.txt" | ||
| "$VENV_DIR/bin/python" -m pip install pytest ruff | ||
| "$VENV_DIR/bin/python" -m ruff check "$SCRIPT_DIR/" | ||
| PYTHONPATH="$SCRIPT_DIR" "$VENV_DIR/bin/python" -m pytest "$SCRIPT_DIR/tests/" -v | ||
| rm -rf "$VENV_DIR" | ||
| ``` | ||
|
|
||
| Both ruff and pytest must pass with zero errors. | ||
|
|
||
| ## Linting | ||
|
|
||
| Ruff is configured in `ruff.toml` at the repo root: | ||
| - Line length: 120 | ||
| - Rules: E (pycodestyle errors), F (pyflakes), W (pycodestyle warnings), I (isort) | ||
|
|
||
| ## What NOT to Do | ||
|
|
||
| - Do not add cross-script imports | ||
| - Do not add dependencies to a shared/root requirements file | ||
| - Do not create scripts that duplicate existing pyopenms CLI tools or OpenMS TOPP tools | ||
| - Do not pin pyopenms to a specific version | ||
| - Do not add `__init__.py` files |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| # CLAUDE.md | ||
|
|
||
| This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. | ||
|
|
||
| ## Project Purpose | ||
|
|
||
| Agentomics is a collection of standalone CLI tools built with [pyopenms](https://pyopenms.readthedocs.io/) for proteomics and metabolomics workflows. These tools fill gaps not yet covered by OpenMS/pyopenms. All code in this repo is agentic-only development β written entirely by AI agents. | ||
|
|
||
| ## Commands | ||
|
|
||
| ```bash | ||
| # Install dependencies for a specific script | ||
| pip install -r scripts/proteomics/peptide_mass_calculator/requirements.txt | ||
|
|
||
| # Lint a specific script | ||
| ruff check scripts/proteomics/peptide_mass_calculator/ | ||
|
|
||
| # Run tests for a specific script | ||
| PYTHONPATH=scripts/proteomics/peptide_mass_calculator python -m pytest scripts/proteomics/peptide_mass_calculator/tests/ -v | ||
|
|
||
| # Lint all scripts | ||
| ruff check scripts/ | ||
|
|
||
| # Run all tests across all scripts | ||
| for d in scripts/*/*/; do PYTHONPATH="$d" python -m pytest "$d/tests/" -v; done | ||
|
|
||
| # Run a script directly | ||
| python scripts/proteomics/peptide_mass_calculator/peptide_mass_calculator.py --sequence PEPTIDEK --charge 2 | ||
| python scripts/metabolomics/isotope_pattern_matcher/isotope_pattern_matcher.py --formula C6H12O6 | ||
| ``` | ||
|
|
||
| ## Architecture | ||
|
|
||
| ### Per-Script Directory Structure | ||
|
|
||
| Each script is a self-contained directory under `scripts/<domain>/<tool_name>/`: | ||
|
|
||
| ``` | ||
| scripts/<domain>/<tool_name>/ | ||
| βββ <tool_name>.py # The tool (importable functions + argparse CLI) | ||
| βββ requirements.txt # pyopenms + script-specific deps | ||
| βββ README.md # Usage examples | ||
| βββ tests/ | ||
| βββ conftest.py # requires_pyopenms marker + sys.path setup | ||
| βββ test_<tool_name>.py | ||
| ``` | ||
|
|
||
| Domains: `proteomics/`, `metabolomics/` | ||
|
|
||
| ### Key Patterns | ||
|
|
||
| - pyopenms import wrapped in try/except with user-friendly error message | ||
| - Mass-to-charge: `(mass + charge * PROTON) / charge` with `PROTON = 1.007276` | ||
| - Every script has dual interface: importable functions + argparse CLI + `__main__` guard | ||
| - Tests use `@requires_pyopenms` skip marker from conftest.py | ||
| - File-I/O scripts use synthetic test data generated with pyopenms objects | ||
|
|
||
| ## Contributing | ||
|
|
||
| See `AGENTS.md` for the full AI contributor guide. Two Claude Code skills are available: | ||
|
|
||
| - **`contribute-script`** β guided workflow for adding a new script | ||
| - **`validate-script`** β validate any script in an isolated venv (ruff + pytest) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
π§© Analysis chain
π Script executed:
Repository: OpenMS/agentomics
Length of output: 43
π Script executed:
Repository: OpenMS/agentomics
Length of output: 773
π Script executed:
Repository: OpenMS/agentomics
Length of output: 1231
Add
import systo the pyopenms import-guard pattern.The documented pattern at lines 75β80 uses
sys.exit()without showingimport sys. Contributors copying this exact snippet will encounter aNameErroron the import failure path.Suggested doc fix
- pyopenms import guard: ```python + import sys try: import pyopenms as oms except ImportError: sys.exit("pyopenms is required. Install it with: pip install pyopenms")π€ Prompt for AI Agents