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 专属工具名。
This commit is contained in:
AI不止语
2026-08-08 14:55:21 +08:00
parent f290def463
commit 441d024cd6
5 changed files with 71 additions and 27 deletions

View File

@@ -133,7 +133,7 @@ AI在开始实现之前我需要了解几个关键问题
|------|------|:---:|:---:|
| [Claude Code](https://claude.ai/code) | CLI | `npx superpowers-zh` | `.claude/skills/` |
| [Copilot CLI](https://githubnext.com/projects/copilot-cli) | CLI | `npx superpowers-zh --tool copilot` | `.claude/skills/` |
| [Hermes Agent](https://github.com/NousResearch/hermes-agent) | CLI | `npx superpowers-zh --tool hermes` | `.hermes/skills/` |
| [Hermes Agent](https://github.com/NousResearch/hermes-agent) | CLI | `npx superpowers-zh --global --tool hermes` | `~/.hermes/skills/` |
| [Cursor](https://cursor.sh) | IDE | `npx superpowers-zh` | `.cursor/skills/` |
| [Windsurf](https://codeium.com/windsurf) | IDE | `npx superpowers-zh` | `.windsurf/skills/` |
| [Kiro](https://kiro.dev) | IDE | `npx superpowers-zh` | `.kiro/steering/` |
@@ -214,7 +214,7 @@ npx superpowers-zh --global --tool claude # 或指定工具
全局安装把 skills 装到工具的**用户级目录**(如 `~/.claude/skills`),一次安装所有项目自动可用,更新时也只需重装一次。**项目级优先、全局兜底**,二者可共存。
支持通用全局安装的工具(均为 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`
支持通用全局安装的工具(均为 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`
| | 项目级(默认) | 全局(`--global` |
|---|---|---|

View File

@@ -133,7 +133,7 @@ AI在開始實作之前我需要了解幾個關鍵問題
|------|------|:---:|:---:|
| [Claude Code](https://claude.ai/code) | CLI | `npx superpowers-zh` | `.claude/skills/` |
| [Copilot CLI](https://githubnext.com/projects/copilot-cli) | CLI | `npx superpowers-zh --tool copilot` | `.claude/skills/` |
| [Hermes Agent](https://github.com/NousResearch/hermes-agent) | CLI | `npx superpowers-zh --tool hermes` | `.hermes/skills/` |
| [Hermes Agent](https://github.com/NousResearch/hermes-agent) | CLI | `npx superpowers-zh --global --tool hermes` | `~/.hermes/skills/` |
| [Cursor](https://cursor.sh) | IDE | `npx superpowers-zh` | `.cursor/skills/` |
| [Windsurf](https://codeium.com/windsurf) | IDE | `npx superpowers-zh` | `.windsurf/skills/` |
| [Kiro](https://kiro.dev) | IDE | `npx superpowers-zh` | `.kiro/steering/` |
@@ -214,7 +214,7 @@ npx superpowers-zh --global --tool claude # 或指定工具
全域安裝把 skills 裝到工具的**使用者級目錄**(如 `~/.claude/skills`),一次安裝所有專案自動可用,更新時也只需重裝一次。**專案級優先、全域兜底**,二者可共存。
支援通用全域安裝的工具(均為 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`
支援通用全域安裝的工具(均為 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`
| | 專案級(預設) | 全域(`--global` |
|---|---|---|

View File

@@ -51,7 +51,7 @@ const LEGACY_AGENT_FILENAMES = ['code-reviewer.md'];
// global.dir 用户级 skills 目录(相对 home
// global.detect home 下用于自动检测该工具是否安装的标记目录
// global.boot 可选,用户级 bootstrap 文件(相对 home无则仅靠 skill 自动发现
// 无 global 的工具Cursor/Kiro/Trae/Aider/DeerFlow/VS Code/Hermes/Claw/Cline/Kilo Code规则是项目级、
// 无 global 的工具Cursor/Kiro/Trae/Aider/DeerFlow/VS Code/Claw/Cline/Kilo Code规则是项目级、
// 或存在于应用内设置,没有稳定的用户级 skills 加载路径 —— --global 会明确拒绝而非写无效路径。
const TARGETS = [
{ name: 'Claude Code', dir: '.claude/skills', detect: '.claude', global: { dir: '.claude/skills', detect: '.claude', boot: '.claude/CLAUDE.md' } },
@@ -74,7 +74,11 @@ const TARGETS = [
{ name: 'Aider', dir: '.aider/skills', detect: '.aider' },
{ name: 'OpenCode', dir: '.opencode/skills', detect: '.opencode', global: { dir: '.config/opencode/skills', detect: '.config/opencode' } },
{ name: 'Qwen Code', dir: '.qwen/skills', detect: '.qwen', global: { dir: '.qwen/skills', detect: '.qwen' } },
{ name: 'Hermes Agent', dir: '.hermes/skills', detect: ['.hermes', 'HERMES.md', '.hermes.md'] },
// Hermes 官方文档:只自动加载 ~/.hermes/skills/"the primary directory and
// source of truth"),项目级目录不被自动发现,外部目录必须写进
// ~/.hermes/config.yaml 的 skills.external_dirs。所以全局才是能直接生效的装法
// 项目级仍保留(便于随仓库分发),但装完会打印需要粘贴的 config.yaml 片段。
{ name: 'Hermes Agent', dir: '.hermes/skills', detect: ['.hermes', 'HERMES.md', '.hermes.md'], global: { dir: '.hermes/skills', detect: '.hermes' } },
{ name: 'Claw Code', dir: '.claw/skills', detect: ['.claw', 'CLAW.md'] },
{ name: 'Qoder', dir: '.qoder/skills', detect: '.qoder', global: { dir: '.qoder/skills', detect: '.qoder' } },
{ name: 'CodeBuddy', dir: '.codebuddy/skills', detect: ['.codebuddy', 'CODEBUDDY.md'] },
@@ -431,7 +435,17 @@ ${skillList}
}
}
function generateHermesBootstrap(projectDir) {
function generateHermesBootstrap(projectDir, isGlobal) {
// 全局模式不写 bootstrapHermes 的用户级指令文件约定未在 docs 证实,
// 往 $HOME 根目录写 HERMES.md 是猜路径 + 污染主目录。~/.hermes/skills/ 里的
// skill 靠 name/description 被 skills_list / skill_view 发现,本就不依赖 bootstrap。
if (isGlobal) {
console.log(' Hermes 全局安装不写 bootstrap 文件(其用户级指令文件约定未证实)。');
console.log(' skills 已在 ~/.hermes/skills/,可用 skills_list / skill_view 发现。');
console.log(' 想让它在项目里自动触发,在该项目跑一次项目级安装以生成 HERMES.md。');
return;
}
const skillEntries = scanSkillEntries(SKILLS_SRC);
const skillList = skillEntries.map(s => `- **${s.name}**: ${s.desc}`).join('\n');
@@ -485,6 +499,25 @@ ${skillList}
writeFileSync(hermesPath, wrapWithSentinel(content), 'utf8');
console.log(` ✅ Hermes Agent: bootstrap -> ${hermesPath}`);
}
// 项目级安装 Hermes 认不到 —— 必须显式登记到 config.yaml。不替用户改配置
// (那是他们的文件),改为打印可直接粘贴的片段。见 issue #45。
if (!isGlobal) {
const abs = resolve(projectDir, '.hermes', 'skills');
console.log('');
console.log(' ⚠️ Hermes 只自动扫描 ~/.hermes/skills/,不会发现项目级目录。');
console.log(' 二选一让它生效:');
console.log('');
console.log(' A) 改用全局安装(推荐,装完即生效):');
console.log(' npx superpowers-zh --global --tool hermes');
console.log('');
console.log(' B) 保留项目级,把这段加进 ~/.hermes/config.yaml');
console.log('');
console.log(' skills:');
console.log(' external_dirs:');
console.log(` - ${abs}`);
console.log('');
}
}
function generateClaudeCodeBootstrap(baseDir, isGlobal) {
@@ -732,7 +765,7 @@ function installForTarget(target, baseDir, isGlobal) {
}
if (target.name === 'Hermes Agent') {
generateHermesBootstrap(baseDir);
generateHermesBootstrap(baseDir, isGlobal);
}
if (target.name === 'Claude Code') {

View File

@@ -2,37 +2,48 @@
在 [Hermes Agent](https://github.com/NousResearch/hermes-agent) 中使用 superpowers-zh 的完整指南。
## 自动安装
## ⚠️ 先看这一条:必须装到全局,否则不生效
[Hermes 官方文档](https://hermes-agent.nousresearch.com/docs/user-guide/features/skills)明确Hermes **只自动加载 `~/.hermes/skills/`**(原文称其为 "the primary directory and source of truth"**项目级目录不会被自动发现**。
所以推荐的装法是全局:
```bash
npx superpowers-zh --global --tool hermes
```
装到 `~/.hermes/skills/`,装完即生效,用 `skills_list` 就能看到 20 个 skill。
> 📌 v1.7.8 及更早版本只支持项目级安装(装到 `<项目>/.hermes/skills/`)—— 那个目录 Hermes 根本不读等于装了不生效。这是我们的实现错误v1.7.9 起修正。见 [#45](https://github.com/jnMetaCode/superpowers-zh/issues/45)。
## 如果你确实要项目级安装
项目级的好处是 skills 可以随仓库一起分发。但**必须显式登记**,否则 Hermes 看不见。
```bash
cd /your/project
npx superpowers-zh --tool hermes
```
安装脚本会将 20 个 skills 复制到 `.hermes/skills/` 目录,并自动生成 `HERMES.md` 引导文件(含工具映射表和 skills 列表)。
安装器会打印出你需要粘贴的配置片段,形如:
如果项目中已存在 `.hermes` 目录或 `HERMES.md` 文件,也会被自动检测到:
```bash
npx superpowers-zh # 自动检测
```yaml
skills:
external_dirs:
- /your/project/.hermes/skills
```
## 手动安装
把它加进 `~/.hermes/config.yaml`。路径支持 `~` 展开和 `${VAR}` 环境变量替换;**配置里不存在的路径会被静默跳过**,所以写错了不会报错,只会"没生效"。
```bash
git clone https://github.com/jnMetaCode/superpowers-zh.git
cp -r superpowers-zh/skills /your/project/.hermes/skills
```
**我们不替你改 `config.yaml`** —— 那是你的配置文件。
## 通过 HERMES.md 引导
项目级安装还会生成 `HERMES.md` 引导文件(含核心规则和 skills 列表),让 Hermes 在合适时机主动检查 skill。全局安装**不写**这个文件 —— Hermes 的用户级指令文件约定没有公开文档,我们不猜路径、也不往你的主目录里写东西。
Hermes Agent 在会话开始时自动加载项目根目录下的 `HERMES.md`(或 `.hermes.md`)作为上下文。安装器会自动生成此文件,内容包括:
## 同名冲突
- 工具映射表Claude Code → Hermes Agent 工具名称)
- 所有可用 skills 的列表和描述
- 核心规则和使用说明
如果同一个 skill 名在 `~/.hermes/skills/` 和某个 `external_dirs` 目录里都存在,**本地(`~/.hermes/skills/`)的版本优先**。
## 通过 config.yaml 配置外部 skills 目录
## 其他 config.yaml 用法
如果希望全局使用 superpowers-zh skills可以在 `~/.hermes/config.yaml` 中配置:

View File

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