Files

69 lines
2.0 KiB
Bash
Executable File

# Gemeinsame Funktionen für die Skill-Skripte. Wird per "source" eingebunden.
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
SKILLS_DIR="$ROOT/skills"
DIST_DIR="$ROOT/dist"
NAME_RE='^[a-z0-9]+(-[a-z0-9]+)*$'
# Alle Skill-Namen (Ordner unter skills/), sortiert.
skill_names() {
local d
for d in "$SKILLS_DIR"/*/; do
[[ -d "$d" ]] && basename "$d"
done | LC_ALL=C sort
}
# Gibt pro Verstoß gegen die Namensregeln eine Zeile aus.
name_errors() {
local n="$1"
[[ "$n" =~ $NAME_RE ]] || echo "Name '$n' ist kein kebab-case (nur a-z, 0-9 und einzelne Bindestriche)"
(( ${#n} <= 64 )) || echo "Name '$n' ist länger als 64 Zeichen"
case "$n" in *claude*|*anthropic*) echo "Name '$n' darf nicht 'claude' oder 'anthropic' enthalten" ;; esac
return 0
}
# Frontmatter-Zeilen (ohne die ---) einer SKILL.md; Exit-Code != 0, wenn keins da ist.
frontmatter() {
tr -d '\r' < "$1" | awk '
NR == 1 { if ($0 != "---") exit 2; next }
$0 == "---" { found = 1; exit }
{ print }
END { if (!found) exit 3 }'
}
# Rohwert eines Frontmatter-Schlüssels (getrimmt, Anführungszeichen noch enthalten).
fm_raw() {
local line v
line="$(grep -m1 -E "^$2[[:space:]]*:" <<< "$1" || true)"
[[ -z "$line" ]] && return 1
v="${line#*:}"
v="${v#"${v%%[![:space:]]*}"}"
v="${v%"${v##*[![:space:]]}"}"
printf '%s' "$v"
}
# Wert eines Frontmatter-Schlüssels ohne umschließende Anführungszeichen.
fm_value() {
local v
v="$(fm_raw "$1" "$2")" || return 1
if [[ "$v" =~ ^\"(.*)\"$ ]] || [[ "$v" =~ ^\'(.*)\'$ ]]; then
v="${BASH_REMATCH[1]}"
fi
printf '%s' "$v"
}
# Erste Überschrift "## ..." aus CHANGELOG.md.
changelog_heading() {
[[ -f "$1/CHANGELOG.md" ]] || return 1
tr -d '\r' < "$1/CHANGELOG.md" | grep -m1 '^## ' || true
}
# Aktuelle Version eines Skills (oberster CHANGELOG-Eintrag) oder leer.
skill_version() {
local h
h="$(changelog_heading "$1")" || return 0
if [[ "$h" =~ ^##\ ([0-9]+\.[0-9]+\.[0-9]+)\ \([0-9]{4}-[0-9]{2}-[0-9]{2}\)[[:space:]]*$ ]]; then
printf '%s' "${BASH_REMATCH[1]}"
fi
}