[tool.poetry]
name = "skill-eval-runner"
version = "0.1.0"
description = "Reusable skill-eval harness: a pip-installable library and CLI for running iterate-then-validate evals against Claude Code skills."
authors = ["Sony Music PDE <webdev@theorchard.com>"]
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.11"
langchain = ">=1.3.1"
langgraph = ">=0.2"
langchain-openai = ">=0.3"
langchain-anthropic = ">=0.3"
langchain-core = ">=0.3"
environs = ">=14.0"
langchain-aws = "^1.5.0"

[tool.poetry.group.dev.dependencies]
ruff = "^0.15.4"
mypy = "^1.19.0"
pytest = "^9.0.2"
pytest-cov = "^7.0.0"
pytest-mock = "^3.15.0"
bump2version = "^1.0.1"

[tool.poetry.scripts]
skill-eval = "skill_eval_runner.cli:main"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

[tool.ruff]
line-length = 88

[tool.ruff.lint]
select = ["C", "E", "F", "W", "B", "I", "UP", "T20", "TID252", "G", "D"]
ignore = ["E501", "B008", "B009", "D203", "D213", "D407"]

[tool.ruff.lint.isort]
combine-as-imports = true
forced-separate = ["tests"]

[tool.ruff.lint.per-file-ignores]
# The CLI and workspace writer use print() for the live progress UX people rely on.
"skill_eval_runner/cli.py" = ["T201"]
"skill_eval_runner/workspace.py" = ["T201"]

[tool.mypy]
python_version = "3.11"
strict = true
pretty = true
color_output = true
show_error_codes = true

# The langchain ecosystem doesn't ship complete type information for everything we
# touch; don't let strict mode fail on their internals.
[[tool.mypy.overrides]]
module = [
    "langchain.*",
    "langchain_core.*",
    "langchain_openai.*",
    "langchain_anthropic.*",
    "langchain_aws.*",
    "langgraph.*",
    "environs.*",
]
ignore_missing_imports = true

[tool.pytest.ini_options]
addopts = [
    "--strict-config",
    "--strict-markers",
]
xfail_strict = true
junit_family = "xunit2"

[tool.coverage.report]
exclude_also = [
    "@abstractmethod",
    "@abc.abstractmethod",
    "if TYPE_CHECKING",
    "raise NotImplementedError",
]
