Publish a skill

Ship an agent skill, declare where it runs, and be honest about how you know.

1. Publish from GitHub

Publishing needs an API key from your settings page. Ownership of the repository is verified with a GitHub collaborator check, so you can only publish a repo you can already write to.

$skillx publish owner/repo
$skillx publish owner/repo --path skills/my-skill --scan
$skillx publish owner/repo --dry-run

--dry-run reports what would be published without writing anything, which is the cheapest way to check your layout.

2. What gets scanned

Every SKILL.md is scanned for prompt injection, invisible Unicode, ANSI escapes, and shell injection. The result is stored as a risk label and shown on your listing: safe, caution, danger, or unknown.

A label is a statement about the content, not about you. Zero-width characters and escape sequences are stripped before storage, so a `caution` result usually means a stray invisible character rather than anything deliberate.

3. Declare where it runs

A compatibility declaration maps a runtime to a status and, for a supported runtime, a semver range:

{
  "agentkit":  { "status": "declared", "versions": ">=1.0.0 <2.0.0" },
  "claude-code": { "status": "unsupported" }
}

Unknown runtimes, an unparseable range, and a version outside the declared range all resolve to blocked rather than to silent support. Declaring nothing is unknown, which is not the same as compatible and is never treated as compatibility by the API, the CLI, or an agent.

4. Declared is not verified

Two tiers are shown on every listing, and they mean different things. declared means you claim the runtime works. verified means a probe recorded evidence against the exact artifact digest.

A listing can reach `declared` and never `verified`, because a mutable listing has no artifact digest to bind evidence to. That is why listing a skill today shows a declaration and never a verified badge: claiming the stronger tier without the evidence would make the badge meaningless for everyone.

Kinds and release states

A package is one of skill, hook-pack, or bundle. Each release carries a state: draft, quarantined, published, or yanked. Only `published` resolves, so a draft or a yanked release is not served and a quarantine is never silent.

Immutable releases and named versions arrive with the registry work; until then, publishing a skill registers and scans it without inventing a release history it cannot prove.

The @agentkit publisher and the ak- slug prefix are reserved for AgentKit kit content. Those releases carry kit provenance and are signed as skillx.release/v2. The registry signature never makes them signed-kit content. Every other release is signed as skillx.release/v1. A kit release drops the ak- directory prefix from its name (@agentkit/plan, never @agentkit/ak-plan), and installing one needs skillx-sh 0.7.0 or later.