Agent Skills Creator Create and improve skills in the Agent Skills open format: full lifecycle from pattern selection through validation and README update. - IS: creating new agent skills and auditing or rewriting existing ones: SKILL.md, references, rules folders, scripts, evaluations. - IS NOT: AGENTS.md/CLAUDE.md instruction files (use ) or general documentation quality (use ). Choose a Mode - New skill → Creation Workflow below. - Audit, improve, or rewrite an existing skill → , which scores eleven audit dimensions, runs an ordered rewrite, then reuses Steps 5-8 for validation and shippin…

\\t'/ }\"\n detail=\"${detail//

Agent Skills Creator Create and improve skills in the Agent Skills open format: full lifecycle from pattern selection through validation and README update. - IS: creating new agent skills and auditing or rewriting existing ones: SKILL.md, references, rules folders, scripts, evaluations. - IS NOT: AGENTS.md/CLAUDE.md instruction files (use ) or general documentation quality (use ). Choose a Mode - New skill → Creation Workflow below. - Audit, improve, or rewrite an existing skill → , which scores eleven audit dimensions, runs an ordered rewrite, then reuses Steps 5-8 for validation and shippin…

\\n'/ }\"\n detail=\"${detail//

Agent Skills Creator Create and improve skills in the Agent Skills open format: full lifecycle from pattern selection through validation and README update. - IS: creating new agent skills and auditing or rewriting existing ones: SKILL.md, references, rules folders, scripts, evaluations. - IS NOT: AGENTS.md/CLAUDE.md instruction files (use ) or general documentation quality (use ). Choose a Mode - New skill → Creation Workflow below. - Audit, improve, or rewrite an existing skill → , which scores eleven audit dimensions, runs an ordered rewrite, then reuses Steps 5-8 for validation and shippin…

\\r'/ }\"\n printf '%s\\t%s\\t%s\\t%s\\n' \"$1\" \"$2\" \"$3\" \"$detail\" >>\"$RESULTS\"\n}\n\n# check \u003cformat|house> \u003ccheck-name> \u003cdetail-on-failure> \u003ccount>\n# A count of 0 passes; anything else fails. Keeps call sites to one line.\ncheck() {\n if [ \"$4\" -eq 0 ]; then record PASS \"$1\" \"$2\" \"\"; else record FAIL \"$1\" \"$2\" \"$3\"; fi\n}\n\nvalidate_skill() {\n skill_dir=\"${1%/}\"\n name=\"$(basename \"$skill_dir\")\"\n md=\"$skill_dir/SKILL.md\"\n\n if [ ! -f \"$md\" ]; then\n record FAIL format skill-md-present \"$skill_dir has no SKILL.md\"\n return\n fi\n\n # --- frontmatter: ruby owns YAML parsing and emits its own result lines ---\n # The magic comment keeps \\p{L} valid when the shell has no UTF-8 locale\n # (LANG unset in CI or a sandbox makes -e scripts US-ASCII and ruby rejects\n # the property), so the check reports the real result instead of \"ruby failed\".\n SKILL_VALIDATION_POLICY=\"$POLICY\" ruby -E UTF-8 -ryaml -e '# encoding: utf-8\n path, folder = ARGV\n src = File.read(path)\n m = src.match(/\\A---\\n(.*?)\\n---\\n/m)\n # Detail explains a failure, so suppress it on PASS to avoid lines that read\n # as their own contradiction (\"PASS name-reserved ... contains a reserved word\").\n def out(status, name, detail) puts [status, \"format\", name, status == \"PASS\" ? \"\" : detail].map { |value| value.to_s.gsub(/[\\t\\r\\n]/, \" \") }.join(\"\\t\") end\n unless m\n out(\"FAIL\", \"frontmatter-present\", \"no --- delimited YAML block at the top\")\n exit\n end\n out(\"PASS\", \"frontmatter-present\", \"\")\n y = begin\n YAML.safe_load(m[1]) || {}\n rescue => e\n out(\"FAIL\", \"frontmatter-parses\", e.message.split(\"\\n\").first.to_s)\n exit\n end\n unless y.is_a?(Hash)\n out(\"FAIL\", \"frontmatter-mapping\", \"frontmatter must be a mapping\")\n exit\n end\n fields = %w[name description license compatibility metadata allowed-tools]\n extra = y.keys - fields\n out(extra.empty? ? \"PASS\" : \"FAIL\", \"frontmatter-portable\", \"unsupported fields: #{extra.join(\", \")}\")\n %w[name description license compatibility allowed-tools].each do |field|\n next unless y.key?(field)\n value = y[field]\n out(value.is_a?(String) ? \"PASS\" : \"FAIL\", \"#{field}-type\", \"#{field} must be a string\")\n end\n if y.key?(\"compatibility\")\n value = y[\"compatibility\"]\n valid = value.is_a?(String) && !value.strip.empty? && value.length \u003c= 500\n out(valid ? \"PASS\" : \"FAIL\", \"compatibility-length\", \"compatibility must contain 1-500 characters\")\n end\n if y.key?(\"metadata\")\n value = y[\"metadata\"]\n valid = value.is_a?(Hash) && value.all? { |k, v| k.is_a?(String) && v.is_a?(String) }\n out(valid ? \"PASS\" : \"FAIL\", \"metadata-types\", \"metadata must map strings to strings\")\n end\n n = y[\"name\"].is_a?(String) ? y[\"name\"] : \"\"\n d = y[\"description\"].is_a?(String) ? y[\"description\"] : \"\"\n def house(status, name, detail)\n return if ENV[\"SKILL_VALIDATION_POLICY\"] == \"private\"\n puts [status, \"house\", name, status == \"PASS\" ? \"\" : detail].map { |value| value.to_s.gsub(/[\\t\\r\\n]/, \" \") }.join(\"\\t\")\n end\n\n if n.strip.empty? then out(\"FAIL\", \"name-present\", \"missing name\")\n else\n out(\"PASS\", \"name-present\", \"\")\n out(n.length \u003c= 64 ? \"PASS\" : \"FAIL\", \"name-length\", \"#{n.length} chars, max 64\")\n out((n == n.downcase && n =~ /\\A[\\p{L}\\p{N}]+(-[\\p{L}\\p{N}]+)*\\z/) ? \"PASS\" : \"FAIL\", \"name-charset\",\n \"#{n.inspect} must be lowercase alphanumeric, single hyphens, no leading or trailing hyphen\")\n house(n =~ /anthropic|claude/ ? \"FAIL\" : \"PASS\", \"name-reserved\", \"#{n.inspect} contains a reserved word\")\n out(n == folder ? \"PASS\" : \"FAIL\", \"name-matches-folder\", \"name #{n.inspect} vs folder #{folder.inspect}\")\n end\n\n if d.strip.empty? then out(\"FAIL\", \"description-present\", \"missing description\")\n else\n out(\"PASS\", \"description-present\", \"\")\n out(d.length \u003c= 1024 ? \"PASS\" : \"FAIL\", \"description-length\", \"#{d.length} chars, max 1024\")\n house(d =~ /\u003c[a-zA-Z\\/]/ ? \"FAIL\" : \"PASS\", \"description-no-xml\", \"contains an XML-ish tag\")\n house(d =~ /Use when/ ? \"PASS\" : \"FAIL\", \"description-triggers\", \"no \\\"Use when\\\" trigger phrase\")\n house(d =~ /\\A\\s*(I |Use this|This skill)/ ? \"FAIL\" : \"PASS\", \"description-third-person\",\n \"opens in first person or as a human summary, not third-person capability\")\n end\n ' \"$md\" \"$name\" >>\"$RESULTS\" 2>/dev/null || record FAIL format frontmatter-parses \"ruby failed on $md\"\n\n if [ \"$POLICY\" = public ]; then\n # --- body ---\n lines=$(wc -l \u003c\"$md\" | tr -d ' ')\n if [ \"$lines\" -lt 500 ]; then\n record PASS house body-under-500-lines \"\"\n else\n record FAIL house body-under-500-lines \"$lines lines, split into references/\"\n fi\n\n # Windows separators, only on lines that look like paths, to avoid flagging\n # regex or LaTeX inside fenced blocks.\n n=$(grep -cE '[A-Za-z0-9_.-]+\\\\[A-Za-z0-9_.-]+\\.(md|json|sh|py|ts)' \"$md\" 2>/dev/null || true)\n check house forward-slashes \"backslash in a file path\" \"${n:-0}\"\n\n # --- references ---\n # Reachability covers every markdown file in the skill, not just references/.\n # Hub skills index subfolders (guidelines/, direction/) from a root track file,\n # so a file counts as reachable if SKILL.md or any root .md names it. Without\n # this, deleting a file and its only link passes silently.\n # Eval fixtures under evals/ are inputs copied into a test workspace, never\n # loaded by the skill, so they are exempt here and from the TOC check.\n # NUL-delimited throughout: a filename with whitespace otherwise word-splits,\n # which made this check pass and the kebab check miss the very name it exists\n # to catch. Process substitution, not a pipe, so $orphans survives the loop.\n orphans=\"\"\n while IFS= read -r -d '' f; do\n base=\"$(basename \"$f\")\"\n named=0\n # Grep each root .md itself. `find -exec grep {} +` hits ARG_MAX (and\n # sandboxes that deny sysconf(_SC_ARG_MAX)), which made every file look\n # unreachable even when SKILL.md named it. -F so a dot is literal.\n for root_md in \"$skill_dir\"/*.md; do\n [ -f \"$root_md\" ] || continue\n [ \"$(basename \"$root_md\")\" = \"NOTICE.md\" ] && continue\n if grep -qF -- \"$base\" \"$root_md\"; then\n named=1\n break\n fi\n done\n [ \"$named\" -eq 1 ] || orphans=\"$orphans $base\"\n done \u003c \u003c(find \"$skill_dir\" -name '*.md' -not -name 'SKILL.md' -not -path '*/rules*' -not -path \"$skill_dir/evals/*\" -print0 2>/dev/null)\n check house all-md-reachable \"unreachable from SKILL.md or a root track file:$orphans\" \\\n \"$(printf '%s' \"$orphans\" | wc -w | tr -d ' ')\"\n\n if [ -d \"$skill_dir/references\" ]; then\n\n # A chain is a reference telling you to load another reference. A prose\n # cross-mention without an imperative is a pointer, not a chain.\n chains=\"\"\n for f in \"$skill_dir\"/references/*.md; do\n [ -f \"$f\" ] || continue\n self=\"$(basename \"$f\")\"\n for g in \"$skill_dir\"/references/*.md; do\n other=\"$(basename \"$g\")\"\n [ \"$self\" = \"$other\" ] && continue\n grep -qiE \"\\b(load|read)\\b[^.]*$other\" \"$f\" && chains=\"$chains $self->$other\"\n done\n done\n check house no-reference-chains \"imperative chain:$chains\" \"$(printf '%s' \"$chains\" | wc -w | tr -d ' ')\"\n else\n record SKIP house references-linked \"no references/ folder\"\n fi\n\n # TOC on long references and track files. Rule files are exempt: _template.md\n # fixes their schema, so they are single-topic by construction and a TOC there\n # is noise, not navigation.\n no_toc=\"\"\n while IFS= read -r -d '' f; do\n fl=$(wc -l \u003c\"$f\" | tr -d ' ')\n [ \"${fl:-0}\" -le 100 ] && continue\n head -20 \"$f\" | grep -qiE '^#{2,3} (contents|table of contents)' || no_toc=\"$no_toc $(basename \"$f\"):${fl}L\"\n done \u003c \u003c(find \"$skill_dir\" -name '*.md' -not -name 'SKILL.md' -not -path '*/rules*' -not -path \"$skill_dir/evals/*\" -print0 2>/dev/null)\n check house toc-over-100-lines \"over 100 lines with no Contents heading:$no_toc\" \\\n \"$(printf '%s' \"$no_toc\" | wc -w | tr -d ' ')\"\n\n # bash 3.2 mis-parses `case` inside $( ), so build this in the current shell.\n bad_names=\"\"\n while IFS= read -r -d '' f; do\n b=\"$(basename \"$f\" .md)\"\n # NOTICE.md carries legal attribution, not authored workflow content.\n if [ \"$b\" = \"SKILL\" ] || [ \"$b\" = \"NOTICE\" ] || [ \"$b\" = \"_sections\" ] || [ \"$b\" = \"_template\" ]; then continue; fi\n printf '%s' \"$b\" | grep -qE '^[a-z0-9]+(-[a-z0-9]+)*

Agent Skills Creator Create and improve skills in the Agent Skills open format: full lifecycle from pattern selection through validation and README update. - IS: creating new agent skills and auditing or rewriting existing ones: SKILL.md, references, rules folders, scripts, evaluations. - IS NOT: AGENTS.md/CLAUDE.md instruction files (use ) or general documentation quality (use ). Choose a Mode - New skill → Creation Workflow below. - Audit, improve, or rewrite an existing skill → , which scores eleven audit dimensions, runs an ordered rewrite, then reuses Steps 5-8 for validation and shippin…

|| bad_names=\"$bad_names ${b// /\u003cspace>}\"\n done \u003c \u003c(find \"$skill_dir\" -name '*.md' -print0 2>/dev/null)\n check house kebab-case-filenames \"not kebab-case:$bad_names\" \"$(printf '%s' \"$bad_names\" | wc -w | tr -d ' ')\"\n\n # Root-level track files belong to the simple/hub pattern only.\n root_md=$(find \"$skill_dir\" -maxdepth 1 -name '*.md' -not -name 'SKILL.md' -not -name 'NOTICE.md' 2>/dev/null | wc -l | tr -d ' ')\n if [ \"$root_md\" -eq 0 ]; then\n record PASS house root-md-hub-only \"\"\n elif grep -qiE '^#{2,3} (modes|tracks)' \"$md\"; then\n record PASS house root-md-hub-only \"\"\n else\n record FAIL house root-md-hub-only \"$root_md root .md files but no Modes or Tracks table in SKILL.md\"\n fi\n\n # --- rules folders ---\n rules_total=0\n found_rules=0\n for rd in \"$skill_dir\"/rules*; do\n [ -d \"$rd\" ] || continue\n found_rules=1\n rname=\"$(basename \"$rd\")\"\n [ -f \"$rd/_sections.md\" ] || record FAIL house rules-sections-present \"$rname/_sections.md missing\"\n [ -f \"$rd/_template.md\" ] || record FAIL house rules-template-present \"$rname/_template.md missing\"\n\n prefixes=\"$(grep -oE '\\(([a-z0-9-]+)\\)' \"$rd/_sections.md\" 2>/dev/null | tr -d '()' | sort -u)\"\n bad_prefix=\"\"\n no_fm=\"\"\n for rf in \"$rd\"/*.md; do\n [ -f \"$rf\" ] || continue\n b=\"$(basename \"$rf\" .md)\"\n case \"$b\" in _*) continue ;; esac\n rules_total=$((rules_total + 1))\n head -1 \"$rf\" | grep -q '^---

Agent Skills Creator Create and improve skills in the Agent Skills open format: full lifecycle from pattern selection through validation and README update. - IS: creating new agent skills and auditing or rewriting existing ones: SKILL.md, references, rules folders, scripts, evaluations. - IS NOT: AGENTS.md/CLAUDE.md instruction files (use ) or general documentation quality (use ). Choose a Mode - New skill → Creation Workflow below. - Audit, improve, or rewrite an existing skill → , which scores eleven audit dimensions, runs an ordered rewrite, then reuses Steps 5-8 for validation and shippin…

|| no_fm=\"$no_fm $b\"\n matched=0\n for p in $prefixes; do\n case \"$b\" in \"$p\"-*) matched=1; break ;; esac\n done\n [ \"$matched\" -eq 0 ] && bad_prefix=\"$bad_prefix $b\"\n done\n check house rules-prefix-in-sections \"prefix not in $rname/_sections.md:$bad_prefix\" \\\n \"$(printf '%s' \"$bad_prefix\" | wc -w | tr -d ' ')\"\n check house rules-frontmatter \"no frontmatter:$no_fm\" \"$(printf '%s' \"$no_fm\" | wc -w | tr -d ' ')\"\n done\n\n # Counts stated in the SKILL.md BODY (priority tables, gotchas) drift too, and\n # the description check below misses them entirely when the description states\n # no count. A body count is valid only if it equals the grand total, one\n # folder's total, or one prefix's total. Anything else is stale.\n if [ \"$found_rules\" -eq 1 ]; then\n valid=\" $rules_total \"\n for rd in \"$skill_dir\"/rules*; do\n [ -d \"$rd\" ] || continue\n valid=\"$valid $(find \"$rd\" -maxdepth 1 -name '*.md' -not -name '_*' | wc -l | tr -d ' ') \"\n for p in $(find \"$rd\" -maxdepth 1 -name '*.md' -not -name '_*' -exec basename {} \\; | sed 's/-.*//' | sort -u); do\n valid=\"$valid $(find \"$rd\" -maxdepth 1 -name \"$p-*.md\" | wc -l | tr -d ' ') \"\n done\n done\n stale=\"\"\n for n in $(grep -oE '[0-9]+ rules' \"$md\" | grep -oE '^[0-9]+' | sort -u); do\n case \"$valid\" in *\" $n \"*) ;; *) stale=\"$stale $n\" ;; esac\n done\n check house rules-body-counts \"SKILL.md states a rule count matching no folder, prefix, or total:$stale\" \\\n \"$(printf '%s' \"$stale\" | wc -w | tr -d ' ')\"\n fi\n\n if [ \"$found_rules\" -eq 1 ]; then\n stated=$(ruby -E UTF-8 -ryaml -e '\n src = File.read(ARGV[0])\n m = src.match(/\\A---\\n(.*?)\\n---\\n/m)\n d = m ? (YAML.safe_load(m[1])[\"description\"].to_s rescue \"\") : \"\"\n puts(d[/(\\d+)\\s+rules/, 1] || \"\")\n ' \"$md\" 2>/dev/null)\n if [ -z \"$stated\" ]; then\n record SKIP house rules-count-reconciles \"description states no rule count\"\n elif [ \"$stated\" = \"$rules_total\" ]; then\n record PASS house rules-count-reconciles \"\"\n else\n record FAIL house rules-count-reconciles \"description says $stated, folders hold $rules_total\"\n fi\n else\n record SKIP house rules-count-reconciles \"no rules folder\"\n fi\n\n # --- hygiene ---\n aux=\"$(find \"$skill_dir\" -maxdepth 1 \\( -name 'README.md' -o -name 'CHANGELOG.md' -o -name 'INSTALLATION_GUIDE.md' \\) -exec basename {} \\; 2>/dev/null | tr '\\n' ' ')\"\n check house no-auxiliary-docs \"auxiliary docs in the skill folder: $aux\" \"$(printf '%s' \"$aux\" | wc -w | tr -d ' ')\"\n\n # Only a real command line counts. Prose warning against cp -R is correct content.\n n=$(grep -rhE '^[[:space:]]*cp -R.*\\.claude/skills' \"$skill_dir\" 2>/dev/null | wc -l | tr -d ' ')\n check house install-not-cp-r \"install instructions use cp -R into ~/.claude/skills\" \"$n\"\n\n # Frontmatter is only read when --- is the first byte of the file. A BOM or a\n # leading blank line loads the body with empty metadata and no error.\n if head -c 3 \"$md\" | grep -q -- '---'; then\n record PASS format frontmatter-first-line \"\"\n else\n record FAIL format frontmatter-first-line \"SKILL.md does not open with --- on line 1 (BOM or leading blank line)\"\n fi\n\n n=$(grep -rlE '(/Users/|/home/)[a-z]' \"$skill_dir\" 2>/dev/null | wc -l | tr -d ' ')\n check house no-absolute-paths \"hardcoded home path; resolve against the installed skill or project directory\" \"$n\"\n\n n=$(grep -rnE 'MCP' \"$skill_dir\" 2>/dev/null | grep -E '`[a-z][a-z0-9]*_[a-z0-9_]+`' | grep -vE 'mcp__|[A-Za-z]:[a-z]' | wc -l | tr -d ' ')\n check house mcp-tools-qualified \"MCP tool named without a Server:tool prefix\" \"$n\"\n\n fi\n\n # Authored evaluation scenarios are data, not executed tests. Validate their\n # local contract so malformed or empty cases cannot masquerade as coverage.\n if [ -f \"$skill_dir/evals/evals.json\" ]; then\n ruby -rjson -e '\n path, name = ARGV\n def fail_case(message)\n puts [\"FAIL\", \"house\", \"eval-scenarios\", message].map { |value| value.to_s.gsub(/[\\t\\r\\n]/, \" \") }.join(\"\\t\")\n exit\n end\n begin\n data = JSON.parse(File.read(path))\n rescue JSON::ParserError => e\n fail_case(\"invalid JSON: #{e.message.lines.first.strip}\")\n end\n fail_case(\"skill_name differs from folder\") unless data.is_a?(Hash) && data[\"skill_name\"] == name\n cases = data[\"evals\"]\n fail_case(\"evals must be a nonempty array\") unless cases.is_a?(Array) && !cases.empty?\n ids = []\n cases.each do |item|\n fail_case(\"case must be an object\") unless item.is_a?(Hash)\n id = item[\"id\"]\n fail_case(\"case id must be a unique positive integer\") unless id.is_a?(Integer) && id > 0 && !ids.include?(id)\n ids \u003c\u003c id\n %w[prompt expected_output].each do |field|\n value = item[field]\n fail_case(\"case #{id}: #{field} must be nonempty text\") unless value.is_a?(String) && !value.strip.empty?\n end\n %w[files assertions].each do |field|\n value = item[field]\n fail_case(\"case #{id}: #{field} must be an array of nonempty strings\") unless value.is_a?(Array) && value.all? { |v| v.is_a?(String) && !v.strip.empty? }\n end\n fail_case(\"case #{id}: missing assertions\") if item[\"assertions\"].empty?\n end\n puts [\"PASS\", \"house\", \"eval-scenarios\", \"#{cases.length} authored cases; behavior not executed\"].map { |value| value.to_s.gsub(/[\\t\\r\\n]/, \" \") }.join(\"\\t\")\n ' \"$skill_dir/evals/evals.json\" \"$name\" >>\"$RESULTS\" 2>/dev/null || record FAIL house eval-scenarios \"evaluation validation failed\"\n else\n record SKIP house eval-scenarios \"no evals/evals.json; behavior coverage not established\"\n fi\n\n if [ \"$POLICY\" = public ]; then\n # --- house style ---\n n=$(find \"$skill_dir\" -name '*.md' -exec perl -CSD -ne 'print if /\\x{2014}/' {} + 2>/dev/null | wc -l | tr -d ' ')\n check house no-em-dashes \"em dash present, restructure with commas, colons, or periods\" \"$n\"\n\n # A retired skill named in backticks is a dead route. The list lives in\n # maintenance/retired-names.tsv (name\u003cTAB>replacement) so a retirement is\n # recorded once and every stale pointer fails here instead of being grepped\n # for by hand.\n retired_file=\"$(cd \"$skill_dir/../..\" 2>/dev/null && pwd)/maintenance/retired-names.tsv\"\n if [ -f \"$retired_file\" ]; then\n stale=\"\"\n while IFS=

Agent Skills Creator Create and improve skills in the Agent Skills open format: full lifecycle from pattern selection through validation and README update. - IS: creating new agent skills and auditing or rewriting existing ones: SKILL.md, references, rules folders, scripts, evaluations. - IS NOT: AGENTS.md/CLAUDE.md instruction files (use ) or general documentation quality (use ). Choose a Mode - New skill → Creation Workflow below. - Audit, improve, or rewrite an existing skill → , which scores eleven audit dimensions, runs an ordered rewrite, then reuses Steps 5-8 for validation and shippin…

\\t' read -r rname rreplacement; do\n [ -n \"$rname\" ] || continue\n case \"$rname\" in \\#*) continue ;; esac\n if grep -rqF -- \"\\`$rname\\`\" \"$skill_dir\" --include='*.md' --include='*.json' 2>/dev/null; then\n stale=\"$stale $rname(use:${rreplacement:-none})\"\n fi\n done \u003c\"$retired_file\"\n check house no-retired-names \"names a retired skill:$stale\" \"$(printf '%s' \"$stale\" | wc -w | tr -d ' ')\"\n else\n record SKIP house no-retired-names \"no maintenance/retired-names.tsv\"\n fi\n\n # The inverse of all-md-reachable: every relative Markdown link in the skill\n # must point at a file that exists. all-md-reachable passes when SKILL.md\n # still names a file that was renamed away; this catches the rename.\n dead=\"\"\n while IFS= read -r -d '' f; do\n dir=\"$(dirname \"$f\")\"\n while IFS= read -r target; do\n [ -n \"$target\" ] || continue\n case \"$target\" in http://*|https://*|\\#*|/*|*'\u003c'*|mailto:*|...) continue ;; esac\n target=\"${target%%#*}\"\n # A bare word like `url` is a prose placeholder, not a path.\n case \"$target\" in *.*|*/*) ;; *) continue ;; esac\n [ -n \"$target\" ] || continue\n [ -e \"$dir/$target\" ] || dead=\"$dead $(basename \"$f\")->$target\"\n done \u003c \u003c(perl -ne 'next if /^\\s*```/ ... /^\\s*```/; while (/\\]\\(([^)\\s]+)\\)/g) { print \"$1\\n\" }' \"$f\")\n done \u003c \u003c(find \"$skill_dir\" -name '*.md' -print0 2>/dev/null)\n check house md-links-resolve \"link target missing:$dead\" \"$(printf '%s' \"$dead\" | wc -w | tr -d ' ')\"\n\n fi\n\n # --- repo integration ---\n repo_root=\"$(cd \"$skill_dir/../..\" 2>/dev/null && pwd)\"\n if [ -f \"$repo_root/README.md\" ] && [ -d \"$repo_root/skills\" ]; then\n { grep -Fq \"skills/$name/SKILL.md\" \"$repo_root/README.md\" || { [ \"$POLICY\" = private ] && grep -Fq \"| \\`$name\\` |\" \"$repo_root/README.md\"; }; } \\\n && record PASS house readme-bullet \"\" \\\n || record FAIL house readme-bullet \"no bullet in README.md\"\n\n if [ \"$POLICY\" = public ] && [ -f \"$repo_root/docs/skills.mdx\" ]; then\n grep -q \"skills/$name/SKILL.md\" \"$repo_root/docs/skills.mdx\" \\\n && record PASS house docs-bullet \"\" \\\n || record FAIL house docs-bullet \"no bullet in docs/skills.mdx\"\n fi\n\n # Count folders holding a SKILL.md, not raw ls: git leaves empty directories\n # behind when a skill is moved out, and those must not inflate the count.\n actual=$(find \"$repo_root/skills\" -maxdepth 2 -name SKILL.md | wc -l | tr -d ' ')\n stated=$(grep -oE '^([0-9]+) skills' \"$repo_root/README.md\" | head -1 | grep -oE '[0-9]+')\n if [ -z \"$stated\" ]; then\n record SKIP house readme-skill-count \"README states no skill count\"\n elif [ \"$stated\" = \"$actual\" ]; then\n record PASS house readme-skill-count \"\"\n else\n record FAIL house readme-skill-count \"README says $stated, skills/ holds $actual\"\n fi\n else\n record SKIP house readme-bullet \"not inside the skills repo\"\n record SKIP house readme-skill-count \"not inside the skills repo\"\n fi\n}\n\n# --- entry point ---\nroot=\"\"\ntarget=\"\"\nall=0\nwhile [ \"$#\" -gt 0 ]; do\n case \"$1\" in\n --format|--policy|--repo)\n [ \"$#\" -ge 2 ] || { echo \"Missing value for $1\" >&2; exit 2; }\n case \"$1\" in --format) FORMAT=\"$2\";; --policy) POLICY=\"$2\";; --repo) root=\"$2\"; all=1;; esac\n shift 2 ;;\n --all) all=1; shift ;;\n -*) echo \"Unknown option: $1\" >&2; exit 2 ;;\n *) [ -z \"$target\" ] || { echo \"Only one skill path is accepted\" >&2; exit 2; }; target=\"$1\"; shift ;;\n esac\ndone\ncase \"$POLICY\" in public|private) ;; *) echo \"Policy must be public or private\" >&2; exit 2;; esac\ncase \"$FORMAT\" in text|tsv) ;; *) echo \"Format must be text or tsv\" >&2; exit 2;; esac\nif { [ \"$all\" -eq 1 ] && [ -n \"$target\" ]; } || { [ \"$all\" -eq 0 ] && [ -z \"$target\" ]; }; then\n echo \"Usage: validate.sh [--format text|tsv] [--policy public|private] SKILL_PATH | --all | --repo REPO\" >&2\n exit 2\nfi\nemit() {\n [ -s \"$RESULTS\" ] || return 0\n if [ \"$FORMAT\" = tsv ]; then\n awk -v skill=\"$name\" -F'\\t' 'BEGIN { OFS=\"\\t\" } { detail=$4; for(i=5;i\u003c=NF;i++) detail=detail \" \" $i; gsub(/\\r/, \" \",detail); print skill,$1,$2,$3,detail }' \"$RESULTS\"\n else\n printf '\\n=== %s\\n' \"$name\"\n awk -F'\\t' '{ printf \" %-5s %-11s %-26s %s\\n\", $1, $2, $3, $4 }' \"$RESULTS\"\n printf ' %s FAIL, %s PASS, %s SKIP\\n' \"$(grep -c '^FAIL' \"$RESULTS\" || true)\" \"$(grep -c '^PASS' \"$RESULTS\" || true)\" \"$(grep -c '^SKIP' \"$RESULTS\" || true)\"\n fi\n if grep -q '^FAIL' \"$RESULTS\"; then any_fail=1; fi\n}\nany_fail=0\nif [ \"$all\" -eq 1 ]; then\n if [ -z \"$root\" ]; then\n here=\"$(cd \"$(dirname \"$0\")\" && pwd)\"\n root=\"$(cd \"$here/../../..\" && pwd)\"\n fi\n [ -d \"$root/skills\" ] || { echo \"Missing skills directory: $root/skills\" >&2; exit 2; }\n count=0\n for d in \"$root\"/skills/*/; do\n [ -d \"$d\" ] || continue\n [ -n \"$(find \"$d\" -type f -print -quit)\" ] || continue\n count=$((count + 1))\n : >\"$RESULTS\"\n validate_skill \"$d\"\n emit\n done\n : >\"$RESULTS\"\n name=_catalogue\n # -E UTF-8: the README holds curly quotes, and with no UTF-8 locale ruby\n # reads it as US-ASCII and String#scan raises instead of reporting.\n ruby -E UTF-8 -e '# encoding: utf-8\n root, policy = ARGV\n path = File.join(root, \"README.md\")\n unless File.file?(path)\n puts [\"FAIL\", \"house\", \"readme-bullet\", \"README.md missing\"].map { |value| value.to_s.gsub(/[\\t\\r\\n]/, \" \") }.join(\"\\t\")\n exit\n end\n text = File.read(path)\n names = text.scan(%r{skills/([a-z0-9-]+)/SKILL\\.md}).flatten\n names += text.scan(/^\\| `([a-z0-9-]+)` \\|/).flatten if policy == \"private\"\n names.uniq.each do |name|\n unless File.file?(File.join(root, \"skills\", name, \"SKILL.md\"))\n puts [\"FAIL\", \"house\", \"readme-bullet\", \"README lists missing skill #{name}\"].map { |value| value.to_s.gsub(/[\\t\\r\\n]/, \" \") }.join(\"\\t\")\n end\n end\n ' \"$root\" \"$POLICY\" >>\"$RESULTS\" || record FAIL house readme-bullet \"catalogue validation failed\"\n emit\n [ \"$count\" -gt 0 ] || { echo \"No skills found in $root\" >&2; exit 2; }\nelse\n validate_skill \"$target\"\n emit\nfi\nexit \"$any_fail\"\n","content_type":"application/x-sh; charset=utf-8","language":"bash","size":23370,"content_sha256":"71a7bb623b112c1fe8e9bfa3fe0df726d934d81e90330cd9a30dade130046789"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Agent Skills Creator","type":"text"}]},{"type":"paragraph","content":[{"text":"Create and improve skills in the Agent Skills open format: full lifecycle from pattern selection through validation and README update.","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"IS:","type":"text","marks":[{"type":"strong"}]},{"text":" creating new agent skills and auditing or rewriting existing ones: SKILL.md, references, rules folders, scripts, evaluations.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"IS NOT:","type":"text","marks":[{"type":"strong"}]},{"text":" AGENTS.md/CLAUDE.md instruction files (use ","type":"text"},{"text":"agents-md","type":"text","marks":[{"type":"code_inline"}]},{"text":") or general documentation quality (use ","type":"text"},{"text":"ghostwriter","type":"text","marks":[{"type":"code_inline"}]},{"text":").","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Choose a Mode","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"New skill → Creation Workflow below.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Audit, improve, or rewrite an existing skill → ","type":"text"},{"text":"references/improving-existing-skills.md","type":"text","marks":[{"type":"code_inline"}]},{"text":", which scores eleven audit dimensions, runs an ordered rewrite, then reuses Steps 5-8 for validation and shipping.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Simplify a skill or update a collection → same reference, plus ","type":"text"},{"text":"references/capability-delta.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" for retention decisions and the collection ledger.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Skill never triggers, triggers on the wrong prompts, or its description is being trimmed in a crowded listing → the Routing Evals section of ","type":"text"},{"text":"references/evaluation-and-iteration.md","type":"text","marks":[{"type":"code_inline"}]},{"text":", then the description. Body edits do not fix routing.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Skill stops after a first draft and hands back for review when nobody asked → \"Say Where the Work Ends\" in ","type":"text"},{"text":"references/authoring-tips.md","type":"text","marks":[{"type":"code_inline"}]},{"text":"; the fix is the scope of done and the review checkpoints, not the steps.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Reference Files","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"File","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Read When","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/capability-delta.md","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Removing generic coaching, evaluating model upgrades, or auditing a whole collection","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/authoring-tips.md","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Default when writing or cutting body content: judgement over rules, constraint calibration, permission and completion scope, degrees of freedom, content patterns, descriptions","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/skill-patterns.md","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Choosing a structural pattern","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/format-specification.md","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Directory layout, spec versus Claude Code-only frontmatter, body substitutions, loading semantics, which host reads the skill from where and what each can do, naming","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/rules-folder-structure.md","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Building a rules-based audit/lint skill","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/improving-existing-skills.md","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Auditing, scoring, simplifying, or rewriting an existing skill; the Module Lens rules for a collection audit","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/executable-code.md","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Skill includes scripts, injects live context with ","type":"text"},{"text":"!","type":"text","marks":[{"type":"code_inline"}]},{"text":", depends on packages, or invokes MCP tools","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/evaluation-and-iteration.md","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Writing ","type":"text"},{"text":"evals/evals.json","type":"text","marks":[{"type":"code_inline"}]},{"text":", testing the keep decision across models, routing tests, ablating constraints, hillclimbing a skill toward a stated goal, or reviewing a skill revision","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/adopt-adapt-author.md","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Before authoring or adopting: checking job ownership, choosing public scope, or deciding whether to vendor, adapt, or replace a third-party skill","type":"text"}]}]}]}]},{"type":"paragraph","content":[{"text":"The validator is the single local statement of mechanical gates. From the repository root:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"skills/agent-skills-creator/scripts/validate.sh skills/\u003cname> # one skill\nskills/agent-skills-creator/scripts/validate.sh --all # every skill in the repo","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Creation Workflow","type":"text"}]},{"type":"paragraph","content":[{"text":"Copy this checklist to track progress:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"text"},"content":[{"text":"Skill creation progress:\n- [ ] Step 1: Choose a pattern\n- [ ] Step 2: Create directory and frontmatter\n- [ ] Step 3: Write SKILL.md body\n- [ ] Step 4: Add reference or rule files\n- [ ] Step 5: Validate\n- [ ] Step 6: Update README.md (and docs/skills.mdx where the repo has one)\n- [ ] Step 7: Smoke-test installation\n- [ ] Step 8: Evaluate and iterate","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 1: Choose a pattern","type":"text"}]},{"type":"paragraph","content":[{"text":"Check for an existing owner of the job before creating a skill; ","type":"text"},{"text":"references/adopt-adapt-author.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" guides reuse and scope.","type":"text"}]},{"type":"paragraph","content":[{"text":"Simple/hub, workflow, rules-based, or mixed. ","type":"text"},{"text":"references/skill-patterns.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" has the shapes, the in-repo example for each, and the problem-to-pattern affinity table.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 2: Create directory and frontmatter","type":"text"}]},{"type":"paragraph","content":[{"text":"Create ","type":"text"},{"text":"skills/\u003cname>/SKILL.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" with ","type":"text"},{"text":"name","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"description","type":"text","marks":[{"type":"code_inline"}]},{"text":", the ","type":"text"},{"text":"---","type":"text","marks":[{"type":"code_inline"}]},{"text":" on line 1. Write the description as a model trigger, not a human summary: what it does, what it covers, then \"Use when...\" with the phrases users actually say, and the key use case first because the listing trims descriptions from the tail when it runs over budget. Keep it as short as it can be while still saying when it applies: every installed description sits in every session, and one that over-claims loads a skill that does not help. ","type":"text"},{"text":"validate.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":" enforces the limits, so write for routing and let the script police the constraints.","type":"text"}]},{"type":"paragraph","content":[{"text":"Decide where the skill will run before adding any other field. Use portable fields for this collection; put genuine runtime prerequisites in ","type":"text"},{"text":"compatibility","type":"text","marks":[{"type":"code_inline"}]},{"text":". Host-specific fields require current host documentation and a deliberately host-specific package. State authorization boundaries in the body when a workflow deploys, sends, or spends, and grant the safe loops just as explicitly; the body carries both sides of that envelope. The format reference distinguishes these contracts.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 3: Write SKILL.md body","type":"text"}]},{"type":"paragraph","content":[{"text":"Read ","type":"text"},{"text":"references/authoring-tips.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" first: it carries the judgement on what to include, how hard to say it, the permission and completion scope, degrees of freedom, content patterns, and progressive disclosure. Build the Gotchas section from observed failures; it is the highest-signal content in any skill.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 4: Add reference or rule files","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Workflow/mixed","type":"text","marks":[{"type":"strong"}]},{"text":": a ","type":"text"},{"text":"references/","type":"text","marks":[{"type":"code_inline"}]},{"text":" folder, each file linked from SKILL.md with a \"Read when\" condition","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Rules-based","type":"text","marks":[{"type":"strong"}]},{"text":": a ","type":"text"},{"text":"rules/","type":"text","marks":[{"type":"code_inline"}]},{"text":" folder; ","type":"text"},{"text":"references/rules-folder-structure.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" covers ","type":"text"},{"text":"_sections.md","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"_template.md","type":"text","marks":[{"type":"code_inline"}]},{"text":", and file naming","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Simple/hub","type":"text","marks":[{"type":"strong"}]},{"text":": track files alongside SKILL.md, linked from a tracks table","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Prefer a reference that is code. An existing implementation or a test suite pins a contract better than prose describing it (\"Reference-as-Spec\"). Split by loading condition, not line count: two topics read at different moments are two files.","type":"text"}]},{"type":"paragraph","content":[{"text":"Advanced, all covered in ","type":"text"},{"text":"references/executable-code.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"references/format-specification.md","type":"text","marks":[{"type":"code_inline"}]},{"text":": ","type":"text"},{"text":"scripts/","type":"text","marks":[{"type":"code_inline"}]},{"text":" for executables the agent composes, resolved relative to the installed SKILL.md; Claude Code can substitute ","type":"text"},{"text":"${CLAUDE_SKILL_DIR}","type":"text","marks":[{"type":"code_inline"}]},{"text":"; ","type":"text"},{"text":"!`command`","type":"text","marks":[{"type":"code_inline"}]},{"text":" injection for data the skill always needs at invocation (a diff, PR comments); ","type":"text"},{"text":"hooks","type":"text","marks":[{"type":"code_inline"}]},{"text":" frontmatter for a PreToolUse gate that should exist only while the skill is active; ","type":"text"},{"text":"config.json","type":"text","marks":[{"type":"code_inline"}]},{"text":" for setup context that would otherwise be re-asked every session.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 5: Validate","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"skills/agent-skills-creator/scripts/validate.sh skills/\u003cname>","type":"text"}]},{"type":"paragraph","content":[{"text":"Output separates ","type":"text"},{"text":"format","type":"text","marks":[{"type":"strong"}]},{"text":" requirements from ","type":"text"},{"text":"house","type":"text","marks":[{"type":"strong"}]},{"text":" conventions, including recommendations adopted as local gates. Fix every FAIL. Run ","type":"text"},{"text":"skills-ref validate \u003cdir>","type":"text","marks":[{"type":"code_inline"}]},{"text":" for an independent metadata and naming check. Neither check establishes behavioral quality or compatibility with every host.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 6: Update README.md","type":"text"}]},{"type":"paragraph","content":[{"text":"Add the skill's bullet under the matching category heading and bump the count; ","type":"text"},{"text":"validate.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":" checks both and names what is missing. Where the repo also ships ","type":"text"},{"text":"docs/skills.mdx","type":"text","marks":[{"type":"code_inline"}]},{"text":", add the same bullet there.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 7: Smoke-test","type":"text"}]},{"type":"paragraph","content":[{"text":"When installation behavior changed, install the edited local source into a disposable target using the installer's documented local-source options. Verify the loaded SKILL.md and a bundled reference or script against the working copy. Do not overwrite a global installation to smoke-test an edit, and do not install the remote default branch as evidence for unpushed changes.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 8: Evaluate and iterate","type":"text"}]},{"type":"paragraph","content":[{"text":"references/evaluation-and-iteration.md","type":"text","marks":[{"type":"code_inline"}]},{"text":". Write 2-3 scenarios in ","type":"text"},{"text":"evals/evals.json","type":"text","marks":[{"type":"code_inline"}]},{"text":", add assertions after the first run, and measure with-skill against without-skill in fresh sessions. That comparison is the keep test: the skill must improve the job enough to justify its cost. Test routing separately with should-trigger and near-miss prompts. Test on each target model, and ablate any rule you suspect is dead weight: delete it, rerun the scenarios, keep it only if one regresses. Chasing a goal past one round is The Hillclimb Loop in that reference, run with the agent-evals CLI.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Gotchas","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"The installed copy under ","type":"text"},{"text":"~/.agents/skills/\u003cname>/","type":"text","marks":[{"type":"code_inline"}]},{"text":" is a copy, not a link to your repo. Editing the repo changes nothing in a running session, and the stale copy loads silently, so a skill can be several commits behind while appearing correct. Verify that an evaluation loads the edited local source.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"A reference-chain failure calls for moving the load condition into SKILL.md, not disguising the same dependency with different wording.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"--agent","type":"text","marks":[{"type":"code_inline"}]},{"text":" on ","type":"text"},{"text":"skills add","type":"text","marks":[{"type":"code_inline"}]},{"text":" is variadic and space-separated (","type":"text"},{"text":"--agent codex cursor","type":"text","marks":[{"type":"code_inline"}]},{"text":"); it consumes arguments until the next one starting with ","type":"text"},{"text":"-","type":"text","marks":[{"type":"code_inline"}]},{"text":". A comma-separated list is validated element-wise and rejected whole as one invalid name. Do not conclude from an empty ","type":"text"},{"text":"~/.codex/skills","type":"text","marks":[{"type":"code_inline"}]},{"text":" that the install failed: any agent whose ","type":"text"},{"text":"skillsDir","type":"text","marks":[{"type":"code_inline"}]},{"text":" is ","type":"text"},{"text":".agents/skills","type":"text","marks":[{"type":"code_inline"}]},{"text":" is treated as universal and installed to ","type":"text"},{"text":"~/.agents/skills/","type":"text","marks":[{"type":"code_inline"}]},{"text":", which those agents read directly.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"toc-over-100-lines","type":"text","marks":[{"type":"code_inline"}]},{"text":" wants ","type":"text"},{"text":"## Contents","type":"text","marks":[{"type":"code_inline"}]},{"text":" inside the first 20 lines of any reference over 100 lines. A Contents heading further down does not count, so the file fails while looking fine.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"A description that omits \"Use when\" fails ","type":"text"},{"text":"description-triggers","type":"text","marks":[{"type":"code_inline"}]},{"text":" outright, but a description that has the phrase and the wrong trigger words fails nothing and simply never routes. The validator cannot see this; only a routing eval can.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"description-length","type":"text","marks":[{"type":"code_inline"}]},{"text":" passes anything under 1024 characters, and a collection of descriptions that each pass can still overrun the host's listing budget together, at which point the host shortens every one of them and the \"Use when\" clauses go first. Judge a description in the listing next to its siblings, not alone.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"A step reading \"stop here and present the result for review\" ends the task on current frontier models even when the user asked for the whole job and is not watching. The step reads as a safety rule, so it is rarely questioned during a constraint cut, and the skill ships stopping one implementation short.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Anti-patterns","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Dumping the full specification into the SKILL.md body instead of a reference file","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Time-sensitive content (\"before August 2025, use...\"), including model names as the reason a rule exists","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"A ","type":"text"},{"text":"context: fork","type":"text","marks":[{"type":"code_inline"}]},{"text":" skill whose body is guidelines rather than a task; the subagent gets conventions and no prompt, and returns nothing","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Vague names (","type":"text"},{"text":"helper","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"utils","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"tools","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"documents","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"data","type":"text","marks":[{"type":"code_inline"}]},{"text":") that give the model nothing to route on","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Related Skills","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"agents-md","type":"text","marks":[{"type":"code_inline"}]},{"text":" for auditing AGENTS.md/CLAUDE.md instruction files","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"ghostwriter","type":"text","marks":[{"type":"code_inline"}]},{"text":" for documentation quality","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Maintenance only: ","type":"text"},{"text":"evals/evals.json","type":"text","marks":[{"type":"code_inline"}]},{"text":" holds the behavioural scenarios and routing prompts for anyone changing this skill. It never loads during a user task, which is the baseline Phase A of ","type":"text"},{"text":"references/improving-existing-skills.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" asks for.","type":"text"}]}]},"metadata":{"date":"2026-11-02","name":"agent-skills-creator","author":"@skillopedia","source":{"stars":180,"repo_name":"agent-skills","origin_url":"https://github.com/mblode/agent-skills/blob/HEAD/skills/agent-skills-creator/SKILL.md","repo_owner":"mblode","body_sha256":"336699e656848c5dc58dea875705e25adea533acddf595de0b024abf3bfcada8","cluster_key":"2c053531aa24f0bead7b5f0b048b1673d4279098518996812d20aae009746811","clean_bundle":{"format":"clean-skill-bundle-v1","source":"mblode/agent-skills/skills/agent-skills-creator/SKILL.md","text_bytes":113827,"source_commit":"391508702523088f564fecfdd95ce76304efb117","skills_sh_rank":13054,"attachment_count":11,"text_attachments":11,"attachment_storage":"skill_attachments","binary_attachments":0},"cluster_size":1,"skill_md_path":"skills/agent-skills-creator/SKILL.md","import_metadata":{"date":"2026-11-02","author":"@skillopedia","version":"v1","category":"general","category_label":"General"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"general","import_tag":"skills-sh-top20k-2026-11","description":"Creates and improves portable Agent Skills with a validator, routing scenarios, and evidence-based keep, cut, merge, or retire decisions. Use when asked to \"write a skill\", \"update all skills\", \"audit my SKILL.md\", \"remove redundant instructions\", or fix skill triggering.","compatibility":"Repository validation requires Bash, Ruby with YAML and JSON, Perl, and standard Unix utilities."}},"renderedAt":1793666503193}

Agent Skills Creator Create and improve skills in the Agent Skills open format: full lifecycle from pattern selection through validation and README update. - IS: creating new agent skills and auditing or rewriting existing ones: SKILL.md, references, rules folders, scripts, evaluations. - IS NOT: AGENTS.md/CLAUDE.md instruction files (use ) or general documentation quality (use ). Choose a Mode - New skill → Creation Workflow below. - Audit, improve, or rewrite an existing skill → , which scores eleven audit dimensions, runs an ordered rewrite, then reuses Steps 5-8 for validation and shippin…