Personal direnv layout recipe (layout pyproject) that wraps stdlib layout python and one-shot bootstraps a Python project to my preferences.
mkdir -p ~/.config/direnv/lib
ln -sf /absolute/path/to/slinkp-pyproject-recipe/pyproject.sh ~/.config/direnv/lib/pyproject.shThe lib resolves templates via the real path of that symlink, so keep the clone where the link points.
In a project directory:
echo 'layout pyproject' > .envrc # or: layout pyproject python3.14
direnv allowgit init .if the directory is not already a git work tree (runs before anything else)- Stdlib
layout pythonbehavior (venv under.direnv/python-$version, onPATH) - Upgrade pip when the venv was just created
PATH_add scripts(sofreeze-requirements/lintwork after bootstrap)- On the first bootstrap, install
githooks/pre-commitas the repository's Git hooks path after any initial skeleton commit
Scaffold missing files only (STDERR warning per skip; never overwrite):
requirements-minimal.txt(seed lint/test/LSP deps + workflow comment)pyproject.toml(Black / flake8 / mypy tool config only)README.md,.gitignore,scripts/freeze-requirements,scripts/lint,githooks/pre-commit
Then sync deps:
- No
requirements.txt:pip install -r requirements-minimal.txt→pip freeze > requirements.txt - Has
requirements.txt: install lockfile → if minimal exists, install minimal + freeze (catch forgotten pins); if minimal was removed, warn and skip that pair
Write marker .direnv/pyproject-bootstrapped (UTC timestamp + recipe URL). Fresh clones lack .direnv/, so they bootstrap again and install.
On the initial bootstrap, only files newly created by the scaffold (including a newly generated requirements.txt) are added. This automatic commit is made only when this invocation just initialized the repository and it has no commits. Otherwise, a notice is printed to STDERR and the files are left unstaged.
After the marker exists: no scaffold, no auto-install/freeze. Missing files are assumed intentional.
- Edit
requirements-minimal.txt(unversioned) pip install -r requirements-minimal.txtfreeze-requirements→ regeneratesrequirements.txtfrom the project venvlint→ runs Black, flake8, optional secrets scanners, and mypy- Commits run
lint --checkthroughgithooks/pre-commit; bypass withgit commit --no-verify
Parked for later (no design detail yet):
- Wrapper script to standardize how tests are run
- Rules/conventions files so agents do things my way