diff --git a/scripts/lint-agents.sh b/scripts/lint-agents.sh index 086b386c..caf61571 100755 --- a/scripts/lint-agents.sh +++ b/scripts/lint-agents.sh @@ -112,6 +112,9 @@ lint_file() { if ! grep -qE -- "^${field}:" <<<"$frontmatter"; then echo "ERROR $file: missing frontmatter field '${field}'" errors=$((errors + 1)) + elif [[ ! "$(get_field "$field" "$file")" =~ [^[:space:]] ]]; then + echo "ERROR $file: frontmatter field '${field}' must not be empty" + errors=$((errors + 1)) fi done diff --git a/scripts/test-convert-frontmatter.sh b/scripts/test-convert-frontmatter.sh index 4162cd48..75df39ff 100755 --- a/scripts/test-convert-frontmatter.sh +++ b/scripts/test-convert-frontmatter.sh @@ -56,4 +56,28 @@ assert_quoted \ "$OUTPUT_DIR/qwen/agents/programmatic-display-buyer.md" \ tools -echo "PASS: converted YAML frontmatter keeps scalar values safely quoted" +# A present but empty required field is unusable discovery metadata. Check the +# source linter directly, including YAML's quoted empty-string form. +cat > "$OUTPUT_DIR/agent.md" <<'EOF' +--- +name: Example Agent +description: Builds useful examples +color: red +--- + +## Identity + +## Core Mission + +## Critical Rules + +EOF +for field in name description color; do + sed "s/^${field}:.*/${field}: \"\"/" "$OUTPUT_DIR/agent.md" > "$OUTPUT_DIR/empty-$field.md" + if "$SCRIPT_DIR/lint-agents.sh" "$OUTPUT_DIR/empty-$field.md" > /dev/null; then + printf 'Expected linter to reject empty %s metadata\n' "$field" >&2 + exit 1 + fi +done + +echo "PASS: converted YAML frontmatter stays quoted and required source metadata is nonempty" diff --git a/scripts/test-convert-outputs.sh b/scripts/test-convert-outputs.sh index b198c96a..d8bd5718 100755 --- a/scripts/test-convert-outputs.sh +++ b/scripts/test-convert-outputs.sh @@ -199,8 +199,10 @@ src_bad = [] for slug, (_gf_desc, _gf_name, path) in list(src.items()): try: data = frontmatter(open(os.path.join(R, path), encoding="utf-8").read()) - assert isinstance(data, dict) and isinstance(data.get("name"), str) \ - and isinstance(data.get("description"), str), "missing name/description" + assert isinstance(data, dict) and all( + isinstance(data.get(field), str) and data[field].strip() + for field in ("name", "description", "color") + ), "missing or empty name/description/color" assert data["description"][:1] not in ('"', "'"), "description starts with a quote character" src[slug] = (data["description"], data["name"], path) except Exception as e: