See More

[tool.poetry] name = "strix-agent" version = "0.4.0" description = "Open-source AI Hackers for your apps" authors = ["Strix "] readme = "README.md" license = "Apache-2.0" keywords = [ "cybersecurity", "security", "vulnerability", "scanner", "pentest", "agent", "ai", "cli", ] classifiers = [ "Development Status :: 3 - Alpha", "Intended Audience :: Information Technology", "Intended Audience :: System Administrators", "Topic :: Security", "License :: OSI Approved :: Apache Software License", "Environment :: Console", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.12", ] packages = [ { include = "strix", format = ["sdist", "wheel"] } ] include = [ "LICENSE", "README.md", "strix/**/*.jinja", "strix/**/*.xml", "strix/**/*.tcss" ] [tool.poetry.scripts] strix = "strix.interface.main:main" [tool.poetry.dependencies] python = "^3.12" fastapi = "*" uvicorn = "*" litellm = { version = "~1.79.1", extras = ["proxy"] } openai = ">=1.99.5,<1.100.0" tenacity = "^9.0.0" numpydoc = "^1.8.0" pydantic = {extras = ["email"], version = "^2.11.3"} ipython = "^9.3.0" openhands-aci = "^0.3.0" playwright = "^1.48.0" rich = "*" docker = "^7.1.0" gql = {extras = ["requests"], version = "^3.5.3"} textual = "^4.0.0" xmltodict = "^0.13.0" pyte = "^0.8.1" requests = "^2.32.0" libtmux = "^0.46.2" [tool.poetry.group.dev.dependencies] # Type checking and static analysis mypy = "^1.16.0" ruff = "^0.11.13" pyright = "^1.1.401" pylint = "^3.3.7" bandit = "^1.8.3" # Testing pytest = "^8.4.0" pytest-asyncio = "^1.0.0" pytest-cov = "^6.1.1" pytest-mock = "^3.14.1" # Development tools pre-commit = "^4.2.0" black = "^25.1.0" isort = "^6.0.1" [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" # ============================================================================ # Type Checking Configuration # ============================================================================ [tool.mypy] python_version = "3.12" strict = true strict_optional = true warn_redundant_casts = true warn_unused_ignores = true warn_return_any = true warn_unreachable = true disallow_untyped_defs = true disallow_any_generics = true disallow_subclassing_any = true disallow_untyped_calls = true disallow_incomplete_defs = true check_untyped_defs = true disallow_untyped_decorators = true no_implicit_optional = true warn_unused_configs = true show_error_codes = true show_column_numbers = true pretty = true # Allow some flexibility for third-party libraries [[tool.mypy.overrides]] module = [ "litellm.*", "tenacity.*", "numpydoc.*", "rich.*", "IPython.*", "openhands_aci.*", "playwright.*", "uvicorn.*", "jinja2.*", "pydantic_settings.*", "jwt.*", "httpx.*", "gql.*", "textual.*", "pyte.*", "libtmux.*", ] ignore_missing_imports = true # ============================================================================ # Ruff Configuration (Fast Python Linter & Formatter) # ============================================================================ [tool.ruff] target-version = "py312" line-length = 100 extend-exclude = [ ".git", ".mypy_cache", ".pytest_cache", ".ruff_cache", "__pycache__", "build", "dist", "migrations", ] [tool.ruff.lint] # Enable comprehensive rule sets select = [ "E", # pycodestyle errors "W", # pycodestyle warnings "F", # Pyflakes "I", # isort "N", # pep8-naming "UP", # pyupgrade "YTT", # flake8-2020 "S", # flake8-bandit "BLE", # flake8-blind-except "FBT", # flake8-boolean-trap "B", # flake8-bugbear "A", # flake8-builtins "COM", # flake8-commas "C4", # flake8-comprehensions "DTZ", # flake8-datetimez "T10", # flake8-debugger "EM", # flake8-errmsg "FA", # flake8-future-annotations "ISC", # flake8-implicit-str-concat "ICN", # flake8-import-conventions "G", # flake8-logging-format "INP", # flake8-no-pep420 "PIE", # flake8-pie "T20", # flake8-print "PYI", # flake8-pyi "PT", # flake8-pytest-style "Q", # flake8-quotes "RSE", # flake8-raise "RET", # flake8-return "SLF", # flake8-self "SIM", # flake8-simplify "TID", # flake8-tidy-imports "TCH", # flake8-type-checking "ARG", # flake8-unused-arguments "PTH", # flake8-use-pathlib "ERA", # eradicate "PD", # pandas-vet "PGH", # pygrep-hooks "PL", # Pylint "TRY", # tryceratops "FLY", # flynt "PERF", # Perflint "RUF", # Ruff-specific rules ] ignore = [ "S101", # Use of assert "S104", # Possible binding to all interfaces "S301", # Use of pickle "COM812", # Missing trailing comma (handled by formatter) "ISC001", # Single line implicit string concatenation (handled by formatter) "PLR0913", # Too many arguments to function call "TRY003", # Avoid specifying long messages outside the exception class "EM101", # Exception must not use a string literal "EM102", # Exception must not use an f-string literal "FBT001", # Boolean positional arg in function definition "FBT002", # Boolean default positional argument in function definition "G004", # Logging statement uses f-string "PLR2004", # Magic value used in comparison "SLF001", # Private member accessed ] [tool.ruff.lint.per-file-ignores] "tests/**/*.py" = [ "S106", # Possible hardcoded password "S108", # Possible insecure usage of temporary file/directory "ARG001", # Unused function argument "PLR2004", # Magic value used in comparison ] "strix/tools/**/*.py" = [ "ARG001", # Unused function argument (tools may have unused args for interface consistency) ] [tool.ruff.lint.isort] force-single-line = false lines-after-imports = 2 known-first-party = ["strix"] known-third-party = ["fastapi", "pydantic"] [tool.ruff.lint.pylint] max-args = 8 [tool.ruff.format] quote-style = "double" indent-style = "space" skip-magic-trailing-comma = false line-ending = "auto" # ============================================================================ # PyRight Configuration (Alternative type checker) # ============================================================================ [tool.pyright] include = ["strix"] exclude = ["**/__pycache__", "build", "dist"] pythonVersion = "3.12" pythonPlatform = "Linux" typeCheckingMode = "strict" reportMissingImports = true reportMissingTypeStubs = false reportGeneralTypeIssues = true reportPropertyTypeMismatch = true reportFunctionMemberAccess = true reportMissingParameterType = true reportMissingTypeArgument = true reportIncompatibleMethodOverride = true reportIncompatibleVariableOverride = true reportInconsistentConstructor = true reportOverlappingOverload = true reportConstantRedefinition = true reportImportCycles = true reportUnusedImport = true reportUnusedClass = true reportUnusedFunction = true reportUnusedVariable = true reportDuplicateImport = true # ============================================================================ # Black Configuration (Code Formatter) # ============================================================================ [tool.black] line-length = 100 target-version = ['py312'] include = '\\.pyi?$' extend-exclude = ''' /( # directories \.eggs | \.git | \.hg | \.mypy_cache | \.tox | \.venv | build | dist )/ ''' # ============================================================================ # isort Configuration (Import Sorting) # ============================================================================ [tool.isort] profile = "black" line_length = 100 multi_line_output = 3 include_trailing_comma = true force_grid_wrap = 0 use_parentheses = true ensure_newline_before_comments = true known_first_party = ["strix"] known_third_party = ["fastapi", "pydantic", "litellm", "tenacity"] # ============================================================================ # Pytest Configuration # ============================================================================ [tool.pytest.ini_options] minversion = "6.0" addopts = [ "--strict-markers", "--strict-config", "--cov=strix", "--cov-report=term-missing", "--cov-report=html", "--cov-report=xml", "--cov-fail-under=80" ] testpaths = ["tests"] python_files = ["test_*.py", "*_test.py"] python_functions = ["test_*"] python_classes = ["Test*"] asyncio_mode = "auto" [tool.coverage.run] source = ["strix"] omit = [ "*/tests/*", "*/migrations/*", "*/__pycache__/*" ] [tool.coverage.report] exclude_lines = [ "pragma: no cover", "def __repr__", "if self.debug:", "if settings.DEBUG", "raise AssertionError", "raise NotImplementedError", "if 0:", "if __name__ == .__main__.:", "class .*\\bProtocol\\):", "@(abc\\.)?abstractmethod", ] # ============================================================================ # Bandit Configuration (Security Linting) # ============================================================================ [tool.bandit] exclude_dirs = ["tests", "docs", "build", "dist"] skips = ["B101", "B601", "B404", "B603", "B607"] # Skip assert, shell injection, subprocess import and partial path checks severity = "medium"