scaffold-python
Scaffold a new plain runnable Python application in an already-created directory. Use for new non-framework Python applications; do not use for publish-first libraries, existing configured Python proj
SKILL.mdskills/scaffold-python/SKILL.md
GitHubScaffold Python Application
Create a small packaged application using scripts/scaffold.py and the canonical
files in assets/. The agent handles eligibility, runtime and dependency
selection, installation, and diagnosis. The script owns baseline file contents.
Do not independently recreate or customise the baseline.
1. Inspect and prepare
- Work in the requested existing directory, or the current directory if unspecified. Inspect before writing and preserve unrelated files.
- Stop if
pyproject.tomlor substantial Python configuration already exists. Do not use this skill for publish-first libraries, frameworks, or workspaces. If an ancestor defines a uv workspace, stop and request a standalone location; do not modify the parent workspace or silently join it. - Require installed uv. Do not install or upgrade uv automatically. Use uv for Python selection, environments, dependencies, and builds.
- Select the newest locally installed final CPython using
uv python list --only-installed --output-format json. Consider only entries whose implementation iscpython, variant isdefault, path exists, and version is exactly three numeric components. Compare version components numerically. Do not infer the runtime from the calendar or a release schedule. - Require CPython 3.11 or newer. Resolve the selected exact version through uv and confirm its actual version, CPython implementation, and final release status. Python has no LTS designation. Never select alpha, beta, release-candidate, free-threaded, or other implementation variants for this baseline.
- Set
UV_PYTHON_DOWNLOADS=neverthroughout. Do not download Python or install it into a temporary directory. Stop if no suitable installed interpreter exists. Keep any explicit interpreter selection consistent across commands. - If the default uv cache is unwritable, set
UV_CACHE_DIRto a writable temporary location and keep it set through all checks. Do not disable TLS verification. - If Git is available, detect an existing repository using Git rather than just
a local
.gitentry. Reuse it without changing parent configuration, or rungit initwhen outside a repository. Stop before generation if Git preparation is blocked. If Git is unavailable, continue and report it as unavailable. Never create a nested repository, commit, push, merge, rebase, or create remotes.
2. Resolve development dependencies
Resolve exact latest stable mutually compatible releases of ruff, mypy,
pytest, and the uv_build build backend for the selected Python. Use uv's
resolver and inspect metadata as needed. A temporary requirements file outside
the project can be resolved with uv pip compile --python-version <exact-version>.
Do not add application runtime dependencies, pytest plugins, or extra tooling.
Report any compatibility fallback instead of silently weakening checks.
Write a temporary JSON input file outside the project with exactly these fields:
| Field | Value |
|---|---|
python |
Selected exact final version, such as 3.14.6 |
uv_build |
Resolved exact stable backend version |
dependencies |
Object with exactly mypy, pytest, and ruff, each an exact stable version |
Version numbers are resolved inputs, not defaults to copy from this document.
3. Generate and install
Resolve paths relative to this skill's directory, then run through uv:
uv run --no-project --python <exact-version> <skill-directory>/scripts/scaffold.py create <project-directory> <inputs.json>
The script derives the distribution, import package, and CLI names from the
existing directory without renaming it. It handles punctuation, numeric prefixes,
and Python keywords. It pins the Python minor line and exact tool/backend
versions, and creates a packaged src/ application with typed entry points,
Ruff, strict mypy, pytest importlib mode, executable check.sh, and VS Code
module debugging using the project .venv on POSIX and Windows.
Existing destination files block generation except .gitignore, whose existing
contents are preserved and missing baseline entries appended. Unsafe paths and
symlink destinations are refused before baseline writes. Do not delete conflicts,
bypass the generator, or overwrite existing files to proceed. A partial write
failure must be reported; do not rerun over partial output.
Do not use uv init to produce a second baseline, add project guidance or README
files, or let uv initialize Git. Run uv lock and uv sync --locked using the
selected Python, and retain uv.lock. Keep uv's editable project installation.
Do not pass --no-install-project, --no-editable, or bypass lock verification.
If resolution fails, diagnose within the stated constraints. If changing resolved
inputs after generation is necessary, report the scaffold as incomplete rather
than editing canonical files around the generator's preservation rule.
In pyproject.toml under [tool.mypy], set python_version = "" to the major.minor
version of the Python interpreter used in this scaffold (for example "3.14").
4. Verify and report
Run every check and inspect its own exit status; stop on an unresolved failure:
uv run --locked ruff format .uv run --no-project --python <exact-version> <skill-directory>/scripts/scaffold.py verify <project-directory> <inputs.json>./check.shuv run --locked <cli-name>uv run --locked python -m <import_package>uv build
Both entry points must print Application is running. and exit successfully.
Confirm that a wheel and source archive exist in dist/. Inspect the editable
installation using importlib.metadata: the distribution's direct_url.json
must mark it editable, and the imported package must resolve under this project's
src/. Inspect git status --short when Git is available.
Completion requires canonical verification and every required check to pass. Report Python and uv versions, derived distribution/package/CLI names, Git outcome, compatibility fallbacks, temporary cache use, and check results. Distinguish passed, failed, blocked before execution, and not attempted; never report an unexecuted operation as a failure. Fix scaffold defects without changing the canonical baseline merely to make a check pass.
Boundaries
Do not add project guidance, ADRs, specifications, README files, licenses, CI/CD,
Docker, environment files, Git hooks, publishing or release tooling, frameworks,
databases, workspace configuration, coverage tooling, or extra task runners.
Use Ruff for formatting and linting, mypy for typing, and pytest for tests.
Do not substitute another checker or add Black, isort, Flake8, tox, nox, Make,
or just. Create only .vscode/launch.json for editor integration; do not add
settings, extension recommendations, source maps, or a project debugpy dependency.
The root executable check.sh remains the project's visible quality gate.