Add development-scripts agent skill
Ports generic-scripts-module-v1 into a routed skill: module anatomy, shared loggers/base modules, Taskfile integration, workflows, and pattern decisions. Fixes a latent defect in the loggers example that silenced all logging in the module scaffold: loggers/lib/--index-api.sh now sources --env-vars-reader.sh, and the reader preserves already-exported values so caller overrides still win. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
# Module Patterns
|
||||
|
||||
A decision guide for what kind of module you are building and how it should connect to the
|
||||
others.
|
||||
|
||||
---
|
||||
|
||||
## 1. Module type
|
||||
|
||||
| Module type | Has `api/` | Has `Taskfile.yml` | Example |
|
||||
|---|:---:|:---:|---|
|
||||
| Support-only library | No | No | `loggers` |
|
||||
| Shared foundation with public commands | Yes | Optional / no | `base` |
|
||||
| Feature module | Yes | Usually yes | `kube`, `github`, `data-migration` |
|
||||
| Wrapper around an external CLI | Yes | Usually yes | `helm`, `openshift`, `github` |
|
||||
|
||||
Pick the type before creating any file — it decides whether `api/` and `Taskfile.yml` exist at
|
||||
all, and adding them later means reworking every consumer that has already started sourcing
|
||||
the module.
|
||||
|
||||
A module with no user-facing command is a support library. Do not give it an `api/` directory
|
||||
speculatively; every file in `api/` is a public interface someone may come to depend on.
|
||||
|
||||
---
|
||||
|
||||
## 2. Dependency sourcing
|
||||
|
||||
| You need | Source |
|
||||
|---|---|
|
||||
| Logging | `./.scripts/loggers/lib/--index-api.sh` |
|
||||
| Shared base functions | `./.scripts/base/lib/--index-api.sh` |
|
||||
| Another module's exported functions | that module's `lib/--index-api.sh` |
|
||||
| Your own module's full runtime, from its `api/` wrapper | your `lib/--index.sh` |
|
||||
|
||||
The rule underneath: **`--index-api.sh` is the public edge between modules; `--index.sh` is a
|
||||
module's own private entrypoint.** Sourcing another module's `--index.sh` runs its reader and
|
||||
validator inside your command — importing its defaults, its required-input checks, and in
|
||||
`base`'s case its `.env` loading. Symptoms show up as variables nobody set, or a validation
|
||||
failure naming a module the user never invoked.
|
||||
|
||||
---
|
||||
|
||||
## 3. Command exposure
|
||||
|
||||
Three independent decisions, in increasing order of commitment:
|
||||
|
||||
1. **`lib/` only** — internal. Reachable from other modules that source your `--index-api.sh`.
|
||||
2. **`api/<command>.sh`** — user-facing. Someone can run it directly from the repository root.
|
||||
3. **Module `Taskfile.yml`** — discoverable through `task --list-all`.
|
||||
4. **Root `Taskfile.yml` include** — a stable public namespace, effectively permanent.
|
||||
|
||||
Escalate only as far as the command genuinely needs. Each step is easy to add later and
|
||||
disruptive to withdraw, because each one is a promise someone may already be relying on.
|
||||
|
||||
---
|
||||
|
||||
## 4. Common mistakes
|
||||
|
||||
- Putting full implementation logic into `api/*.sh`.
|
||||
- Adding a `lib/-*.sh` file and forgetting to source it from `lib/--index-api.sh`.
|
||||
- Parsing CLI flags in implementation files instead of `--env-vars-reader.sh`.
|
||||
- Printing secrets in logs.
|
||||
- Sourcing `base/lib/--index.sh` from a library function and unexpectedly loading `.env`.
|
||||
- Adding root Taskfile includes for experimental modules.
|
||||
- Giving a support-only library an `api/` directory it does not need.
|
||||
- Mixing function prefixes inside one module after a rename.
|
||||
Reference in New Issue
Block a user