Multi-Channel Skill Publisher
Publish ONE skill to ALL agent-skill channels from a single source of truth: the ClawHub skill registry, a ClawHub bundle-plugin package, and a Claude Code plugin marketplace (plai…
TheRacoon
@readysoon
What This Skill Does
Publishes a single AI skill to three distribution channels (ClawHub skill registry, ClawHub bundle-plugin package, and Claude Code plugin marketplace) from one source of truth using a sync script that stamps version and metadata across all manifests.
Replaces maintaining three separate copies of a skill for different publishing platforms by providing a single-source-of-truth workflow with automated version preflight checks.
When to Use It
- Publish a new skill to ClawHub, ClawHub bundle-plugin, and Claude Code marketplace simultaneously
- Rename or rebrand a skill across all three distribution channels without manual duplication
- Bump the version of a published skill and sync it to every registry in one step
- Package an existing skill as a Claude Code plugin with correct plugin.json and marketplace.json manifests
- Convert a ClawHub skill into a bundle-plugin package with openclaw.plugin.json and source-linked commit
- Debug versioning conflicts or display-name drift between the ClawHub web UI and CLI tools
Install
$ openclaw skills install @readysoon/multi-channel-skill-publishermulti-channel-skill-publisher
Release one skill everywhere — without maintaining three diverging copies.
The three channels
| Channel | What it is | Publish via |
|---|---|---|
| ClawHub Skill | searchable skill registry entry | web UI (most reliable) or clawhub publish <dir> --slug <slug> |
| ClawHub Package (bundle-plugin) | plugin package, source-linked to a GitHub commit | clawhub package publish <abs-path> --family bundle-plugin … |
| Claude Code plugin | installable via /plugin from a plain GitHub repo | just git push — the repo IS the marketplace |
0. Layout: one source of truth (SSOT)
Never hand-maintain copies. Canonical files live once, everything else is generated:
repo/
SKILL.md <- SSOT (canonical skill text; YAML frontmatter: name + description)
skill.json <- SSOT (registry metadata; THE version number lives here)
sync.py <- copies SSOT into every target + stamps the version everywhere
clawhub-skill/ <- generated copy for clawhub publish
plugin/ <- the ONE plugin folder, served to BOTH plugin channels
.claude-plugin/plugin.json <- Claude Code manifest (name, displayName, version, …)
openclaw.plugin.json <- OpenClaw manifest, REQUIRED for bundle-plugin publish:
{"id": "...", "name": "...", "version": "...", "configSchema": {}}
skills/<name>/SKILL.md <- generated from SSOT
commands/<name>.md <- optional slash command ($ARGUMENTS)
.claude-plugin/marketplace.json <- makes the repo its own Claude Code marketplace:
{"name": "...", "owner": {...}, "plugins": [{"name": "...", "source": "./plugin"}]}
sync.py (concept): read version from skill.json, copy SKILL.md into clawhub-skill/ and plugin/skills/<name>/, stamp the version into plugin.json, marketplace.json, openclaw.plugin.json. Run it after EVERY edit of the SSOT files.
Make sync.py also run a version preflight: query the live version on both namespaces (clawhub inspect <slug> + clawhub package inspect <name>, parse Latest: x.y.z) and refuse to sync unless skill.json is strictly higher. That turns two whole gotcha classes ("version already exists", web-UI drift) into a hard error before anything reaches the registry. Known blind spot: a just-published version still in the moderation scan is invisible to inspect on BOTH namespaces — the preflight can't see it, and republishing the same number fails at the registry instead.
Release procedure
- Edit only the SSOT files (SKILL.md, skill.json).
- Bump the version in skill.json — it must be HIGHER than what is live on both namespaces:
clawhub inspect <skill-slug> # skill: Latest: x.y.z clawhub package explore <plugin-name> # package: [Bundle Plugin] version - Sync:
python3 sync.py - Commit + push — MANDATORY before step 6 (the package publish links a commit SHA that must exist on GitHub):
First release ever? Bootstrap repo + push in one step:git add -A && git commit -m "Version -> <v>" && git push git rev-parse HEADgh repo create <owner>/<repo> --public --source . --push - Publish the skill. For a FRESH publish (new slug, no rename) the CLI works — use an ABSOLUTE path:
When a rename is involved or the CLI misbehaves, use the web UI: skill page → new version → re-select the folder fresh (browser caches the old selection) → type the display name EXACTLY into the name field → set version → publish.clawhub publish "$(pwd)/clawhub-skill" --slug <skill-slug> --name "<Display Name>" --version <v> - Publish the package (bundle-plugin) — CLI works reliably here; use an ABSOLUTE path:
clawhub package publish "$(pwd)/plugin" \ --family bundle-plugin \ --name <plugin-name> --display-name <DisplayName> \ --version <v> \ --host-targets claude-code \ --source-repo <owner>/<repo> \ --source-commit <HEAD-SHA> \ --source-ref refs/heads/main \ --source-path plugin - Claude Code channel: nothing to do — users install with
/plugin marketplace add <owner>/<repo>→/plugin install <plugin-name>@<marketplace-name>.
Verify
clawhub inspect <skill-slug> # Latest == <v>
clawhub package explore <plugin-name> # Bundle Plugin == <v>
Right after publishing, clawhub inspect returns "Skill is hidden by moderation (pending.publication)" until the security scan clears — transient at first, NOT a failed publish. Poll every ~30 s instead of republishing. Similarly, clawhub package inspect <name> may say "Package not found" while package explore already lists it (indexing/moderation lag) — trust explore for existence.
If it STAYS hidden: your content likely tripped the moderation scanner. clawhub unhide <slug> --yes does NOT work — moderation hides are Forbidden for the owner ("contact a moderator"). Self-serve fix: clean the flagged content, bump, and publish a higher version; escalate to a moderator only if that doesn't surface it. Meanwhile the profile page shows the skill missing under "Skills" while the plugin twin is visible under "Plugins" — that asymmetry is the tell that moderation, not the publish, is the problem.
Gotchas — CLI bugs & workarounds (each cost a real debugging session)
clawhub renameis broken: it errorsnewSlug requiredeven when the new slug IS provided. Rename via the web UI instead. And after a rename, CLIpublishmay still only match the original slug — another reason the web UI is the safer skill-publish path.--nameonclawhub publish(skill flow) can throw a server error — observed on EXISTING/renamed skills; on a fresh first publish (CLI v0.9.0) it worked fine. If it errors: omitting it makes the display name fall back to the folder name (you get a skill literally called "Clawhub Skill"); fix by typing the display name exactly into the web UI name field.- Web-UI upload caches the folder selection. After editing files, re-select the folder fresh or the scanner shows stale content. Sanity check: the file list/preview must show your newest files.
- EVERY clawhub path argument must be absolute — both
clawhub publish(skill) andclawhub package publisherror withPath must be a folderon a relative path. Always pass"$(pwd)/<dir>". - After a failed publish the server rate-limits retries (~45 s). Don't hammer; fix the cause, then retry once. Read errors (
inspect,package inspect) carry the hint too — the(reset in Ns)suffix tells you how long to wait.
Gotchas — registry behavior
- ClawHub search is NAME-driven, not description-semantic. Put the search tokens users will type into the skill name/slug (e.g.
known-error-fixes-database), not only the description. - Skill and package namespaces are separate. The same name can exist as both;
clawhub inspect <name>may hit the skill entry — useclawhub package inspect/package explorefor packages. --family code-pluginrequires apackage.json(it means a Node/code plugin, e.g. an MCP server). A skill bundle is--family bundle-plugin.bundle-pluginrequiresopenclaw.plugin.jsonat the plugin root — minimal valid manifest:{"id", "name", "version", "configSchema": {}}.hostTargets/format do NOT go in the manifest; they are CLI flags (--host-targets, format auto-detectsclaudefrom.claude-plugin/plugin.json).- The Claude Code marketplace needs the repo to be public; a fresh
git pushis all a "release" takes on that channel.
Gotchas — versioning bugs
- Versions are permanent and the display name follows the HIGHEST version number. A stray high version from CLI experiments hijacks the displayed name (and cannot be deleted); the only fix is publishing an even higher version. Never publish throwaway/test versions to your real slug.
- "Version already exists" errors mean the live version is >= yours. Check BOTH namespaces before bumping (skill and package are versioned independently —
clawhub inspect <skill-slug>+clawhub package explore <plugin-name>). The sync.py preflight automates exactly this check. - Web-UI publishes bypass your repo → version drift. Publishing (or auto-bumping) via the web UI updates the registry but NOT your local
skill.json; the next repo-driven release then fails as "too low" or silently ships an older number. After ANY web-UI publish, write the live version back into the SSOTskill.jsonand runsync.py— its preflight flags the drift (live > local) as a hard error. - Keep ONE monotonic version across all channels. The sync script must stamp the same number into
skill.json,plugin.json,marketplace.json, andopenclaw.plugin.json— hand-edited manifests drift apart within a release or two.
Top skills in this category
Skill Vetter
@spclaudehomeSecurity-first skill vetting for AI agents. Use before installing any skill from ClawdHub, GitHub, or other sources. Checks for red flags, permission scope, and suspicious patterns.
Clawdhub
@steipeteUse the ClawdHub CLI to search, install, update, and publish agent skills from clawdhub.com. Use when you need to fetch new skills on the fly, sync installed skills to latest or a specific version, or publish new/updated skill folders with the npm-installed clawdhub CLI.
Evolver
@autogame-17A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution. Communicates with EvoMap...
Evolver
@autogame-17A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution. Communicates with EvoMap...
Openclaw Command Center
@jontsaiMission control dashboard for OpenClaw - real-time session monitoring, LLM usage tracking, cost intelligence, and system vitals. View all your AI agents in o...