opensource-skill-to-github

内容来源:clawhub · 原始地址 · 查看安装指南

原始内容


name: opensource-skill-to-github description: > Quickly open-source a local skill to GitHub (primary) and optionally clawhub.com. Workflow: slug pre-check, fork to opensourceskills, strip internal info, normalize SKILL.md, generate LICENSE/README, init git, push to GitHub with configurable token source, and optionally publish to clawhub. Use when the user says "open-source this skill", "把这个 skill 开源", "发到 github", "publish skill publicly", or "把本地 skill 发开源". Hard rules: never modify the original skill in place, never auto-add force/yes flags, never write tokens to git/remote/memory, and ask the user at decision points.

Open-source a Local Skill to GitHub (+ optional clawhub.com)

把一个本地 skill 端到端开源到 GitHub(主)+ clawhub.com(可选)。 基于多个 skill 开源实践沉淀的完整方法论(见 references/opensource_playbook.md)+ 11 条剔除清单 + 16 项 checklist。 质量优先:每个决策点(LICENSE / slug 冲突 / 内网信息残留 / token)必须等用户拍板。

设计哲学

  • 副本而非演进:原 skill 一行不动;副本放 opensourceskills/<slug>/,独立 commit / 版本号 / sign。
  • 混合形态:能脚本化的(剔除扫描、git init、frontmatter 校验)走脚本;需要决策的(LICENSE、slug rename、token、敏感部门 visibility)走对话。
  • 首版 v1.0.0:clawhub 用户期望"成熟" first release,不用 v0.x 试探。
  • GitHub 主、clawhub 副:本 skill 默认走 GitHub,clawhub 在 §6 可选。skills.sh 通过 GitHub 自动同步无需单独操作。
  • 不硬编码身份 + 一次配置永久用:所有作者/handle/邮箱通过持久化 profile 自动读取,跨 agent / 跨 workspace / skill 重装都不丢。

首次使用:配置开源身份(一次性,跨 agent 持久化)

bash scripts/setup_profile.sh
# 交互式问 3 个字段:
#   Author name        (如 "Evan Song")
#   GitHub handle      (如 "Songhonglei")
#   Author email       (推荐 GitHub noreply: "<handle>@users.noreply.github.com")
# 写入 ~/.config/opensource-skill-to-github/profile.env (chmod 600)

为什么这么放

  • 在用户 $HOME 而非 skill 目录 → skill 升级/重装不丢
  • 在用户 $HOME 而非 workspace → 换 agent / 换 workspace 仍有效(适配 OpenClaw / Claude Code / Cursor 等任意环境)
  • XDG 兼容($XDG_CONFIG_HOME 优先),符合 Linux / macOS 用户文件规范

身份取值优先级(高 → 低):

  1. 脚本命令行参数显式传入
  2. OSG_AUTHOR_NAME / OSG_GITHUB_HANDLE / OSG_AUTHOR_EMAIL 环境变量(适合 CI/CD 或临时覆盖)
  3. ~/.config/opensource-skill-to-github/profile.env ← 主要载体
  4. git config --global user.name/user.email 兜底
  5. 仍缺失 → 报错并指引跑 scripts/setup_profile.sh

常用命令

bash scripts/setup_profile.sh             # 首次/重新引导
bash scripts/setup_profile.sh --show      # 查看当前生效配置 + 来源
bash scripts/setup_profile.sh --path      # 打印 profile 路径
bash scripts/setup_profile.sh --non-interactive  # CI 模式,从 env 读

GitHub push token 配置(可选)

github_push.sh 支持把 token 做成配置项,避免每次真实 repo 发布都重新让用户粘贴。 优先级为:

  1. GITHUB_TOKEN(一次性环境变量)
  2. OSG_GITHUB_TOKEN(长期环境变量或 profile;明文,不推荐)
  3. OSG_GITHUB_TOKEN_CMD(推荐;命令 stdout 第一行返回 token)
  4. gh auth token(已登录 GitHub CLI 时自动读取)

推荐写法:

# 放进 ~/.config/opensource-skill-to-github/profile.env
OSG_GITHUB_TOKEN_CMD="gh auth token"

# 或使用 macOS Keychain,不把 PAT 明文写入 profile
OSG_GITHUB_TOKEN_CMD="security find-generic-password -a $USER -s opensource-skill-to-github.github-token -w"

脚本不会把 token 写入 git remote、命令输出或 memory。若使用一次性 PAT,推送后仍应撤销。

工作流总览(10 步)

每步后面标注「类型」:🔧 脚本(可直接跑)/ 💬 对话(需用户拍板)/ 🔗 引用(调其他 skill)。

⚠️ 首次使用先跑 scripts/setup_profile.sh 配置开源身份(见上节)。已配置过的用户跳过此步。

步骤 类型 工具
0. slug 预检 🔧 scripts/precheck.sh <slug>
1. 决策框架 4 问 💬 对话
2. 副本化 🔧 scripts/fork.sh
3. 11 条剔除清单扫描 + 拍板 🔧 → 💬 scripts/strip_scan.sh 跑完用户拍板每处
4. SKILL.md frontmatter 规范化 🔧 → 💬 scripts/check_frontmatter.py + 手工 edit
5. LICENSE 拍板 + 生成 💬 → 🔧 对话选类型 → scripts/gen_license.sh(author 自动从 profile 读)
6. README + CHANGELOG + .gitignore 生成 🔧 scripts/scaffold.sh(author/handle 自动从 profile 读;changelog 独立文件)
7. 本地 git init 🔧 scripts/git_init.sh(user.name/email 自动从 profile 读)
8. UGLIC 自审(推荐) 🔗 glic-check skill
9. GitHub repo 创建(用户手工)+ push 💬 → 🔧 用户建 repo + scripts/github_push.sh <fork> <repo-name>(handle 自动拼)
10. clawhub 发版(可选)+ memory 沉淀 🔧 → 💬 scripts/clawhub_publish.sh(已登录免 token)+ 沉淀文档
11. 腾讯 skillhub.cn 发版(可选) 🔧 SKILLHUB_CN_TOKEN=skh_xxx scripts/skillhub_cn_publish.sh <fork>

一键前 6 步scripts/run_all.sh <源skill名或绝对路径> [<new-slug>] 会串联 precheck→fork→strip_scan→license→scaffold→git_init(strip 命中仍需人工拍板; push / clawhub / skillhub.cn 因需 token + 确认不自动跑,脚本结束打印手动指引)。

跨 agent 通用性(v1.0.3)

本 skill 可移植到非 OpenClaw 的 agent(Claude Code / Cursor 等):

  • 源 skill 定位fork.sh 支持传 skill 绝对路径,或按名在多目录探测 ($SKILLS_DIR~/.claude/skills~/.cursor/skills./skills~/.openclaw/workspace/skills
  • 输出目录OPENSOURCE_OUT_DIR 覆盖(默认 ./opensourceskills
  • 独立 git repogit_init.sh 只认 fork 自己的 .git,即使 fork 位于某个已是 git repo 的 工作区内也不会误提交到父仓库(v1.0.3 修复,附二次校验)
  • 内网关键词表OSG_STRIP_KEYWORDS env 或 strip_keywords.txt 文件自定义(换公司内网词)

Dependencies

System commands

  • bash (≥ 4.0)
  • git (任意现代版本,新建 repo 推荐 ≥ 2.28 支持 -b main,老 git 有 symbolic-ref 兜底)
  • python3 (≥ 3.8,仅 scripts/check_frontmatter.py 使用,零外部包依赖)
  • curl (用于 Step 9 GitHub repo 存在性预探测 + push 后 sha 验真 + skillhub.cn 发布,可选/按需)
  • rsync (用于 fork.sh 排除 node_modules 复制,缺失时自动回退 cp -r)
  • node + npm (用于安装 clawhub CLI;只在 Step 0 预检和 Step 10 clawhub publish 时需要)
  • clawhub CLI (npm install -g clawhub,只在用 clawhub 渠道时需要)

macOS 兼容

  • base64 已做兜底(-w0 BSD 不支持 → 回退 base64 | tr -d '\n'
  • 其它命令(find / grep / sed / awk)使用 POSIX 子集,跨平台兼容

Step 0: slug 冲突预检(必须第一步)

默认 slug 沿用源 skill 名(即 <source-skill-name>),先用源 skill 名查重,命中再进入 rename 子流程。

scripts/precheck.sh <source-skill-name>
# 实际执行:clawhub inspect <source-skill-name>
命中情况 处理
未注册 ✅ 安全继续,slug = source-skill-name
同 owner 同名 升版本号直接 publish 即可(不需开源新流程)
别人 owner 同名 必须换 slug(加品牌前缀 claw- / openclaw- / 自定义)— 让用户拍板新 slug,重跑 precheck 直到通过
名字不同但概念高度雷同 让用户读对方 SKILL.md 决定差异化定位

Why:clawhub 不支持 slug rename,一旦 publish 就锁死。agent-memory-manager 真撞过 georges91560 已注册同名,预检省 80+ 分钟返工。

退出码

  • 0 = 未注册可继续
  • 3 = 已注册需用户决策
  • 4 = 网络异常(重跑)

Step 1: 决策框架(开源前 4 问,对话拍板)

向用户确认:

  1. 这个 skill 该不该开源:内网耦合多 ≠ 不能开源,可以走"重制版"思路
  2. 走"原 skill 直接演进"还是"副本剥离":内网仍有用户 → 副本;只有少量内网细节 → 演进
  3. 副本起点:已发版稳定版(推荐,更可控),不要拿 dirty WIP 当起点
  4. 重制版要不要扩范围:可以加,但只在副本里加,内网版按原节奏走

默认选副本(本 skill 整套流程围绕"副本"设计)。


Step 2: 副本化

scripts/fork.sh <source-skill-name> [<new-slug>]
# 默认:cp -r skills/<source> opensourceskills/<source>
# 若 slug 改名:opensourceskills/<new-slug>
# 自动删:sign.key、.install-source.json、__pycache__/、*.pyc、.skill-data/、skill_meta.json、*.json.md

强约束:副本和内网版独立 commit、独立版本号、独立 sign.key。绝不原地改原 skill。


Step 3: 11 条剔除清单(扫描 + 报告)

scripts/strip_scan.sh <fork-path>
# 跑两轮:
#  ① 文件层:列必删项当前状态(sign.key / __pycache__ / USAGE.md 重复等)
#  ② 字面层:grep 内网关键词(公司内网域名 / 平台代号 / sso_token 等,见 strip_keywords 配置)
# 输出:零命中 / 命中位置清单

完整 11 条清单和替换映射见 references/strip_checklist.md复杂或大量字面替换的细节场景,可参考 references/opensource_playbook.md 第 3 节做深度处理(progressive disclosure)。

报告输出后必须对话:grep 命中的每一处由用户拍板「保留 / 删除 / 改写」,AI 不自决。


Step 4: SKILL.md frontmatter 规范化

frontmatter 跨 agent 兼容硬约束 3 条(hello-env v1.0.0→v1.0.2 实证):

  1. description> folded scalar(避免引号转义)
  2. description ≤ 1024 字节(Anthropic 上限)
  3. frontmatter 只留 name + description——version / metadata / author / tags 都搬到 Markdown body

Markdown body 顶部 4 行(必加)

- **Version**: 1.0.0
- **License**: MIT
- **Author**: <real name> · [github.com/<handle>](https://github.com/<handle>)
- **Repository**: https://github.com/<handle>/<repo-name>

⚠️ clawhub 卡片只解析 SKILL.md 顶部,README 写得再漂亮都不算。

校验工具:scripts/check_frontmatter.py <skill-path>(4 项校验,0 ERR 才放行)。


Step 5: LICENSE 拍板 + 生成

必须问用户拍板,AI 不自填:

scripts/gen_license.sh <fork-path> <MIT|Apache-2.0|GPL-3.0> "<real name>" <year>

⚠️ 对外署名规则:用对外身份(如 Jane Doe)+ 公网邮箱(*@gmail.com 等),不用内网邮箱。 ⚠️ 脚本会自动清洗作者名中的换行/反引号/分号等危险字符。


Step 6: README.md + CHANGELOG.md + .gitignore 生成

scripts/scaffold.sh <fork-path>
# 生成:
#   README.md    ← 模板含 Quick Start / Features / Install / License / Author;Changelog 段只留指针
#   CHANGELOG.md ← 独立版本历史(Keep a Changelog 惯例),初始含 v1.0.0 条目
#   .gitignore   ← 通用安全规则(id_rsa / *.p12 / *.keystore / certs/*.key / .env / node_modules / __pycache__ 等)

Changelog 惯例(强约束):版本历史一律放独立 CHANGELOG.md——

  • ❌ 不放 SKILL.md:agent 每次触发都读 SKILL.md,历史记录纯属上下文浪费
  • ❌ 不堆 README:版本多了喧宾夺主
  • ✅ SKILL.md / README 各留一行指针 See [CHANGELOG.md](./CHANGELOG.md)
  • strip_scan.sh 会检测 SKILL.md 内嵌 changelog(≥2 条版本记录即 WARN)

README 模板见 references/readme_template.md


Step 7: 本地 git init + 身份配置

scripts/git_init.sh <fork-path> "<user.name>" "<user.email>"
# 执行:
#   git init -b main
#   git symbolic-ref HEAD refs/heads/main  ← 老 git 兜底
#   git config user.name / user.email      ← 必须,容器 git 没有默认
#   git add . && git commit -m "Initial commit: v1.0.0"

Why:容器/PVC 环境 git 没有默认 user.name/email,commit 直接报"不允许空的姓名"(glic-check 首发踩过)。


Step 8: UGLIC 自审(可选但强烈推荐)

调用 glic-check skill 跑 UGLIC 5 维(U/G/L/I/C):

  • 0 ERR 才放行;WARN 全修或文字说明保留理由
  • audit/check 类 skill 额外做「自审 + 三档样本」
# 引用 glic-check skill 跑
# 不在本 skill 内重复实现

完整规则见本 skill references/uglic_quickref.md 或直接读 glic-check skill。


Step 9: GitHub repo 创建 + push

9.1 用户操作(必须用户做,AI 不能自动)

  1. 浏览器登录 GitHub → 新建 repo <repo-name>勾 main 分支,不勾 README/LICENSE/gitignore)
  2. token 可用已配置来源(推荐 OSG_GITHUB_TOKEN_CMD / gh auth token);若没有配置,再生成 Personal Access Token(PAT)并只通过环境变量传一次

9.2 Token 配置与卫生(铁律)

⚠️ 用户贴 token 时第一条回复必须

"我收到了,会用环境变量传一次不落盘,跑完请去 GitHub Settings → Tokens 撤销这个 PAT。"

推荐长期配置:

# profile.env 里配置 token 读取命令,避免每次发布重新粘贴
OSG_GITHUB_TOKEN_CMD="gh auth token"

也支持:

GITHUB_TOKEN=ghp_xxx scripts/github_push.sh <fork-path> <github-handle>/<repo-name>
OSG_GITHUB_TOKEN=ghp_xxx scripts/github_push.sh <fork-path> <github-handle>/<repo-name>

OSG_GITHUB_TOKEN 可写进 profile,但这是明文 token,只在用户明确要求时使用;默认推荐 OSG_GITHUB_TOKEN_CMD 接 GitHub CLI 或 macOS Keychain。

9.3 推送(带 Basic Auth 重试,适配受限网络)

scripts/github_push.sh <fork-path> <github-handle>/<repo-name>
# 实际执行:
#   发布前自动清理派生缓存(_lib_exclude.sh: __pycache__/*.pyc/.DS_Store 等)
#   token 来源: GITHUB_TOKEN → OSG_GITHUB_TOKEN → OSG_GITHUB_TOKEN_CMD → gh auth token
#   AUTH_B64=$(printf "x-access-token:%s" "$RESOLVED_TOKEN" | base64 -w0)
#   git remote add origin https://github.com/<handle>/<repo>.git
#   for i in 1..5: timeout 60 git -c http.extraHeader="Authorization: Basic $AUTH_B64" push origin main && break

Why Basic Auth header:某些受限网络环境 push GitHub 时 bearer 已不认,必须用 Basic Auth header 注入;token 不进 remote URL。

push 完成后:如果本次用了临时 PAT,再次提醒用户 去 GitHub Settings 撤销 PAT;如果用的是 GitHub CLI / Keychain 长期配置,不要求每次撤销。


Step 10: clawhub 发版(可选)+ memory 沉淀

10.1 clawhub publish(可选)

CLAWHUB_TOKEN=clh_xxx scripts/clawhub_publish.sh <fork-abs-path>
# 注意:
#   - 发布前自动清理派生缓存(_lib_exclude.sh: __pycache__/*.pyc/.DS_Store 等)
#   - 必须用绝对路径(相对路径偶发 SKILL.md required 报错)
#   - clawhub 强制 LICENSE 为 MIT-0(本地 LICENSE 文件被忽略,平台特性不是 bug)
#   - clawhub 没有 visibility 参数,用 hide/unhide 控制
#   - rate limit 11999/12000 → sleep 30s 重试

⚠️ CLAWHUB_TOKEN 与 GitHub token 完全独立;临时 token 分别撤销,长期配置分别管理。

10.2 受限发布环境的 visibility(部分内网 hub 特有)

某些内网 hub 会把特定用户/部门标记为「受限」,禁止公开可见(常表现为静默降级为 private)。

  • ⛔ 该类 hub publish 不能设为 public(会强制软降级 private)
  • 禁止自作主张加 --visibility private 救场——降级后 PUT edit 也可能改不回来
  • ✅ 正确做法:去掉 --visibility 参数让发版工具取 Hub 当前值回填
  • clawhub / GitHub / skills.sh 不受此限制,可正常公开
  • ✅ 调 publish/edit 后禁止信 response 字段汇报,必须 detail + PUT edit 空 body 双查真实落库值

10.3 memory 沉淀

提示用户创建 memory/project_<slug>_opensource_fork.md,记录:

  • 决策:为什么开源、为什么走副本、首版号怎么定
  • 改造:CLI 设计、env 变量命名、跨平台兜底
  • 经验:用户拍板的设计问题清单
  • 关联:指向上一个开源 skill 的 memory(链式继承)

通用经验沉淀到 feedback_*.md

⚠️ 沉淀内容红线:memory 笔记只记「决策与经验」,严禁写入任何 token / secret / 明文凭证,也不要抄录内部路径、内网域名、平台代号等敏感上下文。这与 §8「token 绝不落盘到 git/remote/memory」的硬规则一致——发布后的复盘笔记同样受此约束。


常见反模式(一定要避开)

❌ 反模式 ✅ 正确做法
副本里改的同时改原 skill 原 skill 不动,只动副本
副本目录名带 -os / -opensource 后缀 opensourceskills/<原名>/,slug 跟原名一致
v0.1 / v0.x 试探发版 直接 v1.0.0(clawhub 期望"成熟" first release)
GitHub repo 用 dev / master 默认分支 必须 main(老 git git symbolic-ref HEAD refs/heads/main 兜底)
LICENSE 自填假名字 / 占位贡献者 必须问用户拍板 + 真名署名
把内网 grep 结果直接贴 chat 任何内网 grep 输出先脱敏再贴
frontmatter 塞 version / metadata / tags 只留 name + description
changelog 塞进 SKILL.md / 堆在 README 独立 CHANGELOG.md,SKILL.md/README 留指针
凭 response 字段判定 visibility 发版成功 必须 detail 接口二次 GET 验真
AI 自动加 --force / --yes / --i-am-sure 必须用户文字确认
token 写入 git remote / memory / 日志 token 只进环境变量或 OSG_GITHUB_TOKEN_CMD;profile 明文 token 仅在用户明确要求时使用

进一步参考

  • references/strip_checklist.md — 11 条剔除清单 + 字面替换映射
  • references/readme_template.md — README.md 模板
  • references/uglic_quickref.md — UGLIC 5 维速查
  • references/precedents.md — 11 个已开源 skill 先例 + 教学价值
  • 完整开源方法论:references/opensource_playbook.md(16 节全流程 + 快速 checklist)
  • 字面剔除深度场景:references/opensource_playbook.md 第 3 节 + references/strip_checklist.md

版本

当前 v1.0.10。完整版本历史见 CHANGELOG.md