From didmar
Bootstrap a new Python project with the Astral toolchain (UV, Ruff, ty), flake8-stepdown, and pre-commit hooks. Opinionated.
How this skill is triggered — by the user, by Claude, or both
Slash command
/didmar:init-pythonhaikuThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Argument: $ARGUMENTS
references/AGENTS.mdreferences/CONTRIBUTING.mdreferences/Dockerfilereferences/Dockerfile-libreferences/ci.ymlreferences/compose.yamlreferences/dockerignorereferences/gitignorereferences/lib_init.pyreferences/lint.shreferences/main.pyreferences/pre-commit-config.yamlreferences/publish.ymlreferences/pyproject-tool-config.tomlreferences/readme-base.mdreferences/readme-ci.mdreferences/readme-contributing.mdreferences/readme-docker.mdreferences/readme-pypi.mdreferences/test_placeholder.pyArgument: $ARGUMENTS
uv is installed.If pyproject.toml already exists, warn the user and stop.
Parse the argument. If it contains "lib" or "library", use library layout. Otherwise, use app layout (default). Note: the project name is determined by the directory name (UV's default behavior), not parsed from the argument. The argument is only used to determine app vs library layout.
Initialize the project:
uv init --python ">=3.13"<package> from the project name in pyproject.toml (UV converts e.g. dummy-app → dummy_app)mkdir <package>, move main.py to <package>/main.py, create <package>/__init__.py with content """<package> application."""uv init --lib --build-backend hatch --python ">=3.13"<package> by listing src/src/<package>/ to ./<package>/ and rmdir srcpyproject.toml:
[tool.hatch.build.targets.wheel]
packages = ["<package>"]
Note: UV converts names like dummy-library → dummy_library. Use the actual directory name as <package> in all subsequent substitutions.
Append references/pyproject-tool-config.toml verbatim to pyproject.toml. Note: keep [dependency-groups] as the last section in pyproject.toml (step 5 appends it).
Install dev dependencies:
uv add --dev pytest ruff ty pre-commit flake8-stepdown
Note: uv init generates .gitignore and README.md (plus main.py for app layout, or src/<package>/__init__.py and py.typed for library layout).
Steps 6-9 are independent — run them in parallel where possible.
Write references/lint.sh to lint.sh and chmod +x it.
Write references/pre-commit-config.yaml to .pre-commit-config.yaml. Then run uv run pre-commit autoupdate --repo https://github.com/astral-sh/ruff-pre-commit to sync the ruff hook version.
Fix up UV-generated files to pass strict linting:
<package>/main.py.<package>/__init__.py.tests/__init__.py with content: """Test suite."""tests/test_placeholder.py.
<package> with the actual package directory name (needed for coverage).assert True.If .git doesn't exist, run git init. Overwrite .gitignore with references/gitignore.
Install pre-commit hooks:
uv run pre-commit install
Run uv run pytest to verify setup works.
Stage all files first: git add -A (including .python-version). This is needed so that pre-commit hooks can actually check the files.
Run uv run pre-commit run --all-files to verify all hooks pass. If ruff auto-fixes anything, re-stage with git add -A.
Create initial commit with message "Initial project setup with UV, Ruff, ty, flake8-stepdown, and pre-commit".
Use the AskUserQuestion tool to ask the user which optional extras they want. Present options using AskUserQuestion (use multiSelect, split across up to two questions if needed since the tool supports max 4 options per question). The user can pick multiple, all, or none:
dev and prod targets, compose.yaml, and .dockerignore.github/workflows/ci.yml running ruff, ty, and pytest on push and PR.vscode/settings.json with ruff extension as formatter, format-on-save, organize imports on savepytest-cov dev dependency and configure [tool.pytest.ini_options] with --cov and a minimum coverage thresholdCLAUDE.md symlinkOnly include the PyPI packaging option when using library layout (omit it entirely for app layout). Include a "None of the above" option in each question so the user can skip extras without deselecting items manually.
Ordering: Apply extras in this order: Dockerfile + docker compose, GitHub Actions CI, VS Code settings, pytest-cov, PyPI packaging, CONTRIBUTING.md + AGENTS.md. Then implement whichever extras the user selected. Details for each:
Dockerfile, replacing <package> with the actual package name.Dockerfile.compose.yaml..dockerignore.Write references/ci.yml to .github/workflows/ci.yml.
Write references/vscode-settings.json to .vscode/settings.json.
Run uv add --dev pytest-cov, then add to pyproject.toml:
[tool.pytest.ini_options]
addopts = "--cov=<package> --cov-report=term-missing --cov-fail-under=80"
Add PyPI metadata to pyproject.toml:
license and classifiers to the existing [project] section (after dependencies):
license = "MIT"
classifiers = [
"Development Status :: 3 - Alpha",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.13",
]
[project.urls] immediately after [project] (before [build-system]):
[project.urls]
Homepage = "https://github.com/<owner>/<project-name>"
Repository = "https://github.com/<owner>/<project-name>"
Issues = "https://github.com/<owner>/<project-name>/issues"
<owner>/<project-name> from git remote get-url origin if available, otherwise use placeholders. Note any placeholders in the final summary.Write references/publish.yml to .github/workflows/publish.yml.
CONTRIBUTING.md.AGENTS.md.CLAUDE.md as a symlink: ln -s AGENTS.md CLAUDE.mdStart from references/readme-base.md (replace <project-name> and <package> with actual values). For library layout, omit the "Running" subsection. Then conditionally append based on selected extras:
Stage all changes and validate all hooks pass: git add -A && uv run pre-commit run --all-files. If ruff auto-fixes anything, re-stage with git add -A.
Create a new commit with message "Add optional extras: ".
npx claudepluginhub didmar/skills --plugin didmarSets up Python library projects with pyproject.toml, uv, ruff, pytest, pre-commit, and GitHub Actions. Use when creating new libraries or modernizing existing projects.
Sets up modern Python projects with uv, ruff, ty, pytest, hypothesis, src/ layout, and pyproject.toml. Also integrates LLM-stack patterns for Anthropic/OpenAI SDKs.
Sets up Python projects with uv for deps/envs, ruff for linting/formatting, ty for types, pytest for testing. Use for new projects, scripts, or migrations from pip/Poetry.