fix(installer): Aider 支持有两个都会导致「装了不生效」的错(#45 同类)

顺着 #45(Hermes 装错目录)和 #119(Qoder 映射表是编的)这条线,系统查了
我们自己那层工具支持。Aider 查出两处,都实测坐实,都是「装完看着成功、
实际不生效」。

## ① 真实 Aider 项目从来没被自动检测到过

detect 写的是 '.aider',即要求存在一个 `.aider/` 目录 —— 而 **Aider 不创建
这个目录**。它在项目根留下的是 `.aider.` 前缀的产物:

  .aider.conf.yml / .aider.chat.history.md / .aider.tags.cache.v3/

实测:造一个含这三样的目录跑 `npx superpowers-zh`,输出「未检测到任何已知
AI 编程工具」。而 docs/README.aider.md 一直写着「会自动检测 .aider.conf.yml
文件」—— 文档描述的是意图,代码做的是另一回事。

改为认这四个标记(保留 '.aider' 兼容)。

## ② CONVENTIONS.md 不会被 Aider 自动加载

代码注释和文档都写着「Aider 原生支持自动加载此文件」。官方文档
(aider.chat/docs/usage/conventions.html)说的是反的:必须
`aider --read CONVENTIONS.md`,或在 .aider.conf.yml 里写 `read: CONVENTIONS.md`。

最糟的是 docs 的「Skills 未生效」排障第 3 条写着「Aider 会自动读取
CONVENTIONS.md,无需额外配置」—— 用户卡住时来查文档,看到的正好是让他
继续卡住的那句。

改法照搬 #45 的做法:装完打印可直接用的两种激活方式,**不替用户改
.aider.conf.yml**(那是他们的文件)。docs 开头重写,把「还需一步」放最前面,
并注明 v1.7.9 及更早的说法是错的。

## 测试的盲区

verify-release.sh 的检测测试是 `mkdir .aider` 然后断言认出 Aider —— 拿代码
测代码,真实标记一个都没测。已补三个真实标记;顺带修了 case 分支:.yml 也
要按文件建,用目录冒充文件等于测了个假场景。

verify-release 90 -> 93 pass。

## 验证

- 只有 .aider.conf.yml 的目录:正确识别为 Aider,并打印激活提示
- 已有自写 CONVENTIONS.md:追加而不覆盖;卸载后逐字节恢复原内容
- 卸载:.aider 下残留 0 项
- audit.sh 166 pass / 0 warn / 0 fail、verify-release.sh 93 pass / 0 fail

## 范围

bin/superpowers-zh.js、docs/README.aider.md、scripts/verify-release.sh 均为
fork 自有(上游没有 installer 与 docs),零上游偏离。
This commit is contained in:
AI不止语
2026-08-12 18:03:28 +08:00
parent d544eb5505
commit be6dc8c252
3 changed files with 91 additions and 27 deletions

View File

@@ -71,7 +71,14 @@ const TARGETS = [
// 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' },
// Aider 两点都跟直觉相反,都是实测确认的:
// 1) Aider 不创建 `.aider/` 目录,它在项目根留下的是 `.aider.` 前缀的产物
// .aider.conf.yml / .aider.chat.history.md / .aider.tags.cache.v3/)。
// 原来 detect 写 '.aider' 永远匹配不上 —— 真实 Aider 项目从来没被自动检测到过。
// 2) CONVENTIONS.md **不会**被 Aider 自动加载。官方文档aider.chat/docs/usage/
// conventions.html明确要 `aider --read CONVENTIONS.md` 或在 .aider.conf.yml
// 写 `read: CONVENTIONS.md`。所以装完必须打印激活方式,否则又是「装了不生效」。
{ name: 'Aider', dir: '.aider/skills', detect: ['.aider.conf.yml', '.aider.chat.history.md', '.aider.tags.cache.v3', '.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' } },
// Hermes 官方文档:只自动加载 ~/.hermes/skills/"the primary directory and
@@ -373,7 +380,8 @@ ${skillList}
当任务匹配某个 skill 时,读取对应的 \`.aider/skills/<skill-name>/SKILL.md\` 并严格遵循其流程。
`;
// 写入 CONVENTIONS.mdAider 原生支持自动加载此文件)
// 写入 CONVENTIONS.md。注意:Aider **不会**自动加载这个文件(见 TARGETS 里的
// Aider 注释),所以写完必须告诉用户怎么激活,否则装了等于没装。
// 如果已有 CONVENTIONS.md追加而不覆盖
const convPath = resolve(projectDir, 'CONVENTIONS.md');
if (existsSync(convPath)) {
@@ -388,6 +396,18 @@ ${skillList}
writeFileSync(convPath, wrapWithSentinel(content), 'utf8');
console.log(` ✅ Aider: bootstrap -> ${convPath}`);
}
// 激活提示。不替用户改 .aider.conf.yml —— 那是他们的配置文件。
console.log('');
console.log(' ⚠️ Aider 不会自动加载 CONVENTIONS.md还需一步才生效');
console.log('');
console.log(' 每次启动时带上:');
console.log(' aider --read CONVENTIONS.md');
console.log('');
console.log(' 或写进 .aider.conf.yml 一劳永逸:');
console.log('');
console.log(' read: CONVENTIONS.md');
console.log('');
}
function generateGeminiBootstrap(baseDir, isGlobal) {

View File

@@ -2,14 +2,47 @@
在 [Aider](https://aider.chat) 中使用 superpowers-zh 的完整指南。
## 自动安装
## ⚠️ 先看这一条:装完还需要一步才生效
**Aider 不会自动加载 `CONVENTIONS.md`。** [官方文档](https://aider.chat/docs/usage/conventions.html)明确要求显式加载 —— 原文推荐 `aider --read CONVENTIONS.md`,或在配置里写 `read:` 项。
所以装完之后,二选一:
```bash
# 每次启动时带上
aider --read CONVENTIONS.md
```
```yaml
# 或写进 .aider.conf.yml一劳永逸
read: CONVENTIONS.md
```
**我们不替你改 `.aider.conf.yml`** —— 那是你的配置文件。安装器会在装完时把上面两条打印出来提醒你。
> 📌 v1.7.9 及更早版本的文档写着「Aider 会自动读取 CONVENTIONS.md无需额外配置」—— **那是错的**会让你以为装好了其实没生效。这是我们的错误v1.7.10 起更正。
## 安装
```bash
cd /your/project
npx superpowers-zh
npx superpowers-zh --tool aider
```
安装脚本会自动检测 `.aider.conf.yml` 文件并将 skills 复制到 `.aider/skills/` 目录。
会做两件事:
1. 把 20 个 skill 复制到 `.aider/skills/`
2. 生成(或追加)`CONVENTIONS.md`,里面是 skill 索引和触发规则,指向 `.aider/skills/<name>/SKILL.md`
### 关于自动检测
不带 `--tool` 时安装器会扫描项目里的工具标记。**Aider 不创建 `.aider/` 目录** —— 它在项目根留下的是 `.aider.` 前缀的产物,所以我们认这几个:
- `.aider.conf.yml`
- `.aider.chat.history.md`
- `.aider.tags.cache.v3/`
> 📌 v1.7.9 及更早只认 `.aider/` 这个目录,而 Aider 从不创建它 —— 也就是说**真实的 Aider 项目从来没被自动检测到过**,必须手动 `--tool aider`。同样在 v1.7.10 修正。
## 手动安装
@@ -18,26 +51,11 @@ git clone https://github.com/jnMetaCode/superpowers-zh.git
cp -r superpowers-zh/skills /your/project/.aider/skills
```
## 通过 CONVENTIONS.md 引用
> 手动复制不会生成 `CONVENTIONS.md`,你需要自己写一份索引并按上面的方式加载它。建议优先用 `npx superpowers-zh --tool aider`。
Aider 原生支持 `CONVENTIONS.md` 文件。在其中引用 skills
## 只加载部分 skill
```markdown
# 项目约定
## 工作方法论
本项目使用 superpowers-zh skills 作为工作方法论。
Skills 位于 `.aider/skills/` 目录,每个子目录的 SKILL.md 定义一个工作流。
- 新功能开发:先使用 brainstorming skill
- 编写代码:遵循 test-driven-development skill
- 调试问题:使用 systematic-debugging skill
```
## 通过 .aider.conf.yml 配置
`.aider.conf.yml` 中添加 read 配置来加载 skills
`CONVENTIONS.md` 是一份索引(约 4 KB由 Aider 常驻上下文,正文按需读取。如果你只想常驻少数几个 skill 的全文,也可以直接点名:
```yaml
read:
@@ -46,16 +64,37 @@ read:
- .aider/skills/systematic-debugging/SKILL.md
```
注意每个 SKILL.md 都会完整进入上下文,装 20 个的全文开销很大 —— 这正是我们默认走索引式 `CONVENTIONS.md` 的原因。
## 故障排查
### Skills 未生效
1. 确认 `.aider/skills/` 目录存在且包含 skill 文件夹
2. 确保在 `CONVENTIONS.md``.aider.conf.yml` 中引用了 skills
3. Aider 会自动读取 `CONVENTIONS.md`,无需额外配置
按顺序查:
1. **`CONVENTIONS.md` 被加载了吗?** 这是最常见的原因。Aider 启动后用 `/read` 看已加载的只读文件里有没有它。没有的话,回到本文开头那一步。
2. `.aider/skills/` 目录是否存在且包含 skill 子目录。
3. 如果用 `.aider.conf.yml``read:` 配置:确认 Aider 读的是你以为的那份配置。Aider 会依次找 home 目录、git 仓库根、当前目录下的 `.aider.conf.yml`
### 装完没看到激活提示
说明你用的是旧版本。升级:
```bash
npx superpowers-zh@latest --tool aider
```
## 卸载
```bash
npx superpowers-zh --uninstall
```
会删除 `.aider/skills/` 下装过的 skill并从 `CONVENTIONS.md` 中精确切除 superpowers-zh 段(保留你自己写的内容)。`.aider.conf.yml` 我们没动过,所以也不会去改 —— 如果你加过 `read: CONVENTIONS.md`,需要自己删。
## 获取帮助
- 提交 Issuehttps://github.com/jnMetaCode/superpowers-zh/issues
- 项目主页https://github.com/jnMetaCode/superpowers-zh
- Aider 文档https://aider.chat/docs/
- Aider conventions 文档https://aider.chat/docs/usage/conventions.html

View File

@@ -81,6 +81,9 @@ declare -a DETECT=(
".claude:Claude Code" ".cursor:Cursor" ".codex:Codex CLI"
".kiro:Kiro" ".trae:Trae" ".agents:Antigravity"
".openclaw:OpenClaw" ".windsurf:Windsurf" ".aider:Aider"
# Aider 的真实标记:它不创建 .aider/ 目录,留下的是 .aider. 前缀的产物。
# 只测 ".aider" 等于拿代码测代码 —— 真实 Aider 项目一个都匹配不上。
".aider.conf.yml:Aider" ".aider.chat.history.md:Aider" ".aider.tags.cache.v3:Aider"
".opencode:OpenCode" ".qwen:Qwen Code" ".hermes:Hermes Agent"
".claw:Claw Code" ".qoder:Qoder" ".codebuddy:CodeBuddy"
".codeartsdoer:CodeArts" ".clinerules:Cline" ".kilocode:Kilo Code"
@@ -92,7 +95,9 @@ for entry in "${DETECT[@]}"; do
marker="${entry%%:*}"; want="${entry#*:}"
T=$(mktemp -d); cd "$T"
case "$marker" in
*.md|*.json) mkdir -p "$(dirname "$marker")" 2>/dev/null; : > "$marker" ;;
# .yml 也要按「文件」建 —— .aider.conf.yml 是文件不是目录。existsSync 两者都
# 匹配得上,但用目录冒充文件等于测了个假场景,下次改检测逻辑就发现不了问题。
*.md|*.json|*.yml) mkdir -p "$(dirname "$marker")" 2>/dev/null; : > "$marker" ;;
*) mkdir -p "$marker" ;;
esac
got=$(node "$INS" 2>&1 | grep -oE '✅ [A-Za-z][A-Za-z ]*(\[|:)' | sed 's/✅ //; s/ *[:[]$//' | sort -u | tr '\n' ',' | sed 's/,$//')