Claude Skill

skill-writing

Imported from paulrberg/agent-skills/skills/skill-writing.

LLM Mart · 0 points · 0 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download paulrberg-agent-skills-skills_skill-writing-913232a.zip · 12 KB
Part of paulrberg/agent-skills — 42 skills

Install

skills CLI npx skills add https://github.com/PaulRBerg/agent-skills/tree/main/skills/skill-writing
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install paulrberg-agent-skills@llmmart
Git git clone https://github.com/PaulRBerg/agent-skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole paulrberg/agent-skills collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Skill Writing

Bootstrap a project-local skill in .agents/skills/, expose it to Claude Code through a relative symlink, and verify the result with the repository's canonical skill validator.

Model Guidance

Optimize every new skill and its content for GPT-6.1 Sol and Claude Opus 5.5. The summaries below are reminders, not substitutes for the live guides. Read both guides before designing or writing a complex, long-running, multi-tool, or orchestration-heavy skill because their recommendations may evolve.

  • GPT-6.1 Sol prompting guidance (shared GPT-6 guide; evaluate its family-wide recommendations on Sol): Complete authorized work under stated assumptions; make user-instruction precedence over skills explicit; specify writing and delegation preferences; and keep verification proportional to the change.
  • Claude Opus 5.5 prompting guidance: Calibrate effort instead of prompting for more thinking; never ask for reasoning in response text; name the premature stops to avoid and the stops that are wanted; treat text-only turns as reports, not completion; request brief progress updates; explore relevant sources before acting; and name concrete patterns to avoid instead of generic style advice.

Input

  • skill-name (optional): a kebab-case name such as my-skill. If omitted, derive the shortest unambiguous kebab-case domain name for the skill's purpose, without repeating the repository or app name as context (for example price-estimator, not budget-price-estimator), and state the derived name in the completion report. Stop only when a supplied name is invalid or collides with an existing skill (see the collision check in step 2).

Reject --global, explicit destination paths, and other scope overrides. The invocation working directory is the only supported scope.

Workflow

1. Apply the Repository Catalog Guard

Before resolving project-local paths, read the repository instructions applicable to the invocation working directory. If they define a skill source catalog and lifecycle, stop this workflow and follow that repository-owned workflow. Do not create .agents/skills/ or .claude/skills/ paths there.

2. Resolve and Validate the Local Scope

Set <scope> to the working directory where the skill was invoked. Create the source at <scope>/.agents/skills/<name>/ and the Claude Code symlink at <scope>/.claude/skills/<name>. Do not redirect the scope to the repository root when invoked from a nested project or workspace. Never create or modify a skill under ~/.agents, ~/.claude, ~/.codex, or another global installation directory.

The symlink target is always the relative path ../../.agents/skills/<name>.

Reject a collision before writing: stop if either the source directory or symlink path already exists.

3. Read the Current Format Sources

Resolve scripts/fetch-agentskills-spec.sh relative to this skill directory. Run scripts/fetch-agentskills-spec.sh [--refresh] once and read the returned file completely. The helper reuses an integrity-valid specification for 24 hours, conditionally revalidates older entries, and may return a cache validated within seven days when live retrieval fails. Set AGENTSKILLS_CACHE_DIR when the default user cache location is unavailable or unwritable.

Use --refresh for explicitly latest or change-sensitive work, disputed portable-format guidance, or a conflict with validator behavior. A stale result is usable only after reading it; disclose its validation timestamp and retrieval failure in the completion report. If the helper cannot return a valid file, stop before writing. Never fetch the agentskills.io specification directly or create its cache in a repository or skill installation.

Fetch the current Claude Code frontmatter reference with WebFetch. Confirm field shapes, naming rules, and progressive-disclosure conventions from both sources; do not guess because the formats evolve.

4. Define the Contract and Layout

Read references/writing-great-skills.md completely before choosing the contract or layout. It defines the authoring principles, content-routing thresholds, helper runtime defaults, and communication contract.

Define the contract and identify every skill the workflow requires, invokes, or hands off to on any supported branch. Suggestions, examples, related-skill references, and underlying tool capabilities are not dependencies. Create only the directories justified by the selected layout; SKILL.md and agents/openai.yaml are always required.

5. Create the Skill

mkdir -p "<scope>/.agents/skills/<name>/agents"
# Add only the subdirectories the layout calls for:
# mkdir -p "<scope>/.agents/skills/<name>/scripts"
# mkdir -p "<scope>/.agents/skills/<name>/references"

Write <scope>/.agents/skills/<name>/SKILL.md with:

  • Frontmatter sorted alphabetically, with description last. Front-load discovery-time trigger phrases in description.

  • A skill-dependencies array when routing identified dependencies. Use bare names for skills in the same repository and ORG/REPO#SKILL for external skills. Sort by the target skill name (the bare name or substring after #), then by the complete identifier. Require unique strings, resolve every bare dependency in the same repository, and exclude the owning skill as a bare dependency. External repository existence is not validated. Omit the field when no dependencies exist.

  • A short # Title.

  • A one-line summary of what the skill does.

  • Add disable-model-invocation: true or user-invocable: false only when the skill differs from Claude's defaults. Omit disable-model-invocation: false and user-invocable: true because absence already expresses those values.

  • Set coordination: exempt only when the skill's declared default workflow writes no repository files or only repository metadata. When selected, add this ordinary prose declaration to the new skill's body; the fence below is documentation for this authoring skill, not its own declaration:

    This skill is coordination-exempt: skip the ai-coord gate for its declared work.
    

    Explicitly authorized escalation beyond the declared behavior re-enters the gate.

  • ## Arguments (if any) and a lean imperative workflow. Use fixed steps only when order matters; otherwise state the contract and let repository evidence guide execution.

  • Explicit links to every references/ file the workflow may need, each with a one-line note describing when to read it.

  • CLI signatures for every bundled helper, including arguments, output, defaults, and the runtime command, so an agent can invoke it without reading its source.

Use imperative prose and resolve bundled references/, scripts/, examples/, and assets/ paths relative to the owning skill directory. Do not add repository-style support files or authoring artifacts that runtime agents will not use. Quote YAML plain scalars containing a colon followed by a space; otherwise the frontmatter parser may reject them.

Write <scope>/.agents/skills/<name>/agents/openai.yaml with:

policy:
  allow_implicit_invocation: true

Set allow_implicit_invocation to the inverse of SKILL.md disable-model-invocation. If later adding Codex UI metadata or MCP/tool dependencies, merge them into the same file and keep the policy.

6. Create the Claude Code Symlink

Always create a relative symlink so Claude Code picks the skill up from its own discovery path:

mkdir -p "<scope>/.claude/skills"
ln -s "../../.agents/skills/<name>" "<scope>/.claude/skills/<name>"

7. Verify and Report

  • Patch tooling creates files at mode 0644. Before the first verification run, chmod 755 every executable under scripts/ and tests/ (a scaffolded test failing its first run with Permission denied (os error 13) is this cause).
  • test -f "<scope>/.agents/skills/<name>/SKILL.md"
  • test -f "<scope>/.agents/skills/<name>/agents/openai.yaml"
  • readlink "<scope>/.claude/skills/<name>" equals ../../.agents/skills/<name>, and the link resolves to the source directory.
  • test -x every scripts/* and tests/* executable so a missed chmod fails loudly instead of surfacing later as a permission error.
  • ai-skillet doctor --root "<scope>/.agents/skills/<name>" exits 0. This is the canonical local schema and policy gate.
  • Finish with ### 🧩 Skill created: <name>, a tree of created paths, and ### ✅ Verified with the exact checks. Link files by their absolute .agents/skills/<name>/ source paths, never through the .claude/skills/<name> symlink.
  • Commit when the request or standing instructions authorize it; otherwise offer to commit. Do not ask again for authorization already given.

Keep helper stdout, commands, paths, frontmatter, and generated skill content undecorated unless the new skill's output contract requires otherwise.

Files (agent-skills)
  • agents
    • openai.yaml 42 B
      policy:
        allow_implicit_invocation: true
      
  • references
    • writing-great-skills.md 11.8 KB
      # Writing Great Skills
      
      Compact authoring guidance adapted from Matt Pocock's
      [writing-great-skills](https://github.com/mattpocock/skills/tree/main/skills/productivity/writing-great-skills)
      (SKILL.md + GLOSSARY.md).
      
      A skill makes a stochastic system reliably satisfy an observable contract. Predictability means reaching the intended
      outcome while preserving the contract, not following an identical path.
      
      ## Contents
      
      - [Observable contract](#define-the-observable-contract)
      - [Self-containment](#keep-independently-installed-skills-self-contained)
      - [Context and invocation](#spend-context-deliberately)
      - [Frontmatter dialect](#frontmatter-dialect)
      - [Representation and routing](#choose-the-smallest-useful-representation)
      - [Execution](#write-for-reliable-execution)
      - [Background reporting](#design-background-reporting)
      - [Presentation](#keep-presentation-substantive)
      
      ## Define the Observable Contract
      
      Write the smallest interface that makes success checkable:
      
      - **Outcome**: the state or artifact the user should receive.
      - **Invariants**: rules that must hold on every valid path.
      - **Preferred defaults**: opinionated choices that explicit user intent or repository evidence may override.
      - **Authority**: which reads, local writes, external writes, and destructive actions are allowed or gated.
      - **Routing**: prerequisites, tools, scripts, and conditional references needed for each branch.
      - **Stop conditions**: states that require a different workflow, missing authority, or user-owned input.
      - **User communication**: the kickoff, progress, decision, blocker, and completion events worth surfacing, with the
        smallest useful output shape for each.
      - **Completion evidence**: the command, inspection, or artifact that proves the outcome.
      
      Let the agent choose the path inside that contract. Prescribe a sequence only when ordering is safety-critical, a
      prerequisite determines the next action, or a deterministic helper is the simpler interface.
      
      Make completion criteria both checkable and demanding enough to force the required legwork. Prefer criteria such as
      "every modified model accounted for and the scoped check passes" over subjective states such as "understanding reached."
      
      ## Keep Independently Installed Skills Self-Contained
      
      Put reusable guidance in the owning skill and discover target-project conventions at runtime. Do not share references
      across skills or depend on another repository unless that repository is required to perform the task.
      
      ## Spend Context Deliberately
      
      Every skill pays one of two costs:
      
      - **Context load** — a model-invoked skill's `description` sits in the agent's context window every turn, spending
        tokens and attention.
      - **Cognitive load** — a user-invoked skill is invisible to the agent; the human must remember when to invoke it. Spend
        this where human judgment matters.
      
      Choose:
      
      - **Model-invoked** (omit `disable-model-invocation`): the agent and other skills can reach it. Write a model-facing
        description with one trigger phrase per distinct branch.
      - **User-invoked** (`disable-model-invocation: true`): disable automatic model selection. Its description becomes a
        human-facing one-line summary. An explicitly authorized workflow may still load its instructions through supported
        host mechanisms; absence from automatic discovery does not prove it is unavailable.
      
      Inline what every branch needs. Route conditional detail directly from `SKILL.md`; the wording of the link must say when
      to read it. Co-locate a concept's definition, rules, and caveats. Keep each meaning in one authoritative place.
      
      Judge context economy relative to the current target models: remove a sentence when it does not change their behavior,
      and resolve disagreements with representative runs rather than intuition. Prune descriptions hardest because they may
      load on every turn.
      
      Prefer domain-first capability names such as `large-file-refactor`; keep memorable verb-based exceptions when clearer.
      Use familiar domain terms from the user's prompts, docs, and code. Give a model-facing description one trigger per
      distinct branch, without repeating identity already in the body.
      
      ## Frontmatter Dialect
      
      `ai-skillet doctor` accepts an extended top-level field union:
      
      - Portable: `name`, `description`, `license`, `compatibility`, `metadata`, `allowed-tools`.
      - Claude Code: `when_to_use`, `argument-hint`, `arguments`, `disable-model-invocation`, `user-invocable`,
        `disallowed-tools`, `model`, `effort`, `context`, `agent`, `background`, `hooks`, `paths`, `shell`.
      - Repository: `coordination`, `skill-dependencies`.
      
      Unknown fields are errors. `metadata` maps strings to strings; tool, argument, and path fields accept strings or string
      lists; `hooks` is a mapping. `effort` accepts `low`, `medium`, `high`, `xhigh`, or `max`; `context` accepts only `fork`;
      `shell` accepts `bash` or `powershell`. `agent` and `background` require `context: fork`. The entrypoint defines
      invocation defaults and dependency policy.
      
      Use portable-only validators such as `skills-ref` or `agentskills` only when a distribution target explicitly requires
      the strict portable format; they do not replace the canonical local gate.
      
      ## Choose the Smallest Useful Representation
      
      | Content                                                              | Put it in                    | Decision rule                                                                |
      | -------------------------------------------------------------------- | ---------------------------- | ---------------------------------------------------------------------------- |
      | Intent, authority, routing, exceptions, evidence judgment            | `SKILL.md`                   | The model must interpret it on every applicable path.                        |
      | Deterministic computation, parsing, formatting, validation, recovery | `scripts/`                   | Repetition, exactness, or failure handling justifies code.                   |
      | Closed structural shape                                              | Schema plus validator        | Types, required fields, enums, and relationships are mechanically checkable. |
      | Conditional detail, long examples, API or schema documentation       | `references/` or `examples/` | Only some branches need the context.                                         |
      | Templates, media, or files copied into output                        | `assets/`                    | Runtime uses the file without loading it as instructions.                    |
      
      Prefer one deep helper with a small interface over scripts that mirror prose steps. Keep the caller-visible invariant in
      prose, document the CLI and compact result, and leave the implementation algorithm in code. A helper earns its place
      when logic is repeated, deterministic, exact, or recovery-heavy; a shell pipeline past roughly five lines, real error
      handling, or a recurring long heredoc is a strong signal.
      
      Use TypeScript through `bun run scripts/<name>.ts` by default. Use Python through `uv run scripts/<name>.py` when it
      better fits data, text, or file processing. Keep Bash compatible with macOS `/bin/bash` 3.2. Scripts save context only
      when normal runs do not require reading their source and stdout stays compact.
      
      Aim for `SKILL.md` under 500 lines; move sections past roughly 50 lines when they are not core workflow. Move prose,
      examples, or schema documentation past roughly 100 lines into a reference when not core to every branch. Link references
      directly from `SKILL.md`, one level deep, with a routing sentence. Add a table of contents to references over 100 lines;
      for files over 10,000 words, give targeted search patterns in `SKILL.md`. Keep a required rule inline if a direct
      pointer still fails to route reliably.
      
      Bundle a schema only with a real validation route. Keep semantic meaning and permissions in prose. Put output templates
      in `assets/`, and omit repository-style support files, scratch artifacts, and authoring notes that runtime agents do not
      use.
      
      ## Write for Reliable Execution
      
      State outcomes, invariants, and completion evidence as positive, observable acceptance criteria. Keep a negative
      instruction only for an explicit user exclusion or when it is the clearest concise guard against a consequential safety,
      authority, destructive-action, scope, or likely model-failure boundary.
      
      If a workflow completes prematurely, sharpen its completion criterion first; split later steps behind a real context
      boundary only when observed behavior still justifies it.
      
      Make authority and follow-through concrete:
      
      - State that explicit user instructions take precedence over skill defaults. Carry established approvals forward;
        preserve host restrictions and required approval for destructive or external actions.
      - Resolve discoverable facts before asking. Use stated assumptions for routine reversible choices; ask when missing
        user-owned input would change scope, safety, or the intended outcome, and continue independent work.
      - Before requesting approval, prepare the concrete result the user must review within existing authority. When a skill
        rule causes a pause, identify the rule and the action still lacking authorization.
      - Finish authorized work through its required validation. Progress summaries, offers to continue, and milestones do not
        establish completion. Name real stop conditions, including read-only scope, hard limits, and missing authority.
      
      Choose the smallest checks that prove the changed behavior and satisfy repository requirements. Add regression tests for
      meaningful failure modes, not tests that mirror a reversible text or configuration edit. Reuse passing evidence while
      its inputs remain unchanged; broaden or repeat checks only for new edits, failures, or unresolved risk.
      
      Specify delegation when it helps: independent scopes, dependencies, write ownership, and one owner for aggregate checks.
      Use the smallest effective team, honor the user's delegation preference and host limits, and keep dependent mutations
      sequential. A file-count threshold alone is not a reason to delegate.
      
      ## Design Background Reporting
      
      When a skill launches background jobs or agents, decide whether the wait may be long or opaque from expected runtime and
      uncertainty, fan-out or waves, meaningful milestones, and the state already visible in the host. Do not use a universal
      time cutoff.
      
      Make the main agent own monitoring and user reporting until every required unit settles. Announce the units or scope in
      flight and the evidence that will prove completion. Reuse a host-native progress surface only when it exposes meaningful
      live state; otherwise report observed phase changes and milestones, with sparse factual updates during quiet periods.
      
      Never infer completion from elapsed time, event counts, or activity. Use a progress bar or percentage only with an exact
      settled/total denominator. Finish with a compact report distinguishing completed, blocked, failed, and timed-out units,
      their evidence, and the next action.
      
      ## Keep Presentation Substantive
      
      Lead with the outcome and keep the output shape proportional to the information:
      
      - Prefer concise, direct prose for simple results. Add headings, lists, and tables when they clarify the information; do
        not require a multi-section report for a one-line outcome. Honor the user's requested format.
      - Use `🔎` preview/read-only, `⏳` running, `✅` verified success, `⚠️` caveat/approval/risk, `⛔` blocked/not written,
        `❓` unknown, and `↩` reverted/rolled back consistently; pair every status symbol with text.
      - Use at most one non-status domain icon per heading. Reserve tables for repeated fields, trees for real structure, and
        progress bars for measured numerators and denominators.
      - Keep commands, machine-readable output, identifiers, confirmation tokens, diagnostics, safety wording, and copied
        downstream content undecorated.
      - Keep decoration in the reporting wrapper unless the requested artifact calls for it; do not inject emoji into code,
        product copy, user prose, external contributions, or structured data by default.
      
  • scripts
    • fetch-agentskills-spec.sh 8.7 KB
      #!/bin/bash
      
      set -euo pipefail
      
      fresh_limit_seconds=86400
      stale_limit_seconds=604800
      lock_wait_seconds=35
      stale_lock_seconds=60
      
      artifact=specification
      source_url='https://agentskills.io/specification.md'
      body_name='specification.md'
      
      usage() {
        cat >&2 <<'EOF'
      Usage: fetch-agentskills-spec.sh [--refresh]
      
      Reuse a fresh cached agentskills.io specification and revalidate older content.
      Prints the absolute cached file path on stdout.
      EOF
      }
      
      die() {
        printf 'agentskills.io: %s\n' "$1" >&2
        exit "${2:-1}"
      }
      
      refresh=false
      if [ "${1:-}" = '--refresh' ]; then
        refresh=true
        shift
      fi
      
      if [ "$#" -ne 0 ]; then
        usage
        exit 64
      fi
      
      umask 077
      
      if [ -n "${AGENTSKILLS_CACHE_DIR:-}" ]; then
        cache_root=$AGENTSKILLS_CACHE_DIR
      elif [ -n "${XDG_CACHE_HOME:-}" ]; then
        cache_root=$XDG_CACHE_HOME/agentskills.io
      elif [ "$(uname -s)" = 'Darwin' ]; then
        [ -n "${HOME:-}" ] || die 'HOME is required to resolve the cache directory'
        cache_root=$HOME/Library/Caches/agentskills.io
      else
        [ -n "${HOME:-}" ] || die 'HOME is required to resolve the cache directory'
        cache_root=$HOME/.cache/agentskills.io
      fi
      
      mkdir -p "$cache_root" || die "cannot create cache directory: $cache_root"
      cache_root=$(cd "$cache_root" && pwd -P) || die "cannot resolve cache directory: $cache_root"
      
      body_file=$cache_root/$body_name
      metadata_file=$cache_root/$artifact.meta
      lock_dir=$cache_root/$artifact.lock
      
      headers_tmp=''
      body_tmp=''
      metadata_tmp=''
      lock_owned=false
      
      cleanup() {
        if [ -n "$headers_tmp" ]; then
          rm -f "$headers_tmp"
        fi
        if [ -n "$body_tmp" ]; then
          rm -f "$body_tmp"
        fi
        if [ -n "$metadata_tmp" ]; then
          rm -f "$metadata_tmp"
        fi
        if [ "$lock_owned" = true ]; then
          rmdir "$lock_dir" 2>/dev/null || true
        fi
      }
      
      trap cleanup EXIT
      trap 'exit 129' HUP
      trap 'exit 130' INT
      trap 'exit 143' TERM
      
      lock_attempt=0
      while ! mkdir "$lock_dir" 2>/dev/null; do
        now_epoch=$(date -u +%s)
        lock_epoch=$(stat -f '%m' "$lock_dir" 2>/dev/null || stat -c '%Y' "$lock_dir" 2>/dev/null || printf '0\n')
        case "$lock_epoch" in
          ''|*[!0-9]*) lock_epoch=0 ;;
        esac
      
        if [ "$lock_epoch" -gt 0 ] && [ $((now_epoch - lock_epoch)) -gt "$stale_lock_seconds" ]; then
          if rmdir "$lock_dir" 2>/dev/null; then
            continue
          fi
        fi
      
        lock_attempt=$((lock_attempt + 1))
        if [ "$lock_attempt" -ge "$lock_wait_seconds" ]; then
          die "cache lock remained busy for $lock_wait_seconds seconds: $artifact"
        fi
        sleep 1
      done
      lock_owned=true
      
      metadata_value() {
        local key=$1
        local file=$2
      
        [ -f "$file" ] || return 1
        sed -n "s/^${key}=//p" "$file" | sed -n '1p'
      }
      
      validate_body() {
        local file=$1
        local byte_count
      
        [ -f "$file" ] || return 1
        byte_count=$(wc -c <"$file" | tr -d '[:space:]')
        case "$byte_count" in
          ''|*[!0-9]*) return 1 ;;
        esac
        [ "$byte_count" -ge 1024 ] || return 1
        grep -Fq -- '# Specification' "$file" || return 1
        grep -Fq -- "## \`SKILL.md\` format" "$file"
      }
      
      allowed_effective_url() {
        [ "$1" = "$source_url" ]
      }
      
      final_header_value() {
        local header_name=$1
        local file=$2
      
        awk -v wanted="$header_name" '
          /^HTTP\// { value = "" }
          {
            line = $0
            sub(/\r$/, "", line)
            separator = index(line, ":")
            if (separator > 0 && tolower(substr(line, 1, separator - 1)) == tolower(wanted)) {
              value = substr(line, separator + 1)
              sub(/^[[:space:]]+/, "", value)
            }
          }
          END { print value }
        ' "$file"
      }
      
      write_metadata() {
        local effective_url=$1
        local etag=$2
        local last_modified=$3
        local validated_epoch=$4
        local validated_utc=$5
      
        metadata_tmp=$(mktemp "$cache_root/.fetch-agentskills-spec.metadata.XXXXXX")
        {
          printf 'format=1\n'
          printf 'effective_url=%s\n' "$effective_url"
          printf 'etag=%s\n' "$etag"
          printf 'last_modified=%s\n' "$last_modified"
          printf 'validated_at_epoch=%s\n' "$validated_epoch"
          printf 'validated_at_utc=%s\n' "$validated_utc"
        } >"$metadata_tmp"
        mv -f "$metadata_tmp" "$metadata_file"
        metadata_tmp=''
      }
      
      current_format=$(metadata_value format "$metadata_file" 2>/dev/null || true)
      current_effective_url=$(metadata_value effective_url "$metadata_file" 2>/dev/null || true)
      current_etag=$(metadata_value etag "$metadata_file" 2>/dev/null || true)
      current_last_modified=$(metadata_value last_modified "$metadata_file" 2>/dev/null || true)
      current_validated_epoch=$(metadata_value validated_at_epoch "$metadata_file" 2>/dev/null || true)
      current_validated_utc=$(metadata_value validated_at_utc "$metadata_file" 2>/dev/null || true)
      
      have_valid_cache=false
      if [ "$current_format" = 1 ] && [ -n "$current_validated_utc" ] && \
        allowed_effective_url "$current_effective_url" && validate_body "$body_file"; then
        case "$current_validated_epoch" in
          ''|*[!0-9]*) ;;
          *) have_valid_cache=true ;;
        esac
      fi
      
      cache_age=''
      if [ "$have_valid_cache" = true ]; then
        now_epoch=$(date -u +%s)
        cache_age=$((now_epoch - current_validated_epoch))
      fi
      
      if [ "$refresh" = false ] && [ "$have_valid_cache" = true ] && \
        [ "$cache_age" -ge 0 ] && [ "$cache_age" -le "$fresh_limit_seconds" ]; then
        printf 'agentskills.io: cached %s last validated at %s (%s)\n' \
          "$artifact" "$current_validated_utc" "$current_effective_url" >&2
        printf '%s\n' "$body_file"
        exit 0
      fi
      
      headers_tmp=$(mktemp "$cache_root/.fetch-agentskills-spec.headers.XXXXXX")
      body_tmp=$(mktemp "$cache_root/.fetch-agentskills-spec.body.XXXXXX")
      
      response_code=''
      effective_url=''
      
      fetch_once() {
        local conditional=$1
        local curl_output
        local curl_rc
        local curl_args
      
        : >"$headers_tmp"
        : >"$body_tmp"
      
        curl_args=(
          --connect-timeout 10
          --dump-header "$headers_tmp"
          --fail
          --location
          --max-time 30
          --output "$body_tmp"
          --proto '=https'
          --proto-redir '=https'
          --show-error
          --silent
          --write-out '%{http_code}\n%{url_effective}\n'
        )
      
        if [ "$conditional" = true ] && [ -n "$current_etag" ]; then
          curl_args+=(--header "If-None-Match: $current_etag")
        elif [ "$conditional" = true ] && [ -n "$current_last_modified" ]; then
          curl_args+=(--header "If-Modified-Since: $current_last_modified")
        fi
      
        set +e
        curl_output=$(curl "${curl_args[@]}" "$source_url")
        curl_rc=$?
        set -e
        if [ "$curl_rc" -ne 0 ]; then
          return 1
        fi
      
        response_code=$(printf '%s\n' "$curl_output" | sed -n '1p')
        effective_url=$(printf '%s\n' "$curl_output" | sed -n '2p')
        return 0
      }
      
      print_success() {
        local cache_state=$1
        local validated_utc=$2
        local final_url=$3
      
        printf 'agentskills.io: %s %s at %s (%s)\n' \
          "$cache_state" "$artifact" "$validated_utc" "$final_url" >&2
        printf '%s\n' "$body_file"
      }
      
      use_stale_cache() {
        local now_epoch
        local stale_age
      
        [ "$refresh" = false ] || return 1
        [ "$have_valid_cache" = true ] || return 1
      
        now_epoch=$(date -u +%s)
        stale_age=$((now_epoch - current_validated_epoch))
        [ "$stale_age" -ge 0 ] || return 1
        [ "$stale_age" -le "$stale_limit_seconds" ] || return 1
      
        printf 'agentskills.io: stale %s last validated at %s (%s); live retrieval failed\n' \
          "$artifact" "$current_validated_utc" "$current_effective_url" >&2
        printf '%s\n' "$body_file"
        return 0
      }
      
      conditional=false
      if [ "$refresh" = false ] && [ "$have_valid_cache" = true ]; then
        if [ -n "$current_etag" ] || [ -n "$current_last_modified" ]; then
          conditional=true
        fi
      fi
      
      if ! fetch_once "$conditional"; then
        if [ "$refresh" = true ]; then
          die "forced refresh failed for $artifact"
        fi
        if use_stale_cache; then
          exit 0
        fi
        die "could not retrieve $artifact and no cache validated within seven days is available"
      fi
      
      if ! allowed_effective_url "$effective_url"; then
        die "refused unexpected final URL for $artifact: $effective_url"
      fi
      
      if [ "$response_code" = 304 ]; then
        if [ "$have_valid_cache" != true ]; then
          if ! fetch_once false; then
            die "received 304 for unusable $artifact cache and unconditional retrieval failed"
          fi
          if ! allowed_effective_url "$effective_url"; then
            die "refused unexpected final URL for $artifact: $effective_url"
          fi
        else
          validated_epoch=$(date -u +%s)
          validated_utc=$(date -u '+%Y-%m-%dT%H:%M:%SZ')
          write_metadata "$effective_url" "$current_etag" "$current_last_modified" "$validated_epoch" "$validated_utc"
          print_success revalidated "$validated_utc" "$effective_url"
          exit 0
        fi
      fi
      
      if [ "$response_code" != 200 ]; then
        die "unexpected HTTP status for $artifact: $response_code"
      fi
      
      if ! validate_body "$body_tmp"; then
        die "retrieved invalid content for $artifact"
      fi
      
      new_etag=$(final_header_value ETag "$headers_tmp")
      new_last_modified=$(final_header_value Last-Modified "$headers_tmp")
      validated_epoch=$(date -u +%s)
      validated_utc=$(date -u '+%Y-%m-%dT%H:%M:%SZ')
      
      mv -f "$body_tmp" "$body_file"
      body_tmp=''
      write_metadata "$effective_url" "$new_etag" "$new_last_modified" "$validated_epoch" "$validated_utc"
      print_success fetched "$validated_utc" "$effective_url"
      
  • SKILL.md 9.4 KB
    ---
    argument-hint: "[skill-name]"
    compatibility:
      Requires curl and a writable user cache directory; network populates or refreshes the agentskills.io specification.
    name: skill-writing
    description:
      Create/scaffold/init a project-local agent skill under `.agents/skills` in an ordinary repository; defer to repository
      instructions that define a source catalog and lifecycle.
    ---
    
    # Skill Writing
    
    Bootstrap a project-local skill in `.agents/skills/`, expose it to Claude Code through a relative symlink, and verify
    the result with the repository's canonical skill validator.
    
    ## Model Guidance
    
    Optimize every new skill and its content for GPT-6.1 Sol and Claude Opus 5.5. The summaries below are reminders, not
    substitutes for the live guides. Read both guides before designing or writing a complex, long-running, multi-tool, or
    orchestration-heavy skill because their recommendations may evolve.
    
    - [GPT-6.1 Sol prompting guidance](https://developers.openai.com/api/docs/guides/latest-model#prompting-best-practices)
      (shared GPT-6 guide; evaluate its family-wide recommendations on Sol): Complete authorized work under stated
      assumptions; make user-instruction precedence over skills explicit; specify writing and delegation preferences; and
      keep verification proportional to the change.
    - [Claude Opus 5.5 prompting guidance](https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/prompting-claude-opus-5-5):
      Calibrate effort instead of prompting for more thinking; never ask for reasoning in response text; name the premature
      stops to avoid and the stops that are wanted; treat text-only turns as reports, not completion; request brief progress
      updates; explore relevant sources before acting; and name concrete patterns to avoid instead of generic style advice.
    
    ## Input
    
    - **skill-name** (optional): a kebab-case name such as `my-skill`. If omitted, derive the shortest unambiguous
      kebab-case domain name for the skill's purpose, without repeating the repository or app name as context (for example
      `price-estimator`, not `budget-price-estimator`), and state the derived name in the completion report. Stop only when
      a supplied name is invalid or collides with an existing skill (see the collision check in step 2).
    
    Reject `--global`, explicit destination paths, and other scope overrides. The invocation working directory is the only
    supported scope.
    
    ## Workflow
    
    ### 1. Apply the Repository Catalog Guard
    
    Before resolving project-local paths, read the repository instructions applicable to the invocation working directory.
    If they define a skill source catalog and lifecycle, stop this workflow and follow that repository-owned workflow. Do
    not create `.agents/skills/` or `.claude/skills/` paths there.
    
    ### 2. Resolve and Validate the Local Scope
    
    Set `<scope>` to the working directory where the skill was invoked. Create the source at
    `<scope>/.agents/skills/<name>/` and the Claude Code symlink at `<scope>/.claude/skills/<name>`. Do not redirect the
    scope to the repository root when invoked from a nested project or workspace. Never create or modify a skill under
    `~/.agents`, `~/.claude`, `~/.codex`, or another global installation directory.
    
    The symlink target is always the relative path `../../.agents/skills/<name>`.
    
    Reject a collision before writing: stop if either the source directory or symlink path already exists.
    
    ### 3. Read the Current Format Sources
    
    Resolve `scripts/fetch-agentskills-spec.sh` relative to this skill directory. Run
    `scripts/fetch-agentskills-spec.sh [--refresh]` once and read the returned file completely. The helper reuses an
    integrity-valid specification for 24 hours, conditionally revalidates older entries, and may return a cache validated
    within seven days when live retrieval fails. Set `AGENTSKILLS_CACHE_DIR` when the default user cache location is
    unavailable or unwritable.
    
    Use `--refresh` for explicitly latest or change-sensitive work, disputed portable-format guidance, or a conflict with
    validator behavior. A `stale` result is usable only after reading it; disclose its validation timestamp and retrieval
    failure in the completion report. If the helper cannot return a valid file, stop before writing. Never fetch the
    agentskills.io specification directly or create its cache in a repository or skill installation.
    
    Fetch the current [Claude Code frontmatter reference](https://code.claude.com/docs/en/skills#frontmatter-reference) with
    `WebFetch`. Confirm field shapes, naming rules, and progressive-disclosure conventions from both sources; do not guess
    because the formats evolve.
    
    ### 4. Define the Contract and Layout
    
    Read [references/writing-great-skills.md](references/writing-great-skills.md) completely before choosing the contract or
    layout. It defines the authoring principles, content-routing thresholds, helper runtime defaults, and communication
    contract.
    
    Define the contract and identify every skill the workflow requires, invokes, or hands off to on any supported branch.
    Suggestions, examples, related-skill references, and underlying tool capabilities are not dependencies. Create only the
    directories justified by the selected layout; `SKILL.md` and `agents/openai.yaml` are always required.
    
    ### 5. Create the Skill
    
    ```bash
    mkdir -p "<scope>/.agents/skills/<name>/agents"
    # Add only the subdirectories the layout calls for:
    # mkdir -p "<scope>/.agents/skills/<name>/scripts"
    # mkdir -p "<scope>/.agents/skills/<name>/references"
    ```
    
    Write `<scope>/.agents/skills/<name>/SKILL.md` with:
    
    - Frontmatter sorted alphabetically, with `description` last. Front-load discovery-time trigger phrases in
      `description`.
    - A `skill-dependencies` array when routing identified dependencies. Use bare names for skills in the same repository
      and `ORG/REPO#SKILL` for external skills. Sort by the target skill name (the bare name or substring after `#`), then
      by the complete identifier. Require unique strings, resolve every bare dependency in the same repository, and exclude
      the owning skill as a bare dependency. External repository existence is not validated. Omit the field when no
      dependencies exist.
    - A short `# Title`.
    - A one-line summary of what the skill does.
    - Add `disable-model-invocation: true` or `user-invocable: false` only when the skill differs from Claude's defaults.
      Omit `disable-model-invocation: false` and `user-invocable: true` because absence already expresses those values.
    - Set `coordination: exempt` only when the skill's declared default workflow writes no repository files or only
      repository metadata. When selected, add this ordinary prose declaration to the new skill's body; the fence below is
      documentation for this authoring skill, not its own declaration:
    
      ```text
      This skill is coordination-exempt: skip the ai-coord gate for its declared work.
      ```
    
      Explicitly authorized escalation beyond the declared behavior re-enters the gate.
    
    - `## Arguments` (if any) and a lean imperative workflow. Use fixed steps only when order matters; otherwise state the
      contract and let repository evidence guide execution.
    - Explicit links to every `references/` file the workflow may need, each with a one-line note describing _when_ to read
      it.
    - CLI signatures for every bundled helper, including arguments, output, defaults, and the runtime command, so an agent
      can invoke it without reading its source.
    
    Use imperative prose and resolve bundled `references/`, `scripts/`, `examples/`, and `assets/` paths relative to the
    owning skill directory. Do not add repository-style support files or authoring artifacts that runtime agents will not
    use. Quote YAML plain scalars containing a colon followed by a space; otherwise the frontmatter parser may reject them.
    
    Write `<scope>/.agents/skills/<name>/agents/openai.yaml` with:
    
    ```yaml
    policy:
      allow_implicit_invocation: true
    ```
    
    Set `allow_implicit_invocation` to the inverse of `SKILL.md` `disable-model-invocation`. If later adding Codex UI
    metadata or MCP/tool dependencies, merge them into the same file and keep the policy.
    
    ### 6. Create the Claude Code Symlink
    
    Always create a relative symlink so Claude Code picks the skill up from its own discovery path:
    
    ```bash
    mkdir -p "<scope>/.claude/skills"
    ln -s "../../.agents/skills/<name>" "<scope>/.claude/skills/<name>"
    ```
    
    ### 7. Verify and Report
    
    - Patch tooling creates files at mode 0644. Before the first verification run, `chmod 755` every executable under
      `scripts/` and `tests/` (a scaffolded test failing its first run with `Permission denied (os error 13)` is this
      cause).
    - `test -f "<scope>/.agents/skills/<name>/SKILL.md"`
    - `test -f "<scope>/.agents/skills/<name>/agents/openai.yaml"`
    - `readlink "<scope>/.claude/skills/<name>"` equals `../../.agents/skills/<name>`, and the link resolves to the source
      directory.
    - `test -x` every `scripts/*` and `tests/*` executable so a missed `chmod` fails loudly instead of surfacing later as a
      permission error.
    - `ai-skillet doctor --root "<scope>/.agents/skills/<name>"` exits 0. This is the canonical local schema and policy
      gate.
    - Finish with `### 🧩 Skill created: <name>`, a tree of created paths, and `### ✅ Verified` with the exact checks. Link
      files by their absolute `.agents/skills/<name>/` source paths, never through the `.claude/skills/<name>` symlink.
    - Commit when the request or standing instructions authorize it; otherwise offer to commit. Do not ask again for
      authorization already given.
    
    Keep helper stdout, commands, paths, frontmatter, and generated skill content undecorated unless the new skill's output
    contract requires otherwise.
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related