[build-system] requires = ["hatchling<1.31", "jsonschema>=4.26.0"] build-backend = "hatchling.build" [project] name = "hol-guard" version = "3.26.0" description = "Open-source antivirus and runtime protection for AI agents, tools, MCP servers, plugins, skills, and package installs." readme = "README.md" license = "Apache-2.0" requires-python = ">=3.10" authors = [ { name = "HOL", email = "support@hol.org" }, ] keywords = [ "ai antivirus", "ai agent security", "ai agents", "runtime security", "mcp security", "supply chain security", "prompt injection", "secrets detection", "plugin security", "cli", "codex", "claude", "cursor", "gemini", "opencode", ] classifiers = [ "Development Status :: 5 - Production/Stable", "Environment :: Console", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", "Topic :: Security", "Topic :: Software Development :: Quality Assurance", ] dependencies = [ "rich>=14.0,<15", "cryptography>=50.0.0", "keyring>=25.0", "packaging>=24.0", "idna==3.15", "jsonschema>=4.26.0", "pyyaml>=6.0.3", "regex>=2025.0.0,<2027", "requests>=2.32,<3", "tomli>=2.0; python_version < '3.11'", "typing_extensions>=4.15.0", "mcp>=1.28.1,<2; python_version >= '3.10'", "tomlkit>=0.13.3,<1", ] [project.optional-dependencies] cisco = [ "cisco-ai-skill-scanner~=2.0.12", "litellm==1.93.2; python_version < '3.15'", ] dev = [ "basedpyright>=1.39.8", "build>=1.5.0", "pytest>=9.0.3", "pytest-cov>=7.1.0", "ruff>=0.15.15", ] mdm-build = [ "pyinstaller>=6.16,<7", ] publish = [ "twine>=6.2.0", ] [dependency-groups] ci-test = [ "build>=1.5.0", "pytest>=9.0.3", "pytest-cov>=7.1.0", "ruff>=0.15.15", ] cisco-mcp = [ "cisco-ai-mcp-scanner==4.8.1; python_full_version >= '3.11.4'", ] dev = [ "mutmut>=3.4,<4", ] [tool.uv] override-dependencies = [ "aiohttp==3.14.3", "anyio==4.14.2", "click==8.4.1", "cisco-ai-skill-scanner==2.0.12", "fastapi==0.137.1", "importlib-metadata==8.9.0", "jsonschema==4.26.0", "litellm==1.93.2", "magika==1.0.3", "openai==2.41.1", "pyjwt==2.14.0", "python-dotenv==1.2.2", "python-multipart==0.0.32", "starlette==1.3.1", "tokenizers==0.23.1", "urllib3==2.8.0", ] [project.scripts] hol-guard = "codex_plugin_scanner.cli:main" hol-guard-eval = "codex_plugin_scanner.guard.evaluation_cli:main" hol-guard-secrets = "codex_plugin_scanner.guard.secrets.cli:main" plugin-scanner = "codex_plugin_scanner.cli:main" plugin-guard = "codex_plugin_scanner.cli:main" plugin-ecosystem-scanner = "codex_plugin_scanner.cli:main" [project.urls] Homepage = "https://hol.org/guard" Security = "https://hol.org/guard/security" "Security Policy" = "https://github.com/hashgraph-online/hol-guard/blob/main/SECURITY.md" Documentation = "https://github.com/hashgraph-online/hol-guard/tree/main/docs/guard" Repository = "https://github.com/hashgraph-online/hol-guard" Issues = "https://github.com/hashgraph-online/hol-guard/issues" Changelog = "https://github.com/hashgraph-online/hol-guard/releases" Dataset = "https://huggingface.co/datasets/HashgraphOnline/hol-plugin-security" [tool.ruff] target-version = "py310" line-length = 120 [tool.hatch.build.targets.wheel] packages = ["src/codex_plugin_scanner"] [tool.hatch.build.targets.sdist] # Keep all inputs needed to rebuild the wheel and verify frozen projections. # Dashboard assets are already bundled under src; contributor tests live in Git. only-include = [ "src", "scripts", "rust", "contracts", "contributions", "docs/guard/contracts/guard-cloud-review.md", "README.md", "LICENSE", ] [tool.hatch.build.hooks.custom] path = "scripts/build_command_projection_hook.py" [tool.hatch.build.targets.wheel.force-include] "contracts/guard-cloud-review/v2/contract.json" = "codex_plugin_scanner/guard/contracts/data/guard-cloud-review/v2/contract.json" "contracts/guard-cloud-review/v2/command-result.json" = "codex_plugin_scanner/guard/contracts/data/guard-cloud-review/v2/command-result.json" "contracts/guard-cloud-review/v2/fixtures.json" = "codex_plugin_scanner/guard/contracts/data/guard-cloud-review/v2/fixtures.json" "docs/guard/contracts/guard-cloud-review.md" = "codex_plugin_scanner/guard/contracts/data/guard-cloud-review/guard-cloud-review.md" "contracts/extensions/trust-class-map.v1.json" = "codex_plugin_scanner/guard/contracts/data/extensions/trust-class-map.v1.json" "contracts/extensions/contribution.v1.schema.json" = "codex_plugin_scanner/guard/contracts/data/extensions/contribution.v1.schema.json" "contracts/extensions/contribution.v2.schema.json" = "codex_plugin_scanner/guard/contracts/data/extensions/contribution.v2.schema.json" "contributions/extensions" = "codex_plugin_scanner/guard/contracts/data/extensions/contributions" "contracts/mcp-servers/contribution.v1.schema.json" = "codex_plugin_scanner/guard/contracts/data/mcp_servers/contribution.v1.schema.json" "contributions/mcp-servers" = "codex_plugin_scanner/guard/contracts/data/mcp_servers/contributions" [tool.hatch.build] artifacts = [ "src/codex_plugin_scanner/guard/daemon/static/**", "src/codex_plugin_scanner/guard/schemas/**", ] exclude = [ "src/codex_plugin_scanner/_native/guard-command-source", "src/codex_plugin_scanner/_native/source-compiler-manifest.json", "src/codex_plugin_scanner/guard/contracts/data/extensions/native-command-program.v1.json", "src/codex_plugin_scanner/guard/contracts/data/extensions/command-catalog.v1.json", "src/codex_plugin_scanner/guard/contracts/data/extensions/trust-class-map.v1.json", ".guard-live/**", ".guard-package-venv/**", ".guard-e2e/**", ".guard-e2e-prod/**", ".guard-e2e-prod2/**", ".guard-prod-venv/**", ".guard-prod-venv-fresh/**", ".venv/**", ".venv-*/**", "dashboard/node_modules/**", ] [tool.ruff.lint] select = ["E", "F", "W", "I", "N", "UP", "B", "A", "SIM", "RUF"] [tool.ruff.lint.per-file-ignores] "tests/fixtures/mcp-canary-server.py" = ["N999"] "scripts/codex-auto-resume-smoke.py" = ["N999"] "scripts/e2e-cursor-hook-smoke.py" = ["N999"] [tool.pytest.ini_options] testpaths = ["tests"] python_files = ["test_*.py"] addopts = ["--strict-markers", "-m", "not slow"] markers = [ "adapter_contract: verifies the shared security contract for a harness adapter", "daemon_aibom_refresh: enables the daemon AIBOM refresh worker for focused tests", "daemon_bundle_refresh: enables the daemon supply-chain bundle refresh worker for focused tests", "daemon_headless_queue: enables request-triggered daemon cloud sync for focused tests", "daemon_headless_refresh: enables the daemon headless cloud sync worker for focused tests", "daemon_service_workers: enables command queue and live request sync workers for focused tests", "fault_injection: destructive store fault tests; only run with GUARD_FAULT_INJECTION=1", "installed: requires verification through an installed package artifact", "integration: verifies multiple Guard subsystems together", "parser: verifies parsing or normalization security semantics", "policy: verifies policy composition or enforcement semantics", "regression: protects a previously observed defect or security finding", "release: required for a release-candidate verification gate", "security_critical: protects a Guard security boundary that cannot be removed without an equivalent replacement", "slow: marks tests as slow (deselected by default; run with -m slow to include)", "soak: marks long-running acceptance workloads that require explicit opt-in", "compat: verifies a supported Python or platform compatibility contract", ] [tool.coverage.run] source_pkgs = ["codex_plugin_scanner"] branch = true # SonarQube Cloud requires repo-relative paths so CI-generated reports match checked-out sources. relative_files = true [tool.mutmut] source_paths = ["src/codex_plugin_scanner/guard/runtime/command_model.py"] also_copy = [ "src/codex_plugin_scanner", "contracts/extensions", "contracts/guard-cloud-review", "docs/guard/contracts", "rust/crates/guard-command/src", ] pytest_add_cli_args_test_selection = [ "tests/test_guard_command_model.py", "tests/test_guard_command_critical_floors.py", "tests/test_guard_command_corpus.py", ] [tool.basedpyright] include = ["src"] pythonVersion = "3.10" failOnWarnings = false reportImportCycles = false