12 KiB
name, description, license, metadata, compatibility
| name | description | license | metadata | compatibility | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| development-scripts--3darch | Create, refactor, review, document, and maintain shell script modules under a repository's .scripts/ directory — the api/ + lib/ split, the --index.sh / --index-api.sh / --env-vars-reader.sh / --env-vars-validator.sh bootstrap chain, module and root Taskfile.yml integration, logging through the shared loggers module, and shared helpers from the base module. Use when adding a new script module or a new command to an existing one; writing an api/ wrapper or a lib/ implementation function; adding a CLI flag or a required environment variable; wiring a module into task; debugging a script that produces no output, cannot find a function, or unexpectedly loads .env; or reviewing shell module work for naming, sourcing order, and secret-safety — even when the user only says ".scripts", "Taskfile", "task runner", "shell module", or names a specific module like loggers or base. | Proprietary |
|
Requires bash. Taskfile (task) needed only for task-runner integration. Designed for Cline, Claude Code, GitHub Copilot, OpenAI Codex, and other compatible agent environments |
Repository Script Modules
3D Architecture Wizzard Project Adoption
This is the primary project-adopted skill for 3D Architecture Wizzard (3darch).
- Central source: https://gitea.lego-cloud.eu/home-v1-skills-code-agent/development-scripts
- Source branch:
test - Source commit:
5960d5e74713e6b95a403962f479b2b97cb76286 - Adopted repository: https://gitea.lego-cloud.eu/corp-v1-3darch-skills-code-agent/development-scripts--3darch
- Application: https://gitea.lego-cloud.eu/corp-v1-3darch/corp-v1-3darch
- Documentation: https://gitea.lego-cloud.eu/corp-v1-3darch/corp-v1-3darch-documentation
- Environment namespace:
CORP_V1_3DARCH_* - Global diagram skill: https://gitea.lego-cloud.eu/home-v1-skills-code-agent/diagrams-drawio
- Global glossary skill: https://gitea.lego-cloud.eu/home-v1-skills-code-agent/corp-v1--glossary
- Project automation: none; no scheduler job is authorized.
Project engineering peers:
development-branching-strategy--3darch— https://gitea.lego-cloud.eu/corp-v1-3darch-skills-code-agent/development-branching-strategy--3darchdevelopment-gitops-argo-cd--3darch— https://gitea.lego-cloud.eu/corp-v1-3darch-skills-code-agent/development-gitops-argo-cd--3darchdevelopment-monorepo-pnpm--3darch— https://gitea.lego-cloud.eu/corp-v1-3darch-skills-code-agent/development-monorepo-pnpm--3darchdevelopment-scripts--3darch— https://gitea.lego-cloud.eu/corp-v1-3darch-skills-code-agent/development-scripts--3darchdevsecops-ci-cd-gitea--3darch— https://gitea.lego-cloud.eu/corp-v1-3darch-skills-code-agent/devsecops-ci-cd-gitea--3darchdocumentation-docusaurus--3darch— https://gitea.lego-cloud.eu/corp-v1-3darch-skills-code-agent/documentation-docusaurus--3darchtemplate-engine-copier--3darch— https://gitea.lego-cloud.eu/corp-v1-3darch-skills-code-agent/template-engine-copier--3darch
Work rules for shell automation organised as modules under a repository's .scripts/
directory, with a strict public/private split and a fixed sourcing order.
The whole model rests on one idea: api/ is what people run, lib/ is what the code
calls, and a single bootstrap chain guarantees that by the time an implementation function
runs, its environment has been read, validated, and its dependencies sourced.
Scope routing
Pick the reference that matches the change; do not load all of them.
| The change touches | Read |
|---|---|
A reader, validator, implementation function, or api/ wrapper |
references/module-anatomy.md |
The loggers or base module, or logging that produces no output |
references/shared-modules.md |
.env files, per-environment layers, or shipping .scripts/ into a rendered repo |
references/environment-model.md |
A module Taskfile.yml or the root Taskfile.yml |
references/taskfile.md |
| Creating a module, changing one, or checking work before delivery | references/workflows.md |
| Deciding what kind of module something should be | references/module-patterns.md |
Copy-ready modules live in assets/: module-example-v1/ is the scaffold for a new module;
loggers/ and base/ are working reference implementations.
1. Repository model
<target-repository>/
Taskfile.yml # root task runner, includes module Taskfiles
.scripts/
<module>/
api/ # public command wrappers — what users run
lib/ # implementation functions — what the code calls
Taskfile.yml # only when the module is exposed through task
Commands always run from the repository root, never from inside the module:
./.scripts/<module>/api/<command>.sh [args]
task <module-alias>:<task-name> -- [args]
Every . source path in every file is written relative to the repository root
(. ./.scripts/loggers/lib/--index-api.sh). This is why running a script from inside its own
directory fails to find its dependencies — that is the convention working as designed, not a
bug to patch with dirname "$0".
2. Module anatomy
.scripts/<module>/
api/
<command-name>.sh
lib/
--env-vars-reader.sh # defaults + CLI flag parsing
--env-vars-validator.sh # required-input checks
--index-api.sh # sources dependencies + this module's implementations
--index.sh # full runtime bootstrap
-<command-name>.sh # one implementation function per command
Taskfile.yml # optional
| File | Responsibility |
|---|---|
api/<command>.sh |
Thin public entrypoint. Sources lib/--index.sh, calls one function. |
lib/-<command>.sh |
The command implementation function. |
lib/--index-api.sh |
Sources upstream module APIs, then this module's implementation files. |
lib/--index.sh |
Runtime bootstrap: reader, then validator, then API index. |
lib/--env-vars-reader.sh |
Exports defaults and parses CLI arguments into environment variables. |
lib/--env-vars-validator.sh |
Validates required variables, failing with an actionable log. |
Taskfile.yml |
Maps task names to api/ scripts, forwarding {{.CLI_ARGS}}. |
Not every module has every file — a support-only library like loggers has no api/ and no
Taskfile.yml. See references/module-patterns.md.
3. Standard runtime flow
api/<command>.sh
└── source lib/--index.sh
├── source lib/--env-vars-reader.sh # defaults + CLI flags → env vars
├── source lib/--env-vars-validator.sh # required vars present?
└── source lib/--index-api.sh
├── source dependencies (loggers, base, …)
└── source lib/-<command>.sh # defines the function
└── call _<moduleNamespace>_<commandFunction>
The order is load-bearing. The reader runs before the validator so the validator has something to check; both run before the API index so implementation functions see a fully-prepared environment. Reordering produces failures that look like missing variables.
Arguments reach the reader because sourcing happens with the wrapper's own arguments still in
scope — this is why api/ wrappers need no argument forwarding of their own.
4. Naming conventions
| Kind | Convention | Example |
|---|---|---|
| Module directory | lowercase kebab-case | module-example-v1, repositories-nodejs |
| Public command | lowercase kebab-case, action-oriented | initialize-one.sh, find-many-by-query.sh |
| Implementation file | single leading dash | lib/-initialize-one.sh |
| Index / lifecycle file | double leading dash | lib/--index.sh, lib/--env-vars-reader.sh |
| Function | _<moduleNamespace>_<actionName> |
_moduleExampleV1_initializeOne |
| Environment variable | uppercase module prefix | MODULE_EXAMPLE_V1_OUTPUT_DIR |
Kebab-case module names convert to camelCase function namespaces:
| Module | Function prefix | Env prefix |
|---|---|---|
module-example-v1 |
_moduleExampleV1_ |
MODULE_EXAMPLE_V1_ |
repositories-nodejs |
_repositoriesNodejs_ |
REPOSITORIES_NODEJS_ |
operation-utilities |
_operationUtilities_ |
OPERATION_UTILITIES_ |
The dash count is not decoration — it is how you tell at a glance whether a file defines a
command (-name.sh) or wires the module together (--name.sh).
5. Non-negotiable rules
api/wrappers stay thin. Sourcelib/--index.sh, call one function, nothing else. No implementation, no argument parsing, no validation.- CLI flags are parsed only in
--env-vars-reader.sh. Never in an implementation file. - Every new
lib/-*.shgets added tolib/--index-api.sh. Forgetting this is the most common cause of "command not found" for a function that plainly exists. - Readers preserve already-exported values —
export X="${X:-default}"— so a caller can override any setting before invoking the module. A module reader never sources.envfiles itself; thebasemodule owns that. Seereferences/environment-model.md. - Log through
_loggers_*helpers, never rawecho. Loggers write tostderr, keepingstdoutclean for real output. - Never log secrets. Redact tokens, API keys, passwords, and kube config.
- Quote variable expansions unless word splitting is intended.
returnnon-zero from implementation functions; reserveexit 1for validators and bootstrap. Anexitinside a sourced library kills the caller's shell.
6. Creating a module
Full walkthrough in references/workflows.md. The short path:
- Copy
assets/module-example-v1/to.scripts/<new-module>/. - Replace every
module-example-v1path, theMODULE_EXAMPLE_V1_env prefix, and the_moduleExampleV1_function prefix. - Add implementation files as
lib/-<command>.shand source them fromlib/--index-api.sh. - Add
api/<command>.shwrappers for user-facing commands only. - Add a module
Taskfile.yml, and a root include only if the namespace is stable. - Validate (section 7).
7. Validation
# Syntax-check every script in the module
find .scripts/<module> -name '*.sh' -print0 | xargs -0 -n1 bash -n
# Confirm task exposure resolves
task --list
# Run the command itself, from the repository root
./.scripts/<module>/api/<command>.sh --dry-run
bash -n catches syntax errors but not a missing entry in --index-api.sh — that only
surfaces at call time. Always run the command once, from the repository root, before
delivering. A dry-run flag is worth adding precisely so this check is cheap.
8. Mistakes to avoid
- Putting implementation logic into
api/*.sh. - Adding a
lib/-*.shfile and forgetting to source it fromlib/--index-api.sh. - Parsing CLI flags in an implementation function instead of the reader.
- Sourcing
base/lib/--index.shfrom a library function — it reads.envand environment-specific files as a side effect. Usebase/lib/--index-api.shwhen you only need shared functions. - Writing source paths relative to the script instead of the repository root.
- Using
exitinside a sourced implementation function. - Printing secrets, or documenting their values.
- Adding a root
Taskfile.ymlinclude for an experimental module. - Assuming logging works because the code compiles — a logger whose level flags were never
exported is silent and returns 0. See
references/shared-modules.md§3.