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,165 @@
|
||||
# Shared Modules — `loggers` and `base`
|
||||
|
||||
The two foundation modules every other module depends on, and the bootstrap rule that decides
|
||||
whether logging works at all.
|
||||
|
||||
Working implementations are in `assets/loggers/` and `assets/base/`.
|
||||
|
||||
---
|
||||
|
||||
## 1. `loggers` — support-only library
|
||||
|
||||
No `api/` commands, no `Taskfile.yml`. It exists to be sourced.
|
||||
|
||||
```text
|
||||
.scripts/loggers/
|
||||
lib/
|
||||
--env-vars-reader.sh # level flags + padding strings
|
||||
--index-api.sh # sources the reader, then every logger function
|
||||
--index.sh
|
||||
-debug.sh -error.sh -info.sh -trace.sh -warn.sh
|
||||
-empty-line.sh -enable-trailing-new-line.sh -waiting-dot.sh
|
||||
```
|
||||
|
||||
Consume it from any module:
|
||||
|
||||
```bash
|
||||
. ./.scripts/loggers/lib/--index-api.sh
|
||||
```
|
||||
|
||||
Available functions:
|
||||
|
||||
```bash
|
||||
_loggers_info "${FUNCTION_NAME}" "message"
|
||||
_loggers_debug "${FUNCTION_NAME}" "message"
|
||||
_loggers_warn "${FUNCTION_NAME}" "message"
|
||||
_loggers_error "${FUNCTION_NAME}" "message"
|
||||
_loggers_trace "${FUNCTION_NAME}" "message"
|
||||
_loggers_emptyLine
|
||||
```
|
||||
|
||||
Levels are controlled by environment flags, defaulting to everything except trace:
|
||||
|
||||
```bash
|
||||
LOGGER_IS_ENABLED_ERROR=true
|
||||
LOGGER_IS_ENABLED_INFO=true
|
||||
LOGGER_IS_ENABLED_WARN=true
|
||||
LOGGER_IS_ENABLED_DEBUG=true
|
||||
LOGGER_IS_ENABLED_TRACE=false
|
||||
```
|
||||
|
||||
Export any of them before invoking a command to change verbosity for that run:
|
||||
|
||||
```bash
|
||||
LOGGER_IS_ENABLED_DEBUG=false ./.scripts/<module>/api/<command>.sh
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
1. Do not add `api/` wrappers to `loggers` without a real user-facing requirement.
|
||||
2. Keep logger helpers small and side-effect-light.
|
||||
3. Log to `stderr` — `stdout` stays clean so command output remains pipeable.
|
||||
4. Dependent modules source the logger API directly.
|
||||
|
||||
---
|
||||
|
||||
## 2. `base` — shared foundation
|
||||
|
||||
Has public `api/` wrappers but no `Taskfile.yml`. Provides local environment handling and
|
||||
local-storage helpers over `.env` files.
|
||||
|
||||
```text
|
||||
.scripts/base/
|
||||
api/
|
||||
local-storage-ensure-existance-file-dot-env.sh
|
||||
local-storage-read-lines-from-file-dot-env.sh
|
||||
local-storage-reset-file-dot-env.sh
|
||||
local-storage-save-env-variable-2-file-dot-env.sh
|
||||
local-storage-view-file-dot-env.sh
|
||||
lib/
|
||||
--env-vars-reader.sh --env-vars-validator.sh
|
||||
--index-api.sh --index.sh
|
||||
-export-env-variable.sh
|
||||
-export-env-variables-from-file-dot-env.sh
|
||||
-export-env-variables-from-file.sh
|
||||
-get-env-variable-key-from-line.sh
|
||||
-get-env-variable-value-from-line.sh
|
||||
-log-env-vars.sh
|
||||
-prompt-for-env-var.sh
|
||||
local-storage/
|
||||
--index-api.sh
|
||||
-ensure-existance-file.sh -ensure-existance-file-dot-env.sh
|
||||
-read-lines-from-file.sh -read-lines-from-file-dot-env.sh
|
||||
-reset-file.sh -reset-file-dot-env.sh
|
||||
-save-env-variable-2-file.sh -save-env-variable-2-file-dot-env.sh
|
||||
-view-file.sh -view-file-dot-env.sh
|
||||
```
|
||||
|
||||
### Which entrypoint to source — this matters
|
||||
|
||||
```bash
|
||||
# From another module, when you only need base's shared functions:
|
||||
. ./.scripts/base/lib/--index-api.sh
|
||||
|
||||
# Only from base's own api/ wrappers:
|
||||
. ./.scripts/base/lib/--index.sh
|
||||
```
|
||||
|
||||
`base/lib/--index.sh` runs base's reader and validator, and **reads `.env` and
|
||||
environment-specific files as a side effect**. Sourcing it from a library function pulls that
|
||||
whole environment into an unrelated command — values appear that nobody set, and the failure
|
||||
is hard to trace because nothing in the calling module mentions `.env`.
|
||||
|
||||
`--index-api.sh` defines functions and nothing else, which is why it is the correct dependency
|
||||
edge between modules.
|
||||
|
||||
Rules:
|
||||
|
||||
1. Prefer `base/lib/--index-api.sh` from other modules.
|
||||
2. Nested lib packages such as `lib/local-storage/` carry their own `--index-api.sh` and are
|
||||
sourced from the parent's.
|
||||
3. Never log secret values — redact tokens, API keys, passwords, kube config, credentials.
|
||||
|
||||
---
|
||||
|
||||
## 3. The logging bootstrap rule
|
||||
|
||||
**A logger function whose level flag is unset prints nothing and returns 0.**
|
||||
|
||||
Every `_loggers_*` function is guarded by its level flag:
|
||||
|
||||
```bash
|
||||
if [ "${LOGGER_IS_ENABLED_INFO}" = true ]; then ... fi
|
||||
```
|
||||
|
||||
An unset flag is not `true`, so the call is a silent no-op with a success exit code. Nothing
|
||||
fails, nothing warns — the command simply produces no output, which reads like a bug in the
|
||||
command rather than in its bootstrap.
|
||||
|
||||
Those flags are exported by `loggers/lib/--env-vars-reader.sh`. For logging to work, that
|
||||
reader must have run before any logger call.
|
||||
|
||||
In the shipped `assets/loggers/`, `--index-api.sh` sources the reader itself, so any module
|
||||
that sources the logger API gets working logging with no extra step. The reader uses
|
||||
`${VAR:-default}` throughout, so it is safe to source repeatedly and a caller's override
|
||||
still wins.
|
||||
|
||||
**If you are adapting an existing `loggers` module rather than using the shipped one, check
|
||||
this first.** A `--index-api.sh` that sources only the logger function files, without the
|
||||
reader, silences every module that depends on it — while `bash -n` passes and every command
|
||||
exits 0.
|
||||
|
||||
Quick check in any repository:
|
||||
|
||||
```bash
|
||||
grep -n 'env-vars-reader' .scripts/loggers/lib/--index-api.sh \
|
||||
|| echo "WARNING: loggers API does not bootstrap its level flags — logging may be silent"
|
||||
```
|
||||
|
||||
Direct test:
|
||||
|
||||
```bash
|
||||
bash -c '. ./.scripts/loggers/lib/--index-api.sh; _loggers_info "check" "visible?"'
|
||||
```
|
||||
|
||||
No output means the flags were never exported.
|
||||
Reference in New Issue
Block a user