Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions .github/scripts/check-skill-reference-docs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/usr/bin/env bash
set -euo pipefail

cd "$(git rev-parse --show-toplevel)"

errors=0
adoc="docs/modules/ROOT/pages/skills.adoc"
readme="README.md"

# Forward check: every references/*.md on disk must be listed in:
# - the skill's SKILL.md, as `references/<filename>`
# - skills.adoc, as a backtick-wrapped `<filename>` (table cell)
# - README.md, as a bold **<filename>** (list item)
#
# NOTE: these patterns encode the *current* formatting conventions used in
# skills.adoc / README.md / SKILL.md. If those docs are reformatted (e.g. a
# different markup style for the reference tables/lists), this script must
# be updated in lockstep, or every entry will start failing.
#
# Scope: only these three listings are checked. Per-skill "entry point"
# docs (e.g. reqstool-conventions.md, which links to the other convention
# docs) are intentionally not cross-checked, since not every skill has one
# and its link format isn't standardized across skills.
while IFS= read -r -d '' file; do
filename=$(basename "$file")
skill_dir=$(dirname "$(dirname "$file")")
skill_md="$skill_dir/SKILL.md"

if ! grep -qF "references/$filename" "$skill_md"; then
echo "::error::$filename not referenced in $skill_md"
errors=1
fi
if ! grep -qF "\`$filename\`" "$adoc"; then
echo "::error::$filename not referenced in $adoc"
errors=1
fi
if ! grep -qF "**$filename**" "$readme"; then
echo "::error::$filename not referenced in $readme"
errors=1
fi
done < <(find plugins -path '*/references/*.md' -print0)

# Reverse check: every *.md filename listed in skills.adoc / README.md
# reference tables must exist on disk under some references/ directory.
check_reverse() {
local file="$1" pattern="$2" strip_chars="$3"
local filename
while IFS= read -r filename; do
[ -n "$filename" ] || continue
if ! find plugins -path "*/references/$filename" -type f | grep -q .; then
echo "::error::$filename listed in $file but not found under any references/ dir"
errors=1
fi
done < <(grep -oE "$pattern" "$file" | tr -d "$strip_chars" | sort -u)
}

# skills.adoc lists filenames as `reqstool-overview.md` (backtick-wrapped)
check_reverse "$adoc" '`[A-Za-z0-9._-]+\.md`' '`'
# README.md lists filenames as **reqstool-overview.md** (bold)
check_reverse "$readme" '\*\*[A-Za-z0-9._-]+\.md\*\*' '*'

if [ "$errors" -ne 0 ]; then
exit 1
fi

echo "All skill reference docs are consistently listed."
14 changes: 14 additions & 0 deletions .github/workflows/validate-plugins.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,17 @@ jobs:
find . -name "*.json" \
! -path "./.git/*" \
| xargs -I{} sh -c 'jq empty "{}" && echo "OK: {}"'

- name: Check skill reference docs are listed consistently
run: bash .github/scripts/check-skill-reference-docs.sh

- name: Verify the consistency check fails on an undocumented reference doc
run: |
fixture=plugins/reqstool/skills/reqstool-conventions/references/__ci-fixture-undocumented.md
echo "fixture" > "$fixture"
if bash .github/scripts/check-skill-reference-docs.sh; then
echo "::error::expected check-skill-reference-docs.sh to fail for an undocumented reference file"
rm -f "$fixture"
exit 1
fi
rm -f "$fixture"
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ Uses the `reqstool` MCP server (`get_status` tool) when configured. Falls back t

Bundled convention docs that are auto-applied when working with reqstool files:

- **reqstool-overview.md** — what reqstool is, architecture (system/microservice/external), YAML files, imports, filters, implementations, CLI basics
- **reqstool-conventions.md** — overview of config fields and skill conventions
- **reqstool-annotation-conventions.md** — `@Requirements` and `@SVCs` placement rules (Java, Python, TypeScript)
- **reqstool-decomposition-conventions.md** — parent-child hierarchies, dot-notation IDs, lifecycle states
Expand Down
3 changes: 3 additions & 0 deletions docs/modules/ROOT/pages/skills.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ Bundled convention docs that guide the AI assistant:
|===
| Reference file | Description

| `reqstool-overview.md`
| What reqstool is — architecture (system/microservice/external), YAML files, imports, filters, implementations, CLI basics

| `reqstool-conventions.md`
| Entry point — config reference, links to other convention docs

Expand Down
Loading