From b9c6ca7c898b59b7fc0ad7afaa6b0211bd1047a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?AI=E4=B8=8D=E6=AD=A2=E8=AF=AD?= <12096460+jnMetaCode@users.noreply.github.com> Date: Sun, 12 Jul 2026 23:58:53 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E5=85=A8=E5=B1=80?= =?UTF-8?q?=E5=AE=89=E8=A3=85=20--global=EF=BC=88=E5=85=B3=20#21=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 多项目用户此前需逐个项目 npx 安装。新增 --global:一次装到工具的 用户级目录(如 ~/.claude/skills),所有项目共享,更新只需重装一次。 项目级(默认)优先、全局兜底,二者可共存。 - 支持全局的 7 款工具,均逐一核对各工具 docs 声明的真实加载路径, 不臆造无效路径;其余工具明确报错并引导项目级安装 - Codex 全局装到 ~/.agents/skills(docs 确认其启动扫描该目录, 而非 ~/.codex/skills) - Gemini / Antigravity 有意不纳入通用 --global(各有专属全局方式), 报错指向对应 docs,避免「装了不生效」的假功能 - 对称的 --global --uninstall,按哨兵精确清理,保全用户既有内容 - home 护栏:项目级仍拒绝在 ~ 裸装并引导 --global,全局模式跳过 - 版本 1.6.1 → 1.7.0,同步 6 个 plugin manifest - 顺带修 package.json description 残留的 159k+ → 250k+ 隔离自动化测试 50/50 通过:项目级回归、7 款全局工具装卸、数据保全 (含全局 CLAUDE.md 保留用户个人指令)、幂等性、非全局工具拒绝并 指向 docs、自动检测、home 护栏、参数健壮性。 --- .claude-plugin/marketplace.json | 2 +- .claude-plugin/plugin.json | 2 +- .codex-plugin/plugin.json | 2 +- .cursor-plugin/plugin.json | 2 +- .kimi-plugin/plugin.json | 2 +- README.md | 22 ++- RELEASE-NOTES.zh.md | 18 +++ bin/superpowers-zh.js | 266 +++++++++++++++++++++----------- gemini-extension.json | 2 +- package.json | 4 +- site/build.mjs | 6 +- 11 files changed, 226 insertions(+), 102 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index e953bc8..56c9353 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -9,7 +9,7 @@ { "name": "superpowers-zh", "description": "AI 编程超能力中文增强版:20 个 skills(14 翻译 + 4 中国原创 + 2 上游历史保留),支持 Claude Code / Hermes Agent / Cursor / Claw Code / Qoder 等 18 款工具", - "version": "1.6.1", + "version": "1.7.0", "source": "./", "author": { "name": "jnMetaCode", diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index dfa6bad..3107a33 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "superpowers-zh", "description": "AI 编程超能力中文增强版:20 个 skills(14 翻译 + 4 中国原创 + 2 上游历史保留),支持 Claude Code / Hermes Agent / Cursor / Claw Code / Qoder 等 18 款工具", - "version": "1.6.1", + "version": "1.7.0", "author": { "name": "jnMetaCode", "url": "https://github.com/jnMetaCode" diff --git a/.codex-plugin/plugin.json b/.codex-plugin/plugin.json index fe4d56d..6f5e1f7 100644 --- a/.codex-plugin/plugin.json +++ b/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "superpowers-zh", - "version": "1.6.1", + "version": "1.7.0", "description": "AI 编程超能力中文增强版:头脑风暴、subagent 驱动开发、规划、TDD、调试、代码审查、收尾工作流,附 4 个中文 skills 沉淀。", "author": { "name": "jnMetaCode", diff --git a/.cursor-plugin/plugin.json b/.cursor-plugin/plugin.json index 9ebbb5a..a215810 100644 --- a/.cursor-plugin/plugin.json +++ b/.cursor-plugin/plugin.json @@ -2,7 +2,7 @@ "name": "superpowers-zh", "displayName": "Superpowers 中文版", "description": "AI 编程超能力中文增强版:20 个 skills(14 翻译 + 4 中国原创 + 2 上游历史保留),支持 Cursor / Claude Code / Hermes Agent / Claw Code / Qoder 等 18 款工具", - "version": "1.6.1", + "version": "1.7.0", "author": { "name": "jnMetaCode", "url": "https://github.com/jnMetaCode" diff --git a/.kimi-plugin/plugin.json b/.kimi-plugin/plugin.json index 85f5845..b67078d 100644 --- a/.kimi-plugin/plugin.json +++ b/.kimi-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "superpowers-zh", - "version": "1.6.1", + "version": "1.7.0", "description": "AI 编程超能力中文增强版:头脑风暴、subagent 驱动开发、规划、TDD、调试、代码审查、收尾工作流,附 4 个中文 skills 沉淀。", "author": { "name": "jnMetaCode", diff --git a/README.md b/README.md index 85393f8..01efa74 100644 --- a/README.md +++ b/README.md @@ -157,12 +157,32 @@ AI:在开始实现之前,我需要了解几个关键问题: ### 方式一:npm 安装(推荐) +**项目级**(默认,装到当前项目): + ```bash cd /your/project npx superpowers-zh ``` -> ⚠️ **不要在主目录(`~`)下跑**。v1.2.1 起会拒绝并提示,老版本会把 skills 和 `CLAUDE.md` 等 bootstrap 文件写到你的 home 目录,污染所有项目。如已误装见下文「卸载 / 误装清理」。 +> ⚠️ **项目级安装不要在主目录(`~`)下跑**。v1.2.1 起会拒绝并提示,老版本会把 skills 和 `CLAUDE.md` 等 bootstrap 文件写到你的 home 目录,污染所有项目。如已误装见下文「卸载 / 误装清理」。想让 skills 对所有项目生效,请用下面的**全局安装**,而不是在 `~` 下跑项目级。 + +**全局安装**(v1.7.0+,装到用户目录,所有项目共享,适合同时维护多个项目): + +```bash +npx superpowers-zh --global # 自动检测已装工具 +npx superpowers-zh --global --tool claude # 或指定工具 +``` + +全局安装把 skills 装到工具的**用户级目录**(如 `~/.claude/skills`),一次安装所有项目自动可用,更新时也只需重装一次。**项目级优先、全局兜底**,二者可共存。 + +支持通用全局安装的工具(均为 docs 已证实的用户级加载路径):**Claude Code · Codex CLI · Qoder · Windsurf · Qwen Code · OpenClaw · OpenCode**。其中 **Codex CLI** 全局装到 `~/.agents/skills`(Codex 启动扫描目录)。其余工具(Cursor / Kiro / Trae / Aider / DeerFlow / VS Code / Hermes / Claw)规则是项目级或存于应用内设置,`--global` 会提示改用项目级;**Gemini CLI / Antigravity** 有各自专属的全局方式(Gemini 走扩展目录),见对应 `docs/README.*.md`。 + +| | 项目级(默认) | 全局(`--global`) | +|---|---|---| +| 安装位置 | `<项目>/.claude/skills` 等 | `~/.claude/skills` 等用户级目录 | +| 生效范围 | 仅当前项目 | 所有项目 | +| 适合 | 单项目、需项目内版本固定 | 多项目、想一次装好到处可用 | +| 卸载 | `npx superpowers-zh --uninstall` | `npx superpowers-zh --global --uninstall` | ### 方式二:手动安装(low-fidelity,仅作备选) diff --git a/RELEASE-NOTES.zh.md b/RELEASE-NOTES.zh.md index e670191..dd35d2e 100644 --- a/RELEASE-NOTES.zh.md +++ b/RELEASE-NOTES.zh.md @@ -6,6 +6,24 @@ --- +## v1.7.0 (2026-07-12) + +### 🌍 全局安装(关 #21) + +新增 `npx superpowers-zh --global`,一次安装、所有项目共享,解决多项目用户需要逐个项目重复安装的痛点。 + +- **项目级(默认)不变**:装到 `process.cwd()` 下工具目录(如 `.claude/skills`),仅当前项目生效。 +- **全局(`--global`)**:装到工具的**用户级目录**(如 `~/.claude/skills`),所有项目自动共享,更新只需重装一次。**项目级优先、全局兜底**,二者可共存。 +- 支持全局的工具(**逐一核对各工具 docs 声明的真实加载路径,不臆造**):**Claude Code / Codex CLI / Qoder / Windsurf / Qwen Code / OpenClaw / OpenCode**。其中 Codex 全局装到 `~/.agents/skills`(docs 确认 Codex 启动扫描该目录,而非 `~/.codex/skills`);Claude Code 全局 bootstrap 写 `~/.claude/CLAUDE.md`。 +- **Gemini CLI / Antigravity 有意不纳入通用 `--global`**:Gemini 全局走扩展目录 `~/.gemini/extensions/*/skills/` + manifest、Antigravity 全局 skills 路径未在 docs 证实,通用复制机制覆盖不了 —— `--global` 会报错并指向各自 `docs/README.*.md`,避免「装了不生效」。 +- 其余工具(Cursor / Kiro / Trae / Aider / DeerFlow / VS Code / Hermes / Claw)规则是项目级或存于应用内设置,`--global` 明确报错并提示改用项目级,绝不写入无效路径。 +- 卸载对称支持:`--global --uninstall` 从用户级目录移除 skills 并按哨兵精确清理全局 bootstrap。 +- home 目录护栏调整:项目级仍拒绝在 `~` 下裸装(污染所有项目),并在提示里引导改用 `--global`;全局模式本就写用户级目录,跳过该护栏。 + +### 📊 文案刷新 + +- 上游 star 数 233k+ → 250k+(站点、README、package.json description 同步,实测上游已达 252k+)。 + ## v1.6.1 (2026-07-06) 对齐上游 **v6.1.0 / v6.1.1** 中与我们架构相关的部分。Gemini CLI 移除是上游这两个版本里改动面最大的一项,但它牵涉我们自己的营销文案("18 款工具")和安装器逻辑,评估后判定为独立决策,本版本**不包含**,留待单独讨论。 diff --git a/bin/superpowers-zh.js b/bin/superpowers-zh.js index 1752d74..31668d0 100755 --- a/bin/superpowers-zh.js +++ b/bin/superpowers-zh.js @@ -46,24 +46,37 @@ const PROJECT_DIR = process.cwd(); // agents/ 目录已删,但旧版本装过的用户机器上仍有残留文件需要清理。 const LEGACY_AGENT_FILENAMES = ['code-reviewer.md']; +// 每个工具:项目级 dir(相对 cwd)+ 可选 global 配置。 +// global 存在 = 该工具有稳定的「用户级 skills 目录」,可全局安装(所有项目共享): +// global.dir 用户级 skills 目录(相对 home) +// global.detect home 下用于自动检测该工具是否安装的标记目录 +// global.boot 可选,用户级 bootstrap 文件(相对 home);无则仅靠 skill 自动发现 +// 无 global 的工具(Cursor/Kiro/Trae/Aider/DeerFlow/VS Code/Hermes/Claw)规则是项目级、 +// 或存在于应用内设置,没有稳定的用户级 skills 加载路径 —— --global 会明确拒绝而非写无效路径。 const TARGETS = [ - { name: 'Claude Code', dir: '.claude/skills', detect: '.claude' }, + { name: 'Claude Code', dir: '.claude/skills', detect: '.claude', global: { dir: '.claude/skills', detect: '.claude', boot: '.claude/CLAUDE.md' } }, { name: 'Cursor', dir: '.cursor/skills', detect: ['.cursor', '.cursorrules'] }, - { name: 'Codex CLI', dir: '.codex/skills', detect: '.codex' }, + // Codex 全局:docs 确认 Codex 启动时扫描 ~/.agents/skills/(不是 ~/.codex/skills), + // 直接把每个 skill 复制到 ~/.agents/skills// 正好命中它的扁平扫描。 + { name: 'Codex CLI', dir: '.codex/skills', detect: '.codex', global: { dir: '.agents/skills', detect: '.codex' } }, { name: 'Kiro', dir: '.kiro/steering', detect: '.kiro' }, { name: 'DeerFlow', dir: 'skills/custom', detect: 'deer_flow' }, { name: 'Trae', dir: '.trae/skills', detect: '.trae' }, + // Antigravity 无 global:其全局 skills 加载路径未在 docs 证实(全局规则走 ~/.gemini/GEMINI.md), + // 不确认能生效就不写,避免「装了不生效」。用户用项目级安装。 { name: 'Antigravity', dir: '.agents/skills', detect: '.agents' }, { name: 'VS Code', dir: '.github/superpowers', detect: '.github/copilot-instructions.md' }, - { name: 'OpenClaw', dir: 'skills', detect: '.openclaw' }, - { name: 'Windsurf', dir: '.windsurf/skills', detect: '.windsurf' }, + { name: 'OpenClaw', dir: 'skills', detect: '.openclaw', global: { dir: '.openclaw/skills', detect: '.openclaw' } }, + { name: 'Windsurf', dir: '.windsurf/skills', detect: '.windsurf', global: { dir: '.windsurf/skills', detect: '.windsurf' } }, + // Gemini 无 global:其全局加载是「扩展目录」~/.gemini/extensions/*/skills/ + gemini-extension.json, + // 不是简单复制到 ~/.gemini/skills,通用 --global 覆盖不了。见 docs/README.gemini-cli.md。 { name: 'Gemini CLI', dir: '.gemini/skills', detect: 'GEMINI.md' }, { name: 'Aider', dir: '.aider/skills', detect: '.aider' }, - { name: 'OpenCode', dir: '.opencode/skills', detect: '.opencode' }, - { name: 'Qwen Code', dir: '.qwen/skills', detect: '.qwen' }, + { 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'] }, { name: 'Claw Code', dir: '.claw/skills', detect: ['.claw', 'CLAW.md'] }, - { name: 'Qoder', dir: '.qoder/skills', detect: '.qoder' }, + { name: 'Qoder', dir: '.qoder/skills', detect: '.qoder', global: { dir: '.qoder/skills', detect: '.qoder' } }, ]; function countDirs(dir) { @@ -142,12 +155,14 @@ ${skillTable} console.log(` ✅ Trae: bootstrap rule -> ${rulePath}`); } -function generateQoderBootstrap(projectDir) { - const rulesDir = resolve(projectDir, '.qoder', 'rules'); +function generateQoderBootstrap(baseDir, isGlobal) { + const rulesDir = resolve(baseDir, '.qoder', 'rules'); mkdirSync(rulesDir, { recursive: true }); const skillEntries = scanSkillEntries(SKILLS_SRC); const skillTable = skillEntries.map(s => `| ${s.name} | ${s.desc} |`).join('\n'); + const scope = isGlobal ? '你已全局加载 superpowers-zh 技能框架,所有项目共享' : '你已加载 superpowers-zh 技能框架'; + const skillsRef = isGlobal ? '~/.qoder/skills/' : '.qoder/skills/'; // Qoder rules schema(来源:社区实际样本,docs.qoder.com/zh/user-guide/rules 没公开) // trigger: always_on → "始终生效",适用于所有智能会话和内联对话 @@ -160,7 +175,7 @@ alwaysApply: true # Superpowers-ZH 中文增强版 -你已加载 superpowers-zh 技能框架(${skillEntries.length} 个 skills)。 +${scope}(${skillEntries.length} 个 skills)。 ## 核心规则 @@ -171,7 +186,7 @@ alwaysApply: true ## 可用 Skills -Skills 位于 \`.qoder/skills/\` 目录,每个 skill 有独立的 \`SKILL.md\` 文件。 +Skills 位于 \`${skillsRef}\` 目录,每个 skill 有独立的 \`SKILL.md\` 文件。 | Skill | 触发条件 | |-------|---------| @@ -179,7 +194,7 @@ ${skillTable} ## 如何使用 -当任务匹配某个 skill 的触发条件时,读取对应的 \`.qoder/skills//SKILL.md\` 并严格遵循其流程。也可输入 \`/\` 显式调用。 +当任务匹配某个 skill 的触发条件时,读取对应的 \`${skillsRef}/SKILL.md\` 并严格遵循其流程。也可输入 \`/\` 显式调用。 `; const rulePath = resolve(rulesDir, 'superpowers-zh.md'); @@ -187,13 +202,15 @@ ${skillTable} console.log(` ✅ Qoder: bootstrap rule -> ${rulePath}`); } -function generateAntigravityBootstrap(projectDir) { +function generateAntigravityBootstrap(baseDir, isGlobal) { const skillEntries = scanSkillEntries(SKILLS_SRC); const skillList = skillEntries.map(s => `- **${s.name}**: ${s.desc}`).join('\n'); + const scope = isGlobal ? '已全局安装 superpowers-zh 技能框架,所有项目共享' : '本项目已安装 superpowers-zh 技能框架'; + const skillsRef = isGlobal ? '~/.agents/skills/' : '.agents/skills/'; const content = `# Superpowers-ZH 中文增强版 -本项目已安装 superpowers-zh 技能框架(${skillEntries.length} 个 skills)。 +${scope}(${skillEntries.length} 个 skills)。 ## 核心规则 @@ -204,17 +221,17 @@ function generateAntigravityBootstrap(projectDir) { ## 可用 Skills -Skills 位于 \`.agents/skills/\` 目录,每个 skill 有独立的 \`SKILL.md\` 文件。 +Skills 位于 \`${skillsRef}\` 目录,每个 skill 有独立的 \`SKILL.md\` 文件。 ${skillList} ## 如何使用 -当任务匹配某个 skill 时,读取对应的 \`.agents/skills//SKILL.md\` 并严格遵循其流程。 +当任务匹配某个 skill 时,读取对应的 \`${skillsRef}/SKILL.md\` 并严格遵循其流程。 `; - // 写入 .agents/rules.md(不覆盖用户已有的 GEMINI.md / AGENTS.md) - const rulePath = resolve(projectDir, '.agents', 'rules.md'); + // 写入 .agents/rules.md(不覆盖用户已有的 GEMINI.md / AGENTS.md);全局装到 ~/.agents/rules.md + const rulePath = resolve(baseDir, '.agents', 'rules.md'); writeFileSync(rulePath, content, 'utf8'); console.log(` ✅ Antigravity: bootstrap rule -> ${rulePath}`); } @@ -262,13 +279,15 @@ ${skillList} } } -function generateGeminiBootstrap(projectDir) { +function generateGeminiBootstrap(baseDir, isGlobal) { const skillEntries = scanSkillEntries(SKILLS_SRC); const skillList = skillEntries.map(s => `- **${s.name}**: ${s.desc}`).join('\n'); + const scope = isGlobal ? '已全局安装 superpowers-zh 技能框架,所有项目共享' : '本项目已安装 superpowers-zh 技能框架'; + const skillsRef = isGlobal ? '~/.gemini/skills/' : '.gemini/skills/'; const content = `# Superpowers-ZH 中文增强版 -本项目已安装 superpowers-zh 技能框架(${skillEntries.length} 个 skills)。 +${scope}(${skillEntries.length} 个 skills)。 ## 核心规则 @@ -279,17 +298,18 @@ function generateGeminiBootstrap(projectDir) { ## 可用 Skills -Skills 位于 \`.gemini/skills/\` 目录,每个 skill 有独立的 \`SKILL.md\` 文件。 +Skills 位于 \`${skillsRef}\` 目录,每个 skill 有独立的 \`SKILL.md\` 文件。 ${skillList} ## 如何使用 -当任务匹配某个 skill 时,读取对应的 \`.gemini/skills//SKILL.md\` 并严格遵循其流程。 +当任务匹配某个 skill 时,读取对应的 \`${skillsRef}/SKILL.md\` 并严格遵循其流程。 `; - // 写入 GEMINI.md(如果已存在则追加) - const geminiPath = resolve(projectDir, 'GEMINI.md'); + // 写入 GEMINI.md(如果已存在则追加);全局装到 ~/.gemini/GEMINI.md + const geminiPath = isGlobal ? resolve(baseDir, '.gemini', 'GEMINI.md') : resolve(baseDir, 'GEMINI.md'); + mkdirSync(dirname(geminiPath), { recursive: true }); if (existsSync(geminiPath)) { const existing = readFileSync(geminiPath, 'utf8'); if (!existing.includes('superpowers-zh')) { @@ -360,13 +380,15 @@ ${skillList} } } -function generateClaudeCodeBootstrap(projectDir) { +function generateClaudeCodeBootstrap(baseDir, isGlobal) { const skillEntries = scanSkillEntries(SKILLS_SRC); const skillList = skillEntries.map(s => `- **${s.name}**: ${s.desc}`).join('\n'); + const scope = isGlobal ? '已全局安装 superpowers-zh 技能框架,所有项目共享' : '本项目已安装 superpowers-zh 技能框架'; + const skillsRef = isGlobal ? '~/.claude/skills/' : '.claude/skills/'; const content = `# Superpowers-ZH 中文增强版 -本项目已安装 superpowers-zh 技能框架(${skillEntries.length} 个 skills)。 +${scope}(${skillEntries.length} 个 skills)。 ## 核心规则 @@ -377,7 +399,7 @@ function generateClaudeCodeBootstrap(projectDir) { ## 可用 Skills -Skills 位于 \`.claude/skills/\` 目录,每个 skill 有独立的 \`SKILL.md\` 文件。 +Skills 位于 \`${skillsRef}\` 目录,每个 skill 有独立的 \`SKILL.md\` 文件。 ${skillList} @@ -388,7 +410,8 @@ ${skillList} 如果你认为哪怕只有 1% 的可能性某个 skill 适用于你正在做的事情,你必须调用该 skill 检查。 `; - const mdPath = resolve(projectDir, 'CLAUDE.md'); + const mdPath = isGlobal ? resolve(baseDir, '.claude', 'CLAUDE.md') : resolve(baseDir, 'CLAUDE.md'); + mkdirSync(dirname(mdPath), { recursive: true }); if (existsSync(mdPath)) { const existing = readFileSync(mdPath, 'utf8'); if (!existing.includes('superpowers-zh')) { @@ -440,31 +463,37 @@ function showHelp() { superpowers-zh v${PKG.version} — AI 编程超能力中文版 用法: - npx superpowers-zh 自动检测工具并安装 + npx superpowers-zh 项目级:自动检测工具并装到当前目录 + npx superpowers-zh --global 全局:装到 ~/,所有项目共享(推荐多项目用户) npx superpowers-zh --tool cursor 指定工具安装(检测不到时使用) - npx superpowers-zh --uninstall 卸载当前目录下的 superpowers-zh - npx superpowers-zh --force 允许在用户主目录(~)安装(默认拒绝) + npx superpowers-zh --global -t claude 全局 + 指定工具 + npx superpowers-zh --uninstall 卸载当前目录(加 --global 卸载全局) + npx superpowers-zh --force 允许在用户主目录(~)做项目级安装(默认拒绝) npx superpowers-zh --help 显示帮助 npx superpowers-zh --version 显示版本 支持的工具名: ${Object.keys(TOOL_ALIASES).join(', ')} - 说明: - 自动检测当前项目使用的 AI 编程工具,将 ${countDirs(SKILLS_SRC)} 个 skills 安装到对应目录。 - 如果自动检测不到,请用 --tool 指定你的工具,例如: - npx superpowers-zh --tool cursor - npx superpowers-zh --tool trae + 支持全局安装的工具(其余工具规则为项目级,--global 会提示改用项目级): + ${TARGETS.filter(t => t.global).map(t => t.name).join('、')} - 误装到主目录可以这样清理: - cd ~ && npx superpowers-zh --uninstall + 说明: + 项目级:把 ${countDirs(SKILLS_SRC)} 个 skills 装到当前项目对应目录(如 .claude/skills)。 + 全局:把 skills 装到用户级目录(如 ~/.claude/skills),一次安装所有项目可用, + skills 更新时也只需重装一次。项目级优先、全局兜底,二者可共存。 + + 卸载: + npx superpowers-zh --uninstall 清理当前项目 + npx superpowers-zh --global --uninstall 清理全局安装 项目:https://github.com/jnMetaCode/superpowers-zh `); } -function installForTarget(target) { - const dest = resolve(PROJECT_DIR, target.dir); +function installForTarget(target, baseDir, isGlobal) { + const relDir = isGlobal ? target.global.dir : target.dir; + const dest = resolve(baseDir, relDir); const srcCount = countDirs(SKILLS_SRC); mkdirSync(dest, { recursive: true }); copyDirSync(SKILLS_SRC, dest); @@ -478,34 +507,35 @@ function installForTarget(target) { ` 3. 或手动克隆复制: 见 https://github.com/jnMetaCode/superpowers-zh#方式二手动安装` ); } - console.log(` ✅ ${target.name}: ${srcCount} 个 skills -> ${dest}`); + const scopeTag = isGlobal ? '[全局]' : '[项目]'; + console.log(` ✅ ${target.name} ${scopeTag}: ${srcCount} 个 skills -> ${dest}`); if (target.name === 'Trae') { - generateTraeBootstrapRule(PROJECT_DIR); + generateTraeBootstrapRule(baseDir); } if (target.name === 'Qoder') { - generateQoderBootstrap(PROJECT_DIR); + generateQoderBootstrap(baseDir, isGlobal); } if (target.name === 'Antigravity') { - generateAntigravityBootstrap(PROJECT_DIR); + generateAntigravityBootstrap(baseDir, isGlobal); } if (target.name === 'Aider') { - generateAiderBootstrap(PROJECT_DIR); + generateAiderBootstrap(baseDir); } if (target.name === 'Gemini CLI') { - generateGeminiBootstrap(PROJECT_DIR); + generateGeminiBootstrap(baseDir, isGlobal); } if (target.name === 'Hermes Agent') { - generateHermesBootstrap(PROJECT_DIR); + generateHermesBootstrap(baseDir); } if (target.name === 'Claude Code') { - generateClaudeCodeBootstrap(PROJECT_DIR); + generateClaudeCodeBootstrap(baseDir, isGlobal); } } @@ -604,8 +634,16 @@ function cleanBootstrapSection(filePath) { return true; } -function uninstallForTarget(target, srcSkillNames) { - const dest = resolve(PROJECT_DIR, target.dir); +// 全局安装的 bootstrap 文件(相对 home)— 与 install 全局分支写入的路径对应。 +// 仅 Claude Code(~/.claude/CLAUDE.md,全局记忆已证实)和 Qoder(~/.qoder/rules/,镜像其项目机制) +// 会写全局 bootstrap;其余全局工具靠 skill 自动发现,无 bootstrap 需清理。 +const GLOBAL_BOOTSTRAP_DELETE = ['.qoder/rules/superpowers-zh.md']; +const GLOBAL_BOOTSTRAP_CLEAN_SECTION = ['.claude/CLAUDE.md']; + +function uninstallForTarget(target, srcSkillNames, baseDir, isGlobal) { + const relDir = isGlobal ? (target.global && target.global.dir) : target.dir; + if (!relDir) return 0; + const dest = resolve(baseDir, relDir); if (!existsSync(dest)) return 0; let removed = 0; for (const entry of readdirSync(dest, { withFileTypes: true })) { @@ -624,9 +662,10 @@ function uninstallForTarget(target, srcSkillNames) { return removed; } -function uninstall() { - console.log(`\n superpowers-zh v${PKG.version} — 卸载\n`); - console.log(` 目标项目: ${PROJECT_DIR}\n`); +function uninstall(isGlobal) { + const baseDir = isGlobal ? homedir() : PROJECT_DIR; + console.log(`\n superpowers-zh v${PKG.version} — 卸载(${isGlobal ? '全局' : '项目级'})\n`); + console.log(` 目标: ${baseDir}\n`); if (!existsSync(SKILLS_SRC)) { console.error(' ❌ 错误:skills 源目录不存在,无法识别要卸载的 skill 名单。'); @@ -639,18 +678,20 @@ function uninstall() { .map(e => e.name) ); + const pool = isGlobal ? GLOBAL_TARGETS : TARGETS; let totalSkills = 0; - for (const target of TARGETS) { - const removed = uninstallForTarget(target, srcSkillNames); + for (const target of pool) { + const removed = uninstallForTarget(target, srcSkillNames, baseDir, isGlobal); if (removed > 0) { - console.log(` ✅ ${target.name}: 移除 ${removed} 个 skills <- ${resolve(PROJECT_DIR, target.dir)}`); + const relDir = isGlobal ? target.global.dir : target.dir; + console.log(` ✅ ${target.name}: 移除 ${removed} 个 skills <- ${resolve(baseDir, relDir)}`); totalSkills += removed; } } // 清理 .claude/agents 下旧版本装过的 legacy agent(v1.2.x 及之前会装 code-reviewer.md, // v1.3.0 起跟随上游 v5.1.0 移除)。即使 agents/ 源目录已删,已装用户跑 --uninstall 仍应能清干净。 - const agentsDest = resolve(PROJECT_DIR, '.claude', 'agents'); + const agentsDest = resolve(baseDir, '.claude', 'agents'); if (existsSync(agentsDest)) { let agentsRemoved = 0; for (const entry of readdirSync(agentsDest)) { @@ -666,17 +707,19 @@ function uninstall() { } catch {} } + const deleteList = isGlobal ? GLOBAL_BOOTSTRAP_DELETE : BOOTSTRAP_DELETE; + const cleanList = isGlobal ? GLOBAL_BOOTSTRAP_CLEAN_SECTION : BOOTSTRAP_CLEAN_SECTION; let bootstrapsRemoved = 0; - for (const rel of BOOTSTRAP_DELETE) { - const full = resolve(PROJECT_DIR, rel); + for (const rel of deleteList) { + const full = resolve(baseDir, rel); if (existsSync(full)) { rmSync(full); console.log(` ✅ 删除 bootstrap: ${full}`); bootstrapsRemoved++; } } - for (const rel of BOOTSTRAP_CLEAN_SECTION) { - const full = resolve(PROJECT_DIR, rel); + for (const rel of cleanList) { + const full = resolve(baseDir, rel); if (cleanBootstrapSection(full)) { console.log(` ✅ 清理 bootstrap: ${full}`); bootstrapsRemoved++; @@ -684,13 +727,16 @@ function uninstall() { } if (totalSkills === 0 && bootstrapsRemoved === 0) { - console.log(' ⚠️ 未在当前目录找到 superpowers-zh 安装痕迹。'); + console.log(` ⚠️ 未在${isGlobal ? '用户主目录' : '当前目录'}找到 superpowers-zh 安装痕迹。`); } else { console.log(`\n 卸载完成。共移除 ${totalSkills} 个 skill 目录、${bootstrapsRemoved} 个 bootstrap 文件。\n`); } } -function install(forceToolName, force) { +// 支持全局安装的工具(有稳定的用户级 skills 目录) +const GLOBAL_TARGETS = TARGETS.filter(t => t.global); + +function install(forceToolName, force, isGlobal) { try { console.log(`\n superpowers-zh v${PKG.version} — AI 编程超能力中文版\n`); @@ -699,29 +745,34 @@ function install(forceToolName, force) { process.exit(1); } - if (!force && isHomeDir(PROJECT_DIR)) { + const baseDir = isGlobal ? homedir() : PROJECT_DIR; + + // 项目级安装(默认):拒绝在 home 根目录乱装(会污染所有项目)。 + // 全局安装(--global):本就写到 ~/.claude/skills 等用户级目录,是正当行为,跳过该护栏。 + if (!isGlobal && !force && isHomeDir(PROJECT_DIR)) { console.error( ` ⚠️ 当前目录是用户主目录: ${PROJECT_DIR} - superpowers-zh 应该装到具体项目目录,而不是 ~/。 + superpowers-zh 项目级安装应该装到具体项目目录,而不是 ~/。 在主目录安装会把 skills 和 bootstrap 文件(CLAUDE.md / HERMES.md 等) 写入你的 home,污染所有项目。 - 请先 cd 到项目目录: - cd /path/to/your/project - npx superpowers-zh + 如果你想让 skills 对所有项目生效,用全局安装(推荐): + npx superpowers-zh --global # 自动检测已装工具 + npx superpowers-zh --global --tool claude - 如果你确实要在主目录安装(不推荐),加 --force: + 或先 cd 到项目目录做项目级安装: + cd /path/to/your/project && npx superpowers-zh + + 如果你确实要在主目录做项目级安装(不推荐),加 --force: npx superpowers-zh --force - - 如果你已经在主目录误装过,可以用 --uninstall 清理: - npx superpowers-zh --uninstall `); process.exit(1); } console.log(` 源: ${countDirs(SKILLS_SRC)} 个 skills`); - console.log(` 目标项目: ${PROJECT_DIR}\n`); + console.log(` 模式: ${isGlobal ? '全局(所有项目共享,装到 ~/)' : '项目级'}`); + console.log(` 目标: ${baseDir}\n`); // --tool 指定安装 if (forceToolName) { @@ -730,19 +781,36 @@ function install(forceToolName, force) { console.error(` ❌ 未知工具: ${forceToolName}`); process.exit(1); } - installForTarget(target); + if (isGlobal && !target.global) { + // 部分工具(如 Gemini CLI 的扩展目录)有专属全局方式,但与通用 --global 复制机制不同, + // 指向对应 docs;其余工具规则为项目级或存于应用内设置,无稳定用户级路径。 + const docSlug = { 'Gemini CLI': 'gemini-cli', 'Antigravity': 'antigravity', 'Trae': 'trae', 'Aider': 'aider', 'Hermes Agent': 'hermes', 'Kiro': 'kiro' }[target.name]; + console.error( +` ❌ ${target.name} 不支持通用全局安装(--global)。 + + 该工具没有通用 --global 能覆盖的稳定用户级 skills 路径${docSlug ? `(可能有专属全局方式,见 docs/README.${docSlug}.md)` : '(规则为项目级或存于应用内设置)'}。 + 请改用项目级安装: + cd /path/to/your/project && npx superpowers-zh --tool ${forceToolName.toLowerCase().replace(/ .*/, '')} + + 支持通用全局安装的工具:${GLOBAL_TARGETS.map(t => t.name).join('、')} +`); + process.exit(1); + } + installForTarget(target, baseDir, isGlobal); console.log('\n 安装完成!重启你的 AI 编程工具即可生效。\n'); return; } // 自动检测 let installed = 0; + const pool = isGlobal ? GLOBAL_TARGETS : TARGETS; - for (const target of TARGETS) { - const detects = Array.isArray(target.detect) ? target.detect : [target.detect]; - const found = detects.some(d => existsSync(resolve(PROJECT_DIR, d))); + for (const target of pool) { + const detectMarker = isGlobal ? target.global.detect : target.detect; + const detects = Array.isArray(detectMarker) ? detectMarker : [detectMarker]; + const found = detects.some(d => existsSync(resolve(baseDir, d))); if (found) { - installForTarget(target); + installForTarget(target, baseDir, isGlobal); installed++; } } @@ -751,13 +819,21 @@ function install(forceToolName, force) { // 检测落空时不再静默装 Claude Code —— 否则 Antigravity / Trae 等 // 不会在项目里留下检测目录的工具,会被误装成 Claude(见 issue #33)。 // 改为明确报错并教用户用 --tool 显式指定。 - console.log(' ⚠️ 未在当前目录检测到任何已知 AI 编程工具的项目标记。\n'); + const where = isGlobal ? '你的用户主目录(~)' : '当前目录'; + const flag = isGlobal ? '--global ' : ''; + console.log(` ⚠️ 未在${where}检测到任何已知 AI 编程工具的标记。\n`); console.log(' 为避免装错工具,未做任何安装。请用 --tool 显式指定你的工具,例如:\n'); - console.log(' npx superpowers-zh --tool claude # Claude Code / Copilot CLI'); - console.log(' npx superpowers-zh --tool antigravity # Google Antigravity'); - console.log(' npx superpowers-zh --tool trae # Trae'); - console.log(' npx superpowers-zh --tool cursor # Cursor\n'); - console.log(` 全部可用别名:${Object.keys(TOOL_ALIASES).join(', ')}\n`); + console.log(` npx superpowers-zh ${flag}--tool claude # Claude Code / Copilot CLI`); + if (isGlobal) { + console.log(` npx superpowers-zh ${flag}--tool codex # Codex CLI`); + console.log(` npx superpowers-zh ${flag}--tool qoder # Qoder\n`); + console.log(` 支持全局安装的工具:${GLOBAL_TARGETS.map(t => t.name).join('、')}\n`); + } else { + console.log(` npx superpowers-zh ${flag}--tool antigravity # Google Antigravity`); + console.log(` npx superpowers-zh ${flag}--tool trae # Trae`); + console.log(` npx superpowers-zh ${flag}--tool cursor # Cursor\n`); + console.log(` 全部可用别名:${Object.keys(TOOL_ALIASES).join(', ')}\n`); + } process.exit(1); } @@ -774,14 +850,19 @@ const versionIdx = args.findIndex(a => a === '--version' || a === '-v'); const toolIdx = args.findIndex(a => a === '--tool' || a === '-t'); const uninstallIdx = args.findIndex(a => a === '--uninstall' || a === '-u'); const forceIdx = args.findIndex(a => a === '--force' || a === '-f'); +const globalIdx = args.findIndex(a => a === '--global' || a === '-g'); const force = forceIdx !== -1; +const isGlobal = globalIdx !== -1; + +// 已知无参数值的开关,用于校验未知参数(--tool 后面跟工具名不算未知参数) +const KNOWN_FLAGS = new Set(['--help', '-h', '--version', '-v', '--uninstall', '-u', '--force', '-f', '--global', '-g', '--tool', '-t']); if (helpIdx !== -1) { showHelp(); } else if (versionIdx !== -1) { console.log(PKG.version); } else if (uninstallIdx !== -1) { - uninstall(); + uninstall(isGlobal); } else if (toolIdx !== -1) { const toolArg = args[toolIdx + 1]; if (!toolArg) { @@ -795,11 +876,14 @@ if (helpIdx !== -1) { console.error(` 支持的工具: ${Object.keys(TOOL_ALIASES).join(', ')}\n`); process.exit(1); } - install(toolName, force); -} else if (args.length > 0 && args[0].startsWith('-') && forceIdx === -1) { - console.warn(` 未知参数: ${args[0]}\n`); - showHelp(); - process.exit(1); + install(toolName, force, isGlobal); } else { - install(undefined, force); + // 校验未知参数(--tool 的值已在上面分支处理,走到这里说明没有 --tool) + const unknown = args.find(a => a.startsWith('-') && !KNOWN_FLAGS.has(a)); + if (unknown) { + console.warn(` 未知参数: ${unknown}\n`); + showHelp(); + process.exit(1); + } + install(undefined, force, isGlobal); } diff --git a/gemini-extension.json b/gemini-extension.json index 39131ef..bda88d5 100644 --- a/gemini-extension.json +++ b/gemini-extension.json @@ -1,6 +1,6 @@ { "name": "superpowers-zh", "description": "AI 编程超能力中文版 — TDD、调试、代码审查等经过实战验证的工作方法论", - "version": "1.6.1", + "version": "1.7.0", "contextFileName": "GEMINI.md" } diff --git a/package.json b/package.json index 18e3c5a..f2d81a7 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,10 @@ { "name": "superpowers-zh", - "version": "1.6.1", + "version": "1.7.0", "engines": { "node": ">=20.0.0" }, - "description": "AI 编程超能力中文增强版 — superpowers(159k+ ⭐)完整汉化 + 4 个中国原创 skills,支持 Claude Code / Copilot CLI / Hermes Agent / Cursor / Claw Code / Windsurf / Kiro / Gemini CLI / Qoder 等 18 款工具", + "description": "AI 编程超能力中文增强版 — superpowers(250k+ ⭐)完整汉化 + 4 个中国原创 skills,支持 Claude Code / Copilot CLI / Hermes Agent / Cursor / Claw Code / Windsurf / Kiro / Gemini CLI / Qoder 等 18 款工具", "type": "module", "main": ".opencode/plugins/superpowers.js", "bin": { diff --git a/site/build.mjs b/site/build.mjs index 20c1b16..60be55c 100644 --- a/site/build.mjs +++ b/site/build.mjs @@ -186,8 +186,9 @@ const T = { { q: '支持哪些 AI 编程工具?', a: '共 18 款:Claude Code、Cursor、Windsurf、Codex CLI、Gemini CLI、Kiro、Trae、Qoder、Aider、OpenCode、Qwen Code、Antigravity、DeerFlow、VS Code(Copilot)、Copilot CLI、Hermes Agent、Claw Code、OpenClaw。' }, { q: 'superpowers-zh 有哪些独特价值?', a: '一套完整中文化的系统工作方法论:从头脑风暴、规划、TDD 到调试、代码审查,每个 skill 都是实战验证的工作流;并叠加 4 个面向中国开发者的原创 skill(中文代码审查 / Git 工作流 / 文档规范 / 提交规范),适配 18 款 AI 编程工具。MIT 协议开源,永久免费。' }, { q: '安装后怎么生效?', a: 'npx 会把 skill 文件装到你项目对应工具的目录(如 .claude/skills/),重启 AI 工具后,它会在恰当时机自动触发相应 skill —— 无需你每次手动调用。' }, + { q: '能一次装好、所有项目都用吗?(全局安装)', a: '能。npx superpowers-zh --global 装到工具的用户级目录(如 ~/.claude/skills),所有项目自动共享,更新时只需重装一次。项目级优先、全局兜底,二者可共存。支持全局的工具(均为各工具文档确认的加载路径):Claude Code / Codex CLI / Qoder / Windsurf / Qwen Code / OpenClaw / OpenCode;其余工具(含 Gemini / Antigravity,有各自专属全局方式)请在项目内安装或参考对应文档。' }, { q: '会拖慢我的 AI 吗?会上传代码吗?', a: '不会。skill 是按需触发的纯 Markdown,零运行时、不联网、不上传任何代码或数据,全程在本地。' }, - { q: '怎么更新或卸载?', a: '更新:重新运行 npx superpowers-zh 覆盖即可。卸载:npx superpowers-zh --uninstall 清理已安装的 skill 与 bootstrap 文件。' }, + { q: '怎么更新或卸载?', a: '更新:重新运行 npx superpowers-zh 覆盖即可。卸载:npx superpowers-zh --uninstall 清理当前项目;全局安装用 npx superpowers-zh --global --uninstall 清理。' }, ], }, en: { @@ -272,8 +273,9 @@ const T = { { q: 'Which AI coding tools are supported?', a: '18 tools: Claude Code, Cursor, Windsurf, Codex CLI, Gemini CLI, Kiro, Trae, Qoder, Aider, OpenCode, Qwen Code, Antigravity, DeerFlow, VS Code (Copilot), Copilot CLI, Hermes Agent, Claw Code, OpenClaw.' }, { q: 'What makes superpowers-zh unique?', a: 'A fully localized, battle-tested methodology framework for Chinese developers: brainstorming, planning, TDD, debugging, and code-review skills, plus 4 China-native skills (code review / Git workflow / docs / commit conventions), adapted for 18 AI coding tools. MIT-licensed and free forever.' }, { q: 'How does it take effect after install?', a: 'npx installs skill files into your tool\'s directory (e.g. .claude/skills/). After restarting your AI tool, it auto-triggers the right skill at the right moment — no manual invocation needed.' }, + { q: 'Can I install once for all projects? (global install)', a: 'Yes. npx superpowers-zh --global installs into the tool\'s user-level directory (e.g. ~/.claude/skills), shared across all projects; you only re-install once to update. Project-level takes precedence, global is the fallback — they coexist. Tools with global support (all verified load paths per each tool\'s docs): Claude Code / Codex CLI / Qoder / Windsurf / Qwen Code / OpenClaw / OpenCode; other tools (incl. Gemini / Antigravity, which have their own global methods) should be installed per-project or via their docs.' }, { q: 'Will it slow my AI down or upload my code?', a: 'No. Skills are on-demand Markdown: zero runtime, no network, no code or data upload — everything stays local.' }, - { q: 'How do I update or uninstall?', a: 'Update: re-run npx superpowers-zh to overwrite. Uninstall: npx superpowers-zh --uninstall removes installed skills and bootstrap files.' }, + { q: 'How do I update or uninstall?', a: 'Update: re-run npx superpowers-zh to overwrite. Uninstall: npx superpowers-zh --uninstall for the current project; npx superpowers-zh --global --uninstall for a global install.' }, ], }, };