|
| 1 | +--- |
| 2 | +name: pyckage |
| 3 | +description: > |
| 4 | + Build Python packages the right way — R-inspired philosophy for scaffolding, API design, |
| 5 | + testing, docs, deprecation lifecycle, and PyPI release using uv, rich, pytest, and |
| 6 | + mkdocs-material. Activate when creating/structuring Python packages, designing APIs, |
| 7 | + naming functions, adding user messages/errors, writing tests, setting up docs, managing |
| 8 | + deprecations, or publishing to PyPI. |
| 9 | +argument-hint: "[scaffold|api|test|docs|lifecycle|release] [package-name]" |
| 10 | +--- |
| 11 | + |
| 12 | +# pyckage |
| 13 | + |
| 14 | +A skill for building Python packages with the philosophy of the R package ecosystem: |
| 15 | +clear user communication, principled API design, living documentation, and ceremonial lifecycle management. |
| 16 | + |
| 17 | +The guiding question for every decision: *"What would make this package feel like a thoughtful, professional tool — not just a collection of functions?"* |
| 18 | + |
| 19 | +--- |
| 20 | + |
| 21 | +## How This Skill Is Organized |
| 22 | + |
| 23 | +This SKILL.md gives you the philosophy and the map. For implementation details, read the |
| 24 | +relevant reference file from `references/`: |
| 25 | + |
| 26 | +| What you're doing | Read | |
| 27 | +|---|---| |
| 28 | +| Starting a new package or setting up structure | [references/01-scaffold.md](references/01-scaffold.md) | |
| 29 | +| Designing function names, errors, user messages | [references/02-api-design.md](references/02-api-design.md) | |
| 30 | +| Writing or organizing tests | [references/03-testing.md](references/03-testing.md) | |
| 31 | +| Setting up or writing documentation | [references/04-docs.md](references/04-docs.md) | |
| 32 | +| Adding deprecations or managing versions | [references/05-lifecycle.md](references/05-lifecycle.md) | |
| 33 | +| Releasing to PyPI or setting up CI/CD | [references/06-release.md](references/06-release.md) | |
| 34 | + |
| 35 | +Read only what's relevant to the current task. Don't load everything at once. |
| 36 | + |
| 37 | +--- |
| 38 | + |
| 39 | +## The Five Principles |
| 40 | + |
| 41 | +Before touching any reference file, internalize these. They inform every decision. |
| 42 | + |
| 43 | +### 1. User communication is a first-class concern |
| 44 | +Every message a user sees — errors, warnings, progress, success — should be intentional. |
| 45 | +Use `rich` for structure and color. Use a consistent message hierarchy. Never let a raw |
| 46 | +traceback be the user's only feedback. The R `cli` package set this standard; `rich` is how |
| 47 | +we meet it in Python. |
| 48 | + |
| 49 | +### 2. Function names form a grammar |
| 50 | +Names should be guessable. Use `verb_noun()` patterns. Group related functions with shared |
| 51 | +prefixes. A user should be able to predict `read_parquet()` after seeing `read_csv()`. |
| 52 | +Consistency is more important than cleverness. |
| 53 | + |
| 54 | +### 3. Lifecycle deserves ceremony |
| 55 | +Deprecations are promises to users. When something changes, warn early, warn clearly, and |
| 56 | +give users a path forward. Never silently break things. Never deprecate without a timeline. |
| 57 | + |
| 58 | +### 4. Documentation lives next to code |
| 59 | +Docstrings are not optional and not a final step. They are written at the same time as the |
| 60 | +function. Use Google style consistently. `mkdocstrings` turns them into a website automatically. |
| 61 | + |
| 62 | +### 5. There is a whole game |
| 63 | +A user should be able to see a complete, working package early — not after mastering every |
| 64 | +detail. Scaffold first, refine later. |
| 65 | + |
| 66 | +--- |
| 67 | + |
| 68 | +## Anatomy of a pyckage-style Package |
| 69 | + |
| 70 | +``` |
| 71 | +my-package/ |
| 72 | +├── pyproject.toml ← single source of truth (uv-managed) |
| 73 | +├── README.md ← the story and quickstart |
| 74 | +├── CHANGELOG.md ← user-facing version history |
| 75 | +├── mkdocs.yml ← docs config (project root, not inside docs/) |
| 76 | +├── src/ |
| 77 | +│ └── my_package/ |
| 78 | +│ ├── __init__.py ← clean public API surface |
| 79 | +│ ├── py.typed ← PEP 561 marker for type checkers |
| 80 | +│ ├── errors.py ← structured exception hierarchy (public contract) |
| 81 | +│ ├── _messages.py ← rich console, message helpers |
| 82 | +│ └── core.py ← actual logic |
| 83 | +├── tests/ |
| 84 | +│ ├── conftest.py ← shared fixtures |
| 85 | +│ └── test_core.py |
| 86 | +└── docs/ |
| 87 | + ├── index.md |
| 88 | + └── api.md |
| 89 | +``` |
| 90 | + |
| 91 | +Key decisions encoded here: |
| 92 | +- **src layout** always — prevents accidental imports from the project root |
| 93 | +- **`errors.py`** is always its own file — errors are a public contract (no underscore: users import these directly) |
| 94 | +- **`_messages.py`** centralizes all user-facing output — never scattered `print()` calls |
| 95 | +- **`__init__.py`** is curated, not auto-imported — users see only what's intentional |
| 96 | + |
| 97 | +--- |
| 98 | + |
| 99 | +## Argument Routing |
| 100 | + |
| 101 | +When invoked with `/pyckage <subcommand>`, route based on the first argument: |
| 102 | + |
| 103 | +| Invocation | Action | |
| 104 | +|---|---| |
| 105 | +| `/pyckage scaffold <name>` | Read [references/01-scaffold.md](references/01-scaffold.md) and create a new package named `<name>` | |
| 106 | +| `/pyckage api` | Read [references/02-api-design.md](references/02-api-design.md) and review/improve the current package's API | |
| 107 | +| `/pyckage test` | Read [references/03-testing.md](references/03-testing.md) and set up or improve tests | |
| 108 | +| `/pyckage docs` | Read [references/04-docs.md](references/04-docs.md) and set up or improve documentation | |
| 109 | +| `/pyckage lifecycle` | Read [references/05-lifecycle.md](references/05-lifecycle.md) and manage deprecations | |
| 110 | +| `/pyckage release` | Read [references/06-release.md](references/06-release.md) and walk through the release ritual | |
| 111 | +| `/pyckage` (no args) | Assess the current project against all five principles and suggest improvements | |
| 112 | + |
| 113 | +When invoked without a subcommand (auto-triggered or plain `/pyckage`), use the Quick Decision Guide below. |
| 114 | + |
| 115 | +--- |
| 116 | + |
| 117 | +## Quick Decision Guide |
| 118 | + |
| 119 | +**User asks to scaffold / create a new package:** |
| 120 | +→ Read [references/01-scaffold.md](references/01-scaffold.md). Walk through the whole game first. |
| 121 | + |
| 122 | +**User asks about function names, API shape, or error messages:** |
| 123 | +→ Read [references/02-api-design.md](references/02-api-design.md). Apply naming conventions and message hierarchy. |
| 124 | + |
| 125 | +**User asks about tests or is writing test code:** |
| 126 | +→ Read [references/03-testing.md](references/03-testing.md). Enforce pytest conventions and fixture patterns. |
| 127 | + |
| 128 | +**User asks about docs, docstrings, or mkdocs:** |
| 129 | +→ Read [references/04-docs.md](references/04-docs.md). Enforce Google docstrings and mkdocs-material setup. |
| 130 | + |
| 131 | +**User mentions deprecating something, versioning, or breaking changes:** |
| 132 | +→ Read [references/05-lifecycle.md](references/05-lifecycle.md). Apply the deprecation ceremony. |
| 133 | + |
| 134 | +**User wants to publish, release, or set up CI:** |
| 135 | +→ Read [references/06-release.md](references/06-release.md). Walk through PyPI + GitHub Actions setup. |
| 136 | + |
| 137 | +**Multiple concerns at once:** |
| 138 | +→ Read the most relevant reference first. Reference others by name when needed. |
| 139 | + |
| 140 | +--- |
| 141 | + |
| 142 | +## Tone When Helping |
| 143 | + |
| 144 | +- Be opinionated. This skill exists to have opinions. Don't offer five options when one is right. |
| 145 | +- Explain the *why* behind conventions, especially when they come from the R world. |
| 146 | +- When translating an R concept to Python, name the translation explicitly: |
| 147 | + `"This is the Python equivalent of rlang::abort() — here's how it maps."` |
| 148 | +- Push back gently on anti-patterns (scattered `print()`, flat structure, inconsistent names) |
| 149 | + but always offer the better path immediately. |
0 commit comments