skill-cli template

Scaffold for a Claude Code skill whose CLI is Python + click instead of a bash script — a SKILL.md, a thin .sh shim that keeps the alias installer working, a single-file PEP 723 uv script holding all the logic, and click CliRunner tests.

Scaffolded with the new-skill skill:

new-skill <name> --description "…"          # -> .claude/skills/<name>/

This README and .scaffold-notes.md document the template itself and are not copied into the scaffolded skill.

Why Python for a skill CLI

From the survey in data/log/2026-08-10-bash-skills-python-click-ranking.md: bash skills that build or parse JSON, embed python3 heredocs, take many flags, or do HTTP with retries are the ones worth writing in Python. Thin orchestration of other CLIs (git, ssh, docker) stays in bash. This template is for the first kind.

What it encodes, one lesson per file:

file the lesson
scripts/<name>.sh the shim must stay — install-skill-aliases.sh only scans *.sh for # @alias:.
scripts/<pkg>.py uv-script shebang + # /// script deps, so click needs no venv management.
Step param type ONE repeatable typed option, not --wait/--click/--shot — click collects each option's occurrences separately, so splitting them loses interleaved order.
post_json dict → requests(json=…): no shell quoting, no jq, and no E2BIG when a payload carries base64.
load_env_claude private defaults come from the gitignored .env.claude, walked up from the script.
err / die / emit stdout = result (--json for machines), stderr = chatter, 1 handled failure / 2 usage.
scripts/test_<pkg>.py CliRunner gives a skill real tests for the price of one file.

Placeholders

key meaning default
@@NAME@@ kebab-case skill name = alias on PATH required
@@PKG@@ snake_case module name NAME with -_
@@TITLE@@ human title in SKILL.md NAME
@@DESCRIPTION@@ the frontmatter description: — this is what makes the skill discoverable, so write it as "what it does + when to use it" required
@@ENVPREFIX@@ env-var prefix, e.g. @@ENVPREFIX@@_URL NAME upper, -_

Add a placeholder by dropping @@KEY@@ into a template file and a matching key into the vars JSON.

Description
No description provided
Readme 32 KiB
Languages
Python 94.1%
Shell 5.9%