From f21c0b293a42beed60356c68bc86f627b76dc4fd Mon Sep 17 00:00:00 2001
From: luoyanglang <238804951+luoyanglang@users.noreply.github.com>
Date: Sat, 25 Apr 2026 07:39:55 +0000
Subject: [PATCH] fix(skills): remove broken default skills hub
---
README.md | 45 ++++++++--------
docs/remote-skills-guide.md | 36 +++++++------
docs/remote-skills-quickstart.md | 80 +++++++++++++--------------
scripts/skill_manager.py | 86 ++++++++++++++---------------
tests/test_skill_manager.py | 92 ++++++++++++++++++++++++++++++++
5 files changed, 215 insertions(+), 124 deletions(-)
create mode 100644 tests/test_skill_manager.py
diff --git a/README.md b/README.md
index 15ab905..dfc7cbb 100644
--- a/README.md
+++ b/README.md
@@ -550,24 +550,24 @@ edict/
#### 2️⃣ CLI 命令(最灵活)
```bash
-# 从 GitHub 添加 code_review skill 到中书省
+# 从 GitHub 添加 mmx_cli skill 到门下省
python3 scripts/skill_manager.py add-remote \
- --agent zhongshu \
- --name code_review \
- --source https://raw.githubusercontent.com/openclaw-ai/skills-hub/main/code_review/SKILL.md \
- --description "代码审查技能"
+ --agent menxia \
+ --name mmx_cli \
+ --source https://raw.githubusercontent.com/MiniMax-AI/cli/main/skill/SKILL.md \
+ --description "MiniMax 多模态 CLI 技能"
-# 一键导入官方 skills 库到指定 agents
+# 一键导入默认 skills 到指定 agents
python3 scripts/skill_manager.py import-official-hub \
- --agents zhongshu,menxia,shangshu,bingbu,xingbu
+ --agents menxia,shangshu
# 列出所有已添加的远程 skills
python3 scripts/skill_manager.py list-remote
# 更新某个 skill 到最新版本
python3 scripts/skill_manager.py update-remote \
- --agent zhongshu \
- --name code_review
+ --agent menxia \
+ --name mmx_cli
```
#### 3️⃣ API 请求(自动化集成)
@@ -577,25 +577,22 @@ python3 scripts/skill_manager.py update-remote \
curl -X POST http://localhost:7891/api/add-remote-skill \
-H "Content-Type: application/json" \
-d '{
- "agentId": "zhongshu",
- "skillName": "code_review",
- "sourceUrl": "https://raw.githubusercontent.com/...",
- "description": "代码审查"
+ "agentId": "menxia",
+ "skillName": "mmx_cli",
+ "sourceUrl": "https://raw.githubusercontent.com/MiniMax-AI/cli/main/skill/SKILL.md",
+ "description": "MiniMax 多模态 CLI 技能"
}'
# 查看所有远程 skills
curl http://localhost:7891/api/remote-skills-list
```
-**官方 Skills Hub:** https://github.com/openclaw-ai/skills-hub
+**默认可导入 Skill:**
支持的 Skills:
-- `code_review` — 代码审查(Python/JS/Go)
-- `api_design` — API 设计审查
-- `security_audit` — 安全审计
-- `data_analysis` — 数据分析
-- `doc_generation` — 文档生成
-- `test_framework` — 测试框架设计
+- `mmx_cli` — MiniMax 多模态 CLI 技能(文本、图像、视频、语音、音乐、搜索)
+
+如果你有自己的 Skills Hub,可以通过 `OPENCLAW_SKILLS_HUB_BASE` 或 `~/.openclaw/skills-hub-url` 配置自定义源。
详见 [🎓 远程 Skills 资源管理指南](docs/remote-skills-guide.md)
@@ -636,7 +633,7 @@ curl http://localhost:7891/api/remote-skills-list
- **[🎓 远程 Skills 资源管理指南](docs/remote-skills-guide.md)** — Skills 生态
- 从网上连接和增补 skills,支持 GitHub/Gitee/任意 HTTPS URL
- - 官方 Skills Hub 预设能力库
+ - 默认 Skills 源和自定义 Hub 支持
- CLI 工具 + 看板 UI + Restful API
- Skills 文件规范与安全防护
- 支持版本管理和一键更新
@@ -711,17 +708,17 @@ docker compose up
**排查**:
```bash
# 测试网络连通性
-curl -I https://raw.githubusercontent.com/openclaw-ai/skills-hub/main/code_review/SKILL.md
+curl -I https://raw.githubusercontent.com/MiniMax-AI/cli/main/skill/SKILL.md
# 如果超时,使用代理
export https_proxy=http://your-proxy:port
-python3 scripts/skill_manager.py import-official-hub --agents zhongshu
+python3 scripts/skill_manager.py import-official-hub --agents menxia
```
**常见原因**:
- 中国大陆访问 GitHub raw 资源需要代理
- 网络超时(已增加到 30 秒 + 自动重试 3 次)
-- 官方 Skills Hub 仓库维护中
+- 默认 skill 源无法访问,或自定义 Skills Hub 配置错误
diff --git a/docs/remote-skills-guide.md b/docs/remote-skills-guide.md
index 49b54e0..112af1d 100644
--- a/docs/remote-skills-guide.md
+++ b/docs/remote-skills-guide.md
@@ -7,7 +7,7 @@
- **GitHub 仓库** (raw.githubusercontent.com)
- **任何 HTTPS URL** (需返回有效的 skill 文件)
- **本地文件路径**
-- **内置仓库** (官方 skills 库)
+- **默认 Skills 源** (经验证可访问的内置导入源)
---
@@ -157,28 +157,32 @@ python3 scripts/skill_manager.py remove-remote \
---
-## 官方 Skills 库
+## 默认 Skills 源
-### OpenClaw Skills Hub
+### MiniMax CLI Skill
-> **官方 skills 库地址**: https://github.com/openclaw-ai/skills-hub
+默认导入源包含经验证可访问的 MiniMax CLI skill。旧的 `openclaw-ai/skills-hub` 仓库当前不可用,因此不再作为默认官方源。
可用 skills 列表:
| Skill 名称 | 描述 | 适用 Agent | 源 URL |
|-----------|------|----------|--------|
-| `code_review` | 代码审查(支持 Python/JS/Go) | 兵部/刑部 | https://raw.githubusercontent.com/openclaw-ai/skills-hub/main/code_review/SKILL.md |
-| `api_design` | API 设计审查 | 兵部/工部 | https://raw.githubusercontent.com/openclaw-ai/skills-hub/main/api_design/SKILL.md |
-| `security_audit` | 安全审计 | 刑部 | https://raw.githubusercontent.com/openclaw-ai/skills-hub/main/security_audit/SKILL.md |
-| `data_analysis` | 数据分析 | 户部 | https://raw.githubusercontent.com/openclaw-ai/skills-hub/main/data_analysis/SKILL.md |
-| `doc_generation` | 文档生成 | 礼部 | https://raw.githubusercontent.com/openclaw-ai/skills-hub/main/doc_generation/SKILL.md |
-| `test_framework` | 测试框架设计 | 工部/刑部 | https://raw.githubusercontent.com/openclaw-ai/skills-hub/main/test_framework/SKILL.md |
+| `mmx_cli` | MiniMax 多模态 CLI 技能 | 门下省/尚书省 | https://raw.githubusercontent.com/MiniMax-AI/cli/main/skill/SKILL.md |
-**一键导入官方 skills**
+如果你维护自己的 Skills Hub,可以使用以下方式指定 Hub base URL。指定后,`import-official-hub` 会按 `//SKILL.md` 解析 `code_review`、`api_design`、`security_audit`、`data_analysis`、`doc_generation`、`test_framework` 等传统 skill 名称。
+
+```bash
+export OPENCLAW_SKILLS_HUB_BASE=https://your-hub/raw-base
+
+# 或写入本地配置
+echo "https://your-hub/raw-base" > ~/.openclaw/skills-hub-url
+```
+
+**一键导入默认 skills**
```bash
python3 scripts/skill_manager.py import-official-hub \
- --agents zhongshu,menxia,shangshu,bingbu,xingbu,libu
+ --agents menxia,shangshu
```
---
@@ -360,7 +364,7 @@ compatibleAgents: [bingbu, xingbu, menxia]
2. **大小限制**: 最多 10 MB
3. **超时保护**: 下载超过 30 秒自动中止
4. **路径遍历防护**: 检查解析后的 skill 名称,禁用 `../` 模式
-5. **checksum 验证**: 可选的 GPG 签名验证(仅官方库)
+5. **checksum 验证**: 可选的 GPG 签名验证(适用于可信发布源)
### 隔离执行
@@ -397,7 +401,7 @@ A: 不支持(安全考虑)。可以:
**Q: 如何创建自己的 skills 库?**
-A: 参考 [OpenClaw Skills Hub](https://github.com/openclaw-ai/skills-hub) 的结构创建自己的仓库,然后:
+A: 按 `/SKILL.md` 的结构创建自己的仓库,然后:
```bash
git clone https://github.com/yourname/my-skills-hub.git
@@ -406,7 +410,7 @@ cd my-skills-hub
# 提交 & 推送到 GitHub
```
-然后通过 URL 或官方库导入功能添加即可。
+然后通过 URL 添加,或通过 `OPENCLAW_SKILLS_HUB_BASE` / `~/.openclaw/skills-hub-url` 配置为自定义 Hub 后导入。
---
@@ -442,7 +446,7 @@ python3 scripts/skill_manager.py check-updates --interval weekly
### 5. 贡献社区
-成熟的 skills 可向 [OpenClaw Skills Hub](https://github.com/openclaw-ai/skills-hub) 贡献。
+成熟的 skills 可以沉淀到你自己的公开 Skills Hub,并通过 `OPENCLAW_SKILLS_HUB_BASE` 分享给团队使用。
---
diff --git a/docs/remote-skills-quickstart.md b/docs/remote-skills-quickstart.md
index 367aaa5..a9e2132 100644
--- a/docs/remote-skills-quickstart.md
+++ b/docs/remote-skills-quickstart.md
@@ -10,21 +10,21 @@ python3 dashboard/server.py
# 输出: 三省六部看板启动 → http://127.0.0.1:7891
```
-### 2. 添加官方 Skill(CLI)
+### 2. 添加默认 Skill(CLI)
```bash
-# 为中书省添加代码审查 skill
+# 为门下省添加 MiniMax CLI skill
python3 scripts/skill_manager.py add-remote \
- --agent zhongshu \
- --name code_review \
- --source https://raw.githubusercontent.com/openclaw-ai/skills-hub/main/code_review/SKILL.md \
- --description "代码审查能力"
+ --agent menxia \
+ --name mmx_cli \
+ --source https://raw.githubusercontent.com/MiniMax-AI/cli/main/skill/SKILL.md \
+ --description "MiniMax 多模态 CLI 技能"
# 输出:
# ⏳ 正在从 https://raw.githubusercontent.com/... 下载...
-# ✅ 技能 code_review 已添加到 zhongshu
-# 路径: /Users/xxx/.openclaw/workspace-zhongshu/skills/code_review/SKILL.md
-# 大小: 2048 字节
+# ✅ 技能 mmx_cli 已添加到 menxia
+# 路径: /Users/xxx/.openclaw/workspace-menxia/skills/mmx_cli/SKILL.md
+# 大小: 14655 字节
```
### 3. 列出所有远程 Skills
@@ -37,7 +37,7 @@ python3 scripts/skill_manager.py list-remote
#
# Agent | Skill 名称 | 描述 | 添加时间
# ------------|----------------------|--------------------------------|----------
-# zhongshu | code_review | 代码审查能力 | 2026-03-02
+# menxia | mmx_cli | MiniMax 多模态 CLI 技能 | 2026-03-02
```
### 4. 查看 API 响应
@@ -50,11 +50,11 @@ curl http://localhost:7891/api/remote-skills-list | jq .
# "ok": true,
# "remoteSkills": [
# {
-# "skillName": "code_review",
-# "agentId": "zhongshu",
+# "skillName": "mmx_cli",
+# "agentId": "menxia",
# "sourceUrl": "https://raw.githubusercontent.com/...",
-# "description": "代码审查能力",
-# "localPath": "/Users/xxx/.openclaw/workspace-zhongshu/skills/code_review/SKILL.md",
+# "description": "MiniMax 多模态 CLI 技能",
+# "localPath": "/Users/xxx/.openclaw/workspace-menxia/skills/mmx_cli/SKILL.md",
# "addedAt": "2026-03-02T14:30:00Z",
# "lastUpdated": "2026-03-02T14:30:00Z",
# "status": "valid"
@@ -69,44 +69,47 @@ curl http://localhost:7891/api/remote-skills-list | jq .
## 常见操作
-### 一键导入官方库中的所有 skills
+### 一键导入默认 skills
```bash
python3 scripts/skill_manager.py import-official-hub \
- --agents zhongshu,menxia,shangshu,bingbu,xingbu
+ --agents menxia,shangshu
```
-这会自动为每个 agent 添加:
-- **zhongshu**: code_review, api_design, doc_generation
-- **menxia**: code_review, api_design, security_audit, data_analysis, doc_generation, test_framework
-- **shangshu**: 同 menxia(协调者)
-- **bingbu**: code_review, api_design, test_framework
-- **xingbu**: code_review, security_audit, test_framework
+这会为指定 agent 添加默认可用的 `mmx_cli` skill。旧的 `openclaw-ai/skills-hub` 仓库当前不可用,因此不再作为默认官方源。
+
+如果你维护自己的 Skills Hub,可以通过环境变量或本地配置指定:
+
+```bash
+export OPENCLAW_SKILLS_HUB_BASE=https://your-hub/raw-base
+# 或
+echo "https://your-hub/raw-base" > ~/.openclaw/skills-hub-url
+```
### 更新某个 Skill 到最新版本
```bash
python3 scripts/skill_manager.py update-remote \
- --agent zhongshu \
- --name code_review
+ --agent menxia \
+ --name mmx_cli
# 输出:
# ⏳ 正在从 https://raw.githubusercontent.com/... 下载...
-# ✅ 技能 code_review 已添加到 zhongshu
+# ✅ 技能 mmx_cli 已添加到 menxia
# ✅ 技能已更新
-# 路径: /Users/xxx/.openclaw/workspace-zhongshu/skills/code_review/SKILL.md
-# 大小: 2156 字节
+# 路径: /Users/xxx/.openclaw/workspace-menxia/skills/mmx_cli/SKILL.md
+# 大小: 14655 字节
```
### 移除某个 Skill
```bash
python3 scripts/skill_manager.py remove-remote \
- --agent zhongshu \
- --name code_review
+ --agent menxia \
+ --name mmx_cli
# 输出:
-# ✅ 技能 code_review 已从 zhongshu 移除
+# ✅ 技能 mmx_cli 已从 menxia 移除
```
---
@@ -119,10 +122,10 @@ python3 scripts/skill_manager.py remove-remote \
2. 进入 🔧 **技能配置** 面板
3. 点击 **➕ 添加远程 Skill** 按钮
4. 填写表单:
- - **Agent**: 从下拉列表选择(如 zhongshu)
- - **Skill 名称**: 输入内部 ID 如 `code_review`
- - **远程 URL**: 粘贴 GitHub URL 如 `https://raw.githubusercontent.com/openclaw-ai/skills-hub/main/code_review/SKILL.md`
- - **中文描述**: 可选,如 `代码审查能力`
+ - **Agent**: 从下拉列表选择(如 menxia)
+ - **Skill 名称**: 输入内部 ID 如 `mmx_cli`
+ - **远程 URL**: 粘贴 GitHub URL 如 `https://raw.githubusercontent.com/MiniMax-AI/cli/main/skill/SKILL.md`
+ - **中文描述**: 可选,如 `MiniMax 多模态 CLI 技能`
5. 点击 **导入** 按钮
6. 等待 1-2 秒,看到 ✅ 成功提示
@@ -247,11 +250,11 @@ curl http://localhost:7891/api/remote-skills-list
"ok": true,
"remoteSkills": [
{
- "skillName": "code_review",
- "agentId": "zhongshu",
+ "skillName": "mmx_cli",
+ "agentId": "menxia",
"sourceUrl": "https://raw.githubusercontent.com/...",
- "description": "代码审查能力",
- "localPath": "/Users/xxx/.openclaw/workspace-zhongshu/skills/code_review/SKILL.md",
+ "description": "MiniMax 多模态 CLI 技能",
+ "localPath": "/Users/xxx/.openclaw/workspace-menxia/skills/mmx_cli/SKILL.md",
"addedAt": "2026-03-02T14:30:00Z",
"lastUpdated": "2026-03-02T14:30:00Z",
"status": "valid"
@@ -333,4 +336,3 @@ ls -la ~/.openclaw/workspace-zhongshu/skills/
- 📚 [完整指南](remote-skills-guide.md)
- 🏛️ [架构文档](task-dispatch-architecture.md)
- 🤝 [项目贡献](../CONTRIBUTING.md)
-
diff --git a/scripts/skill_manager.py b/scripts/skill_manager.py
index b220b62..2dc8249 100644
--- a/scripts/skill_manager.py
+++ b/scripts/skill_manager.py
@@ -14,7 +14,7 @@ Usage:
python3 scripts/skill_manager.py remove-remote --agent zhongshu --name code_review
- python3 scripts/skill_manager.py import-official-hub --agents zhongshu,menxia,shangshu
+ python3 scripts/skill_manager.py import-official-hub --agents menxia,shangshu
"""
import sys
import json
@@ -60,7 +60,7 @@ def _download_file(url: str, timeout: int = 30, retries: int = 3) -> str:
if 'timed out' in str(last_error).lower() or '超时' in str(last_error):
hint = '\n 💡 提示: 如果在中国大陆,请设置代理 export https_proxy=http://proxy:port'
elif '404' in str(last_error):
- hint = '\n 💡 提示: 官方 Skills Hub 可能尚未发布该 skill,请检查 URL 是否正确'
+ hint = '\n 💡 提示: 远程 skill URL 不存在,请检查 URL 或自定义 Skills Hub 配置'
raise Exception(f'{last_error} (已重试 {retries} 次){hint}')
@@ -218,34 +218,45 @@ def remove_remote(agent_id: str, name: str) -> bool:
return False
-OFFICIAL_SKILLS_HUB_BASE = 'https://raw.githubusercontent.com/openclaw-ai/skills-hub/main'
-# 备用镜像(GitHub 国内访问不稳定时自动切换)
-_FALLBACK_HUB_BASES = [
- 'https://ghproxy.com/https://raw.githubusercontent.com/openclaw-ai/skills-hub/main',
- 'https://raw.gitmirror.com/openclaw-ai/skills-hub/main',
-]
-
-# 支持通过环境变量覆盖 Hub 地址
+# 支持通过环境变量或本地配置指定自定义 Hub 地址
_HUB_BASE_ENV = 'OPENCLAW_SKILLS_HUB_BASE'
-def _get_hub_url(skill_name):
- """获取 skill 的 Hub URL,支持环境变量覆盖"""
+
+def _get_configured_hub_base():
+ """Return a user-provided skills hub base URL, if configured."""
+ env_base = os.environ.get(_HUB_BASE_ENV)
+ if env_base:
+ return env_base
+
hub_url_file = OCLAW_HOME / 'skills-hub-url'
- base = hub_url_file.read_text().strip() if hub_url_file.exists() else None
- base = base or os.environ.get(_HUB_BASE_ENV) or OFFICIAL_SKILLS_HUB_BASE
+ return hub_url_file.read_text().strip() if hub_url_file.exists() else None
+
+
+def _get_hub_url(base, skill_name):
+ """获取 skill 的 Hub URL,支持环境变量/本地配置覆盖"""
return f'{base.rstrip("/")}/{skill_name}/SKILL.md'
OFFICIAL_SKILLS_HUB = {
- 'code_review': _get_hub_url('code_review'),
- 'api_design': _get_hub_url('api_design'),
- 'security_audit': _get_hub_url('security_audit'),
- 'data_analysis': _get_hub_url('data_analysis'),
- 'doc_generation': _get_hub_url('doc_generation'),
- 'test_framework': _get_hub_url('test_framework'),
'mmx_cli': 'https://raw.githubusercontent.com/MiniMax-AI/cli/main/skill/SKILL.md',
}
+_HUB_SKILL_NAMES = (
+ 'code_review',
+ 'api_design',
+ 'security_audit',
+ 'data_analysis',
+ 'doc_generation',
+ 'test_framework',
+)
+
+_configured_hub_base = _get_configured_hub_base()
+if _configured_hub_base:
+ OFFICIAL_SKILLS_HUB.update({
+ skill_name: _get_hub_url(_configured_hub_base, skill_name)
+ for skill_name in _HUB_SKILL_NAMES
+ })
+
SKILL_AGENT_MAPPING = {
'code_review': ('bingbu', 'xingbu', 'menxia'),
'api_design': ('bingbu', 'gongbu', 'menxia'),
@@ -258,14 +269,12 @@ SKILL_AGENT_MAPPING = {
def import_official_hub(agent_ids: list) -> bool:
- """从官方 Skills Hub 导入指定的 skills 到指定 agents。
+ """从默认 Skills 源或自定义 Hub 导入 skills 到指定 agents。
如果未指定 agents,使用该 skill 的推荐 agents。
"""
- if not agent_ids:
- print('❌ 未指定 agent,使用推荐配置...\n')
- for skill_name, recommended_agents in SKILL_AGENT_MAPPING.items():
- agent_ids.extend(recommended_agents)
- agent_ids = list(set(agent_ids))
+ requested_agents = list(agent_ids)
+ if not requested_agents:
+ print('ℹ️ 未指定 agent,使用推荐配置...\n')
total = 0
success = 0
@@ -273,27 +282,14 @@ def import_official_hub(agent_ids: list) -> bool:
for skill_name, url in OFFICIAL_SKILLS_HUB.items():
# 确定目标 agents
- target_agents = agent_ids
- if not agent_ids:
- target_agents = SKILL_AGENT_MAPPING.get(skill_name, ['menxia'])
+ target_agents = requested_agents or list(SKILL_AGENT_MAPPING.get(skill_name, ['menxia']))
print(f'\n📥 正在导入 skill: {skill_name}')
print(f' 目标 agents: {", ".join(target_agents)}')
- # 尝试主 URL,失败则自动切换镜像
- effective_url = url
for agent_id in target_agents:
total += 1
- ok = add_remote(agent_id, skill_name, effective_url, f'官方 skill:{skill_name}')
- if not ok and effective_url == url:
- # 主 URL 失败,尝试镜像
- for fb_base in _FALLBACK_HUB_BASES:
- fb_url = f'{fb_base.rstrip("/")}/{skill_name}/SKILL.md'
- print(f' 🔄 尝试镜像: {fb_url}')
- ok = add_remote(agent_id, skill_name, fb_url, f'官方 skill:{skill_name}')
- if ok:
- effective_url = fb_url # 后续 agent 也用这个镜像
- break
+ ok = add_remote(agent_id, skill_name, url, f'默认 skill:{skill_name}')
if ok:
success += 1
else:
@@ -305,10 +301,10 @@ def import_official_hub(agent_ids: list) -> bool:
for f in failed:
print(f' - {f}')
print(f'\n💡 排查建议:')
- print(f' 1. 检查网络: curl -I {OFFICIAL_SKILLS_HUB_BASE}/code_review/SKILL.md')
+ print(f' 1. 检查网络: curl -I ')
print(f' 2. 设置代理: export https_proxy=http://your-proxy:port')
- print(f' 3. 使用镜像: export {_HUB_BASE_ENV}=https://ghproxy.com/{OFFICIAL_SKILLS_HUB_BASE}')
- print(f' 4. 自定义源: echo "https://your-mirror/skills" > {OCLAW_HOME / "skills-hub-url"}')
+ print(f' 3. 自定义 Hub: export {_HUB_BASE_ENV}=https://your-hub/raw-base')
+ print(f' 4. 自定义源: echo "https://your-hub/raw-base" > {OCLAW_HOME / "skills-hub-url"}')
print(f' 5. 单独重试: python3 scripts/skill_manager.py add-remote --agent --name --source ')
return success == total
@@ -339,7 +335,7 @@ def main():
remove_parser.add_argument('--name', required=True, help='Skill 名称')
# import-official-hub
- import_parser = subparsers.add_parser('import-official-hub', help='从官方库导入 skills')
+ import_parser = subparsers.add_parser('import-official-hub', help='从默认 Skills 源或自定义 Hub 导入 skills')
import_parser.add_argument('--agents', default='', help='逗号分隔的 Agent IDs(可选)')
# check-updates
diff --git a/tests/test_skill_manager.py b/tests/test_skill_manager.py
new file mode 100644
index 0000000..0b1a52c
--- /dev/null
+++ b/tests/test_skill_manager.py
@@ -0,0 +1,92 @@
+import importlib.util
+import os
+import tempfile
+import unittest
+from pathlib import Path
+from unittest import mock
+
+
+def _load_skill_manager(openclaw_home, hub_base=None):
+ root = Path(__file__).resolve().parents[1]
+ script_path = root / "scripts" / "skill_manager.py"
+
+ env = {"OPENCLAW_HOME": str(openclaw_home)}
+ if hub_base is not None:
+ env["OPENCLAW_SKILLS_HUB_BASE"] = hub_base
+
+ spec = importlib.util.spec_from_file_location("skill_manager_under_test", script_path)
+ module = importlib.util.module_from_spec(spec)
+ with mock.patch.dict(os.environ, env, clear=False):
+ if hub_base is None:
+ os.environ.pop("OPENCLAW_SKILLS_HUB_BASE", None)
+ spec.loader.exec_module(module)
+ return module
+
+
+class SkillManagerTests(unittest.TestCase):
+ def test_default_skills_do_not_use_removed_openclaw_hub(self):
+ with tempfile.TemporaryDirectory() as tmp:
+ skill_manager = _load_skill_manager(Path(tmp) / ".openclaw")
+
+ self.assertIn("mmx_cli", skill_manager.OFFICIAL_SKILLS_HUB)
+ self.assertTrue(
+ all(
+ "openclaw-ai/skills-hub" not in url
+ for url in skill_manager.OFFICIAL_SKILLS_HUB.values()
+ )
+ )
+
+ def test_custom_hub_base_restores_hub_skill_urls(self):
+ with tempfile.TemporaryDirectory() as tmp:
+ skill_manager = _load_skill_manager(
+ Path(tmp) / ".openclaw",
+ hub_base="https://example.com/openclaw-skills",
+ )
+
+ self.assertEqual(
+ skill_manager.OFFICIAL_SKILLS_HUB["code_review"],
+ "https://example.com/openclaw-skills/code_review/SKILL.md",
+ )
+ self.assertEqual(
+ skill_manager.OFFICIAL_SKILLS_HUB["test_framework"],
+ "https://example.com/openclaw-skills/test_framework/SKILL.md",
+ )
+ self.assertEqual(
+ skill_manager.OFFICIAL_SKILLS_HUB["mmx_cli"],
+ "https://raw.githubusercontent.com/MiniMax-AI/cli/main/skill/SKILL.md",
+ )
+
+ def test_import_official_hub_uses_per_skill_recommended_agents(self):
+ with tempfile.TemporaryDirectory() as tmp:
+ skill_manager = _load_skill_manager(Path(tmp) / ".openclaw")
+
+ calls = []
+
+ def fake_add_remote(agent_id, skill_name, source_url, description=""):
+ calls.append((agent_id, skill_name, source_url, description))
+ return True
+
+ with mock.patch.object(skill_manager, "add_remote", fake_add_remote):
+ self.assertTrue(skill_manager.import_official_hub([]))
+
+ self.assertEqual(
+ calls,
+ [
+ (
+ "menxia",
+ "mmx_cli",
+ "https://raw.githubusercontent.com/MiniMax-AI/cli/main/skill/SKILL.md",
+ "默认 skill:mmx_cli",
+ ),
+ (
+ "shangshu",
+ "mmx_cli",
+ "https://raw.githubusercontent.com/MiniMax-AI/cli/main/skill/SKILL.md",
+ "默认 skill:mmx_cli",
+ ),
+ ],
+ )
+
+
+if __name__ == "__main__":
+ unittest.main()