A skill is a directory with a SKILL.md file at its root. That file declares the skill identity and tells the agent how to use the package. The directory can also contain scripts, references, assets, templates, and other files the instructions point to.
Keep the first version small. Start with instructions only, install it, test it explicitly in one thread, then add dependencies or runtime tools only when the workflow needs them.
Create A Skill
For a Pioneer-native skill, write the contract in YAML frontmatter at the top of SKILL.md. Do not create _meta.json for new native skills; that file exists for imported OpenClaw-style or registry-style packages.
Create a directory
Create one directory named after the skill slug. The root of that directory must contain SKILL.md.
Write native frontmatter
Add name, slug, description, and any optional fields the skill actually needs. Keep identity, dependency, metadata, path, policy, and runtime declarations in YAML frontmatter.
Write the instructions
In the Markdown body, tell the agent when to use the skill, what files to read, what commands are allowed or expected, what setup steps exist, and what output shape to produce.
Add resources only when needed
Add references/ for longer docs, scripts/ for repeatable helpers, and assets/ for templates or files the skill uses. Mention each resource from SKILL.md; Pioneer does not auto-load supporting files.
Package one top-level directory
Archive the skill from its parent directory so the archive expands to exactly one top-level folder containing SKILL.md.
Install and test explicitly
Install the folder or archive in the desktop Skills view, review validation and health diagnostics, attach the skill from the composer, and test it before enabling implicit invocation.
mkdir repo-review
$EDITOR repo-review/SKILL.md
tar -czf repo-review.tar.gz repo-review
The first test prompt should be low-risk:
Read the repo-review skill and explain what you will do. Do not call tools yet.
After that, run the smallest real task that proves the instructions work.
Package Layout
repo-review/
SKILL.md
references/
review-checklist.md
scripts/
collect-context.sh
assets/
report-template.md
Only SKILL.md is required. Supporting folders are conventional:
| Folder | Use it for |
|---|
references/ | Longer documentation the agent should read only when needed. |
scripts/ | Repeatable commands or helpers the skill instructions can call. |
assets/ | Templates, examples, images, or other files used as inputs or outputs. |
For native Pioneer skills, put the skill contract in YAML frontmatter inside SKILL.md.
_meta.json is compatibility support for imported OpenClaw-style or registry-style skills. For Pioneer-native skills, use YAML frontmatter in SKILL.md. If _meta.json exists, its identity fields can override frontmatter identity fields, so do not include it unless you intentionally need compatibility behavior.
Other files are packaged with the skill, but they are not loaded automatically. Mention them from SKILL.md so the agent knows when to read or use them.
Minimal SKILL.md
---
name: repo-review
slug: repo-review
description: Review code in this repository using the team's review checklist. Use when the user asks for a code review, regression risk check, or release-readiness pass.
---
# Repo Review
Read `references/review-checklist.md` before reviewing application code.
Prioritize correctness bugs, behavior changes, missing tests, and security risks.
Lead with findings ordered by severity. Include file and line references when available.
For native Pioneer skills, include slug explicitly in the YAML frontmatter. The open Agent Skills strict profile requires name and description; Pioneer-native packages should provide all three fields in SKILL.md.
Frontmatter Fields
Use YAML frontmatter between the opening and closing --- markers. Field names are case-sensitive. Empty strings are trimmed and treated as missing. Unknown top-level fields are ignored by the parser, so do not rely on a custom top-level field unless another system reads it.
The body after frontmatter must not be empty. Pioneer stores the body as the full instruction text returned by read_skill.
---
name: repo-review
slug: repo-review
owner: platform
description: Review code in this repository using the team's checklist. Use when the user asks for a code review, regression risk check, or release-readiness pass.
version: "1.2.0"
license: Apache-2.0
compatibility: Requires git and GitHub CLI on the gateway host.
user-invocable: true
disable-model-invocation: false
paths:
- "crates/**"
- "apps/**"
allowed-tools: Read Bash(git:*) Bash(gh:*)
dependencies:
env:
- GH_TOKEN
api_keys:
- OPENAI_API_KEY
bins:
- git
commands:
- gh
mcp:
- github
config:
- skills.review.enabled
metadata:
author: platform-team
homepage: https://example.com/skills/repo-review
runtime:
tools:
- tool_slug: run-review-helper
description: Run the repository review helper script.
kind: shell
parameters:
type: object
properties:
target:
type: string
additionalProperties: false
execution_class: exclusive
config:
command:
- scripts/collect-context.sh
output_policy:
llm:
mode: summary_only
---
# Repo Review
Read `references/review-checklist.md` before reviewing application code.
Frontmatter Summary
| Field | Status | Type | Accepted YAML | Default / precedence | Meaning |
|---|
name | Native required by convention; Agent Skills strict-required | string | name: repo-review | Falls back to _meta.json.displayName, then slug if missing | Human-facing skill name. Native skills should set it directly in frontmatter. |
slug | Required to parse | string | slug: repo-review | _meta.json.slug overrides frontmatter when present | Stable machine name. Pioneer normalizes it and installs the skill as owner/slug. |
description | Native required by convention; Agent Skills strict-required | string | description: Review code... | Falls back to the first non-empty body line if missing | Short capability and trigger description shown before the full skill body is read. |
owner | Optional | string | owner: platform | _meta.json.owner or _meta.json.ownerId override frontmatter; otherwise derived from nested source path or pioneer | Namespace used in the qualified slug. |
version | Optional | string | version: "1.2.0" | _meta.json.version, then _meta.json.latest.version, then frontmatter | Version hint shown in catalog and health data. Quote numeric-looking versions. |
license | Optional | string | license: Apache-2.0 | None | License label for review and catalog display. |
compatibility | Optional | string | compatibility: Requires git. | None | Short compatibility note. |
metadata | Optional | object or JSON-object string | metadata: {author: team} or nested YAML object | {} | Additional metadata retained with the skill definition. This is frontmatter metadata, not _meta.json. |
allowed-tools | Optional | string or string array | allowed-tools: Read Bash(git:*) | Empty list | Agent Skills tool allowlist hint. Strict conformance expects a string. |
dependencies | Optional | object | dependencies: { bins: [git] } | Empty dependency set | Local requirements checked by install, health, and runtime flows. |
paths | Optional | string or string array | paths: ["crates/**"] | Empty list | Path match hints used during skill resolution. |
user-invocable | Optional | boolean | user-invocable: true | true | Whether users can select the skill explicitly. |
disable-model-invocation | Optional | boolean | disable-model-invocation: false | false | Whether automatic model-side invocation is disabled. |
runtime | Optional | object | runtime: { tools: [...] } | No runtime tools | Dynamic tool declarations. Advanced; most skills should omit it. |
Field Reference
Each section below describes one top-level YAML frontmatter field. The contract details are based on the current Pioneer parser behavior.
name
| Property | Value |
|---|
| Status | Native required by convention; required by Agent Skills strict conformance. |
| Type | string |
| Accepted YAML | name: repo-review |
| Default / precedence | Frontmatter name; if missing, imported compatibility packages can fall back to _meta.json.displayName, then slug. |
| Parser behavior | Empty string is treated as missing. Non-string values report contract.name.type. |
Use name for the display name stored in the compiled skill definition.
Accepted type: string.
Strict Agent Skills conformance requires name. The strict profile also checks that it is 64 characters or less and does not start with -, end with -, or contain --.
For imported compatibility packages, Pioneer can fall back to _meta.json.displayName, then slug, but that sidecar fallback is not the native authoring path. New Pioneer skills should set name directly in frontmatter.
Prefer a short lowercase hyphen name when you want maximum compatibility:
slug
| Property | Value |
|---|
| Status | Required to parse. |
| Type | string |
| Accepted YAML | slug: repo-review |
| Default / precedence | _meta.json.slug overrides frontmatter slug when the compatibility sidecar exists. |
| Parser behavior | Empty string is treated as missing. Non-string values report contract.slug.type. The final slug is normalized to lowercase hyphen form. Missing slug is a parse error. |
Use slug for stable machine identity.
Accepted type: string.
Pioneer-native skills must set slug in SKILL.md frontmatter. The slug is normalized to lowercase hyphen form. For example, Repo Review becomes repo-review. The installed qualified slug is owner/slug, such as platform/repo-review.
For imported OpenClaw-style or registry-style packages, Pioneer can also read _meta.json.slug. Treat that as a compatibility path, not the recommended way to author a new Pioneer skill.
Use lowercase letters, digits, and hyphens in the file to avoid surprises:
slug: github-issue-triage
description
| Property | Value |
|---|
| Status | Native required by convention; required by Agent Skills strict conformance. |
| Type | string |
| Accepted YAML | description: Review code when the user asks for a review. |
| Default / precedence | Frontmatter description; if missing, Pioneer falls back to the first non-empty body line. |
| Parser behavior | Empty string is treated as missing. Non-string values report contract.description.type. |
Use description to tell Pioneer and the model when the skill is relevant.
description: Review code in this repository using the team's checklist. Use when the user asks for a code review, regression risk check, or release-readiness pass.
Accepted type: string.
This is the most important discovery field. Keep both parts in the same string:
- what the skill does
- when it should be used
Strict Agent Skills conformance requires description and limits it to 1024 characters. If it is missing, Pioneer falls back to the first non-empty body line, but that fallback is worse for discovery and reports strict conformance issues.
owner
| Property | Value |
|---|
| Status | Optional. |
| Type | string |
| Accepted YAML | owner: platform |
| Default / precedence | _meta.json.owner, then _meta.json.ownerId, then frontmatter owner, then nested source path owner, then pioneer. |
| Parser behavior | Empty string is treated as missing. Non-string values report contract.owner.type. The final owner is normalized to lowercase hyphen form. |
Use owner to put the skill in a namespace.
Accepted type: string.
Pioneer uses owner with slug to create the qualified slug:
For native Pioneer skills, set owner in frontmatter when you need a namespace other than the default. If no owner is provided, Pioneer can derive it from a nested source path. Otherwise it defaults to pioneer.
For imported compatibility packages, _meta.json.owner or _meta.json.ownerId can also provide the owner. When present, sidecar identity fields take precedence over frontmatter identity fields, so do not include _meta.json in a native skill unless you intentionally want that override behavior.
version
| Property | Value |
|---|
| Status | Optional. |
| Type | string |
| Accepted YAML | version: "1.2.0" |
| Default / precedence | _meta.json.version, then _meta.json.latest.version, then frontmatter version. |
| Parser behavior | Empty string is treated as missing. Non-string values report contract.version.type. Quote numeric-looking values so YAML does not parse them as numbers. |
Use version as a catalog and health hint.
Accepted type: string.
Quote versions so YAML does not reinterpret values such as 1.2 as numbers. For native Pioneer skills, put the version hint in frontmatter.
For imported compatibility packages, Pioneer can read _meta.json.version or _meta.json.latest.version. Those sidecar values take precedence over frontmatter version when present.
Pioneer stores this as a version hint. It is not a package manager lock and does not enforce semantic version rules.
license
| Property | Value |
|---|
| Status | Optional. |
| Type | string |
| Accepted YAML | license: Apache-2.0 |
| Default / precedence | No default. Frontmatter only. |
| Parser behavior | Empty string is treated as missing by the parser. Strict conformance rejects an explicitly empty license. Non-string values report contract.license.type. |
Use license to describe the package license.
Accepted type: string.
Strict conformance rejects an explicitly empty license. It does not validate SPDX values today, but SPDX-style values are easiest to review.
compatibility
| Property | Value |
|---|
| Status | Optional. |
| Type | string |
| Accepted YAML | compatibility: Requires git and GitHub CLI on the gateway host. |
| Default / precedence | No default. Frontmatter only. |
| Parser behavior | Empty string is treated as missing. Non-string values report contract.compatibility.type. Strict conformance allows 1..=500 characters when provided. |
Use compatibility for short constraints a reviewer should see.
compatibility: Requires macOS or Linux, git, and GitHub CLI on the gateway host.
Accepted type: string.
Strict conformance allows it when it is between 1 and 500 characters. Put long setup docs in references/ instead of making this field long.
| Property | Value |
|---|
| Status | Optional. |
| Type | YAML object or JSON-object string |
| Accepted YAML | metadata: {author: platform-team} or a nested YAML object. |
| Default / precedence | {}. Frontmatter only; _meta.json is a separate compatibility sidecar and is not this field. |
| Parser behavior | YAML mappings are converted to JSON objects. String values must parse as JSON objects. Plain strings, arrays, numbers, booleans, and invalid JSON report metadata validation issues. |
Use metadata for extra structured data that should travel with the skill definition.
Accepted types:
- YAML object
- JSON-object string
Recommended YAML object form:
metadata:
author: platform-team
homepage: https://example.com/skills/repo-review
support: "#ai-tools"
Accepted JSON string form:
metadata: '{"author":"platform-team","homepage":"https://example.com/skills/repo-review"}'
If metadata is a YAML string, it must parse as a JSON object. Plain text metadata is reported as invalid. An unquoted inline form like metadata: {author: platform-team} is a YAML object, not a string, and is also accepted.
Pioneer recognizes two nested namespaces from compatibility ecosystems:
metadata:
openclaw:
os:
- darwin
- linux
requires:
bins:
- node
- npm
config:
- skills.browser.enabled
skillKey: openclaw/browser
homepage: https://docs.openclaw.ai
clawdbot:
emoji: "*"
homepage: https://example.com
requires:
commands:
- agent-browser
bins:
- node
Known dependency metadata is merged into the compiled dependency set:
metadata.openclaw.requires.bins
metadata.openclaw.requires.config
metadata.clawdbot.requires.commands
metadata.clawdbot.requires.bins
Strict Agent Skills conformance is intentionally narrower: top-level custom metadata values should be strings. Nested objects are strict-compatible only for openclaw and clawdbot.
| Property | Value |
|---|
| Status | Optional. |
| Type | string or array of strings |
| Accepted YAML | allowed-tools: Read Bash(git:*) or a YAML list of strings. |
| Default / precedence | Empty list. Frontmatter only. |
| Parser behavior | String form is split on whitespace. List form is accepted by Pioneer but is not Agent Skills strict-compatible. Non-string list items report contract.allowed-tools.item_type; other value types report contract.allowed-tools.type. |
Use allowed-tools as an Agent Skills allowlist hint.
Strict-compatible form:
allowed-tools: Read Bash(git:*) Bash(gh:*)
Accepted by Pioneer but not strict-compatible:
allowed-tools:
- Read
- Bash(git:*)
- Bash(gh:*)
Accepted types:
- string, split on whitespace
- array of strings
Pioneer parses and stores this field on the skill runtime definition. It is a declaration from the skill contract, not a replacement for gateway policy. Runtime exposure still depends on actual configured tools, trust, dynamic-tool settings, and policy.
dependencies
| Property | Value |
|---|
| Status | Optional. |
| Type | object |
| Accepted YAML | dependencies: { bins: [git], env: [GH_TOKEN] } or nested YAML object. |
| Default / precedence | Empty dependency set. Frontmatter dependencies plus recognized compatibility metadata dependencies are merged into the compiled dependency set. |
| Parser behavior | The top-level value must be a mapping. Supported child fields are env, api_keys, bins, commands, mcp, and config; each child accepts a string or array of strings. Unknown child fields are ignored. |
Use dependencies when missing local state should be visible in install, health, and runtime checks.
Dependencies are checks, not setup scripts. Pioneer checks whether the declared environment variable, binary, command, MCP server, or API key is already available on the gateway host. It does not install missing dependencies from this field.
Do not declare a binary or command in dependencies if the skill’s own setup instructions are supposed to install it first. That can make the skill look broken before the agent has a chance to follow the setup flow. In that case, put the setup flow in the instruction body and declare only external requirements that must already exist.
dependencies:
env:
- GH_TOKEN
api_keys:
- OPENAI_API_KEY
bins:
- git
commands:
- gh
mcp:
- github
config:
- skills.review.enabled
Accepted type: object.
Each dependency list accepts either a string or an array of strings:
dependencies:
bins: git
commands:
- gh
Supported dependency fields:
| Field | Status | Type | Accepted YAML | Checked today | Meaning |
|---|
env | Optional | string or string array | env: GH_TOKEN or env: [GH_TOKEN] | Yes | Environment variables that must be set and non-empty. |
api_keys | Optional | string or string array | api_keys: OPENAI_API_KEY or api_keys: [OPENAI_API_KEY] | Yes | API key environment variables that must be set and non-empty. |
bins | Optional | string or string array | bins: git or bins: [git, rg] | Yes | Executables that must be available in PATH. |
commands | Optional | string or string array | commands: gh or commands: [gh] | Yes | Commands that must be available in PATH. |
mcp | Optional | string or string array | mcp: github or mcp: [github] | Yes | MCP server names that must be available to the dependency checker. |
config | Optional | string or string array | config: skills.review.enabled or config: [skills.review.enabled] | Stored, not baseline-enforced | Config keys retained in the compiled dependency set. |
If install is blocked by a dependency failure, install the missing binary, set the environment variable, register the MCP server, or install the skill on a gateway that has those dependencies.
paths
| Property | Value |
|---|
| Status | Optional. |
| Type | string or array of strings |
| Accepted YAML | paths: "docs/**" or paths: ["crates/**", "apps/**"] |
| Default / precedence | Empty list. Frontmatter only. |
| Parser behavior | Empty strings are ignored. Non-string list items report contract.paths.item_type; other value types report contract.paths.type. |
Use paths to hint that a skill is relevant when a turn touches matching files or directories.
paths:
- "crates/**"
- "apps/web/**"
Accepted types:
Single-string form:
Path matches participate in turn resolution. They do not grant filesystem permissions and do not install the skill into those paths.
user-invocable
| Property | Value |
|---|
| Status | Optional. |
| Type | boolean |
| Accepted YAML | user-invocable: true or user-invocable: false |
| Default / precedence | true. Frontmatter only. |
| Parser behavior | Must be a YAML boolean. Strings such as "true" and "false" report contract.user-invocable.type and the default is used. |
Use user-invocable to control explicit user selection.
Accepted type: boolean.
Default:
Use false for internal helper skills that should not appear as something a user selects directly:
This field must be a YAML boolean, not a string. Use true or false, not "true" or "false".
disable-model-invocation
| Property | Value |
|---|
| Status | Optional. |
| Type | boolean |
| Accepted YAML | disable-model-invocation: false or disable-model-invocation: true |
| Default / precedence | false. Frontmatter only. |
| Parser behavior | Must be a YAML boolean. Strings such as "true" and "false" report contract.disable-model-invocation.type and the default is used. |
Use disable-model-invocation to prevent automatic model-side invocation.
disable-model-invocation: false
Accepted type: boolean.
Default:
disable-model-invocation: false
Set it to true when the skill should be available only through explicit user or client selection:
disable-model-invocation: true
This is separate from workspace policy. Workspace policy can still disable the skill or keep it explicit-only even when this field is false.
runtime
| Property | Value |
|---|
| Status | Optional; advanced. |
| Type | object with optional tools array |
| Accepted YAML | runtime: { tools: [...] } or nested YAML object. |
| Default / precedence | No runtime tools. Frontmatter only. |
| Parser behavior | runtime must decode as an object. Invalid runtime shape reports contract.runtime.type. Invalid tool slugs or invalid output_policy entries report runtime validation issues and those tools are skipped. |
Use runtime only when the skill must expose callable tools.
Accepted type: object with optional tools array.
Most skills should omit runtime. Instructions, references, and scripts are easier to review. Runtime tools add policy, trust, dependency, and output-safety concerns.
runtime:
tools:
- tool_slug: run-review-helper
description: Run the repository review helper script.
kind: shell
parameters:
type: object
properties:
target:
type: string
additionalProperties: false
execution_class: exclusive
config:
command:
- scripts/collect-context.sh
output_policy:
llm:
mode: summary_only
timeline:
mode: summary
max_chars: 2000
Supported runtime tool fields:
| Field | Status | Type | Accepted YAML | Default | Meaning |
|---|
tool_slug | Required | string | tool_slug: run-review-helper | None | Tool slug inside the skill. Normalized to lowercase hyphen form. |
description | Optional | string | description: Run the review helper. | Runtime tool '<tool_slug>' | Model-facing tool description. |
kind | Required | enum string | kind: shell | None | One of shell, http, or function_proxy. |
parameters | Optional | JSON schema object | parameters: {type: object} | Open object | Function-call argument schema exposed to the model. |
execution_class | Optional | enum string | execution_class: exclusive | shared | One of shared, exclusive, or session_scoped. |
config | Optional | object | config: {command: [scripts/run.sh]} | {} | Runtime-specific configuration. |
output_policy | Optional | object | output_policy: {llm: {mode: summary_only}} | Host default | Requested output projection policy. Host caps may narrow or reject it. |
Runtime tool kinds:
| Kind | Required or common config | Behavior |
|---|
shell | config.command as an array of strings, or command in call arguments | Runs a command through the gateway’s exec_command runtime. |
http | config.url, or url in call arguments | Makes an HTTP request from the gateway. Supports defaults for method, headers, and timeout_ms. |
function_proxy | config.target_tool | Wraps another available tool. Call arguments are forwarded to the target tool. |
Runtime tools are still subject to gateway configuration, trust policy, dependency rechecks, output policy caps, duplicate-name checks, and per-skill tool limits. A declared tool may be excluded even when the skill installs.
Native Pioneer skills should use YAML frontmatter in SKILL.md for name, slug, owner, version, description, dependencies, metadata, and runtime declarations.
Pioneer still supports _meta.json beside SKILL.md so imported OpenClaw-style or registry-style skills can keep their existing package identity metadata. The parser reads only a small set of sidecar identity fields:
{
"owner": "openclaw",
"ownerId": "openclaw",
"slug": "browser",
"version": "1.2.0",
"latest": {
"version": "1.2.0"
},
"displayName": "Browser"
}
Supported _meta.json fields:
| Field | Type | Meaning |
|---|
owner | string | Owner namespace override. |
ownerId | string | Alternate owner namespace field used by compatibility packages. |
slug | string | Slug override. |
version | string | Version hint override. |
latest.version | string | Fallback version hint. |
displayName | string | Fallback display name when frontmatter name is missing. |
Precedence rules:
_meta.json.slug takes precedence over frontmatter slug.
_meta.json.owner or _meta.json.ownerId takes precedence over frontmatter owner.
_meta.json.version or _meta.json.latest.version takes precedence over frontmatter version.
_meta.json.displayName is used only when frontmatter name is missing.
Do not put native-only fields such as description, dependencies, paths, allowed-tools, metadata, user-invocable, disable-model-invocation, or runtime in _meta.json. Pioneer reads those from SKILL.md frontmatter.
Package And Install Details
Archive from the parent directory:
tar -czf repo-review.tar.gz repo-review
The archive must contain a single top-level root, such as repo-review/, and that root must contain SKILL.md.
Install the package from the desktop Skills view. After upload, read validation issues, dependency diagnostics, security findings, and policy state before using the skill in important work. New installs should stay explicit-only until the skill has been tested in at least one low-risk thread.
Quality Checklist
- The skill has a short, stable
slug.
- The
description says exactly when the skill should be used.
- The body tells the agent what to do, what files to read, and what output shape to produce.
- Large details live in
references/ and are linked from the body.
- Scripts are executable, deterministic, and tested before packaging.
- Dependencies are declared when missing state should block install or use.
- Runtime tools are avoided unless the workflow truly needs callable tools.
- The first install is tested on a sandbox gateway or low-risk workspace.
Related Pages