[build-system] requires = ["setuptools>=68", "wheel"] build-backend = "setuptools.build_meta" [project] name = "semhood" version = "0.1.0" description = "AST-based semantic code search that knows the neighborhood — every result comes with its call graph. MCP server included." readme = "README.md" license = "MIT" license-files = ["LICENSE"] authors = [{name = "Ahmed Gamil"}] requires-python = ">=3.11" keywords = [ "code-search", "semantic-search", "rag", "ast", "tree-sitter", "mcp", "llm", "embeddings", ] classifiers = [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Topic :: Software Development", "Topic :: Software Development :: Code Generators", "Topic :: Text Processing :: Indexing", ] dependencies = [ # Core "fastapi>=0.110.0", "uvicorn[standard]>=0.27.0", "pydantic>=2.5.0", "pyyaml>=6.0", "httpx>=0.27.0", "typer>=0.9.0", "rich>=13.0.0", "python-dotenv>=1.0.0", # Tree-sitter — multi-language parsing "tree-sitter>=0.22.0", "tree-sitter-python>=0.23.0", "tree-sitter-javascript>=0.23.0", "tree-sitter-typescript>=0.23.0", "tree-sitter-java>=0.23.0", "tree-sitter-go>=0.23.0", "tree-sitter-php>=0.23.0", "tree-sitter-c-sharp>=0.23.0", "tree-sitter-ruby>=0.23.0", "tree-sitter-rust>=0.23.0", "tree-sitter-cpp>=0.23.0", # Vector DB (Qdrant default) "qdrant-client>=1.7.0", # MCP server "mcp>=1.0.0", ] [project.optional-dependencies] voyage = ["voyageai>=0.2.0"] openai = ["openai>=1.10.0"] anthropic = ["anthropic>=0.18.0"] cohere = ["cohere>=4.40"] local = [ "sentence-transformers>=2.3.0", "torch>=2.1.0", ] chroma = ["chromadb>=0.5.0"] all = [ "voyageai>=0.2.0", "openai>=1.10.0", "anthropic>=0.18.0", "cohere>=4.40", "sentence-transformers>=2.3.0", "torch>=2.1.0", "chromadb>=0.5.0", ] dev = [ "pytest>=8.0.0", "pytest-asyncio>=0.23.0", "pytest-cov>=4.1.0", "ruff>=0.2.0", "build>=1.0.0", "twine>=4.0.0", "openai>=1.10.0", # exercised by the OpenRouter provider test ] [project.urls] Homepage = "https://github.com/ahmeedgamil/semhood" Documentation = "https://github.com/ahmeedgamil/semhood#readme" Repository = "https://github.com/ahmeedgamil/semhood" Issues = "https://github.com/ahmeedgamil/semhood/issues" [project.scripts] semhood = "semhood.cli.commands:app" semhood-mcp = "semhood.mcp_server:main" # ------------------------------------------------------------------------- # Tooling # ------------------------------------------------------------------------- [tool.setuptools] include-package-data = true [tool.setuptools.packages.find] include = ["semhood*"] exclude = ["tests*", "sample_project*", "qdrant_data*"] [tool.setuptools.package-data] semhood = ["py.typed", "resources/skills/*.md"] [tool.pytest.ini_options] testpaths = ["tests_py"] asyncio_mode = "auto" addopts = "-q" [tool.ruff] line-length = 100 target-version = "py311" [tool.ruff.lint] select = ["E", "F", "I", "B", "UP", "RUF"] ignore = [ "E501", # line length — handled by the formatter, not worth failing on "UP042", # str+Enum is an intentional, widely-used pattern here "RUF012", # class-level constant collections; not actually mutated ]