#!/usr/bin/env bash set -euo pipefail # Enforces agentskills.io's skill-authoring.md guidance: keep SKILL.md within # 500 lines and roughly 5,000 tokens, so the full body doesn't crowd out # conversation history and other active skills once loaded into context. Vale # can't express a whole-file length ceiling (its checks operate on text # patterns, not raw file size), so this is a plain script instead of a Vale # rule. # # Both ceilings are inclusive: a file at exactly MAX_LINES or MAX_WORDS passes, # and only one past it fails. That matches skill-audit/scripts/validate.sh, # which has always used `line_count <= 500` as its pass condition — the two # previously disagreed at exactly 500 lines, so a SKILL.md could pass its own # audit and still be blocked by the commit hook. # # Token counts aren't computed exactly here — word count (`wc -w`) is used as # a proxy. This repo's own SKILL.md corpus measures ~5.7-6.5 characters per # word, which at the standard ~4-characters-per-token English approximation # works out to roughly 1.6-1.7 tokens per word. MAX_WORDS below is calibrated # from that measured ratio against the 5,000-token ceiling, with margin — it's # still a proxy, not exact BPE tokenization, but now grounded in actual repo # content rather than an unverified "conservative" assumption. MAX_LINES=500 MAX_WORDS=2900 FAIL=0 for f in "$@"; do [[ -f "$f" ]] || continue # awk's NR counts the final line even without a trailing newline, matching # Python's splitlines() semantics (used by skill-audit/scripts/validate.sh # for its own line count) — `wc -l` undercounts by 1 in that case. lines=$(awk 'END{print NR}' "$f") if (( lines > MAX_LINES )); then echo "ERROR: $f has $lines lines, exceeding the $MAX_LINES-line ceiling (agentskills.io skill-authoring.md)" >&2 FAIL=1 fi words=$(wc -w < "$f") if (( words > MAX_WORDS )); then echo "ERROR: $f has $words words (proxy for tokens), exceeding the $MAX_WORDS-word ceiling (~5,000 tokens, agentskills.io skill-authoring.md)" >&2 FAIL=1 fi done exit $FAIL