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:
2026-07-30 22:18:55 +03:00
co-authored by Claude Opus 5
parent 39d051b6f0
commit 31a5408a6c
57 changed files with 2051 additions and 1 deletions
+165
View File
@@ -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.