mirror of
https://github.com/usestrix/strix.git
synced 2026-08-21 18:52:47 +02:00
Move the Vite frontend source into strix/viewer/frontend and rename the built bundle to strix/viewer/static, so all the viewer's pieces live under one directory. Updated the server bundle path, vite outDir, packaging (pyproject exclude, PyInstaller spec), Makefile, gitignore, and docs to match. Avoided naming the bundle dir 'dist' since gitignore matches that unanchored and would drop the shipped bundle.
357 lines
11 KiB
TOML
357 lines
11 KiB
TOML
[project]
|
|
name = "strix-agent"
|
|
version = "1.1.0"
|
|
description = "Open-source AI Hackers for your apps"
|
|
readme = "README.md"
|
|
license = "Apache-2.0"
|
|
requires-python = ">=3.12"
|
|
authors = [
|
|
{ name = "Strix", email = "hi@usestrix.com" },
|
|
]
|
|
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",
|
|
"Programming Language :: Python :: 3.13",
|
|
"Programming Language :: Python :: 3.14",
|
|
]
|
|
dependencies = [
|
|
"openai-agents[litellm]==0.14.6",
|
|
"openai>=2.26.0,<2.45",
|
|
"litellm",
|
|
"pydantic>=2.11.3",
|
|
"pydantic-settings>=2.13.0",
|
|
"rich",
|
|
"docker>=7.1.0",
|
|
"textual>=6.0.0",
|
|
"requests>=2.32.0",
|
|
"cvss>=3.2",
|
|
"caido-sdk-client>=0.2.0",
|
|
"reportlab>=4.0",
|
|
"pypdf>=5.0",
|
|
"cryptography>=42",
|
|
]
|
|
|
|
[project.optional-dependencies]
|
|
vertex = ["google-auth>=2.0.0"]
|
|
bedrock = ["boto3>=1.28.0"]
|
|
|
|
[project.scripts]
|
|
strix = "strix.interface.main:main"
|
|
|
|
[dependency-groups]
|
|
dev = [
|
|
"mypy>=1.16.0",
|
|
"ruff>=0.11.13",
|
|
"pyright>=1.1.401",
|
|
"bandit>=1.8.3",
|
|
"pre-commit>=4.2.0",
|
|
"pyinstaller>=6.17.0; python_version >= '3.12' and python_version < '3.15'",
|
|
"pytest>=8.3",
|
|
"pytest-asyncio>=0.24",
|
|
]
|
|
|
|
[tool.pytest.ini_options]
|
|
asyncio_mode = "auto"
|
|
|
|
[build-system]
|
|
requires = ["hatchling"]
|
|
build-backend = "hatchling.build"
|
|
|
|
[tool.hatch.build.targets.wheel]
|
|
packages = ["strix"]
|
|
# The prebuilt viewer bundle under strix/viewer/static/ ships automatically
|
|
# (hatchling includes non-.py files under the package). The Vite SOURCE lives
|
|
# under the package dir too (strix/viewer/frontend/) but must never ship in the wheel.
|
|
exclude = ["strix/viewer/frontend", "strix/viewer/frontend/**"]
|
|
|
|
# ============================================================================
|
|
# 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.*",
|
|
"rich.*",
|
|
"jinja2.*",
|
|
"textual.*",
|
|
"cvss.*",
|
|
"docker.*",
|
|
"caido_sdk_client.*",
|
|
"pydantic_settings.*",
|
|
"reportlab.*",
|
|
"pypdf.*",
|
|
]
|
|
ignore_missing_imports = true
|
|
disable_error_code = ["import-untyped"]
|
|
|
|
[[tool.mypy.overrides]]
|
|
module = ["tests.*"]
|
|
disallow_untyped_decorators = false
|
|
|
|
# ============================================================================
|
|
# Ruff Configuration (Fast Python Linter & Formatter)
|
|
# ============================================================================
|
|
|
|
[tool.ruff]
|
|
target-version = "py312"
|
|
line-length = 100
|
|
extend-exclude = [
|
|
".git",
|
|
".mypy_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
|
|
"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]
|
|
# Test doubles use fixture tokens/passwords and match a callee signature whose
|
|
# args they intentionally ignore.
|
|
"tests/test_viewer_auth.py" = ["S105", "S106", "ARG001"]
|
|
"tests/test_report_pdf.py" = ["S105", "S106"]
|
|
# Stdlib HTTP handler overrides (do_GET/do_POST) and lazy imports that avoid a
|
|
# circular dependency with strix.telemetry / strix.viewer.report_pdf.
|
|
"strix/viewer/server.py" = ["N802", "PLC0415"]
|
|
# Lazy telemetry import to avoid importing PostHog before the viewer starts.
|
|
"strix/viewer/cli.py" = ["PLC0415"]
|
|
# Lazy imports inside functions to avoid circular dependency with
|
|
# strix.telemetry / strix.report.dedupe / cvss.
|
|
"strix/tools/notes/tools.py" = ["PLC0415", "TC002"]
|
|
"strix/tools/finish/tool.py" = ["PLC0415", "TC002"]
|
|
"strix/tools/reporting/tool.py" = ["PLC0415", "TC002"]
|
|
"strix/tools/**/*.py" = [
|
|
"ARG001", # Unused function argument (tools may have unused args for interface consistency)
|
|
]
|
|
# Custom Docker subclass duplicates parent body; some imports are for annotations.
|
|
# Backend factories import their backend's deps lazily so deployments
|
|
# that pick a different backend don't need every backend's libs installed.
|
|
"strix/runtime/backends.py" = ["PLC0415"]
|
|
"strix/runtime/docker_client.py" = [
|
|
"TC002", # Manifest, Container imported for annotations
|
|
"TC003", # uuid imported for annotation
|
|
]
|
|
# SDK function-tool wrappers: the SDK calls get_type_hints() at registration
|
|
# time to derive the JSON schema, which evaluates annotations at runtime —
|
|
# so RunContextWrapper / Tool / TResponseInputItem must be imported eagerly,
|
|
# not under TYPE_CHECKING.
|
|
"strix/tools/todo/tools.py" = ["TC002"]
|
|
"strix/tools/thinking/tool.py" = ["TC002"]
|
|
"strix/tools/web_search/tool.py" = ["TC002"]
|
|
"strix/tools/proxy/tools.py" = ["TC002", "PLR0911"]
|
|
"strix/tools/agents_graph/tools.py" = ["TC002"]
|
|
"strix/agents/factory.py" = ["TC002"]
|
|
# Entry point: ``Path`` is used at runtime by the typing of the
|
|
# session_manager call; importing under TYPE_CHECKING would defer
|
|
# resolution past where mypy needs it.
|
|
"strix/core/runner.py" = ["TC003", "PLR0912", "PLR0915", "PLC0415"]
|
|
# ReportState carries scan artifact/report fields and
|
|
# a runtime ``Callable`` annotation on ``vulnerability_found_callback``.
|
|
"strix/report/state.py" = ["TC003", "PLR0912", "PLR0915", "E501", "PERF401"]
|
|
"strix/report/usage.py" = ["PLC0415"]
|
|
"strix/config/models.py" = ["PLC0415"]
|
|
# Interface utility branches per scope-mode / target-type combination;
|
|
# splitting would obscure the decision tree without simplifying it.
|
|
"strix/interface/utils.py" = ["PLR0912", "BLE001", "PLC0415"]
|
|
# CLI / TUI / main keep extensive lazy imports + broad exception
|
|
# swallows for resilience around terminal-rendering errors.
|
|
"strix/interface/cli.py" = ["BLE001", "PLC0415"]
|
|
"strix/interface/tui/app.py" = ["BLE001", "PLC0415", "PLR0912", "PLR0915", "SIM105"]
|
|
"strix/interface/main.py" = ["BLE001", "PLC0415", "PLR0912", "PLR0915"]
|
|
"strix/interface/tui/renderers/agent_message_renderer.py" = ["PLC0415"]
|
|
|
|
[tool.ruff.lint.isort]
|
|
force-single-line = false
|
|
lines-after-imports = 2
|
|
known-first-party = ["strix"]
|
|
known-third-party = ["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 = ["pydantic", "litellm"]
|
|
|
|
# ============================================================================
|
|
# Bandit Configuration (Security Linting)
|
|
# ============================================================================
|
|
|
|
[tool.bandit]
|
|
exclude_dirs = ["docs", "build", "dist"]
|
|
skips = ["B101", "B601", "B404", "B603", "B607"] # Skip assert, shell injection, subprocess import and partial path checks
|
|
severity = "medium"
|