diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..14fb1d6 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,25 @@ +name: Build + +on: + push: + branches: ["main"] + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.11" + cache: pip + - name: Install build tools + run: pip install build + - name: Build package + run: python -m build + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: dist + path: dist/ diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..485d73b --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,19 @@ +name: Lint + +on: + push: + branches: ["main"] + pull_request: + +jobs: + ruff: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.11" + - name: Install ruff + run: pip install ruff + - name: Run ruff + run: ruff check . diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..8f7119f --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,25 @@ +name: Test + +on: + push: + branches: ["main"] + pull_request: + +jobs: + pytest: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.11", "3.12"] + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + cache: pip + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python -m pip install -e ".[dev]" + - name: Run pytest + run: pytest -v diff --git a/.gitignore b/.gitignore index 66a06a9..6e7051d 100644 --- a/.gitignore +++ b/.gitignore @@ -20,7 +20,6 @@ venv/ .idea/ .agents/ .claude/ -.github/ .cursor/ .cursorrules .evoscientist/ diff --git a/EvoScientist/EvoScientist.py b/EvoScientist/EvoScientist.py index 2861284..8840a69 100644 --- a/EvoScientist/EvoScientist.py +++ b/EvoScientist/EvoScientist.py @@ -13,7 +13,6 @@ Usage: ... """ -import os from datetime import datetime from pathlib import Path diff --git a/EvoScientist/cli.py b/EvoScientist/cli.py index 6c864c3..bec5788 100644 --- a/EvoScientist/cli.py +++ b/EvoScientist/cli.py @@ -113,7 +113,7 @@ def _cmd_list_skills() -> None: if not skills: console.print("[dim]No user skills installed.[/dim]") - console.print(f"[dim]Install with:[/dim] /install-skill ") + console.print("[dim]Install with:[/dim] /install-skill ") console.print(f"[dim]Skills directory:[/dim] [cyan]{_shorten_path(str(USER_SKILLS_DIR))}[/cyan]") console.print() return diff --git a/EvoScientist/skills_manager.py b/EvoScientist/skills_manager.py index b3bf4a4..7a063f6 100644 --- a/EvoScientist/skills_manager.py +++ b/EvoScientist/skills_manager.py @@ -34,7 +34,6 @@ import subprocess import tempfile from dataclasses import dataclass from pathlib import Path -from typing import Iterator import yaml diff --git a/EvoScientist/stream/display.py b/EvoScientist/stream/display.py index 7b100c6..d8bd3f0 100644 --- a/EvoScientist/stream/display.py +++ b/EvoScientist/stream/display.py @@ -194,7 +194,7 @@ def _render_subagent_section(sa: 'SubAgentState', compact: bool = False) -> list pending.append(tc) succeeded = sum(1 for _, tr in completed if tr.get("success", True)) - failed = len(completed) - succeeded + _ = len(completed) - succeeded # failed count, unused for now # Build display name display_name = f"Cooking with {sa.name}" diff --git a/pyproject.toml b/pyproject.toml index 50d6fe4..a29ebe2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,7 +32,12 @@ dependencies = [ ] [project.optional-dependencies] -dev = ["pytest>=8.0", "pytest-cov>=5.0"] +dev = [ + "pytest>=8.0", + "pytest-cov>=5.0", + "ruff>=0.5", + "build>=1.0", +] [project.urls] "Homepage" = "https://github.com/EvoScientist/EvoScientist" diff --git a/tests/conftest.py b/tests/conftest.py index a172812..7cce355 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,7 +1,5 @@ """Shared fixtures for EvoScientist tests.""" -import os -import tempfile import pytest diff --git a/tests/test_backends.py b/tests/test_backends.py index 4a8fda0..06689e4 100644 --- a/tests/test_backends.py +++ b/tests/test_backends.py @@ -1,9 +1,6 @@ """Tests for EvoScientist/backends.py — validate_command, path conversion, resolve_path.""" -import os -import tempfile -import pytest from EvoScientist.backends import ( validate_command, diff --git a/tests/test_imports.py b/tests/test_imports.py index 107741b..8abdebf 100644 --- a/tests/test_imports.py +++ b/tests/test_imports.py @@ -12,37 +12,29 @@ needs_api_key = pytest.mark.skipif( def test_import_stream_utils(): from EvoScientist.stream.utils import ( is_success, - format_tool_compact, - truncate, - has_args, - count_lines, - truncate_with_line_hint, ) assert callable(is_success) def test_import_stream_emitter(): - from EvoScientist.stream.emitter import StreamEventEmitter, StreamEvent + from EvoScientist.stream.emitter import StreamEventEmitter assert callable(StreamEventEmitter.thinking) def test_import_stream_tracker(): - from EvoScientist.stream.tracker import ToolCallTracker, ToolCallInfo + from EvoScientist.stream.tracker import ToolCallTracker assert ToolCallTracker is not None def test_import_backends(): from EvoScientist.backends import ( validate_command, - convert_virtual_paths_in_command, - CustomSandboxBackend, - ReadOnlyFilesystemBackend, ) assert callable(validate_command) def test_import_prompts(): - from EvoScientist.prompts import get_system_prompt, RESEARCHER_INSTRUCTIONS + from EvoScientist.prompts import get_system_prompt assert callable(get_system_prompt) @@ -54,6 +46,6 @@ def test_import_tools(): @needs_api_key def test_import_package_exports(): - from EvoScientist import EvoScientist_agent, create_cli_agent + from EvoScientist import EvoScientist_agent # Just verify they are importable; don't call them without API key assert EvoScientist_agent is not None diff --git a/tests/test_skills_manager.py b/tests/test_skills_manager.py index 4b3412a..c6ca3f4 100644 --- a/tests/test_skills_manager.py +++ b/tests/test_skills_manager.py @@ -1,15 +1,11 @@ """Tests for EvoScientist.skills_manager module.""" -import os -import shutil -import tempfile from pathlib import Path from unittest import mock import pytest from EvoScientist.skills_manager import ( - SkillInfo, _parse_skill_md, _parse_github_url, _is_github_url, diff --git a/tests/test_stream_tracker.py b/tests/test_stream_tracker.py index 2f4304e..408d103 100644 --- a/tests/test_stream_tracker.py +++ b/tests/test_stream_tracker.py @@ -1,6 +1,6 @@ """Tests for EvoScientist/stream/tracker.py.""" -from EvoScientist.stream.tracker import ToolCallTracker, ToolCallInfo +from EvoScientist.stream.tracker import ToolCallTracker class TestToolCallTracker: