@bgicli/bgicli 2.2.8 → 2.2.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data/skills/anthropic-algorithmic-art/SKILL.md +405 -0
- package/data/skills/anthropic-canvas-design/SKILL.md +130 -0
- package/data/skills/anthropic-claude-api/SKILL.md +243 -0
- package/data/skills/anthropic-doc-coauthoring/SKILL.md +375 -0
- package/data/skills/anthropic-docx/SKILL.md +590 -0
- package/data/skills/anthropic-frontend-design/SKILL.md +42 -0
- package/data/skills/anthropic-internal-comms/SKILL.md +32 -0
- package/data/skills/anthropic-mcp-builder/SKILL.md +236 -0
- package/data/skills/anthropic-pdf/SKILL.md +314 -0
- package/data/skills/anthropic-pptx/SKILL.md +232 -0
- package/data/skills/anthropic-skill-creator/SKILL.md +485 -0
- package/data/skills/anthropic-webapp-testing/SKILL.md +96 -0
- package/data/skills/anthropic-xlsx/SKILL.md +292 -0
- package/data/skills/arxiv-database/SKILL.md +362 -0
- package/data/skills/astropy/SKILL.md +329 -0
- package/data/skills/ctx-advanced-evaluation/SKILL.md +402 -0
- package/data/skills/ctx-bdi-mental-states/SKILL.md +311 -0
- package/data/skills/ctx-context-compression/SKILL.md +272 -0
- package/data/skills/ctx-context-degradation/SKILL.md +206 -0
- package/data/skills/ctx-context-fundamentals/SKILL.md +201 -0
- package/data/skills/ctx-context-optimization/SKILL.md +195 -0
- package/data/skills/ctx-evaluation/SKILL.md +251 -0
- package/data/skills/ctx-filesystem-context/SKILL.md +287 -0
- package/data/skills/ctx-hosted-agents/SKILL.md +260 -0
- package/data/skills/ctx-memory-systems/SKILL.md +225 -0
- package/data/skills/ctx-multi-agent-patterns/SKILL.md +257 -0
- package/data/skills/ctx-project-development/SKILL.md +291 -0
- package/data/skills/ctx-tool-design/SKILL.md +271 -0
- package/data/skills/dhdna-profiler/SKILL.md +162 -0
- package/data/skills/generate-image/SKILL.md +183 -0
- package/data/skills/geomaster/SKILL.md +365 -0
- package/data/skills/get-available-resources/SKILL.md +275 -0
- package/data/skills/hamelsmu-build-review-interface/SKILL.md +96 -0
- package/data/skills/hamelsmu-error-analysis/SKILL.md +164 -0
- package/data/skills/hamelsmu-eval-audit/SKILL.md +183 -0
- package/data/skills/hamelsmu-evaluate-rag/SKILL.md +177 -0
- package/data/skills/hamelsmu-generate-synthetic-data/SKILL.md +131 -0
- package/data/skills/hamelsmu-validate-evaluator/SKILL.md +212 -0
- package/data/skills/hamelsmu-write-judge-prompt/SKILL.md +144 -0
- package/data/skills/hf-cli/SKILL.md +174 -0
- package/data/skills/hf-mcp/SKILL.md +178 -0
- package/data/skills/hugging-face-dataset-viewer/SKILL.md +121 -0
- package/data/skills/hugging-face-datasets/SKILL.md +542 -0
- package/data/skills/hugging-face-evaluation/SKILL.md +651 -0
- package/data/skills/hugging-face-jobs/SKILL.md +1042 -0
- package/data/skills/hugging-face-model-trainer/SKILL.md +717 -0
- package/data/skills/hugging-face-paper-pages/SKILL.md +239 -0
- package/data/skills/hugging-face-paper-publisher/SKILL.md +624 -0
- package/data/skills/hugging-face-tool-builder/SKILL.md +110 -0
- package/data/skills/hugging-face-trackio/SKILL.md +115 -0
- package/data/skills/hugging-face-vision-trainer/SKILL.md +593 -0
- package/data/skills/huggingface-gradio/SKILL.md +245 -0
- package/data/skills/matlab/SKILL.md +376 -0
- package/data/skills/modal/SKILL.md +381 -0
- package/data/skills/openai-cloudflare-deploy/SKILL.md +224 -0
- package/data/skills/openai-develop-web-game/SKILL.md +149 -0
- package/data/skills/openai-doc/SKILL.md +80 -0
- package/data/skills/openai-figma/SKILL.md +42 -0
- package/data/skills/openai-figma-implement-design/SKILL.md +264 -0
- package/data/skills/openai-gh-address-comments/SKILL.md +25 -0
- package/data/skills/openai-gh-fix-ci/SKILL.md +69 -0
- package/data/skills/openai-imagegen/SKILL.md +174 -0
- package/data/skills/openai-jupyter-notebook/SKILL.md +107 -0
- package/data/skills/openai-linear/SKILL.md +87 -0
- package/data/skills/openai-netlify-deploy/SKILL.md +247 -0
- package/data/skills/openai-notion-knowledge-capture/SKILL.md +56 -0
- package/data/skills/openai-notion-meeting-intelligence/SKILL.md +60 -0
- package/data/skills/openai-notion-research-documentation/SKILL.md +59 -0
- package/data/skills/openai-notion-spec-to-implementation/SKILL.md +58 -0
- package/data/skills/openai-openai-docs/SKILL.md +69 -0
- package/data/skills/openai-pdf/SKILL.md +67 -0
- package/data/skills/openai-playwright/SKILL.md +147 -0
- package/data/skills/openai-render-deploy/SKILL.md +479 -0
- package/data/skills/openai-screenshot/SKILL.md +267 -0
- package/data/skills/openai-security-best-practices/SKILL.md +86 -0
- package/data/skills/openai-security-ownership-map/SKILL.md +206 -0
- package/data/skills/openai-security-threat-model/SKILL.md +81 -0
- package/data/skills/openai-sentry/SKILL.md +123 -0
- package/data/skills/openai-sora/SKILL.md +178 -0
- package/data/skills/openai-speech/SKILL.md +144 -0
- package/data/skills/openai-spreadsheet/SKILL.md +145 -0
- package/data/skills/openai-transcribe/SKILL.md +81 -0
- package/data/skills/openai-vercel-deploy/SKILL.md +77 -0
- package/data/skills/openai-yeet/SKILL.md +28 -0
- package/data/skills/pennylane/SKILL.md +224 -0
- package/data/skills/polars-bio/SKILL.md +374 -0
- package/data/skills/primekg/SKILL.md +97 -0
- package/data/skills/pymatgen/SKILL.md +689 -0
- package/data/skills/qiskit/SKILL.md +273 -0
- package/data/skills/qutip/SKILL.md +316 -0
- package/data/skills/recursive-decomposition/SKILL.md +185 -0
- package/data/skills/rowan/SKILL.md +427 -0
- package/data/skills/scholar-evaluation/SKILL.md +298 -0
- package/data/skills/sentry-create-alert/SKILL.md +210 -0
- package/data/skills/sentry-fix-issues/SKILL.md +126 -0
- package/data/skills/sentry-pr-code-review/SKILL.md +105 -0
- package/data/skills/sentry-python-sdk/SKILL.md +317 -0
- package/data/skills/sentry-setup-ai-monitoring/SKILL.md +217 -0
- package/data/skills/stable-baselines3/SKILL.md +297 -0
- package/data/skills/sympy/SKILL.md +498 -0
- package/data/skills/trailofbits-ask-questions-if-underspecified/SKILL.md +85 -0
- package/data/skills/trailofbits-audit-context-building/SKILL.md +302 -0
- package/data/skills/trailofbits-differential-review/SKILL.md +220 -0
- package/data/skills/trailofbits-insecure-defaults/SKILL.md +117 -0
- package/data/skills/trailofbits-modern-python/SKILL.md +333 -0
- package/data/skills/trailofbits-property-based-testing/SKILL.md +123 -0
- package/data/skills/trailofbits-semgrep-rule-creator/SKILL.md +172 -0
- package/data/skills/trailofbits-sharp-edges/SKILL.md +292 -0
- package/data/skills/trailofbits-variant-analysis/SKILL.md +142 -0
- package/data/skills/transformers.js/SKILL.md +637 -0
- package/data/skills/writing/SKILL.md +419 -0
- package/dist/bgi.js +66 -2
- package/package.json +1 -1
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: modern-python
|
|
3
|
+
description: Configures Python projects with modern tooling (uv, ruff, ty). Use when creating projects, writing standalone scripts, or migrating from pip/Poetry/mypy/black.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Modern Python
|
|
7
|
+
|
|
8
|
+
Guide for modern Python tooling and best practices, based on [trailofbits/cookiecutter-python](https://github.com/trailofbits/cookiecutter-python).
|
|
9
|
+
|
|
10
|
+
## When to Use This Skill
|
|
11
|
+
|
|
12
|
+
- Creating a new Python project or package
|
|
13
|
+
- Setting up `pyproject.toml` configuration
|
|
14
|
+
- Configuring development tools (linting, formatting, testing)
|
|
15
|
+
- Writing Python scripts with external dependencies
|
|
16
|
+
- Migrating from legacy tools (when user requests it)
|
|
17
|
+
|
|
18
|
+
## When NOT to Use This Skill
|
|
19
|
+
|
|
20
|
+
- **User wants to keep legacy tooling**: Respect existing workflows if explicitly requested
|
|
21
|
+
- **Python < 3.11 required**: These tools target modern Python
|
|
22
|
+
- **Non-Python projects**: Mixed codebases where Python isn't primary
|
|
23
|
+
|
|
24
|
+
## Anti-Patterns to Avoid
|
|
25
|
+
|
|
26
|
+
| Avoid | Use Instead |
|
|
27
|
+
|-------|-------------|
|
|
28
|
+
| `[tool.ty]` python-version | `[tool.ty.environment]` python-version |
|
|
29
|
+
| `uv pip install` | `uv add` and `uv sync` |
|
|
30
|
+
| Editing pyproject.toml manually to add deps | `uv add <pkg>` / `uv remove <pkg>` |
|
|
31
|
+
| `hatchling` build backend | `uv_build` (simpler, sufficient for most cases) |
|
|
32
|
+
| Poetry | uv (faster, simpler, better ecosystem integration) |
|
|
33
|
+
| requirements.txt | PEP 723 for scripts, pyproject.toml for projects |
|
|
34
|
+
| mypy / pyright | ty (faster, from Astral team) |
|
|
35
|
+
| `[project.optional-dependencies]` for dev tools | `[dependency-groups]` (PEP 735) |
|
|
36
|
+
| Manual virtualenv activation (`source .venv/bin/activate`) | `uv run <cmd>` |
|
|
37
|
+
| pre-commit | prek (faster, no Python runtime needed) |
|
|
38
|
+
|
|
39
|
+
**Key principles:**
|
|
40
|
+
- Always use `uv add` and `uv remove` to manage dependencies
|
|
41
|
+
- Never manually activate or manage virtual environments—use `uv run` for all commands
|
|
42
|
+
- Use `[dependency-groups]` for dev/test/docs dependencies, not `[project.optional-dependencies]`
|
|
43
|
+
|
|
44
|
+
## Decision Tree
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
What are you doing?
|
|
48
|
+
│
|
|
49
|
+
├─ Single-file script with dependencies?
|
|
50
|
+
│ └─ Use PEP 723 inline metadata (./references/pep723-scripts.md)
|
|
51
|
+
│
|
|
52
|
+
├─ New multi-file project (not distributed)?
|
|
53
|
+
│ └─ Minimal uv setup (see Quick Start below)
|
|
54
|
+
│
|
|
55
|
+
├─ New reusable package/library?
|
|
56
|
+
│ └─ Full project setup (see Full Setup below)
|
|
57
|
+
│
|
|
58
|
+
└─ Migrating existing project?
|
|
59
|
+
└─ See Migration Guide below
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Tool Overview
|
|
63
|
+
|
|
64
|
+
| Tool | Purpose | Replaces |
|
|
65
|
+
|------|---------|----------|
|
|
66
|
+
| **uv** | Package/dependency management | pip, virtualenv, pip-tools, pipx, pyenv |
|
|
67
|
+
| **ruff** | Linting AND formatting | flake8, black, isort, pyupgrade, pydocstyle |
|
|
68
|
+
| **ty** | Type checking | mypy, pyright (faster alternative) |
|
|
69
|
+
| **pytest** | Testing with coverage | unittest |
|
|
70
|
+
| **prek** | Pre-commit hooks ([setup](./references/prek.md)) | pre-commit (faster, Rust-native) |
|
|
71
|
+
|
|
72
|
+
### Security Tools
|
|
73
|
+
|
|
74
|
+
| Tool | Purpose | When It Runs |
|
|
75
|
+
|------|---------|--------------|
|
|
76
|
+
| **shellcheck** | Shell script linting | pre-commit |
|
|
77
|
+
| **detect-secrets** | Secret detection | pre-commit |
|
|
78
|
+
| **actionlint** | Workflow syntax validation | pre-commit, CI |
|
|
79
|
+
| **zizmor** | Workflow security audit | pre-commit, CI |
|
|
80
|
+
| **pip-audit** | Dependency vulnerability scanning | CI, manual |
|
|
81
|
+
| **Dependabot** | Automated dependency updates | scheduled |
|
|
82
|
+
|
|
83
|
+
See [security-setup.md](./references/security-setup.md) for configuration and usage.
|
|
84
|
+
|
|
85
|
+
## Quick Start: Minimal Project
|
|
86
|
+
|
|
87
|
+
For simple multi-file projects not intended for distribution:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# Create project with uv
|
|
91
|
+
uv init myproject
|
|
92
|
+
cd myproject
|
|
93
|
+
|
|
94
|
+
# Add dependencies
|
|
95
|
+
uv add requests rich
|
|
96
|
+
|
|
97
|
+
# Add dev dependencies
|
|
98
|
+
uv add --group dev pytest ruff ty
|
|
99
|
+
|
|
100
|
+
# Run code
|
|
101
|
+
uv run python src/myproject/main.py
|
|
102
|
+
|
|
103
|
+
# Run tools
|
|
104
|
+
uv run pytest
|
|
105
|
+
uv run ruff check .
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Full Project Setup
|
|
109
|
+
If starting from scratch, ask the user if they prefer to use the Trail of Bits cookiecutter template to bootstrap a complete project with already preconfigured tooling.
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
uvx cookiecutter gh:trailofbits/cookiecutter-python
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### 1. Create Project Structure
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
uv init --package myproject
|
|
119
|
+
cd myproject
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
This creates:
|
|
123
|
+
```
|
|
124
|
+
myproject/
|
|
125
|
+
├── pyproject.toml
|
|
126
|
+
├── README.md
|
|
127
|
+
├── src/
|
|
128
|
+
│ └── myproject/
|
|
129
|
+
│ └── __init__.py
|
|
130
|
+
└── .python-version
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 2. Configure pyproject.toml
|
|
134
|
+
|
|
135
|
+
See [pyproject.md](./references/pyproject.md) for complete configuration reference.
|
|
136
|
+
|
|
137
|
+
Key sections:
|
|
138
|
+
```toml
|
|
139
|
+
[project]
|
|
140
|
+
name = "myproject"
|
|
141
|
+
version = "0.1.0"
|
|
142
|
+
requires-python = ">=3.11"
|
|
143
|
+
dependencies = []
|
|
144
|
+
|
|
145
|
+
[dependency-groups]
|
|
146
|
+
dev = [{include-group = "lint"}, {include-group = "test"}, {include-group = "audit"}]
|
|
147
|
+
lint = ["ruff", "ty"]
|
|
148
|
+
test = ["pytest", "pytest-cov"]
|
|
149
|
+
audit = ["pip-audit"]
|
|
150
|
+
|
|
151
|
+
[tool.ruff]
|
|
152
|
+
line-length = 100
|
|
153
|
+
target-version = "py311"
|
|
154
|
+
|
|
155
|
+
[tool.ruff.lint]
|
|
156
|
+
select = ["ALL"]
|
|
157
|
+
ignore = ["D", "COM812", "ISC001"]
|
|
158
|
+
|
|
159
|
+
[tool.pytest]
|
|
160
|
+
addopts = ["--cov=myproject", "--cov-fail-under=80"]
|
|
161
|
+
|
|
162
|
+
[tool.ty.terminal]
|
|
163
|
+
error-on-warning = true
|
|
164
|
+
|
|
165
|
+
[tool.ty.environment]
|
|
166
|
+
python-version = "3.11"
|
|
167
|
+
|
|
168
|
+
[tool.ty.rules]
|
|
169
|
+
# Strict from day 1 for new projects
|
|
170
|
+
possibly-unresolved-reference = "error"
|
|
171
|
+
unused-ignore-comment = "warn"
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### 3. Install Dependencies
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
# Install all dependency groups
|
|
178
|
+
uv sync --all-groups
|
|
179
|
+
|
|
180
|
+
# Or install specific groups
|
|
181
|
+
uv sync --group dev
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### 4. Add Makefile
|
|
185
|
+
|
|
186
|
+
```makefile
|
|
187
|
+
.PHONY: dev lint format test build
|
|
188
|
+
|
|
189
|
+
dev:
|
|
190
|
+
uv sync --all-groups
|
|
191
|
+
|
|
192
|
+
lint:
|
|
193
|
+
uv run ruff format --check && uv run ruff check && uv run ty check src/
|
|
194
|
+
|
|
195
|
+
format:
|
|
196
|
+
uv run ruff format .
|
|
197
|
+
|
|
198
|
+
test:
|
|
199
|
+
uv run pytest
|
|
200
|
+
|
|
201
|
+
build:
|
|
202
|
+
uv build
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Migration Guide
|
|
206
|
+
|
|
207
|
+
When a user requests migration from legacy tooling:
|
|
208
|
+
|
|
209
|
+
### From requirements.txt + pip
|
|
210
|
+
|
|
211
|
+
First, determine the nature of the code:
|
|
212
|
+
|
|
213
|
+
**For standalone scripts**: Convert to PEP 723 inline metadata (see [pep723-scripts.md](./references/pep723-scripts.md))
|
|
214
|
+
|
|
215
|
+
**For projects**:
|
|
216
|
+
```bash
|
|
217
|
+
# Initialize uv in existing project
|
|
218
|
+
uv init --bare
|
|
219
|
+
|
|
220
|
+
# Add dependencies using uv (not by editing pyproject.toml)
|
|
221
|
+
uv add requests rich # add each package
|
|
222
|
+
|
|
223
|
+
# Or import from requirements.txt (review each package before adding)
|
|
224
|
+
# Note: Complex version specifiers may need manual handling
|
|
225
|
+
grep -v '^#' requirements.txt | grep -v '^-' | grep -v '^\s*$' | while read -r pkg; do
|
|
226
|
+
uv add "$pkg" || echo "Failed to add: $pkg"
|
|
227
|
+
done
|
|
228
|
+
|
|
229
|
+
uv sync
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Then:
|
|
233
|
+
1. Delete `requirements.txt`, `requirements-dev.txt`
|
|
234
|
+
2. Delete virtual environment (`venv/`, `.venv/`)
|
|
235
|
+
3. Add `uv.lock` to version control
|
|
236
|
+
|
|
237
|
+
### From setup.py / setup.cfg
|
|
238
|
+
|
|
239
|
+
1. Run `uv init --bare` to create pyproject.toml
|
|
240
|
+
2. Use `uv add` to add each dependency from `install_requires`
|
|
241
|
+
3. Use `uv add --group dev` for dev dependencies
|
|
242
|
+
4. Copy non-dependency metadata (name, version, description, etc.) to `[project]`
|
|
243
|
+
5. Delete `setup.py`, `setup.cfg`, `MANIFEST.in`
|
|
244
|
+
|
|
245
|
+
### From flake8 + black + isort
|
|
246
|
+
|
|
247
|
+
1. Remove flake8, black, isort via `uv remove`
|
|
248
|
+
2. Delete `.flake8`, `pyproject.toml [tool.black]`, `[tool.isort]` configs
|
|
249
|
+
3. Add ruff: `uv add --group dev ruff`
|
|
250
|
+
4. Add ruff configuration (see [ruff-config.md](./references/ruff-config.md))
|
|
251
|
+
5. Run `uv run ruff check --fix .` to apply fixes
|
|
252
|
+
6. Run `uv run ruff format .` to format
|
|
253
|
+
|
|
254
|
+
### From mypy / pyright
|
|
255
|
+
|
|
256
|
+
1. Remove mypy/pyright via `uv remove`
|
|
257
|
+
2. Delete `mypy.ini`, `pyrightconfig.json`, or `[tool.mypy]`/`[tool.pyright]` sections
|
|
258
|
+
3. Add ty: `uv add --group dev ty`
|
|
259
|
+
4. Run `uv run ty check src/`
|
|
260
|
+
|
|
261
|
+
## Quick Reference: uv Commands
|
|
262
|
+
|
|
263
|
+
| Command | Description |
|
|
264
|
+
|---------|-------------|
|
|
265
|
+
| `uv init` | Create new project |
|
|
266
|
+
| `uv init --package` | Create distributable package |
|
|
267
|
+
| `uv add <pkg>` | Add dependency |
|
|
268
|
+
| `uv add --group dev <pkg>` | Add to dependency group |
|
|
269
|
+
| `uv remove <pkg>` | Remove dependency |
|
|
270
|
+
| `uv sync` | Install dependencies |
|
|
271
|
+
| `uv sync --all-groups` | Install all dependency groups |
|
|
272
|
+
| `uv run <cmd>` | Run command in venv |
|
|
273
|
+
| `uv run --with <pkg> <cmd>` | Run with temporary dependency |
|
|
274
|
+
| `uv build` | Build package |
|
|
275
|
+
| `uv publish` | Publish to PyPI |
|
|
276
|
+
|
|
277
|
+
### Ad-hoc Dependencies with `--with`
|
|
278
|
+
|
|
279
|
+
Use `uv run --with` for one-off commands that need packages not in your project:
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
# Run Python with a temporary package
|
|
283
|
+
uv run --with requests python -c "import requests; print(requests.get('https://httpbin.org/ip').json())"
|
|
284
|
+
|
|
285
|
+
# Run a module with temporary deps
|
|
286
|
+
uv run --with rich python -m rich.progress
|
|
287
|
+
|
|
288
|
+
# Multiple packages
|
|
289
|
+
uv run --with requests --with rich python script.py
|
|
290
|
+
|
|
291
|
+
# Combine with project deps (adds to existing venv)
|
|
292
|
+
uv run --with httpx pytest # project deps + httpx
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
**When to use `--with` vs `uv add`:**
|
|
296
|
+
- `uv add`: Package is a project dependency (goes in pyproject.toml/uv.lock)
|
|
297
|
+
- `--with`: One-off usage, testing, or scripts outside a project context
|
|
298
|
+
|
|
299
|
+
See [uv-commands.md](./references/uv-commands.md) for complete reference.
|
|
300
|
+
|
|
301
|
+
## Quick Reference: Dependency Groups
|
|
302
|
+
|
|
303
|
+
```toml
|
|
304
|
+
[dependency-groups]
|
|
305
|
+
dev = ["ruff", "ty"]
|
|
306
|
+
test = ["pytest", "pytest-cov", "hypothesis"]
|
|
307
|
+
docs = ["sphinx", "myst-parser"]
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
Install with: `uv sync --group dev --group test`
|
|
311
|
+
|
|
312
|
+
## Best Practices Checklist
|
|
313
|
+
|
|
314
|
+
- [ ] Use `src/` layout for packages
|
|
315
|
+
- [ ] Set `requires-python = ">=3.11"`
|
|
316
|
+
- [ ] Configure ruff with `select = ["ALL"]` and explicit ignores
|
|
317
|
+
- [ ] Use ty for type checking
|
|
318
|
+
- [ ] Enforce test coverage minimum (80%+)
|
|
319
|
+
- [ ] Use dependency groups instead of extras for dev tools
|
|
320
|
+
- [ ] Add `uv.lock` to version control
|
|
321
|
+
- [ ] Use PEP 723 for standalone scripts
|
|
322
|
+
|
|
323
|
+
## Read Next
|
|
324
|
+
|
|
325
|
+
- [migration-checklist.md](./references/migration-checklist.md) - Step-by-step migration cleanup
|
|
326
|
+
- [pyproject.md](./references/pyproject.md) - Complete pyproject.toml reference
|
|
327
|
+
- [uv-commands.md](./references/uv-commands.md) - uv command reference
|
|
328
|
+
- [ruff-config.md](./references/ruff-config.md) - Ruff linting/formatting configuration
|
|
329
|
+
- [testing.md](./references/testing.md) - pytest and coverage setup
|
|
330
|
+
- [pep723-scripts.md](./references/pep723-scripts.md) - PEP 723 inline script metadata
|
|
331
|
+
- [prek.md](./references/prek.md) - Fast pre-commit hooks with prek
|
|
332
|
+
- [security-setup.md](./references/security-setup.md) - Security hooks and dependency scanning
|
|
333
|
+
- [dependabot.md](./references/dependabot.md) - Automated dependency updates
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: property-based-testing
|
|
3
|
+
description: Provides guidance for property-based testing across multiple languages and smart contracts. Use when writing tests, reviewing code with serialization/validation/parsing patterns, designing features, or when property-based testing would provide stronger coverage than example-based tests.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Property-Based Testing Guide
|
|
7
|
+
|
|
8
|
+
Use this skill proactively during development when you encounter patterns where PBT provides stronger coverage than example-based tests.
|
|
9
|
+
|
|
10
|
+
## When to Invoke (Automatic Detection)
|
|
11
|
+
|
|
12
|
+
**Invoke this skill when you detect:**
|
|
13
|
+
|
|
14
|
+
- **Serialization pairs**: `encode`/`decode`, `serialize`/`deserialize`, `toJSON`/`fromJSON`, `pack`/`unpack`
|
|
15
|
+
- **Parsers**: URL parsing, config parsing, protocol parsing, string-to-structured-data
|
|
16
|
+
- **Normalization**: `normalize`, `sanitize`, `clean`, `canonicalize`, `format`
|
|
17
|
+
- **Validators**: `is_valid`, `validate`, `check_*` (especially with normalizers)
|
|
18
|
+
- **Data structures**: Custom collections with `add`/`remove`/`get` operations
|
|
19
|
+
- **Mathematical/algorithmic**: Pure functions, sorting, ordering, comparators
|
|
20
|
+
- **Smart contracts**: Solidity/Vyper contracts, token operations, state invariants, access control
|
|
21
|
+
|
|
22
|
+
**Priority by pattern:**
|
|
23
|
+
|
|
24
|
+
| Pattern | Property | Priority |
|
|
25
|
+
|---------|----------|----------|
|
|
26
|
+
| encode/decode pair | Roundtrip | HIGH |
|
|
27
|
+
| Pure function | Multiple | HIGH |
|
|
28
|
+
| Validator | Valid after normalize | MEDIUM |
|
|
29
|
+
| Sorting/ordering | Idempotence + ordering | MEDIUM |
|
|
30
|
+
| Normalization | Idempotence | MEDIUM |
|
|
31
|
+
| Builder/factory | Output invariants | LOW |
|
|
32
|
+
| Smart contract | State invariants | HIGH |
|
|
33
|
+
|
|
34
|
+
## When NOT to Use
|
|
35
|
+
|
|
36
|
+
Do NOT use this skill for:
|
|
37
|
+
- Simple CRUD operations without transformation logic
|
|
38
|
+
- One-off scripts or throwaway code
|
|
39
|
+
- Code with side effects that cannot be isolated (network calls, database writes)
|
|
40
|
+
- Tests where specific example cases are sufficient and edge cases are well-understood
|
|
41
|
+
- Integration or end-to-end testing (PBT is best for unit/component testing)
|
|
42
|
+
|
|
43
|
+
## Property Catalog (Quick Reference)
|
|
44
|
+
|
|
45
|
+
| Property | Formula | When to Use |
|
|
46
|
+
|----------|---------|-------------|
|
|
47
|
+
| **Roundtrip** | `decode(encode(x)) == x` | Serialization, conversion pairs |
|
|
48
|
+
| **Idempotence** | `f(f(x)) == f(x)` | Normalization, formatting, sorting |
|
|
49
|
+
| **Invariant** | Property holds before/after | Any transformation |
|
|
50
|
+
| **Commutativity** | `f(a, b) == f(b, a)` | Binary/set operations |
|
|
51
|
+
| **Associativity** | `f(f(a,b), c) == f(a, f(b,c))` | Combining operations |
|
|
52
|
+
| **Identity** | `f(x, identity) == x` | Operations with neutral element |
|
|
53
|
+
| **Inverse** | `f(g(x)) == x` | encrypt/decrypt, compress/decompress |
|
|
54
|
+
| **Oracle** | `new_impl(x) == reference(x)` | Optimization, refactoring |
|
|
55
|
+
| **Easy to Verify** | `is_sorted(sort(x))` | Complex algorithms |
|
|
56
|
+
| **No Exception** | No crash on valid input | Baseline property |
|
|
57
|
+
|
|
58
|
+
**Strength hierarchy** (weakest to strongest):
|
|
59
|
+
No Exception → Type Preservation → Invariant → Idempotence → Roundtrip
|
|
60
|
+
|
|
61
|
+
## Decision Tree
|
|
62
|
+
|
|
63
|
+
Based on the current task, read the appropriate section:
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
TASK: Writing new tests
|
|
67
|
+
→ Read [{baseDir}/references/generating.md]({baseDir}/references/generating.md) (test generation patterns and examples)
|
|
68
|
+
→ Then [{baseDir}/references/strategies.md]({baseDir}/references/strategies.md) if input generation is complex
|
|
69
|
+
|
|
70
|
+
TASK: Designing a new feature
|
|
71
|
+
→ Read [{baseDir}/references/design.md]({baseDir}/references/design.md) (Property-Driven Development approach)
|
|
72
|
+
|
|
73
|
+
TASK: Code is difficult to test (mixed I/O, missing inverses)
|
|
74
|
+
→ Read [{baseDir}/references/refactoring.md]({baseDir}/references/refactoring.md) (refactoring patterns for testability)
|
|
75
|
+
|
|
76
|
+
TASK: Reviewing existing PBT tests
|
|
77
|
+
→ Read [{baseDir}/references/reviewing.md]({baseDir}/references/reviewing.md) (quality checklist and anti-patterns)
|
|
78
|
+
|
|
79
|
+
TASK: Test failed, need to interpret
|
|
80
|
+
→ Read [{baseDir}/references/interpreting-failures.md]({baseDir}/references/interpreting-failures.md) (failure analysis and bug classification)
|
|
81
|
+
|
|
82
|
+
TASK: Need library reference
|
|
83
|
+
→ Read [{baseDir}/references/libraries.md]({baseDir}/references/libraries.md) (PBT libraries by language, includes smart contract tools)
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## How to Suggest PBT
|
|
87
|
+
|
|
88
|
+
When you detect a high-value pattern while writing tests, **offer PBT as an option**:
|
|
89
|
+
|
|
90
|
+
> "I notice `encode_message`/`decode_message` is a serialization pair. Property-based testing with a roundtrip property would provide stronger coverage than example tests. Want me to use that approach?"
|
|
91
|
+
|
|
92
|
+
**If codebase already uses a PBT library** (Hypothesis, fast-check, proptest, Echidna), be more direct:
|
|
93
|
+
|
|
94
|
+
> "This codebase uses Hypothesis. I'll write property-based tests for this serialization pair using a roundtrip property."
|
|
95
|
+
|
|
96
|
+
**If user declines**, write good example-based tests without further prompting.
|
|
97
|
+
|
|
98
|
+
## When NOT to Use PBT
|
|
99
|
+
|
|
100
|
+
- Simple CRUD without complex validation
|
|
101
|
+
- UI/presentation logic
|
|
102
|
+
- Integration tests requiring complex external setup
|
|
103
|
+
- Prototyping where requirements are fluid
|
|
104
|
+
- User explicitly requests example-based tests only
|
|
105
|
+
|
|
106
|
+
## Red Flags
|
|
107
|
+
|
|
108
|
+
- Recommending trivial getters/setters
|
|
109
|
+
- Missing paired operations (encode without decode)
|
|
110
|
+
- Ignoring type hints (well-typed = easier to test)
|
|
111
|
+
- Overwhelming user with candidates (limit to top 5-10)
|
|
112
|
+
- Being pushy after user declines
|
|
113
|
+
|
|
114
|
+
## Rationalizations to Reject
|
|
115
|
+
|
|
116
|
+
Do not accept these shortcuts:
|
|
117
|
+
|
|
118
|
+
- **"Example tests are good enough"** - If serialization/parsing/normalization is involved, PBT finds edge cases examples miss
|
|
119
|
+
- **"The function is simple"** - Simple functions with complex input domains (strings, floats, nested structures) benefit most from PBT
|
|
120
|
+
- **"We don't have time"** - PBT tests are often shorter than comprehensive example suites
|
|
121
|
+
- **"It's too hard to write generators"** - Most PBT libraries have excellent built-in strategies; custom generators are rarely needed
|
|
122
|
+
- **"The test failed, so it's a bug"** - Failures require validation; see [interpreting-failures.md]({baseDir}/references/interpreting-failures.md)
|
|
123
|
+
- **"No crash means it works"** - "No exception" is the weakest property; always push for stronger guarantees
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: semgrep-rule-creator
|
|
3
|
+
description: Creates custom Semgrep rules for detecting security vulnerabilities, bug patterns, and code patterns. Use when writing Semgrep rules or building custom static analysis detections.
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Bash
|
|
6
|
+
- Read
|
|
7
|
+
- Write
|
|
8
|
+
- Edit
|
|
9
|
+
- Glob
|
|
10
|
+
- Grep
|
|
11
|
+
- WebFetch
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Semgrep Rule Creator
|
|
15
|
+
|
|
16
|
+
Create production-quality Semgrep rules with proper testing and validation.
|
|
17
|
+
|
|
18
|
+
## When to Use
|
|
19
|
+
|
|
20
|
+
**Ideal scenarios:**
|
|
21
|
+
- Writing Semgrep rules for specific bug patterns
|
|
22
|
+
- Writing rules to detect security vulnerabilities in your codebase
|
|
23
|
+
- Writing taint mode rules for data flow vulnerabilities
|
|
24
|
+
- Writing rules to enforce coding standards
|
|
25
|
+
|
|
26
|
+
## When NOT to Use
|
|
27
|
+
|
|
28
|
+
Do NOT use this skill for:
|
|
29
|
+
- Running existing Semgrep rulesets
|
|
30
|
+
- General static analysis without custom rules (use `static-analysis` skill)
|
|
31
|
+
|
|
32
|
+
## Rationalizations to Reject
|
|
33
|
+
|
|
34
|
+
When writing Semgrep rules, reject these common shortcuts:
|
|
35
|
+
|
|
36
|
+
- **"The pattern looks complete"** → Still run `semgrep --test --config <rule-id>.yaml <rule-id>.<ext>` to verify. Untested rules have hidden false positives/negatives.
|
|
37
|
+
- **"It matches the vulnerable case"** → Matching vulnerabilities is half the job. Verify safe cases don't match (false positives break trust).
|
|
38
|
+
- **"Taint mode is overkill for this"** → If data flows from user input to a dangerous sink, taint mode gives better precision than pattern matching.
|
|
39
|
+
- **"One test is enough"** → Include edge cases: different coding styles, sanitized inputs, safe alternatives, and boundary conditions.
|
|
40
|
+
- **"I'll optimize the patterns first"** → Write correct patterns first, optimize after all tests pass. Premature optimization causes regressions.
|
|
41
|
+
- **"The AST dump is too complex"** → The AST reveals exactly how Semgrep sees code. Skipping it leads to patterns that miss syntactic variations.
|
|
42
|
+
|
|
43
|
+
## Anti-Patterns
|
|
44
|
+
|
|
45
|
+
**Too broad** - matches everything, useless for detection:
|
|
46
|
+
```yaml
|
|
47
|
+
# BAD: Matches any function call
|
|
48
|
+
pattern: $FUNC(...)
|
|
49
|
+
|
|
50
|
+
# GOOD: Specific dangerous function
|
|
51
|
+
pattern: eval(...)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Missing safe cases in tests** - leads to undetected false positives:
|
|
55
|
+
```python
|
|
56
|
+
# BAD: Only tests vulnerable case
|
|
57
|
+
# ruleid: my-rule
|
|
58
|
+
dangerous(user_input)
|
|
59
|
+
|
|
60
|
+
# GOOD: Include safe cases to verify no false positives
|
|
61
|
+
# ruleid: my-rule
|
|
62
|
+
dangerous(user_input)
|
|
63
|
+
|
|
64
|
+
# ok: my-rule
|
|
65
|
+
dangerous(sanitize(user_input))
|
|
66
|
+
|
|
67
|
+
# ok: my-rule
|
|
68
|
+
dangerous("hardcoded_safe_value")
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**Overly specific patterns** - misses variations:
|
|
72
|
+
```yaml
|
|
73
|
+
# BAD: Only matches exact format
|
|
74
|
+
pattern: os.system("rm " + $VAR)
|
|
75
|
+
|
|
76
|
+
# GOOD: Matches all os.system calls with taint tracking
|
|
77
|
+
mode: taint
|
|
78
|
+
pattern-sources:
|
|
79
|
+
- pattern: input(...)
|
|
80
|
+
pattern-sinks:
|
|
81
|
+
- pattern: os.system(...)
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Strictness Level
|
|
85
|
+
|
|
86
|
+
This workflow is **strict** - do not skip steps:
|
|
87
|
+
- **Read documentation first**: See [Documentation](#documentation) before writing Semgrep rules
|
|
88
|
+
- **Test-first is mandatory**: Never write a rule without tests
|
|
89
|
+
- **100% test pass is required**: "Most tests pass" is not acceptable
|
|
90
|
+
- **Optimization comes last**: Only simplify patterns after all tests pass
|
|
91
|
+
- **Avoid generic patterns**: Rules must be specific, not match broad patterns
|
|
92
|
+
- **Prioritize taint mode**: For data flow vulnerabilities
|
|
93
|
+
- **One YAML file - one Semgrep rule**: Each YAML file must contain only one Semgrep rule; don't combine multiple rules in a single file
|
|
94
|
+
- **No generic rules**: When targeting a specific language for Semgrep rules - avoid generic pattern matching (`languages: generic`)
|
|
95
|
+
- **Forbidden `todook` and `todoruleid` test annotations**: `todoruleid: <rule-id>` and `todook: <rule-id>` annotations in tests files for future rule improvements are forbidden
|
|
96
|
+
|
|
97
|
+
## Overview
|
|
98
|
+
|
|
99
|
+
This skill guides creation of Semgrep rules that detect security vulnerabilities and code patterns. Rules are created iteratively: analyze the problem, write tests first, analyze AST structure, write the rule, iterate until all tests pass, optimize the rule.
|
|
100
|
+
|
|
101
|
+
**Approach selection:**
|
|
102
|
+
- **Taint mode** (prioritize): Data flow issues where untrusted input reaches dangerous sinks
|
|
103
|
+
- **Pattern matching**: Simple syntactic patterns without data flow requirements
|
|
104
|
+
|
|
105
|
+
**Why prioritize taint mode?** Pattern matching finds syntax but misses context. A pattern `eval($X)` matches both `eval(user_input)` (vulnerable) and `eval("safe_literal")` (safe). Taint mode tracks data flow, so it only alerts when untrusted data actually reaches the sink—dramatically reducing false positives for injection vulnerabilities.
|
|
106
|
+
|
|
107
|
+
**Iterating between approaches:** It's okay to experiment. If you start with taint mode and it's not working well (e.g., taint doesn't propagate as expected, too many false positives/negatives), switch to pattern matching. Conversely, if pattern matching produces too many false positives on safe cases, try taint mode instead. The goal is a working rule—not rigid adherence to one approach.
|
|
108
|
+
|
|
109
|
+
**Output structure** - exactly 2 files in a directory named after the rule-id:
|
|
110
|
+
```
|
|
111
|
+
<rule-id>/
|
|
112
|
+
├── <rule-id>.yaml # Semgrep rule
|
|
113
|
+
└── <rule-id>.<ext> # Test file with ruleid/ok annotations
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Quick Start
|
|
117
|
+
|
|
118
|
+
```yaml
|
|
119
|
+
rules:
|
|
120
|
+
- id: insecure-eval
|
|
121
|
+
languages: [python]
|
|
122
|
+
severity: HIGH
|
|
123
|
+
message: User input passed to eval() allows code execution
|
|
124
|
+
mode: taint
|
|
125
|
+
pattern-sources:
|
|
126
|
+
- pattern: request.args.get(...)
|
|
127
|
+
pattern-sinks:
|
|
128
|
+
- pattern: eval(...)
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Test file (`insecure-eval.py`):
|
|
132
|
+
```python
|
|
133
|
+
# ruleid: insecure-eval
|
|
134
|
+
eval(request.args.get('code'))
|
|
135
|
+
|
|
136
|
+
# ok: insecure-eval
|
|
137
|
+
eval("print('safe')")
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Run tests (from rule directory): `semgrep --test --config <rule-id>.yaml <rule-id>.<ext>`
|
|
141
|
+
|
|
142
|
+
## Quick Reference
|
|
143
|
+
|
|
144
|
+
- For commands, pattern operators, and taint mode syntax, see [quick-reference.md]({baseDir}/references/quick-reference.md).
|
|
145
|
+
- For detailed workflow and examples, you MUST see [workflow.md]({baseDir}/references/workflow.md)
|
|
146
|
+
|
|
147
|
+
## Workflow
|
|
148
|
+
|
|
149
|
+
Copy this checklist and track progress:
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
Semgrep Rule Progress:
|
|
153
|
+
- [ ] Step 1: Analyze the Problem
|
|
154
|
+
- [ ] Step 2: Write Tests First
|
|
155
|
+
- [ ] Step 3: Analyze AST structure
|
|
156
|
+
- [ ] Step 4: Write the rule
|
|
157
|
+
- [ ] Step 5: Iterate until all tests pass (semgrep --test)
|
|
158
|
+
- [ ] Step 6: Optimize the rule (remove redundancies, re-test)
|
|
159
|
+
- [ ] Step 7: Final Run
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Documentation
|
|
163
|
+
|
|
164
|
+
**REQUIRED**: Before writing any rule, use WebFetch to read **all** of these 7 links with Semgrep documentation:
|
|
165
|
+
|
|
166
|
+
1. [Rule Syntax](https://raw.githubusercontent.com/semgrep/semgrep-docs/refs/heads/main/docs/writing-rules/rule-syntax.md)
|
|
167
|
+
2. [Pattern Syntax](https://raw.githubusercontent.com/semgrep/semgrep-docs/refs/heads/main/docs/writing-rules/pattern-syntax.mdx)
|
|
168
|
+
3. [Testing Rules](https://raw.githubusercontent.com/semgrep/semgrep-docs/refs/heads/main/docs/writing-rules/testing-rules.md)
|
|
169
|
+
4. [Taint analysis](https://raw.githubusercontent.com/semgrep/semgrep-docs/refs/heads/main/docs/writing-rules/data-flow/taint-mode/overview.md)
|
|
170
|
+
5. [Advanced techniques for taint analysis](https://raw.githubusercontent.com/semgrep/semgrep-docs/refs/heads/main/docs/writing-rules/data-flow/taint-mode/advanced.md)
|
|
171
|
+
6. [Constant propagation](https://raw.githubusercontent.com/semgrep/semgrep-docs/refs/heads/main/docs/writing-rules/data-flow/constant-propagation.md)
|
|
172
|
+
7. [Trail of Bits Testing Handbook - Semgrep chapter](https://raw.githubusercontent.com/trailofbits/testing-handbook/refs/heads/main/content/docs/static-analysis/semgrep/10-advanced.md)
|