diff --git a/README.md b/README.md index 588953c..3df3bbb 100644 --- a/README.md +++ b/README.md @@ -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`) | |---|---|---| diff --git a/README.zh-Hant.md b/README.zh-Hant.md index 45773fa..5053b9f 100644 --- a/README.zh-Hant.md +++ b/README.zh-Hant.md @@ -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`) | |---|---|---| diff --git a/bin/superpowers-zh.js b/bin/superpowers-zh.js index 88500a8..774560b 100755 --- a/bin/superpowers-zh.js +++ b/bin/superpowers-zh.js @@ -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) { + // 全局模式不写 bootstrap:Hermes 的用户级指令文件约定未在 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') { diff --git a/docs/README.hermes.md b/docs/README.hermes.md index 870cfa7..c53317c 100644 --- a/docs/README.hermes.md +++ b/docs/README.hermes.md @@ -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` 中配置: diff --git a/scripts/verify-release.sh b/scripts/verify-release.sh index 8b030e5..70c0a4e 100755 --- a/scripts/verify-release.sh +++ b/scripts/verify-release.sh @@ -106,8 +106,8 @@ done echo "" echo "─── C. --global:7 款应成功,其余应明确拒绝且退出码 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