Skip to content

fix: move reference files to ref/ subdirectories #35

fix: move reference files to ref/ subdirectories

fix: move reference files to ref/ subdirectories #35

Workflow file for this run

name: Validate Skills
on:
push:
branches: [main, develop]
pull_request:
permissions:
contents: read
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 24
cache: npm
- run: npm ci
- name: Markdown lint
run: npx markdownlint-cli2
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: "3.12"
- run: pip install skills-ref
- name: Validate all skills (Agent Skills spec)
run: |
set -e
for skill_md in $(find . -name SKILL.md -not -path './.changeset/*' -not -path '*/node_modules/*'); do
skill_dir=$(dirname "$skill_md")
echo "Validating $skill_dir..."
agentskills validate "$skill_dir"
done
echo "All skills valid ✅"
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 24
cache: npm
- run: npm ci
- name: Build skills.zip
run: npm run build
- name: Verify skills.zip contents
run: |
set -e
echo "📦 Checking dist/skills.zip..."
FILES=$(unzip -l dist/skills.zip | tail -n +4 | head -n -2 | awk '{print $4}')
# Every SKILL.md must be in the zip
for skill_md in $(find . -name SKILL.md -not -path './.changeset/*' -not -path '*/node_modules/*'); do
relative="${skill_md#./}"
if echo "$FILES" | grep -qF "$relative"; then
echo " ✅ $relative"
else
echo " ❌ MISSING: $relative"
exit 1
fi
done
# LICENSE + README must be present
for f in LICENSE LICENSE-CC0 README.md; do
if echo "$FILES" | grep -qF "$f"; then
echo " ✅ $f"
else
echo " ❌ MISSING: $f"
exit 1
fi
done
# No node_modules in the zip
if echo "$FILES" | grep -q "node_modules"; then
echo " ❌ node_modules found in skills.zip!"
exit 1
fi
echo "skills.zip verified ✅"
- name: Upload skills.zip
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: skills-zip
path: dist/skills.zip
skills-discovery:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 24
- name: Verify .well-known/skills/index.json is up to date
run: |
set -e
node generate-skills-index.mjs
if ! git diff --exit-code .well-known/skills/index.json; then
echo "❌ .well-known/skills/index.json is out of date!"
echo "Run: node generate-skills-index.mjs"
exit 1
fi
echo ".well-known/skills/index.json is up to date ✅"
- name: Verify README lists all skills
run: |
set -e
MISSING=0
for skill_md in $(find . -name SKILL.md -not -path './.changeset/*' -not -path '*/node_modules/*'); do
name=$(sed -n '/^---$/,/^---$/p' "$skill_md" | grep '^name:' | head -1 | sed 's/^name:\s*//')
if [ -n "$name" ] && ! grep -q "$name" README.md; then
echo "❌ Skill '$name' (from $skill_md) not found in README.md"
MISSING=1
else
echo " ✅ $name"
fi
done
if [ "$MISSING" -eq 1 ]; then
echo "README.md is missing skills — update the Available Skills table"
exit 1
fi
echo "README lists all skills ✅"
package-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 24
cache: npm
- name: npm pack (simulate publish)
run: |
TARBALL=$(npm pack 2>/dev/null | tail -1)
echo "TARBALL=$TARBALL" >> "$GITHUB_ENV"
echo "Packed: $TARBALL"
- name: Verify tarball contents
run: |
set -e
FILES=$(tar tzf "$TARBALL")
# Every SKILL.md must be in the tarball
for skill_md in $(find . -name SKILL.md -not -path './.changeset/*' -not -path '*/node_modules/*'); do
relative="${skill_md#./}"
expected="package/$relative"
if echo "$FILES" | grep -qF "$expected"; then
echo " ✅ $relative"
else
echo " ❌ MISSING: $relative"
exit 1
fi
done
# No node_modules in tarball
if echo "$FILES" | grep -q "node_modules"; then
echo " ❌ node_modules found in tarball!"
exit 1
fi
# LICENSE files must be present
for f in LICENSE LICENSE-CC0 README.md; do
if echo "$FILES" | grep -qF "package/$f"; then
echo " ✅ $f"
else
echo " ❌ MISSING: $f"
exit 1
fi
done
echo "Tarball contents verified ✅"
- name: pi install (from tarball)
run: |
set -e
npm install -g @mariozechner/pi-coding-agent
export HOME=$(mktemp -d)
mkdir -p "$HOME/.pi/agent"
echo '{}' > "$HOME/.pi/agent/settings.json"
EXTRACT_DIR=$(mktemp -d)
tar xzf "$TARBALL" -C "$EXTRACT_DIR"
pi install "$EXTRACT_DIR/package"
OUTPUT=$(pi list 2>&1)
echo "$OUTPUT"
if echo "$OUTPUT" | grep -q "package"; then
echo "pi install verified ✅"
else
echo "❌ Package not found in pi list"
exit 1
fi
- name: skills add — default discovery (no flags)
run: |
set -e
WORK_DIR=$(mktemp -d)
tar xzf "$TARBALL" -C "$WORK_DIR"
REPO_DIR="$WORK_DIR/package"
# Test what 'skills add' finds with zero flags — baseline behavior
echo "=== Default discovery (no --full-depth) ==="
export HOME=$(mktemp -d)
DEFAULT_OUTPUT=$(npx -y skills add "$REPO_DIR" --list 2>&1) || true
echo "$DEFAULT_OUTPUT"
# Count skills found in default mode
DEFAULT_COUNT=$(echo "$DEFAULT_OUTPUT" | grep -oP 'Found \K[0-9]+' || echo "0")
echo "Default discovery found: $DEFAULT_COUNT skill(s)"
echo ""
echo "=== Full-depth discovery (--full-depth) ==="
FULL_OUTPUT=$(npx -y skills add "$REPO_DIR" --list --full-depth 2>&1) || true
echo "$FULL_OUTPUT"
FULL_COUNT=$(echo "$FULL_OUTPUT" | grep -oP 'Found \K[0-9]+' || echo "0")
echo "Full-depth discovery found: $FULL_COUNT skill(s)"
# Full-depth must find all skills
EXPECTED=$(find "$REPO_DIR" -name SKILL.md | wc -l)
if [ "$FULL_COUNT" -lt "$EXPECTED" ]; then
echo "⚠️ Full-depth found $FULL_COUNT but repo has $EXPECTED SKILL.md files"
fi
echo "Discovery baseline captured ✅"
- name: skills add — install all skills
run: |
set -e
WORK_DIR=$(mktemp -d)
tar xzf "$TARBALL" -C "$WORK_DIR"
REPO_DIR="$WORK_DIR/package"
export HOME=$(mktemp -d)
OUTPUT=$(npx -y skills add "$REPO_DIR" --full-depth --all 2>&1) || true
echo "$OUTPUT"
# Verify every skill was installed
SKILL_NAMES=$(find "$REPO_DIR" -name SKILL.md | while read f; do
sed -n '/^---$/,/^---$/p' "$f" | grep '^name:' | head -1 | sed 's/^name:\s*//'
done)
FAILED=0
for name in $SKILL_NAMES; do
if echo "$OUTPUT" | grep -qi "$name"; then
echo " ✅ $name installed"
else
echo " ❌ $name NOT found in output"
FAILED=1
fi
done
if [ "$FAILED" -eq 1 ]; then
echo "❌ Some skills failed to install"
exit 1
fi
echo "All skills installed via 'skills add' ✅"
- name: skills add — install each skill individually
run: |
set -e
WORK_DIR=$(mktemp -d)
tar xzf "$TARBALL" -C "$WORK_DIR"
REPO_DIR="$WORK_DIR/package"
SKILL_NAMES=$(find "$REPO_DIR" -name SKILL.md | while read f; do
sed -n '/^---$/,/^---$/p' "$f" | grep '^name:' | head -1 | sed 's/^name:\s*//'
done)
FAILED=0
for name in $SKILL_NAMES; do
export HOME=$(mktemp -d)
OUTPUT=$(npx -y skills add "$REPO_DIR" --skill "$name" --full-depth --all 2>&1) || true
if echo "$OUTPUT" | grep -qi "$name"; then
echo " ✅ skills add --skill $name"
else
echo " ❌ skills add --skill $name FAILED"
echo "$OUTPUT" | tail -5
FAILED=1
fi
done
if [ "$FAILED" -eq 1 ]; then
echo "❌ Some individual skill installs failed"
exit 1
fi
echo "All individual skill installs verified ✅"