Skip to main content

In this article

Contributing Skills to HVE Core

This guide defines the requirements, standards, and best practices for contributing skill packages to the hve-core library.

⚙️ Common Standards: See AI Artifacts Common Standards for shared requirements (XML blocks, markdown quality, RFC 2119, validation, testing).

What is a Skill?

A skill is a self-contained package that provides guidance and utilities for specific tasks. Unlike agents or prompts that guide conversation flows, skills bundle documentation, and optionally executable scripts, to perform concrete operations. A skill can be purely documentation-driven (providing structured knowledge and instructions) or can include cross-platform scripts for automated task execution.

Skill vs Agent vs Prompt

ArtifactPurposeIncludes ScriptsUser Interaction
SkillTask execution with utilitiesOptionalMinimal after invocation
AgentConversational guidanceNoMulti-turn conversation
PromptSingle-session workflowNoOne-shot execution

Use Cases for Skills

Create a skill when you need to:

  • Package structured knowledge and instructions for a specific task domain
  • Bundle documentation with executable scripts for automated task execution
  • Provide cross-platform utilities (PowerShell required, bash recommended)
  • Standardize common development tasks
  • Share reusable tooling across projects

Skills Not Accepted

The following skill types will likely be rejected:

ReasonDetails
Duplicate SkillsSkills that replicate functionality of existing tools or skills
Missing PowerShell ScriptsSkills that include a scripts/ directory without a .ps1 file when the skill targets PowerShell or cross-platform execution (Python skills can instead package executable modules under scripts/)
Undocumented UtilitiesScripts without comprehensive SKILL.md documentation
Untested SkillsSkills that lack unit tests or fail to achieve 80% code coverage

File Structure Requirements

Location

Skill files are typically organized in a package subdirectory by convention:

.github/skills/{package-id}/<skill-name>/
├── SKILL.md # Main skill definition (required)
├── SECURITY.md # STRIDE model (required for executable runtimes)
├── scripts/ # Executable scripts or Python package entry points (optional)
│ ├── <pkg>/ # Python package directory (optional for Python skills)
│ │ └── __init__.py
│ ├── <action>.ps1 # PowerShell script (required for PowerShell/cross-platform skills)
│ └── <action>.sh # Bash script (recommended)
├── references/ # Additional documentation (optional)
│ └── REFERENCE.md # Detailed technical reference
├── assets/ # Static resources (optional)
├── templates/ # Document or configuration templates (optional)
├── examples/
│ └── README.md # Usage examples (recommended)
└── tests/
├── <action>.Tests.ps1 # Pester unit tests (required for PowerShell)
└── fuzz_harness.py # Atheris fuzz harness (required for Python)

NOTE

Marketplace package recipes can reference artifacts from any canonical subfolder. Standard component paths are declared in .github/plugin/marketplace.json and resolve to canonical source files.

The scripts/ directory is optional. When present, it MUST contain at least one PowerShell script for PowerShell or cross-platform skills, and it SHOULD contain at least one .sh file when a bash implementation is also provided. Python skills may instead package executable modules under scripts/<package>/__init__.py and still satisfy the scripts requirement. Skills without scripts are valid and function as documentation-driven knowledge packages.

Skill Security Model

A skill that ships an executable runtime MUST include SECURITY.md next to SKILL.md when it performs network egress, handles credentials, starts subprocesses, or parses untrusted documents or content. Purely instructional skills and local validation scripts without an external runtime surface do not require a dedicated model.

Follow the skill security model guidance and start from the skill security model template. The repository security model lists existing examples and the complete inclusion rule under Skill Security Models.

Naming Convention

  • Use lowercase kebab-case for directory names: video-to-gif
  • Main definition file MUST be named SKILL.md
  • Script names should describe their action: convert.sh, validate.ps1
  • Only recognized subdirectories are allowed: scripts, references, assets, examples, tests, templates (the tests directory is excluded from extension and CLI outputs)

Frontmatter Requirements

Required Fields

name (string, MANDATORY)

PropertyValue
PurposeUnique identifier for the skill
FormatLowercase kebab-case matching the directory name
Examplevideo-to-gif

description (string, MANDATORY)

PropertyValue
PurposeConcise explanation of skill functionality
FormatSingle sentence describing the skill; no attribution suffix
Example'Video-to-GIF conversion skill with FFmpeg two-pass optimization'

Frontmatter Example

---
name: video-to-gif
description: 'Video-to-GIF conversion skill with FFmpeg two-pass optimization'
---

Optional Fields

user-invocable (boolean, optional)

PropertyValue
PurposeControls visibility in the VS Code slash command menu
Defaulttrue
When trueSkill appears in the / menu for manual invocation via /skill-name
When falseSkill does not appear in the / menu; loaded only by semantic matching or explicit #file: reference
Use caseSet false for background skills that support other workflows without direct user invocation

disable-model-invocation (boolean, optional)

PropertyValue
PurposeControls whether Copilot automatically loads the skill via semantic matching
Defaultfalse
When falseCopilot loads the skill automatically when the task description semantically matches the description field
When trueSkill is only loaded via manual /skill-name slash command invocation
Use caseSet true for skills with high token cost or niche applicability that should not load automatically

argument-hint (string, optional)

PropertyValue
PurposeDisplays expected inputs in the VS Code prompt picker
FormatBrief text with required arguments first, then optional arguments
ConventionsUse [] for positional arguments, key=value for named parameters, {option1|option2} for enumerations, ... for free-form text
Example"input=video.mp4 [--fps={5|10|15|24}] [--width=1280]"

license (string, optional)

PropertyValue
PurposeSPDX license identifier for the skill content
DefaultRepository license when omitted
Use caseSkills that incorporate third-party content under a specific license (e.g. CC-BY-SA-4.0, MIT)
ExampleMIT

compatibility (string, optional)

PropertyValue
PurposeRuntime requirements or prerequisites for the skill
Use caseSkills that depend on interpreters, CLI tools, credentials, or other runtime dependencies
Example"Requires Python 3.11+, uv package manager, and network access for API calls"

metadata (object, optional)

PropertyValue
PurposeProvenance and versioning metadata for the skill
Use caseSkills that track authorship, upstream framework versions, or source documentation

Recognized metadata fields:

FieldTypeDescription
authorsstringAuthor or organization responsible for the skill content
spec_versionstringVersion of the skill specification format
framework_revisionstringVersion of the upstream framework the skill is based on
last_updatedstringDate the skill was last updated in ISO 8601 format
skill_based_onstringURL of the specification the skill structure is based on
content_based_onstringURL of the upstream content the skill references derive from

Invocation Control Matrix

user-invocabledisable-model-invocation/ MenuSemantic LoadingInvocation Method
true (default)false (default)YesYesAutomatic + manual
truetrueYesNoManual /skill-name only
falsefalseNoYesAutomatic only
falsetrueNoNoOnly via #file: reference

Frontmatter Example with Optional Fields

---
name: pr-reference
description: 'Generate PR reference XML files with commit history and diffs for pull request workflows'
user-invocable: true
disable-model-invocation: false
argument-hint: "[--base-branch=origin/main] [--exclude-markdown]"
---

This example demonstrates a skill configured for both automatic semantic loading and manual /pr-reference invocation, with argument hints displayed in the prompt picker.

Frontmatter Example with License and Metadata

---
name: owasp-llm
description: 'OWASP Top 10 for LLM Applications (2025) vulnerability knowledge base'
license: CC-BY-SA-4.0
user-invocable: false
metadata:
authors: "OWASP LLM Applications Security Initiative"
spec_version: "1.0"
framework_revision: "1.0.0"
last_updated: "2026-02-13"
content_based_on: "https://genai.owasp.org/resource/owasp-top-10-for-llm-applications-2025/"
---

This example demonstrates a skill incorporating third-party content with provenance tracking. Skills referencing external frameworks should include license to identify the content license and metadata to track source attribution.

Marketplace Recipe Registration

Distributable skills must be declared under the skills field of the hve-core entry in .github/plugin/marketplace.json. Declare the .github-root-relative canonical skills/<package>/<skill> directory, not its SKILL.md file, and keep the directory name equal to the skill name.

Add non-stable lifecycle disclosure only through x-hve.componentMaturity, update docs/plugins/hve-core.md, then run npm run lint:marketplace, npm run validate:skills, and npm run docs:generate:check.

SKILL.md Content Structure

Required Sections

1. Title (H1)

Clear, descriptive heading matching skill purpose:

# Video-to-GIF Conversion Skill

2. Overview

Explains what the skill does and its approach:

This skill converts video files to optimized GIF animations using FFmpeg two-pass palette optimization.

3. Prerequisites

Lists installation requirements for each platform:

## Prerequisites

FFmpeg MUST be installed and available in your system PATH.

### macOS

\`\`\`bash
brew install ffmpeg
\`\`\`

### Linux

\`\`\`bash
sudo apt install ffmpeg
\`\`\`

### Windows

\`\`\`powershell
choco install ffmpeg
\`\`\`

4. Quick Start

Shows basic usage with default settings:

## Quick Start

\`\`\`bash
./scripts/convert.sh input.mp4
\`\`\`

5. Parameters Reference (when scripts are included)

Documents all configurable options with defaults. Include this section when the skill contains scripts with configurable parameters.

## Parameters

| Parameter | Default | Description |
|-----------|---------|--------------|
| --fps | 10 | Frame rate |
| --width | 480 | Output width |

6. Script Reference (when scripts are included)

Documents both bash and PowerShell usage. Include this section when the skill contains a scripts/ directory.

## Script Reference

### convert.sh (Bash)

\`\`\`bash
./convert.sh --input video.mp4 --fps 15
\`\`\`

### convert.ps1 (PowerShell)

\`\`\`powershell
./convert.ps1 -InputPath video.mp4 -Fps 15
\`\`\`

7. Troubleshooting

Common issues and solutions:

## Troubleshooting

### Tool not found

Verify the dependency is in your PATH...

Do not add the standard Copilot attribution footer to SKILL.md. Skill definition files under .github/skills/*/SKILL.md must remain free of the attribution footer, and the footer should be omitted from skill documentation entirely.

Script Requirements

Scripts are optional for skills. A skill can function purely as a documentation-driven knowledge package without any scripts. When a skill includes a scripts/ directory, a PowerShell implementation is required and a bash implementation is recommended for cross-platform support.

Bash Scripts

Bash scripts MUST:

  • Use #!/usr/bin/env bash shebang
  • Enable strict mode: set -euo pipefail
  • Follow main function pattern
  • Include usage function with --help support
  • Check for required dependencies
  • Handle platform differences (macOS vs Linux)

See bash.instructions.md for complete standards.

PowerShell Scripts

PowerShell scripts MUST:

  • Use #Requires -Version 7.4 after the copyright header
  • Use [CmdletBinding()] attribute
  • Include comment-based help (.SYNOPSIS, .DESCRIPTION, .PARAMETER, .EXAMPLE)
  • Validate parameters with [ValidateScript()], [ValidateRange()], or [ValidateSet()]
  • Check for required dependencies
  • Use proper error handling

See powershell.instructions.md for complete standards.

Unit Testing Requirements

All skill scripts MUST include unit tests that achieve a minimum of 80% code coverage. Tests are co-located inside the skill directory to keep each skill self-contained.

Test File Location

Place test files in a tests/ subdirectory within the skill directory:

.github/skills/<skill-name>/
└── tests/
└── <script-name>.Tests.ps1

PowerShell Tests

PowerShell skill scripts require Pester 5.x tests:

  • Use .Tests.ps1 suffix matching the source script name
  • Follow the same conventions as scripts/tests/ (see Testing Architecture)
  • Pester configuration is defined at scripts/tests/pester.config.ps1; co-located skill tests run when their tests/ directories are included in the Pester run paths (for example via CI or explicit test invocation)

Minimal example:

Describe 'Convert-VideoToGif' {
It 'Validates input file exists' {
{ ./convert.ps1 -InputPath 'nonexistent.mp4' } | Should -Throw
}
}

Python Tests

Python skill scripts require pytest:

  • Use test_<script_name>.py naming convention
  • Place tests in the tests/ subdirectory alongside PowerShell tests
  • Configure pytest and ruff in a pyproject.toml at the skill root
  • When a Python skill has a tests/ directory, [tool.ruff.lint].select in pyproject.toml MUST include "I" so isort enforcement is active for test files
  • Commit uv.lock alongside pyproject.toml at the skill root so Dependabot can resolve and patch Python dependencies under .github/skills/**
  • npm run validate:skills warns when pyproject.toml is present without uv.lock, and it fails when the validation run is executed with -WarningsAsErrors

Do not commit opaque binary test fixtures such as .pptx or .xlsx files. Binary fixtures can conceal macros, OLE objects, or other content that is difficult to audit. Generate them from reviewable Python code in conftest.py and write them to pytest's temporary directory at test time:

from pathlib import Path

import pytest

from tests.fixture_factory import generate_minimal_fixture


@pytest.fixture(scope="session")
def minimal_fixture(tmp_path_factory: pytest.TempPathFactory) -> Path:
fixture_path = tmp_path_factory.mktemp("fixtures") / "minimal.pptx"
generate_minimal_fixture(fixture_path)
return fixture_path

Keep the generator deterministic and minimal so reviewers can audit every element it creates. If generation depends on library internals, such as bundled layout names, declare a compatible lower-bound dependency version and explain that fixture dependency in the dependency manifest.

Fuzz Harness (Python Skills)

Python skills with a tests/ directory MUST include a fuzz harness for OSSF Scorecard Fuzzing compliance:

  • Create tests/fuzz_harness.py as a polyglot file that runs as both a pytest test and an Atheris fuzz target
  • Add a fuzz dependency group with atheris>=3.0 in pyproject.toml
  • Add python_files = ["test_*.py", "fuzz_harness.py"] to [tool.pytest.ini_options] for pytest discovery
  • The harness uses try: import atheris to detect availability and degrade gracefully when not installed
  • Validation enforces this convention: builds fail when a Python skill has tests but no fuzz harness

Packaging Note

Co-located tests/ directories are automatically excluded from the VSIX extension package. No additional contributor action is needed.

Supported Languages

Skills may include scripts in any of these supported languages. Each language has specific tooling and CI expectations.

LanguageScript ExtensionTest FrameworkLinter / AnalyzerCI Coverage
Bash.shN/AshellcheckLint only
PowerShell.ps1Pester 5.xPSScriptAnalyzerFull (lint + test)
Python.pypytestruff (line-length=88, target-version=py311)Full (lint + test)

Requesting New Language Support

To request support for a new programming language:

  1. Open a Skill Request issue
  2. Select the desired language in the Programming Language dropdown (choose "Other" if unlisted)
  3. Describe the tooling requirements: test framework, linter, CI integration needs
  4. A maintainer will evaluate feasibility and update this table when support is added

Examples Directory

The examples/ subdirectory SHOULD include:

  • Quick usage examples for common scenarios
  • Test data generation instructions
  • Quality comparison guides
  • Batch processing patterns

Path Portability

Skill packages are self-contained and relocatable. The skill root directory varies by distribution context:

ContextSkill Root Example
In-repo.github/skills/<package>/<skill>/
Copilot CLI plugin~/.copilot/installed-plugins/_direct/<plugin>/skills/<skill>/
VS Code extension~/.vscode/extensions/<publisher>.<ext>-<version>/skills/<skill>/
Plugin outputplugins/<package>/skills/<skill>/

The .github/ directory does not exist in any distributed context. All file references and script paths within a skill must be relative to the skill root, never repo-root-relative.

  • Use ./scripts/<script-name>.sh instead of ./.github/skills/<package>/<skill>/scripts/<script-name>.sh
  • Use references/<reference-name>.md instead of .github/skills/<package>/<skill>/references/<reference-name>.md
  • From files in subdirectories (such as references/), use ../scripts/ to reach sibling directories

This rule applies to all files in the skill: SKILL.md, reference documents, assets, and code examples in documentation. Repo-root-relative paths break portability and will fail validation.

Semantic Skill Loading

VS Code Copilot uses progressive disclosure to load skills efficiently. Understanding this model helps authors write effective description fields and helps callers invoke skills correctly.

How Skills are Discovered

Copilot reads the name and description fields from all SKILL.md files at startup. This lightweight metadata (~100 tokens per skill) enables relevance matching without loading full skill content.

How Skills are Loaded

When a user request or caller description semantically matches a skill's description:

  1. Level 1 (Discovery): Copilot matches the task against name and description frontmatter (always loaded, ~100 tokens per skill).
  2. Level 2 (Instructions): The full SKILL.md body loads into context with script usage, parameters, and troubleshooting (under 5000 tokens recommended).
  3. Level 3 (Resources): Scripts, examples, and references in the skill directory load on-demand during execution.

Writing Effective Descriptions

The description field is the semantic key for automatic loading. Craft descriptions that are:

  • Specific enough for accurate matching (include the primary action verb and artifact type)
  • Broad enough to cover all use cases (avoid narrowing to one scenario)
  • Containing searchable terms that callers naturally use

How Callers Invoke Skills

Prompts, agents, and instructions should describe the task intent rather than referencing script paths. Copilot matches task descriptions against skill description fields and loads the skill on-demand.

Avoid hardcoded script paths, platform detection logic, or extension fallback code in caller files.

For explicit invocation, use the /skill-name slash command in chat.

Validation Checklist

Before submitting your skill, verify:

Structure

  • Directory at .github/skills/<skill-name>/
  • SKILL.md present with valid frontmatter
  • If scripts/ directory exists: at least one .ps1 file present (.sh recommended)
  • Only recognized subdirectories used (scripts, references, assets, examples, tests, templates)
  • Examples README (recommended)

Frontmatter

  • Valid YAML between --- delimiters
  • name field present and matches directory name
  • description field present and descriptive
  • Optional: user-invocable set appropriately (default true works for most skills)
  • Optional: disable-model-invocation set appropriately (default false works for most skills)
  • Optional: argument-hint provides useful input guidance if set
  • Optional: license set when skill content uses a specific license
  • Optional: compatibility describes runtime requirements when applicable
  • Optional: metadata includes provenance fields when skill references external content

Scripts (when included)

  • scripts/ directory contains at least one .ps1 file
  • PowerShell script passes PSScriptAnalyzer
  • If bash scripts are included: follows bash.instructions.md
  • When both exist, scripts implement equivalent functionality
  • Help and usage documentation included

Testing

  • Unit tests present in tests/ subdirectory
  • PowerShell tests use .Tests.ps1 naming convention
  • Tests pass locally via npm run test:ps
  • Python skills include tests/fuzz_harness.py (required for Scorecard compliance)
  • Fuzz harness passes in pytest mode: uv run pytest tests/fuzz_harness.py -v

Documentation

  • All required SKILL.md sections present
  • Prerequisites documented per platform
  • Parameters fully documented
  • Troubleshooting section included
  • Attribution footer absent

Automated Validation

Run these commands before submission:

npm run lint:frontmatter # Validate SKILL.md frontmatter
npm run lint:ps # Validate PowerShell scripts (when present)
npm run lint:md # Validate markdown formatting
npm run validate:skills # Validate skill directory structure
npm run test:ps # Run PowerShell unit tests
npm run docs:test # Validate Docusaurus artifact counts
npm run docs:generate # Scaffold reference page under docs/reference/skills/ (new skills)
npm run lint:asset-docs # Validate asset reference pages and AUTO-GENERATED regions

When a skill contains SECURITY.md, npm run validate:skills also enforces its canonical heading structure: trust buckets use ## Bucket Bn headings, and STRIDE categories plus Risk Rating use H3 headings.

All checks MUST pass before merge.


🤖 Crafted with precision by ✨Copilot following brilliant human instruction, then carefully refined by our team of discerning human reviewers.