Skip to content

Commit 441d024

Browse files
committed
fix(installer): Hermes 支持一直是坏的 —— 改为全局安装并给出可粘贴配置(#45
## 我们装错了目录,一直没生效 #45 报告人说「项目级 .hermes/skills/ 里的 20 个 skill 全部返回 404,必须手动 复制到 ~/.hermes/skills/ 才被识别」。查官方文档核实,他是对的: hermes-agent.nousresearch.com/docs/user-guide/features/skills 明确 Hermes 只自动加载 ~/.hermes/skills/(原文 "the primary directory and source of truth"),项目级目录不被自动发现;外部目录必须写进 ~/.hermes/config.yaml 的 skills.external_dirs。 而我们从支持 Hermes 起就只装项目级 .hermes/skills/ —— 那个目录 Hermes 根本 不读。这不是「不好用」,是「装了完全不生效」,比不支持更糟。 ## 改法 - TARGETS 给 Hermes 加 global(~/.hermes/skills),全局成为推荐装法 - 项目级仍保留(skills 可随仓库分发),但装完打印**可直接粘贴**的配置片段: skills: external_dirs: - <项目绝对路径>/.hermes/skills 不替用户改 config.yaml —— 那是他们的文件。文档里也写明「配置里不存在的 路径会被静默跳过」,所以写错不会报错、只会没生效。 - 全局模式**不写 bootstrap**:Hermes 的用户级指令文件约定没有公开文档, 往 $HOME 根目录写 HERMES.md 是猜路径 + 污染主目录。实测确认全局装完 $HOME 根目录 0 个文件、卸载 0 残留。 ## 文档与清单 - docs/README.hermes.md 开头重写,把「必须全局」放在最前面,并注明 v1.7.8 及更早只支持项目级 = 装了不生效,是我们的实现错误 - 简繁 README:全局支持清单加 Hermes Agent,工具表的安装命令改为 --global - verify-release.sh 的 GLOBAL_OK 加 hermes、GLOBAL_NO 移除 ## 验证 - 全局:装 20 skills 到 ~/.hermes/skills、$HOME 根目录 0 文件、卸载 0 残留 - 项目级:正确打印 A/B 两种方案与绝对路径的 config.yaml 片段 - audit.sh 166 pass / 0 warn / 0 fail、verify-release.sh 90 pass / 0 fail 注:#45 的后半部分(7 个 skill 文件里 24 处硬编码 Claude 工具名)本次未动。 那属于行为塑造内容,且 references/hermes-tools.md 已有完整映射表, 应走「强化映射表引用」而非把正文改成某个 harness 专属工具名。
1 parent f290def commit 441d024

5 files changed

Lines changed: 70 additions & 26 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ AI:在开始实现之前,我需要了解几个关键问题:
133133
|------|------|:---:|:---:|
134134
| [Claude Code](https://claude.ai/code) | CLI | `npx superpowers-zh` | `.claude/skills/` |
135135
| [Copilot CLI](https://githubnext.com/projects/copilot-cli) | CLI | `npx superpowers-zh --tool copilot` | `.claude/skills/` |
136-
| [Hermes Agent](https://github.com/NousResearch/hermes-agent) | CLI | `npx superpowers-zh --tool hermes` | `.hermes/skills/` |
136+
| [Hermes Agent](https://github.com/NousResearch/hermes-agent) | CLI | `npx superpowers-zh --global --tool hermes` | `~/.hermes/skills/` |
137137
| [Cursor](https://cursor.sh) | IDE | `npx superpowers-zh` | `.cursor/skills/` |
138138
| [Windsurf](https://codeium.com/windsurf) | IDE | `npx superpowers-zh` | `.windsurf/skills/` |
139139
| [Kiro](https://kiro.dev) | IDE | `npx superpowers-zh` | `.kiro/steering/` |
@@ -214,7 +214,7 @@ npx superpowers-zh --global --tool claude # 或指定工具
214214

215215
全局安装把 skills 装到工具的**用户级目录**(如 `~/.claude/skills`),一次安装所有项目自动可用,更新时也只需重装一次。**项目级优先、全局兜底**,二者可共存。
216216

217-
支持通用全局安装的工具(均为 docs 已证实的用户级加载路径):**Claude Code · Codex CLI · Qoder · Windsurf · Qwen Code · OpenClaw · OpenCode · Crush**。其中 **Codex CLI** 全局装到 `~/.agents/skills`(Codex 启动扫描目录)。其余工具(Cursor / Kiro / Trae / Aider / DeerFlow / VS Code / Hermes / Claw / Cline / Kilo Code)规则是项目级或存于应用内设置,`--global` 会提示改用项目级;**Gemini CLI / Antigravity** 有各自专属的全局方式(Gemini 走扩展目录),见对应 `docs/README.*.md`
217+
支持通用全局安装的工具(均为 docs 已证实的用户级加载路径):**Claude Code · Codex CLI · Qoder · Windsurf · Qwen Code · OpenClaw · OpenCode · Crush · Hermes Agent**。其中 **Codex CLI** 全局装到 `~/.agents/skills`(Codex 启动扫描目录)。其余工具(Cursor / Kiro / Trae / Aider / DeerFlow / VS Code / Claw / Cline / Kilo Code)规则是项目级或存于应用内设置,`--global` 会提示改用项目级;**Gemini CLI / Antigravity** 有各自专属的全局方式(Gemini 走扩展目录),见对应 `docs/README.*.md`
218218

219219
| | 项目级(默认) | 全局(`--global`|
220220
|---|---|---|

README.zh-Hant.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ AI:在開始實作之前,我需要了解幾個關鍵問題:
133133
|------|------|:---:|:---:|
134134
| [Claude Code](https://claude.ai/code) | CLI | `npx superpowers-zh` | `.claude/skills/` |
135135
| [Copilot CLI](https://githubnext.com/projects/copilot-cli) | CLI | `npx superpowers-zh --tool copilot` | `.claude/skills/` |
136-
| [Hermes Agent](https://github.com/NousResearch/hermes-agent) | CLI | `npx superpowers-zh --tool hermes` | `.hermes/skills/` |
136+
| [Hermes Agent](https://github.com/NousResearch/hermes-agent) | CLI | `npx superpowers-zh --global --tool hermes` | `~/.hermes/skills/` |
137137
| [Cursor](https://cursor.sh) | IDE | `npx superpowers-zh` | `.cursor/skills/` |
138138
| [Windsurf](https://codeium.com/windsurf) | IDE | `npx superpowers-zh` | `.windsurf/skills/` |
139139
| [Kiro](https://kiro.dev) | IDE | `npx superpowers-zh` | `.kiro/steering/` |
@@ -214,7 +214,7 @@ npx superpowers-zh --global --tool claude # 或指定工具
214214

215215
全域安裝把 skills 裝到工具的**使用者級目錄**(如 `~/.claude/skills`),一次安裝所有專案自動可用,更新時也只需重裝一次。**專案級優先、全域兜底**,二者可共存。
216216

217-
支援通用全域安裝的工具(均為 docs 已證實的使用者級載入路徑):**Claude Code · Codex CLI · Qoder · Windsurf · Qwen Code · OpenClaw · OpenCode · Crush**。其中 **Codex CLI** 全域裝到 `~/.agents/skills`(Codex 啟動掃描目錄)。其餘工具(Cursor / Kiro / Trae / Aider / DeerFlow / VS Code / Hermes / Claw / Cline / Kilo Code)規則是專案級或存於應用內設定,`--global` 會提示改用專案級;**Gemini CLI / Antigravity** 有各自專屬的全域方式(Gemini 走擴充目錄),見對應 `docs/README.*.md`
217+
支援通用全域安裝的工具(均為 docs 已證實的使用者級載入路徑):**Claude Code · Codex CLI · Qoder · Windsurf · Qwen Code · OpenClaw · OpenCode · Crush · Hermes Agent**。其中 **Codex CLI** 全域裝到 `~/.agents/skills`(Codex 啟動掃描目錄)。其餘工具(Cursor / Kiro / Trae / Aider / DeerFlow / VS Code / Claw / Cline / Kilo Code)規則是專案級或存於應用內設定,`--global` 會提示改用專案級;**Gemini CLI / Antigravity** 有各自專屬的全域方式(Gemini 走擴充目錄),見對應 `docs/README.*.md`
218218

219219
| | 專案級(預設) | 全域(`--global`|
220220
|---|---|---|

bin/superpowers-zh.js

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ const LEGACY_AGENT_FILENAMES = ['code-reviewer.md'];
5151
// global.dir 用户级 skills 目录(相对 home)
5252
// global.detect home 下用于自动检测该工具是否安装的标记目录
5353
// global.boot 可选,用户级 bootstrap 文件(相对 home);无则仅靠 skill 自动发现
54-
// 无 global 的工具(Cursor/Kiro/Trae/Aider/DeerFlow/VS Code/Hermes/Claw/Cline/Kilo Code)规则是项目级、
54+
// 无 global 的工具(Cursor/Kiro/Trae/Aider/DeerFlow/VS Code/Claw/Cline/Kilo Code)规则是项目级、
5555
// 或存在于应用内设置,没有稳定的用户级 skills 加载路径 —— --global 会明确拒绝而非写无效路径。
5656
const TARGETS = [
5757
{ name: 'Claude Code', dir: '.claude/skills', detect: '.claude', global: { dir: '.claude/skills', detect: '.claude', boot: '.claude/CLAUDE.md' } },
@@ -74,7 +74,11 @@ const TARGETS = [
7474
{ name: 'Aider', dir: '.aider/skills', detect: '.aider' },
7575
{ name: 'OpenCode', dir: '.opencode/skills', detect: '.opencode', global: { dir: '.config/opencode/skills', detect: '.config/opencode' } },
7676
{ name: 'Qwen Code', dir: '.qwen/skills', detect: '.qwen', global: { dir: '.qwen/skills', detect: '.qwen' } },
77-
{ name: 'Hermes Agent', dir: '.hermes/skills', detect: ['.hermes', 'HERMES.md', '.hermes.md'] },
77+
// Hermes 官方文档:只自动加载 ~/.hermes/skills/("the primary directory and
78+
// source of truth"),项目级目录不被自动发现,外部目录必须写进
79+
// ~/.hermes/config.yaml 的 skills.external_dirs。所以全局才是能直接生效的装法;
80+
// 项目级仍保留(便于随仓库分发),但装完会打印需要粘贴的 config.yaml 片段。
81+
{ name: 'Hermes Agent', dir: '.hermes/skills', detect: ['.hermes', 'HERMES.md', '.hermes.md'], global: { dir: '.hermes/skills', detect: '.hermes' } },
7882
{ name: 'Claw Code', dir: '.claw/skills', detect: ['.claw', 'CLAW.md'] },
7983
{ name: 'Qoder', dir: '.qoder/skills', detect: '.qoder', global: { dir: '.qoder/skills', detect: '.qoder' } },
8084
{ name: 'CodeBuddy', dir: '.codebuddy/skills', detect: ['.codebuddy', 'CODEBUDDY.md'] },
@@ -431,7 +435,17 @@ ${skillList}
431435
}
432436
}
433437

434-
function generateHermesBootstrap(projectDir) {
438+
function generateHermesBootstrap(projectDir, isGlobal) {
439+
// 全局模式不写 bootstrap:Hermes 的用户级指令文件约定未在 docs 证实,
440+
// 往 $HOME 根目录写 HERMES.md 是猜路径 + 污染主目录。~/.hermes/skills/ 里的
441+
// skill 靠 name/description 被 skills_list / skill_view 发现,本就不依赖 bootstrap。
442+
if (isGlobal) {
443+
console.log(' ℹ️ Hermes 全局安装不写 bootstrap 文件(其用户级指令文件约定未证实)。');
444+
console.log(' skills 已在 ~/.hermes/skills/,可用 skills_list / skill_view 发现。');
445+
console.log(' 想让它在项目里自动触发,在该项目跑一次项目级安装以生成 HERMES.md。');
446+
return;
447+
}
448+
435449
const skillEntries = scanSkillEntries(SKILLS_SRC);
436450
const skillList = skillEntries.map(s => `- **${s.name}**: ${s.desc}`).join('\n');
437451

@@ -485,6 +499,25 @@ ${skillList}
485499
writeFileSync(hermesPath, wrapWithSentinel(content), 'utf8');
486500
console.log(` ✅ Hermes Agent: bootstrap -> ${hermesPath}`);
487501
}
502+
503+
// 项目级安装 Hermes 认不到 —— 必须显式登记到 config.yaml。不替用户改配置
504+
// (那是他们的文件),改为打印可直接粘贴的片段。见 issue #45。
505+
if (!isGlobal) {
506+
const abs = resolve(projectDir, '.hermes', 'skills');
507+
console.log('');
508+
console.log(' ⚠️ Hermes 只自动扫描 ~/.hermes/skills/,不会发现项目级目录。');
509+
console.log(' 二选一让它生效:');
510+
console.log('');
511+
console.log(' A) 改用全局安装(推荐,装完即生效):');
512+
console.log(' npx superpowers-zh --global --tool hermes');
513+
console.log('');
514+
console.log(' B) 保留项目级,把这段加进 ~/.hermes/config.yaml:');
515+
console.log('');
516+
console.log(' skills:');
517+
console.log(' external_dirs:');
518+
console.log(` - ${abs}`);
519+
console.log('');
520+
}
488521
}
489522

490523
function generateClaudeCodeBootstrap(baseDir, isGlobal) {
@@ -732,7 +765,7 @@ function installForTarget(target, baseDir, isGlobal) {
732765
}
733766

734767
if (target.name === 'Hermes Agent') {
735-
generateHermesBootstrap(baseDir);
768+
generateHermesBootstrap(baseDir, isGlobal);
736769
}
737770

738771
if (target.name === 'Claude Code') {

docs/README.hermes.md

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,48 @@
22

33
[Hermes Agent](https://github.com/NousResearch/hermes-agent) 中使用 superpowers-zh 的完整指南。
44

5-
## 自动安装
5+
## ⚠️ 先看这一条:必须装到全局,否则不生效
6+
7+
[Hermes 官方文档](https://hermes-agent.nousresearch.com/docs/user-guide/features/skills)明确:Hermes **只自动加载 `~/.hermes/skills/`**(原文称其为 "the primary directory and source of truth"),**项目级目录不会被自动发现**
8+
9+
所以推荐的装法是全局:
610

711
```bash
8-
cd /your/project
9-
npx superpowers-zh --tool hermes
12+
npx superpowers-zh --global --tool hermes
1013
```
1114

12-
安装脚本会将 20 个 skills 复制到 `.hermes/skills/` 目录,并自动生成 `HERMES.md` 引导文件(含工具映射表和 skills 列表)
15+
装到 `~/.hermes/skills/`,装完即生效,用 `skills_list` 就能看到 20 个 skill
1316

14-
如果项目中已存在 `.hermes` 目录或 `HERMES.md` 文件,也会被自动检测到:
17+
> 📌 v1.7.8 及更早版本只支持项目级安装(装到 `<项目>/.hermes/skills/`)—— 那个目录 Hermes 根本不读,等于装了不生效。这是我们的实现错误,v1.7.9 起修正。见 [#45](https://github.com/jnMetaCode/superpowers-zh/issues/45)
18+
19+
## 如果你确实要项目级安装
20+
21+
项目级的好处是 skills 可以随仓库一起分发。但**必须显式登记**,否则 Hermes 看不见。
1522

1623
```bash
17-
npx superpowers-zh # 自动检测
24+
cd /your/project
25+
npx superpowers-zh --tool hermes
1826
```
1927

20-
## 手动安装
28+
安装器会打印出你需要粘贴的配置片段,形如:
2129

22-
```bash
23-
git clone https://github.com/jnMetaCode/superpowers-zh.git
24-
cp -r superpowers-zh/skills /your/project/.hermes/skills
30+
```yaml
31+
skills:
32+
external_dirs:
33+
- /your/project/.hermes/skills
2534
```
2635
27-
## 通过 HERMES.md 引导
36+
把它加进 `~/.hermes/config.yaml`。路径支持 `~` 展开和 `${VAR}` 环境变量替换;**配置里不存在的路径会被静默跳过**,所以写错了不会报错,只会"没生效"。
37+
38+
**我们不替你改 `config.yaml`** —— 那是你的配置文件。
39+
40+
项目级安装还会生成 `HERMES.md` 引导文件(含核心规则和 skills 列表),让 Hermes 在合适时机主动检查 skill。全局安装**不写**这个文件 —— Hermes 的用户级指令文件约定没有公开文档,我们不猜路径、也不往你的主目录里写东西。
2841

29-
Hermes Agent 在会话开始时自动加载项目根目录下的 `HERMES.md`(或 `.hermes.md`)作为上下文。安装器会自动生成此文件,内容包括:
42+
## 同名冲突
3043

31-
- 工具映射表(Claude Code → Hermes Agent 工具名称)
32-
- 所有可用 skills 的列表和描述
33-
- 核心规则和使用说明
44+
如果同一个 skill 名在 `~/.hermes/skills/` 和某个 `external_dirs` 目录里都存在,**本地(`~/.hermes/skills/`)的版本优先**。
3445

35-
## 通过 config.yaml 配置外部 skills 目录
46+
## 其他 config.yaml 用法
3647

3748
如果希望全局使用 superpowers-zh skills,可以在 `~/.hermes/config.yaml` 中配置:
3849

scripts/verify-release.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ done
106106

107107
echo ""
108108
echo "─── C. --global:7 款应成功,其余应明确拒绝且退出码 1 ───"
109-
declare -a GLOBAL_OK=(claude codex openclaw windsurf opencode qwen qoder crush)
110-
declare -a GLOBAL_NO=(cursor kiro trae aider deerflow vscode hermes claw gemini antigravity codebuddy codearts cline kilocode)
109+
declare -a GLOBAL_OK=(claude codex openclaw windsurf opencode qwen qoder crush hermes)
110+
declare -a GLOBAL_NO=(cursor kiro trae aider deerflow vscode claw gemini antigravity codebuddy codearts cline kilocode)
111111
for tool in "${GLOBAL_OK[@]}"; do
112112
H=$(mktemp -d)
113113
if HOME="$H" node "$INS" --global --tool "$tool" >/dev/null 2>&1; then ok; else bad "--global $tool 应成功但失败"; fi

0 commit comments

Comments
 (0)