Skill Release Plus

Other

Multi-hub skill publisher. Sign → Audit (placeholder) → Pack (clean tar.gz with exclude rules) → Publish to clawhub.com, skillhub.cn (Tencent Cloud), or GitHub Releases, all in one command. Pluggable adapter framework — add your own hub via a user-hook script (subprocess + JSON envelope). Single source of truth: one exclude.json, one signing pass, one package, fan out to N targets. Default target: clawhub only. Use --target all for all three real hubs, or --target user-hook:./my-script.sh for custom destinations. Triggers on: publish skill, release skill, push to skill hub, ship skill to multiple hubs, 发布 skill, 上传到 clawhub, 发布到 skillhub.cn.

Install

openclaw skills install @songhonglei/skill-release-plus

skill-release-plus

Version: 1.0.3
Author: Evan Song <github.com/Songhonglei> Repo: https://github.com/Songhonglei/build-better-skills/tree/main/skills/skill-release-plus License: MIT (this repo) — clawhub mirror auto-uses MIT-0 (platform-enforced)
Part of: build-better-skills suite — see Stages for the lifecycle map.

Sign → Pack → Publish to multiple skill hubs in one command. Supports clawhub.com, skillhub.cn (Tencent Cloud), GitHub Releases, and any custom hub via a user-hook script.


Quick start

# Default: publish to clawhub only
python3 scripts/release.py --slug my-skill -m "first release" --version 1.0.0

# Publish to all three real hubs at once
python3 scripts/release.py --slug my-skill -m "ship it" --version 1.0.0 --target all

# Custom hub via user hook
python3 scripts/release.py --slug my-skill -m "v1" --version 1.0.0 \
    --target user-hook:/path/to/my-publish.sh

# Check token readiness before publishing
python3 scripts/release.py --check --target all

# Dry-run (sign + pack, skip publish)
python3 scripts/release.py --slug my-skill -m "test" --version 1.0.0 --dry-run

# Inspect current exclude rules
python3 scripts/release.py --show-exclude

Supported targets

TargetStatusAuthNotes
clawhubSRP_CLAWHUB_TOKEN (env) or clawhub loginWraps the clawhub CLI
skillhub-cnSRP_SKILLHUB_CN_TOKEN (env)Tencent Cloud — POST /api/v1/community/skills/publish (multipart). Rate-limit 3 publish/min/token. Auto-retries on 429.
github-releaseSRP_GITHUB_TOKEN (env)Pure git + GitHub REST API (no gh CLI required). Supports owner/repo[/subdir] for monorepo layouts.
user-hook:<path>Hook-definedYour script receives metadata via env vars + JSON stdin, returns {"ok": true, "url": "..."} on stdout

Not supported: cn.clawhub-mirror.com (ByteDance Volcano) is a read-only public mirror of clawhub.com — publishing to clawhub automatically syncs there. There is no separate publish endpoint.


Installation

# Install Python 3.8+ (standard library only, no pip install needed)
git clone https://github.com/Songhonglei/build-better-skills.git
cd build-better-skills/skills/skill-release-plus

# Or install via clawhub:
clawhub install skill-release-plus

Dependencies:

  • Python 3.8+ (standard library only — urllib, subprocess, tarfile, json, argparse, dataclasses, pathlib)
  • git 2.x (for github-release target only)
  • clawhub CLI (for clawhub target only — auto-detected from $PATH)
  • skill-sign (optional — for content signing; skipped if not installed)
  • PyYAML (optional — improves SKILL.md frontmatter parsing for edge cases; stdlib fallback handles description: "..." single-line and description: > folded scalar without it)

Configuration

Resolution priority (highest → lowest):

  1. CLI args (--slug, --target, --version, etc.)
  2. Process env vars (SRP_* private namespace)
  3. Project-local ./.env
  4. Global ~/.config/skill-release-plus/.env
  5. Missing required key → onboarding prompt (interactive)

Environment variables (all SRP_* prefixed)

VariableRequired forDescription
SRP_CLAWHUB_TOKENclawhub targetclawhub API token (or run clawhub login)
SRP_SKILLHUB_CN_TOKENskillhub-cn targetTencent skillhub.cn personal token (starts with skh_)
SRP_GITHUB_TOKENgithub-release targetGitHub PAT with repo scope
SRP_GITHUB_OWNERgithub-release (optional)Default repo owner (defaults to authenticated user)
SRP_GITHUB_REPOgithub-release (optional)Default repo name (defaults to slug)
SRP_GITHUB_BRANCHgithub-release (optional)Default branch (default: main)
SRP_GITHUB_BASIC_AUTH_HEADERgithub-release (optional)If true, use HTTP Basic Auth header instead of URL-embedded token
SRP_DEFAULT_TARGETSoptionalComma-separated default target list (default: clawhub)
SRP_OUTPUT_DIRoptionalPackage output directory (default: <cwd>/output/skill-release)
SRP_SIGN_OPTIONALoptionalIf true, skip signing when skill-sign not installed (default: true)
SRP_SIGN_SCRIPToptionalExplicit path to sign.py (overrides auto-detection of skill-sign)

Architecture

release.py (dispatcher, 352 LOC)
  ├─ _lib_config.py         (4-layer config + parse_targets, 289 LOC)
  ├─ _lib_package.py        (sign / pack / exclude rules / multipart, 305 LOC)
  ├─ _lib_adapters_base.py  (BaseAdapter ABC, 98 LOC)
  └─ _adapter_*.py:
       ├─ clawhub          (CLI wrap, 185 LOC)
       ├─ github-release   (git + GitHub REST API, 392 LOC)
       ├─ skillhub-cn     (Tencent Cloud HTTP/multipart, 308 LOC)
       └─ user-hook       (subprocess + JSON envelope, 140 LOC)

Design principles:

  • Single source of truth: One config/exclude.json, one signing pass, one tar.gz, fan out to N targets
  • Adapter independence: Each adapter is a separate Python module subclassing BaseAdapter; no cross-adapter coupling
  • Fail-open by default: One target failing does not block others (dispatcher reports per-target status)
  • Protocol-agnostic base: BaseAdapter doesn't assume HTTP / multipart / git — adapters own their protocol

Writing a custom adapter (user-hook)

Create an executable script:

#!/bin/bash
# my-publisher.sh
set -e

# Hook receives:
#   $SRP_HOOK_SLUG, $SRP_HOOK_VERSION, $SRP_HOOK_CHANGELOG,
#   $SRP_HOOK_TAR_PATH, $SRP_HOOK_SKILL_DIR, $SRP_HOOK_DISPLAY_NAME

curl -sf -F "package=@$SRP_HOOK_TAR_PATH" \
     -F "version=$SRP_HOOK_VERSION" \
     "https://my-private-hub.example.com/publish"

# Print JSON envelope on stdout for the dispatcher to parse
echo '{"ok": true, "url": "https://my-private-hub.example.com/skills/'"$SRP_HOOK_SLUG"'"}'

Then invoke:

chmod +x my-publisher.sh
python3 scripts/release.py --slug my-skill -m "v1" --version 1.0.0 \
    --target user-hook:./my-publisher.sh

Exclude rules

Default config/exclude.json strips:

  • VCS: .git, .svn, .hg
  • IDE: .idea, .vscode, .DS_Store, Thumbs.db
  • Build artifacts: __pycache__, *.pyc, node_modules, dist, build
  • Secrets: .env, .secrets, *.pem, *.key, .token
  • Test/dev: tests/__pycache__, .pytest_cache, .tox
  • See full list: python3 scripts/release.py --show-exclude

Command reference

usage: release.py [-h] [--slug SLUG] [--changelog CHANGELOG]
                  [--version VERSION] [--display-name DISPLAY_NAME]
                  [--skill-dir SKILL_DIR] [--target TARGET] [--dry-run]
                  [--show-exclude] [--check]

options:
  -h, --help            show this help message and exit
  --slug SLUG           skill slug (lowercase, digits, hyphens)
  --changelog, -m       release changelog
  --version VERSION     explicit version (semver); default: auto-bump patch
  --display-name        human-readable display name (default: slug)
  --skill-dir SKILL_DIR  path to skill source directory (default: ./<slug>)
  --target TARGET       comma-separated targets, or "all". Default: clawhub.
                        Special: user-hook:<path> for custom hooks.
  --dry-run             sign + pack but skip publish
  --show-exclude        print current exclude rules and exit
  --check               check token readiness for selected targets

Exit codes:

  • 0 — all targets succeeded
  • 1 — at least one target failed (others may have succeeded)
  • 2 — invalid arguments or config error

Triggers

This skill should be used when the user says:

  • "publish skill X to clawhub / skillhub.cn / GitHub"
  • "ship my skill to multiple hubs"
  • "release X.Y.Z of my skill"
  • "发布 skill 到 clawhub"
  • "把 skill 推到 skillhub.cn"
  • "skill 同时发到三个 hub"
  • "用 user-hook 发到我自己的 hub"

Limitations

  • skillhub-cn rate limit: 3 publish/minute/token. Dispatcher waits and retries on 429.
  • github-release requires explicit --version: No auto-tag-bump (would require parsing existing tags reliably across owner/repo combos).
  • skillhub-cn requires description in SKILL.md frontmatter (≤1024 bytes). YAML folded (>) scalar is supported.
  • No rollback: If 2/3 targets succeed and 1 fails, you must manually clean up the 2 successes or accept partial state.

License

MIT (this repo). See LICENSE.

Note: when this skill is published to clawhub.com, the platform enforces MIT-0 license metadata on hub mirror — original repo MIT license is unchanged.