blob: ab345a034a1267d97eafc500d94013644aa3b8a9 [file]
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "agent-guard"
version = "0.1.0"
description = "Deterministic Claude Code PreToolUse guard dispatcher: blocks gh/git commands that would ping maintainers, carry a Co-Authored-By trailer, mark-ready prematurely, leak security language publicly, or empty a PR via force-push."
readme = "README.md"
requires-python = ">=3.11"
license = { text = "Apache-2.0" }
# stdlib-only on purpose — the hook fires on every Bash call and is invoked as
# `python3 src/agent_guard/__init__.py`, never via `uv run`, so it must not need
# a built/installed environment to run.
dependencies = []
[project.scripts]
agent-guard = "agent_guard:main"
[tool.hatch.build.targets.wheel]
packages = ["src/agent_guard"]
[tool.ruff]
line-length = 110
target-version = "py311"
src = ["src", "tests"]
# guards.d holds duck-typed `guard(ctx)` plugin files (a drop-dir, not part of
# the typed package). They are exercised by the discovery tests, not linted as
# package code — same contract a skill-contributed guard in an adopter repo has.
extend-exclude = ["src/agent_guard/guards.d"]
[tool.ruff.lint]
select = ["E", "W", "F", "I", "B", "UP", "SIM", "C4", "RUF"]
ignore = ["E501"]
[tool.ruff.lint.per-file-ignores]
"tests/**" = ["B", "SIM"]
[tool.mypy]
python_version = "3.11"
# Type-check the shipped engine; tests are exercised by pytest. guards.d is a
# duck-typed plugin drop-dir (see the [tool.ruff] note).
files = ["src"]
exclude = ['(^|/)guards\.d/']
warn_unused_ignores = true
warn_redundant_casts = true
warn_unreachable = true
check_untyped_defs = true
no_implicit_optional = true
disallow_untyped_defs = true
disallow_incomplete_defs = true
[[tool.mypy.overrides]]
module = "tests.*"
disallow_untyped_defs = false
disallow_incomplete_defs = false
[tool.pytest.ini_options]
minversion = "8.0"
addopts = "-ra -q"
testpaths = ["tests"]
[dependency-groups]
# Shared static-analysis + test toolchain, pinned to the same versions as the
# workspace root so every sub-project's own environment is self-contained.
# The workspace checks run each tool via `uv run --directory <member>
# --project . python -m <tool>` — see tools/dev/run-workspace-check.sh.
dev = [
"mypy>=2.1.0",
"pytest>=9.1.1",
"ruff>=0.15.20",
]