[build-system] requires = ["hatchling"] build-backend = "hatchling.build" [project] name = "skillspector" version = "2.1.4" description = "SkillSpector: Security scanner for AI agent skills (Claude Code, Cursor, and similar). Scans skills for vulnerabilities, malicious patterns, and security risks before installation. Supports Git repos, URLs, zips, and local directories; runs static pattern checks and optional LLM semantic analysis; outputs terminal, JSON, and Markdown reports with risk scoring." readme = "README.md" license = "Apache-2.0" requires-python = ">=3.12,<3.14" keywords = [ "security", "ai-agents", "vulnerability-scanner", "claude-code", "skills", ] classifiers = [ "Development Status :: 3 - Alpha", "Environment :: Console", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Topic :: Security", "Topic :: Software Development :: Quality Assurance", ] dependencies = [ # Typer <0.24 uses click>=8.0.0; 0.24+ requires click>=8.2.1 which conflicts with semgrep (click 8.1.x) "typer>=0.23.0,<0.24", "rich>=14.3.0", "httpx>=0.28.0", "pyyaml>=6.0.1", "pydantic>=2.12.0", "openai>=2.25.0", "langgraph>=1.0.10", "langgraph-cli[inmem]>=0.4.14", "langchain-core>=1.2.17", "langchain-openai>=1.1.10", "langsmith>=0.7.30", "yara-python>=4.5.0", ] [project.optional-dependencies] dev = [ "pytest>=9.0.0", "pytest-asyncio>=1.3.0", "pytest-cov>=7.0.0", "ruff>=0.15.0", "mypy>=1.19.0", "build>=1.4.0", "twine>=6.2.0", "poetry>=2.3.0", ] [project.scripts] skillspector = "skillspector.cli:app" [project.urls] Homepage = "https://github.com/NVIDIA/skillspector" Documentation = "https://github.com/NVIDIA/skillspector#readme" Issues = "https://github.com/NVIDIA/skillspector/issues" [tool.hatch.build] exclude = [".claude/", ".cursor/", ".agents/"] [tool.hatch.build.targets.wheel] packages = ["src/skillspector"] artifacts = [ "src/skillspector/yara_rules/*.yar", "src/skillspector/yara_rules/*.yara", "src/skillspector/providers/*/model_registry.yaml", ] [tool.ruff] line-length = 100 target-version = "py312" [tool.ruff.lint] select = ["E", "F", "W", "I", "N", "UP", "B", "C4"] ignore = ["E501"] [tool.mypy] python_version = "3.12" warn_return_any = true warn_unused_ignores = true disallow_untyped_defs = true [tool.coverage.run] branch = true relative_files = true source = ["src/skillspector"] [tool.pytest.ini_options] testpaths = ["tests"] asyncio_mode = "auto" markers = ["integration: end-to-end tests that invoke the full graph (may call LLMs)"] addopts = "-m 'not integration'"