.agents/skills/shell-scripts/SKILL.md
Enforces quality, safety, and consistency for shell scripts in the Skill System Foundry .github/scripts/ directory. Triggers when creating, editing, reviewing, or debugging any .sh file under .github/scripts/, modifying GitHub Actions workflows that call shell scripts, or working with CI automation scripts. Also triggers when asked to add a new CI helper script, fix shellcheck violations, handle GitHub Actions environment variables, or write new .sh scripts for CI. Use this skill for any shell scripting work in the repository.
npx skillsauth add milanhorvatovic/skill-system-foundry shell-scriptsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Enforces quality, safety, and consistency for all shell scripts under .github/scripts/ in the Skill System Foundry repository.
These scripts are CI helpers called by GitHub Actions workflows. They handle coverage badge updates and per-file coverage checks. They run in ephemeral CI environments and must be reliable, secure, and shellcheck-clean.
.github/
├── scripts/
│ ├── check-per-file-coverage.py ← enforces per-file branch coverage minimum
│ └── update-coverage-badge.sh ← pushes coverage.json to orphan badges branch
├── workflows/
│ ├── python-tests.yaml ← runs tests, coverage, badge update
│ ├── shellcheck.yaml ← lints all .sh files with shellcheck
│ ├── codex-code-review.yaml ← Codex PR review via codex-ai-code-review-action
│ └── release.yml ← bundles and uploads release assets
├── instructions/
│ ├── markdown.instructions.md ← Markdown review rules
│ └── scripts.instructions.md ← Python review rules
├── copilot-instructions.md ← top-level review guidance
└── CODEOWNERS ← requires code-owner approval
Every script starts with:
#!/bin/bash
set -euo pipefail
set -e — exit immediately on non-zero returnset -u — treat unset variables as errorsset -o pipefail — propagate pipe failuresValidate all required environment variables at the top of the script, before any work:
# Validate required environment variables
: "${BASE_SHA:?Environment variable BASE_SHA is required}"
: "${HEAD_SHA:?Environment variable HEAD_SHA is required}"
: "${GITHUB_OUTPUT:?Environment variable GITHUB_OUTPUT is required}"
This pattern uses parameter expansion with :? — if the variable is unset or empty, the script exits immediately with the error message. Group all validations together at the top.
All .sh files must pass shellcheck with no warnings. The shellcheck.yaml workflow runs automatically on PRs that modify .github/scripts/*.sh and on pushes to main.
Common shellcheck rules to watch:
"$VAR" not $VARlocal var; var=$(...) not local var=$(cmd)"$(cmd)" not $(cmd).github/scripts/ is protected by CODEOWNERS — changes require code-owner approval. This is a security boundary: these scripts run in CI with access to secrets and write permissions.
Every script follows this structure:
#!/bin/bash
set -euo pipefail
# Validate required environment variables
: "${VAR1:?Environment variable VAR1 is required}"
: "${VAR2:?Environment variable VAR2 is required}"
# <Brief description of what this script does.>
#
# Environment variables:
# VAR1 — description of what this variable provides
# VAR2 — description of what this variable provides
#
# Outputs:
# output-name=value → written to $GITHUB_OUTPUT
# path/to/file → created on disk
The header documents: purpose, required environment variables with descriptions, and outputs (both $GITHUB_OUTPUT values and files created).
Use >> append, not > overwrite:
echo "has-changes=true" >> "$GITHUB_OUTPUT"
Never echo secrets. Use environment variables set by the workflow:
env:
HAS_OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY != '' }}
Check the boolean string, not the secret itself:
if [ "$HAS_OPENAI_API_KEY" != "true" ]; then
echo "OPENAI_API_KEY is not set. Skipping."
echo "allowed=false" >> "$GITHUB_OUTPUT"
exit 0
fi
Use ::warning:: and ::error:: prefixes for structured log output:
echo "::warning::Base SHA ${BASE_SHA} not found locally — fetching from origin"
echo "::error::CODEX_REVIEW_USERS repository variable is not set."
The repository uses permission isolation across workflow jobs:
contents: read only. Cannot modify the repo.pull-requests: write).When adding new scripts:
uses: actions/checkout@de0fac...Use mktemp for temporary directories and trap for cleanup:
WORK_DIR=$(mktemp -d)
trap 'rm -rf "$WORK_DIR"' EXIT
This ensures cleanup runs even on errors (because set -e triggers EXIT).
.github/scripts/<name>.sh with the standard headerchmod +x .github/scripts/<name>.shshellcheck .github/scripts/<name>.sh locally before pushingbash .github/scripts/<name>.sh (not sh — these are bash scripts)env: blocks in the workflow step to pass variablesif [ "$CONDITION" = "true" ]; then
echo "proceed=true" >> "$GITHUB_OUTPUT"
else
echo "proceed=false" >> "$GITHUB_OUTPUT"
exit 0 # Clean exit — not a failure
fi
if printf '%s' "$RAW_JSON" | jq . > output.json 2>/dev/null; then
handle_success
else
echo "::error::Invalid JSON in output"
exit 1
fi
# Fetch with authentication fallback
if ! git cat-file -e "${BASE_SHA}^{commit}" 2>/dev/null; then
git fetch --no-tags origin "${BASE_SHA}"
fi
git init "$WORK_DIR/repo"
cp "$WORK_DIR/coverage.json" "$WORK_DIR/repo/coverage.json"
git -C "$WORK_DIR/repo" checkout --orphan badges
git -C "$WORK_DIR/repo" add coverage.json
git -C "$WORK_DIR/repo" \
-c user.name="github-actions[bot]" \
-c user.email="github-actions[bot]@users.noreply.github.com" \
commit -m "Update coverage badge [skip ci]"
Key details: use [skip ci] to prevent infinite loops, use github-actions[bot] as committer, propagate auth headers from actions/checkout.
set -euo pipefail at the top$VAR instead of "$VAR")> instead of >> for $GITHUB_OUTPUT (overwrites previous outputs)sh and bash syntax (these are bash scripts, call with bash)trap cleanup for temporary files@v6) instead of commit SHA pinstools
Greets a recipient through one of two registered tones — formal or casual — by dispatching to a dedicated capability. Activates when the conversation asks for a tone-specific welcome or a switch between formal and casual greetings; use when comparing the two styles. Demonstrates the router pattern in the Skill System Foundry — a thin SKILL.md entry point routing to capability files, with allowed-tools declared in frontmatter so capability shell fences pass validation.
testing
Greets a single recipient with a friendly welcome message rendered in a formal or casual tone. Activates when the conversation asks to say hello or welcome someone; use when a minimal standalone skill is needed. Demonstrates the smallest valid standalone skill in the Skill System Foundry — required name and description frontmatter plus an optional metadata block — and how its layout passes validation.
testing
Designs and evolves AI-agnostic skill systems. Triggers on skill/capability creation, role definition, or router migration; use when auditing consistency or improving token efficiency.
development
Governs the configuration.yaml file that serves as the single source of truth for all validation rules in the Skill System Foundry. Triggers when adding, modifying, or reviewing validation rules, limits, patterns, or reserved words. Also triggers when working with constants.py, yaml_parser.py, or any code that reads from configuration.yaml. Use this skill when asked to add a new validation check, change a limit or threshold, update reserved word lists, add SPDX license identifiers, modify regex patterns, or troubleshoot why a validation rule is not working as expected. Activates on mentions of configuration, validation rules, constants, thresholds, or pattern definitions.