Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,15 @@ repos:
additional_dependencies:
- tomli
priority: 0
- repo: local
hooks:
- id: check-skills-documented
name: check-skills-documented
entry: uv run --frozen --offline hooks/check-skills-documented.py
language: system
always_run: true
pass_filenames: false
priority: 0
- repo: local
hooks:
- id: deptry
Expand Down
26 changes: 25 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,33 @@ Follow standard contributing guidelines as documented in CONTRIBUTING.md.

## Agent Skills

The .agent/skills directory contains agent skills.
The `.agents/skills` directory contains agent skills.

### Important skills

- Always run static checks using the `usethis-qa-static-checks` skill before finishing a task.
- If modifying Python code, always use the `usethis-python-code`, `usethis-python-code-modify`, and `usethis-python-module-layout-modify` skills.

### Skills registry

<!-- This list is validated by the hooks/check-skills-documented.py hook. -->

| Skill | Description |
| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `github-actions-update` | Update GitHub Actions workflows |
| `usethis-file-remove` | Remove files from the project |
| `usethis-pre-commit` | Guidance on pre-commit hooks — this project uses prek, not pre-commit directly |
| `usethis-prek-add-hook` | Add a prek hook for dev |
| `usethis-prek-hook-bespoke-create` | Write bespoke prek hooks as Python scripts for custom project-specific checks |
| `usethis-python-code` | Guidelines for Python code design decisions such as when to share vs. duplicate code |
| `usethis-python-code-modify` | Modify Python code (e.g. refactor, add new code, or delete code) |
| `usethis-python-enum` | Style and testing conventions for working with Python enums |
| `usethis-python-functions` | Guidelines for Python function design, including return types and signature simplicity |
| `usethis-python-module-layout-modify` | Modify the Python module layout (create, move, rename, or delete modules) |
| `usethis-python-ruff` | Guidelines for complying with Ruff linter rules instead of suppressing them |
| `usethis-python-test-affected-find` | Identify tests that are potentially affected by code changes, to catch regressions before CI |
| `usethis-qa-import-linter` | Use the Import Linter software on the usethis project |
| `usethis-qa-static-checks` | Perform static code checks |
| `usethis-skills-create` | Create new agent skills (SKILL.md files) following best practices for content quality, structure, and discoverability |
| `usethis-skills-modify` | Modify agent skills (SKILL.md files) |
| `usethis-test-with-coverage` | Write tests that achieve full code coverage and verify coverage locally before pushing |
45 changes: 45 additions & 0 deletions hooks/check-skills-documented.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
"""Check that all skills in .agents/skills/ are mentioned in AGENTS.md."""

from __future__ import annotations

import sys
from pathlib import Path

AGENTS_MD = Path("AGENTS.md")
SKILLS_DIR = Path(".agents/skills")


def main() -> int:
if not AGENTS_MD.is_file():
print(f"ERROR: {AGENTS_MD} not found.", file=sys.stderr)
return 1

if not SKILLS_DIR.is_dir():
print(f"ERROR: {SKILLS_DIR} directory not found.", file=sys.stderr)
return 1

agents_md_content = AGENTS_MD.read_text()

missing = [
d.name
for d in sorted(SKILLS_DIR.iterdir())
if d.is_dir() and d.name not in agents_md_content
]

if missing:
print(
"ERROR: The following skills are not mentioned in AGENTS.md:",
file=sys.stderr,
)
for skill in missing:
print(f" - {skill}", file=sys.stderr)
print(file=sys.stderr)
print("Please add them to the skills registry in AGENTS.md.", file=sys.stderr)
return 1

print("All skills are documented in AGENTS.md.")
return 0


if __name__ == "__main__":
raise SystemExit(main())
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ lint.select = [
]
lint.ignore = [ "PLR2004", "S101", "SIM108" ]
lint.per-file-ignores."!tests/**/*.py" = [ "ARG002", "PT" ]
lint.per-file-ignores."hooks/**" = [ "D", "INP001" ]
lint.per-file-ignores."src/usethis/_ui/interface/**/*.py" = [ "PLR0913", "TC001" ]
lint.per-file-ignores."tests/**" = [ "D", "INP", "S603", "TC" ]
lint.flake8-bugbear.extend-immutable-calls = [ "typer.Argument", "typer.Option" ]
Expand Down
Loading