Batch-sync locally developed Skills to two public platforms:
- ClawHub — International general-purpose Skills community, MIT-0 license enforced
- Tencent SkillHub — Skills community optimized for Chinese users, no license restrictions
Supports reading .gitignore to intelligently ignore sensitive files and temporary files. The two platforms can publish independently or in parallel.
Dependencies
System dependencies
| Dependency | Purpose | Installation method |
|---|---|---|
rsync |
prepare-publish.sh Copy filtered files to a temporary publishing directory |
Bundled with macOS; Linux: sudo apt-get install rsync |
git |
prepare-publish.sh Use git ls-files to precisely match tracked files |
Bundled with macOS; Linux: sudo apt-get install git |
| Python 3 | Run the Tencent SkillHub CLI (Python script) | Bundled with macOS; Linux: sudo apt-get install python3 |
CLI tools (install on demand according to the target platform)
| CLI | Purpose | Installation command | Required scenario |
|---|---|---|---|
clawhub |
Publish to ClawHub | See ClawHub official documentation | Only when publishing to ClawHub |
skillhub |
Publish to Tencent SkillHub | Official CLI,skillhub self-upgrade upgrade (must be ≥ 2026.7.29) |
Only when publishing to SkillHub |
⚠️ Version requirement (important)
Tencent
skillhubCLI must be ≥ 2026.7.29 to supportpublish/login. Earlier versions (such as 2026.3.18) only havesearch/install, and cannot publish. Runskillhub self-upgradeto upgrade to the latest version; when unsure, first useskillhub self-upgrade --check-onlyto check whether a new version is available.
First-time installation checklist (SkillHub publishing)
# 1. 安装 CLI(macOS/Linux)
curl -fsSL https://skillhub-1388575217.cos.ap-guangzhou.myqcloud.com/install/install.sh | bash
# 2. 升级到支持发布的版本(≥ 2026.7.29)
skillhub self-upgrade
# 3. 验证(应含 publish/login 命令)
skillhub --help
# 4. 登录(token 从 https://skillhub.cn 个人设置获取,skh_ 前缀)
skillhub login --key skh_xxx
# 5. 确认身份
skillhub auth whoami
ClawHub enforces the MIT-0 license(no attribution required, commercial use allowed). Tencent SkillHub has no license restrictions, so CC-BY-NC / MIT / Apache, etc. can all be published.
Key ClawHub license terms(from the official Skill Format documentation, verified as of 2026-08):
- "All skills published on ClawHub are licensed under
MIT-0." —— All publishing is equivalent to MIT-0.- "Anyone may use, modify, and redistribute published skills, including commercially." —— Anyone is allowed to use them commercially.
- "Attribution is not required." —— Attribution is not required.
- "ClawHub does not support per-skill license overrides." —— Per-skill license overrides are not supported(writing
license: CC-BY-NCin frontmatter does not take effect at the platform level).- "Do not add conflicting license terms in
SKILL.md." —— It is forbidden to add conflicting license terms within SKILL.md。Therefore (split strategy: publish one skill to only one platform, do not distribute it repeatedly):
- General-purpose tool skills under the MIT license → publish only to ClawHub(those already published to ClawHub are no longer repeatedly published to SkillHub)
- Legal skills under restrictive licenses such as CC-BY-NC → publish only to SkillHub(Conflicts with ClawHub MIT-0, ClawHub does not accept it)
- ClawHub slug is taken, cannot be published → publish to SkillHub instead
i.e.
platformschoose one of the two ([clawhub]or[skillhub]), no longer write[clawhub, skillhub]. SkillHub is a distribution channel for content that ClawHub cannot accept (legal category, slug conflicts), not a duplicate publishing location for MIT tools.For ClawHub license details, see ClawHub Skill Format official documentation
Platform comparison
| Dimension | ClawHub | Tencent SkillHub |
|---|---|---|
| CLI tool | clawhub |
skillhub(official CLI,skillhub self-upgrade upgrade;must be ≥ 2026.7.29 to support publish/login) |
| Login command | clawhub login |
skillhub login --key skh_xxx |
| Publish command | clawhub publish <path> --slug --name --version --changelog |
skillhub publish <path> [--version] [--changelog] [--dry-run] |
| skill identifier | --slug + --name(passed via command line) |
slug + displayName(prepare-publish.sh injects a temporary copy from sync-allowlist.yaml; the source SKILL.md does not contain it) |
| Visibility | None | — (no such concept) |
| License | Mandatory MIT-0 | Unrestricted |
| Default registry/API | Built-in | https://api.skillhub.cn |
| Official tutorial | — | https://skillhub.cn/tutorials#publish-via-cli |
Prerequisites
Required fields in SKILL.md frontmatter
---
name: skill-name
description: 技能描述
version: "1.0.0" # 推荐但不强制
homepage: https://github.com/cat-xierluo/legal-skills # 自动设置
---
slug / displayName are not written into SKILL.md. What SkillHub needs is
slug(defaults toname, overridden insync-allowlist.yamlwhen there is a duplicate name / it is taken) anddisplayName(Chinese display name), which are pushed down to the localconfig/sync-allowlist.yaml, and before publishingprepare-publish.shautomatically injects them into the temporary copy's frontmatter. The source SKILL.md only keeps the standard skill fields, decoupling platform metadata from the skill itself.
CLI installation
For the complete installation method and version requirements of the CLI tool, see the "Dependencies" section at the beginning of this document.
Quickly verify it is installed:
clawhub --version # ClawHub
skillhub --help # SkillHub(确认含 publish/login 命令即为发布版)
Usage
1. Log in to the platform (first-time use)
ClawHub:
clawhub login
Tencent SkillHub(uses API Token, format skh_xxx, obtained from SkillHub personal settings):
# token 从 https://skillhub.cn 个人设置获取(skh_ 前缀)
skillhub login --key skh_xxx
# 如需临时使用其他 token 覆盖登录态(不写入本地)
skillhub login --key skh_yyy
After logging in, the token is stored locally, and subsequent publish commands do not need to pass the token again. You can also temporarily override it with
skillhub publishduring--token skh_xxx.
2. Verify login status
# ClawHub
clawhub whoami
# 腾讯 SkillHub
skillhub auth whoami
3. Sync skills
ClawHub
Sync a single skill:
clawhub sync skills/<skill-name>
Sync all skills:
clawhub sync --all
Note:
--allis subject to the constraints ofskills/clawhub-sync/config/sync-allowlist.yaml. Only skills whoseplatformsarray includesclawhubwill be synced to ClawHub.
Tencent SkillHub
SkillHub recommends publishing skills one by one (via the publish command specifying the directory, with the identifier coming from the SKILL.md frontmatter, see "Single Skill Sync Workflow" below).
# 发布目录(自动打包)
skillhub publish ./my-skill
# 指定版本和 changelog
skillhub publish ./my-skill --version 1.2.0 --changelog "新增xxx"
# 先预检(只校验 + 打包,不实际发请求)
skillhub publish ./my-skill --dry-run
SkillHub uses
slug+displayName(injected before publishing by prepare-publish.sh from sync-allowlist.yaml into a temporary copy; the source SKILL.md does not contain it) to identify the skill, and the namespace is bound to the account (no need to specify it on the command line when publishing). There is no concept of visibility.
Interactive selection sync: the user can specify the list of skills to sync and the target platform, and I will execute the sync commands one by one.
Single Skill Sync Workflow
Use this workflow when you need to sync a specified skill (rather than all of them). The process is common to both platforms; only the "Execute Publish" step differs in commands.
Pre-checks
-
Check login status
clawhub whoami # ClawHub skillhub auth whoami # 腾讯 SkillHub -
Check the whitelist
- Read
skills/clawhub-sync/config/sync-allowlist.yaml - Confirm that the target skill exists, and that its
platformsarray includes the target platform (clawhuborskillhub)
- Read
-
Check the license(required only for ClawHub)
- Read the
licensefield in the SKILL.md frontmatter of the target skill - ClawHub: only skills with an MIT license can be synced
- SkillHub: no license restrictions, all can be synced
- Read the
Version detection
Compare the two version numbers (read the records according to the target platform):
| Source | Location | Format |
|---|---|---|
| New version | skills/<skill-name>/SKILL.md frontmatter of version |
"1.2.0" |
| Recorded version | skills/clawhub-sync/config/sync-records.yaml in records.<skill>.platforms.<platform>.version |
"1.1.0" |
Version comparison logic(semantic versioning):
new_version > recorded_version → 需要同步
new_version == recorded_version → 跳过(无变化)
new_version < recorded_version → 警告(版本回退?)
recorded_version 为 null → 需要同步(首次发布)
Execute sync
Step 1: Prepare the publish directory
# ClawHub(默认平台,可省略 --platform)
bash skills/clawhub-sync/scripts/prepare-publish.sh skills/<skill-name>
# 腾讯 SkillHub
bash skills/clawhub-sync/scripts/prepare-publish.sh --platform skillhub skills/<skill-name>
The script creates a temporary directory:
- ClawHub:
/tmp/clawhub-publish-<skill-name> - SkillHub:
/tmp/skillhub-publish-<skill-name>
Step 2: Execute publish
ClawHub(use clawhub publish, explicitly specify slug and name):
clawhub publish /tmp/clawhub-publish-<skill-name> \
--slug <skill-name> \
--name "<Display Name>" \
--version "<新版本号>" \
--changelog "<变更说明>"
⚠️ You must specify --slug and --name
- The temporary directory name may contain a prefix (such as
clawhub-publish-), causing an incorrect slug at publish time--slug <skill-name>Ensure the correct skill identifier is used--name "<Display Name>"Ensure the correct name is displayed on ClawHub
Tencent SkillHub(use skillhub publish, specify version and changelog):
skillhub publish /tmp/skillhub-publish-<skill-name> \
--version "<新版本号>" \
--changelog "<变更说明>"
Tencent identifies skills by slug + displayName: these two fieldsare not written into the source SKILL.md, but before publishing are read by
prepare-publish.shfromconfig/sync-allowlist.yamland injected into the frontmatter of the temporary copy (slug defaults toname, displayName takes the configureddisplay_name). namespace is bound to the account (no need to specify it on the command line when publishing), and there is no concept of visibility. The version number and changelog are passed explicitly via--version/--changelog; without--version, they are determined by the CLI. Before publishing, you can add--dry-runto do a dry run only.
Step 3: Update the sync record
Update skills/clawhub-sync/config/sync-records.yaml, writing a record under the corresponding platform:
records:
<skill-name>:
platforms:
clawhub: # 或 skillhub
version: "<新版本号>"
last_sync: "<ISO 8601 时间>"
git_hash: "<当前 commit hash>"
status: synced
changelog_summary: "<变更说明>"
url: "https://clawhub.ai/skills/<skill-name>" # ClawHub
# 或 SkillHub:
# url: "https://skillhub.cn/skills/<slug>"
publish_id: "<从命令输出获取>"
Example: sync a skill (publish to the corresponding platform according to the routing policy)
A. MIT tool → ClawHub (using git-batch-commit as an example)
# 1. 检查白名单
grep -A1 "git-batch-commit:" skills/clawhub-sync/config/sync-allowlist.yaml
# 输出:platforms: [clawhub] # MIT 工具,只发 ClawHub
# 2. 比较版本
# SKILL.md: version: "1.2.0"
# sync-records.yaml: platforms.clawhub.version: "1.1.0" → 需要同步
# 3. 准备并发布到 ClawHub
bash skills/clawhub-sync/scripts/prepare-publish.sh skills/git-batch-commit
clawhub publish /tmp/clawhub-publish-git-batch-commit \
--slug git-batch-commit --name "Git Batch Commit" \
--version "1.2.0" --changelog "本次变更说明"
# 4. 更新 sync-records.yaml 的 platforms.clawhub 字段
B. CC-BY-NC legal category → SkillHub (using legal-qa-extractor as an example)
# 1. 检查白名单
grep -A2 "legal-qa-extractor:" skills/clawhub-sync/config/sync-allowlist.yaml
# 输出:platforms: [skillhub] + display_name: "法律问答知识提取"
# 2. 准备(--platform skillhub 会自动从配置读 display_name/slug 注入临时副本 frontmatter)
bash skills/clawhub-sync/scripts/prepare-publish.sh --platform skillhub skills/legal-qa-extractor
# 3. 发布到 SkillHub
skillhub publish /tmp/skillhub-publish-legal-qa-extractor \
--version "<新版本号>" --changelog "<变更说明>"
# 4. 更新 sync-records.yaml 的 platforms.skillhub 字段
Failure handling
- On sync failure, record
status: failed - Do not retry; let the user decide the next action
- Record the failure reason to
changelog_summary
SkillHub-specific notes
Token acquisition
- Log in to SkillHub
- Generate an API Token in personal settings (format
skh_xxx, prefixskh_) - Use
skillhub login --key skh_xxxto save it locally
skillhub login --key skh_xxx
skillhub auth whoami # 确认身份
Security reminder: A Token is equivalent to an account password,Neverwrite to config files or commit to Git.
skillhub loginThe token has been saved locally, so subsequent publish commands do not need to pass the token again (the CLI reads it automatically); if you need to temporarily override it, you can use it whenskillhub publishwith--token skh_xxx。
slug / namespace and version number rules
Tencent SkillHub uses slug + displayName + namespace(account-bound) to identify a skill.slug/displayName are not written into the source SKILL.md, but in config/sync-allowlist.yaml configuration, and before publishing are injected by prepare-publish.sh into the frontmatter of a temporary copy:
- slug: kebab-case, 2-128 characters (validation regex measured in practice). Default = skill directory name (i.e.
name); insync-allowlist.yamloverride with theslug:field (to handle duplicate names/being occupied). A slug is unique within the same namespace, and may be duplicated across namespaces (e.g.@cat-xierluo/md2worddoes not conflict with someone else's@xxx/md2word) - namespace: namespace,bound to the account(server-side
@<namespace>/<slug>format), the publish commanddoes not need and cannotspecify it on the command line—the CLI uses the identity of the logged-in account, and the server automatically assigns it under your namespace. Your namespace can be found byskillhub search <你的skill>viewing the@xxx/slugprefix of a published skill - version: valid SemVer (
major.minor.patch), e.g.1.0.0. It is recommended to start from0.1.0or1.0.0. A published version cannot be modified; only a new version can be published
API host
The default API host is https://api.skillhub.cn. If you need to override it,skillhub publish use --host <URL> to specify it.
SKILL.md frontmatter requirements
When publishing to Tencent SkillHub, skill metadata is read from the SKILL.md frontmatter (of the temporary copy).The source SKILL.md does not need to include slug/displayName——prepare-publish.sh will read from config/sync-allowlist.yaml and inject into the temporary copy:
| Field | Source | Description |
|---|---|---|
slug |
Defaults to name;sync-allowlist.yaml of slug: can override |
kebab-case, 2-128 characters |
displayName |
sync-allowlist.yaml of display_name:(required) |
SkillHub display name (Chinese) |
version |
Source SKILL.md frontmatter (or --version override) |
valid SemVer |
summary |
Source SKILL.md (optional) | short summary |
description |
Source SKILL.md (optional) | longer description |
tags |
Source SKILL.md (optional) | tag array |
license |
Source SKILL.md (optional) | license identifier |
homepage |
Source SKILL.md (optional) | homepage URL |
Differences between ClawHub and Tencent fields: ClawHub uses the
namefield + command-line--slug/--name; Tencent usesslug+displayName(injected into a temporary copy, not written in the source file; namespace is bound to the account). The source SKILL.md only keepsname/description/versionand other standard fields. The identity requirements of both platforms are satisfied by the publishing process (command-line parameters / config injection), without polluting the skill itself.
CLI version note
Tencent skillhub CLI is a Python script.Old versions (< 2026.7.29) do not support publish/login; run skillhub self-upgrade to upgrade to the latest version; if unsure, first use skillhub self-upgrade --check-only to check whether a new version is available.
Publish rate limit (avoid concurrent rate limiting)
The Tencent SkillHub API has a rate limit on publish requests.Multiple consecutive skillhub publish will trigger rate limiting(error "Too many requests, please try again later"); a single publish failure requires a retry and will slow down the entire batch process.
Measured safe interval: between each skillhub publish , sleep 12-15 seconds. The estimated total time to publish N in a batch ≈ N × (single publish time + 15s).
Recommended approach(Serial + sleep, do not parallelize):
while IFS='|' read -r s v; do
bash prepare-publish.sh --platform skillhub "skills/$s" >/dev/null 2>&1
echo "$s: $(skillhub publish /tmp/skillhub-publish-$s --version "$v" --changelog '...' 2>&1 | tail -1)"
sleep 15
done <<EOF
skill-a|1.0.0
skill-b|1.1.0
EOF
Failure handling: When encountering a rate limit error, do not immediately re-run the entire batch.sleep 30-60 seconds later, retry only the failed skill (from sync-records.yaml see which platforms are still pending)。
Avoid:for s in ...; do (skillhub publish $s &); done(parallel) —— 100% triggers rate limiting.
Sync strategy
Version number handling
- From the skill's
CHANGELOG.mdfirst line extract the version number - Format requirements:
## [x.y.z] - YYYY-MM-DD - Automatically handle the
vprefix (v1.0.0→1.0.0)
Automatic fields
| Field | Handling method |
|---|---|
homepage |
Automatically set to the GitHub repository URL |
version |
Extracted from CHANGELOG.md (if not specified in SKILL.md) |
Sync scope control (whitelist mechanism)
Configuration file: skills/clawhub-sync/config/sync-allowlist.yaml(skill self-contained)
Priority: whitelist > default ignore rules
- If
sync-allowlist.yamlexists: Only sync the skills listed in the file, and only sync to the platforms listed in itsplatformsarray - If
sync-allowlist.yamldoes not exist: Use the default ignore rules (ignore test/, private-skills/, node_modules/)
Configuration format (structured platforms field):
# MIT 许可证 → 只发 ClawHub(不重复发 SkillHub)
md2word:
platforms: [clawhub]
# CC-BY-NC 许可证 → 只发 SkillHub(ClawHub 强制 MIT-0,冲突)
legal-qa-extractor:
platforms: [skillhub]
display_name: "法律问答知识提取"
# ClawHub slug 被占用 → 改发 SkillHub
# some-skill:
# platforms: [skillhub]
To enable/disable a platform for a skill, adjust its platforms array (commenting out the entire entry means the skill will not be published).
Configuration files and privacy (example vs local)
Configuration files are split into a public template and a local real one, making it easy for others to reuse this skill:
| File | Role | In repository | Contains local real data |
|---|---|---|---|
config/sync-allowlist.example.yaml |
Public template | ✅ In repository | No |
config/sync-records.example.yaml |
Public template | ✅ In repository | Use placeholders |
config/sync-allowlist.yaml |
Local real configuration | ❌ Excluded by gitignore | — |
config/sync-records.yaml |
Local real configuration | ❌ Excluded by gitignore | Fill in the actual publish_id, etc. |
First-time use: Copy
.example.yamlremove the.examplesuffix, and fill in your actual data.sync-allowlist.yamlIn addition toplatforms, also configure for each skilldisplay_name(SkillHub display name, required) and optionalslug(overrides when there is a name conflict); before publishing,prepare-publish.shinjects a temporary copy; the source SKILL.md does not contain these two fields.sync-records.yamlrecordpublish_idand wait for the publish result.Root directory
.gitignore's**/config/*.yaml+!**/config/*.example.yamlrulesapply to both ClawHub and SkillHub platforms(sharing the sameprepare-publish.shfiltering logic). In actual testing when publishingclawhub-syncitself, the realsync-allowlist.yaml/sync-records.yamldoes not enter the temporary directory; only the.example.yamltemplate is uploaded.Root directory
.gitignorehas passed the**/config/*.yaml+!**/config/*.example.yamlrules, automatically excluding real configuration and keeping templates.
File filtering rules
During publishing, .gitignore filtering rules are automatically applied to ensure sensitive files and temporary files are not uploaded. Both platforms share the same filtering logic.
Dual filtering mechanism:
- Project root .gitignore - Automatically detects the Git repository root's
.gitignore - Skill internal .gitignore - If the skill directory has its own
.gitignore, it will be additionally applied
Default exclusions(always in effect):
.git/- Git directorynode_modules/- Node.js dependencies__pycache__/- Python cache.DS_Store- macOS system files
Sync process
Before each sync, it will automatically:
- Create a temporary directory - The prefix varies by platform:
/tmp/clawhub-publish-<skill>or/tmp/skillhub-publish-<skill> - Copy the filtered files - Use rsync to copy files following .gitignore rules
- Publish to the target platform - Execute the corresponding platform's publish command from the temporary directory
- Clean up the temporary directory - Automatically cleaned up after publishing is complete
Manually prepare the publish directory
If you need to manually check the files to be published:
# ClawHub(默认)
bash skills/clawhub-sync/scripts/prepare-publish.sh skills/trademark-assistant
ls -la /tmp/clawhub-publish-trademark-assistant/
# 腾讯 SkillHub
bash skills/clawhub-sync/scripts/prepare-publish.sh --platform skillhub skills/trademark-assistant
ls -la /tmp/skillhub-publish-trademark-assistant/
Security best practices
Pre-publish checklist
- Confirm that
.gitignoreincludes all sensitive file patterns - Use
prepare-publish.shto check the files to be published - Do not include API keys, passwords, etc. in the skill
- Use
.env.exampleinstead of.envfiles
Common sensitive files
.env- Environment variables (use.env.exampleas a template)config.yaml- Configuration files (useconfig.example.yamlas a template)*.db,*.sqlite- Database fileslogs/- Log directorydownloads/,output/- Output directory
Fix an already-published skill
If you find that an already-published skill contains sensitive information:
- Update immediately - Remove sensitive files from the skill directory
- Update .gitignore - Ensure they will not be included again in the future
- Republish - Use
clawhub publishorskillhub publishto update the corresponding platform - Contact platform support - If you need to delete the old version
Important reminder:
- Both platforms are public platforms: published skills can be accessed by anyone
- Do not include customer information: case files, communication records, etc. should be excluded
- Do not include credentials: API keys, tokens, etc. should use environment variables
FAQ
Version number not updated?
Check the CHANGELOG.md format:
## [1.0.0] - 2026-03-21
### 新增
- 新功能描述
Sync failed?
- ClawHub: run
clawhub sync --dry-runto check the configuration - SkillHub: confirm that
skillhub auth whoamilogin is normal,sync-allowlist.yamlhasdisplay_nameconfigured for the skill (slug defaults to name; when display_name is missing, prepare-publish.sh fails closed with an error) - Confirm the SKILL.md frontmatter format is correct
- Check the whitelist: whether the target skill's
platformsincludes the target platform
ClawHub reports a license conflict?
Licenses such as CC-BY-NC conflict with ClawHub MIT-0 and cannot be published to ClawHub. For such skills, publish to SkillHub instead (no license restrictions). See ClawHub Skill Format official documentation。
Input/Output
Input
- Required: locally developed skill directory
- Optional: specified skill name list, target platform (clawhub / skillhub), whitelist configuration
Output
- Sync result report (success/failure list, grouped by platform)
- Error information (if any)
Sync records
After each sync, config/sync-records.yaml record files are updated, making traceability and incremental sync easier. Records are stored separately by platform.
Record structure
records:
<skill-name>:
platforms:
clawhub: # ClawHub 平台记录
<fields>
skillhub: # 腾讯 SkillHub 平台记录
<fields>
Record fields
| Field | Description | Applicable platform |
|---|---|---|
version |
Version number at sync time | Both |
last_sync |
Last sync time (ISO 8601) | Both |
git_hash |
Commit hash at sync time | Both |
status |
synced / pending / failed / skipped / slug_conflict / deleted |
Both |
changelog_summary |
Change summary | Both |
url |
Platform publish address | Both |
publish_id |
Platform-internal ID | Both |
namespace |
Namespace (account-bound, such as cat-xierluo; not passed at publish time, recorded for tracing the install command) |
SkillHub |
Record example
records:
md2word:
platforms:
clawhub:
version: "1.1.8"
last_sync: "2026-03-24T16:42:00+08:00"
git_hash: "fbb1db4"
status: synced
changelog_summary: "全书自动更新目录域"
url: "https://clawhub.ai/skills/md2word"
publish_id: "k97dtn63cty6ezwzj9g9ry85818axkdq"
skillhub:
namespace: "cat-xierluo"
version: "1.1.8"
last_sync: "2026-08-01T10:00:00+08:00"
git_hash: "fbb1db4"
status: synced
changelog_summary: "首次发布 SkillHub"
url: "https://skillhub.cn/cat-xierluo/md2word"
publish_id: "sh_xxxxxxxxxxxxxxxx"
Purpose
- Incremental sync: only sync skills with
status: pendingor version updates (judged independently by platform) - Traceability: use
git_hashto trace the code state at publish time - Quick access: use
urlto directly access the skill page on the platform